2017-12-15 15:12:01 +01:00
|
|
|
// (C) Copyright 2015 Martin Dougiamas
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
import { Injectable } from '@angular/core';
|
2018-03-01 16:55:49 +01:00
|
|
|
import { CoreSitesProvider } from '@providers/sites';
|
|
|
|
import { CoreSite } from '@classes/site';
|
2017-12-15 15:12:01 +01:00
|
|
|
import * as moment from 'moment';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Service that provides some features regarding course overview.
|
|
|
|
*/
|
|
|
|
@Injectable()
|
|
|
|
export class CoreCoursesMyOverviewProvider {
|
2018-01-29 10:05:20 +01:00
|
|
|
static EVENTS_LIMIT = 20;
|
|
|
|
static EVENTS_LIMIT_PER_COURSE = 10;
|
2018-01-12 14:28:46 +01:00
|
|
|
protected ROOT_CACHE_KEY = 'myoverview:';
|
2017-12-15 15:12:01 +01:00
|
|
|
|
2018-01-29 10:05:20 +01:00
|
|
|
constructor(private sitesProvider: CoreSitesProvider) { }
|
2017-12-15 15:12:01 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get calendar action events for the given course.
|
|
|
|
*
|
|
|
|
* @param {number} courseId Only events in this course.
|
|
|
|
* @param {number} [afterEventId] The last seen event id.
|
|
|
|
* @param {string} [siteId] Site ID. If not defined, use current site.
|
|
|
|
* @return {Promise<{events: any[], canLoadMore: number}>} Promise resolved when the info is retrieved.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
getActionEventsByCourse(courseId: number, afterEventId?: number, siteId?: string):
|
|
|
|
Promise<{ events: any[], canLoadMore: number }> {
|
2017-12-15 15:12:01 +01:00
|
|
|
|
|
|
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
2018-01-29 10:05:20 +01:00
|
|
|
const time = moment().subtract(14, 'days').unix(), // Check two weeks ago.
|
2017-12-15 15:12:01 +01:00
|
|
|
data: any = {
|
|
|
|
timesortfrom: time,
|
|
|
|
courseid: courseId,
|
|
|
|
limitnum: CoreCoursesMyOverviewProvider.EVENTS_LIMIT_PER_COURSE
|
|
|
|
},
|
|
|
|
preSets = {
|
|
|
|
cacheKey: this.getActionEventsByCourseCacheKey(courseId)
|
|
|
|
};
|
|
|
|
|
|
|
|
if (afterEventId) {
|
|
|
|
data.aftereventid = afterEventId;
|
|
|
|
}
|
|
|
|
|
2018-01-29 10:05:20 +01:00
|
|
|
return site.read('core_calendar_get_action_events_by_course', data, preSets).then((courseEvents): any => {
|
2017-12-15 15:12:01 +01:00
|
|
|
if (courseEvents && courseEvents.events) {
|
|
|
|
return this.treatCourseEvents(courseEvents, time);
|
|
|
|
}
|
2018-01-29 10:05:20 +01:00
|
|
|
|
2017-12-15 15:12:01 +01:00
|
|
|
return Promise.reject(null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get cache key for get calendar action events for the given course value WS call.
|
|
|
|
*
|
|
|
|
* @param {number} courseId Only events in this course.
|
|
|
|
* @return {string} Cache key.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
protected getActionEventsByCourseCacheKey(courseId: number): string {
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.getActionEventsByCoursesCacheKey() + ':' + courseId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get calendar action events for a given list of courses.
|
|
|
|
*
|
|
|
|
* @param {number[]} courseIds Course IDs.
|
|
|
|
* @param {string} [siteId] Site ID. If not defined, use current site.
|
|
|
|
* @return {Promise<{[s: string]: {events: any[], canLoadMore: number}}>} Promise resolved when the info is retrieved.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
getActionEventsByCourses(courseIds: number[], siteId?: string): Promise<{ [s: string]:
|
|
|
|
{ events: any[], canLoadMore: number } }> {
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
2018-01-29 10:05:20 +01:00
|
|
|
const time = moment().subtract(14, 'days').unix(), // Check two weeks ago.
|
2017-12-15 15:12:01 +01:00
|
|
|
data = {
|
|
|
|
timesortfrom: time,
|
|
|
|
courseids: courseIds,
|
|
|
|
limitnum: CoreCoursesMyOverviewProvider.EVENTS_LIMIT_PER_COURSE
|
|
|
|
},
|
|
|
|
preSets = {
|
|
|
|
cacheKey: this.getActionEventsByCoursesCacheKey()
|
|
|
|
};
|
|
|
|
|
2018-01-29 10:05:20 +01:00
|
|
|
return site.read('core_calendar_get_action_events_by_courses', data, preSets).then((events): any => {
|
2017-12-15 15:12:01 +01:00
|
|
|
if (events && events.groupedbycourse) {
|
2018-01-29 10:05:20 +01:00
|
|
|
const courseEvents = {};
|
2017-12-15 15:12:01 +01:00
|
|
|
|
|
|
|
events.groupedbycourse.forEach((course) => {
|
|
|
|
courseEvents[course.courseid] = this.treatCourseEvents(course, time);
|
|
|
|
});
|
|
|
|
|
|
|
|
return courseEvents;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.reject(null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get cache key for get calendar action events for a given list of courses value WS call.
|
|
|
|
*
|
|
|
|
* @return {string} Cache key.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
protected getActionEventsByCoursesCacheKey(): string {
|
2018-01-12 14:28:46 +01:00
|
|
|
return this.ROOT_CACHE_KEY + 'bycourse';
|
2017-12-15 15:12:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get calendar action events based on the timesort value.
|
|
|
|
*
|
|
|
|
* @param {number} [afterEventId] The last seen event id.
|
|
|
|
* @param {string} [siteId] Site ID. If not defined, use current site.
|
|
|
|
* @return {Promise<{events: any[], canLoadMore: number}>} Promise resolved when the info is retrieved.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
getActionEventsByTimesort(afterEventId: number, siteId?: string): Promise<{ events: any[], canLoadMore: number }> {
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
2018-01-29 10:05:20 +01:00
|
|
|
const time = moment().subtract(14, 'days').unix(), // Check two weeks ago.
|
2017-12-15 15:12:01 +01:00
|
|
|
data: any = {
|
|
|
|
timesortfrom: time,
|
|
|
|
limitnum: CoreCoursesMyOverviewProvider.EVENTS_LIMIT
|
|
|
|
},
|
|
|
|
preSets = {
|
|
|
|
cacheKey: this.getActionEventsByTimesortCacheKey(afterEventId, data.limitnum),
|
|
|
|
getCacheUsingCacheKey: true,
|
|
|
|
uniqueCacheKey: true
|
|
|
|
};
|
|
|
|
|
|
|
|
if (afterEventId) {
|
|
|
|
data.aftereventid = afterEventId;
|
|
|
|
}
|
|
|
|
|
2018-01-29 10:05:20 +01:00
|
|
|
return site.read('core_calendar_get_action_events_by_timesort', data, preSets).then((events): any => {
|
2017-12-15 15:12:01 +01:00
|
|
|
if (events && events.events) {
|
2018-01-29 10:05:20 +01:00
|
|
|
const canLoadMore = events.events.length >= data.limitnum ? events.lastid : undefined;
|
2017-12-15 15:12:01 +01:00
|
|
|
|
|
|
|
// Filter events by time in case it uses cache.
|
|
|
|
events = events.events.filter((element) => {
|
|
|
|
return element.timesort >= time;
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
events: events,
|
|
|
|
canLoadMore: canLoadMore
|
|
|
|
};
|
|
|
|
}
|
2018-01-29 10:05:20 +01:00
|
|
|
|
2017-12-15 15:12:01 +01:00
|
|
|
return Promise.reject(null);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get prefix cache key for calendar action events based on the timesort value WS calls.
|
|
|
|
*
|
|
|
|
* @return {string} Cache key.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
protected getActionEventsByTimesortPrefixCacheKey(): string {
|
2018-01-12 14:28:46 +01:00
|
|
|
return this.ROOT_CACHE_KEY + 'bytimesort:';
|
2017-12-15 15:12:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get cache key for get calendar action events based on the timesort value WS call.
|
|
|
|
*
|
|
|
|
* @param {number} [afterEventId] The last seen event id.
|
|
|
|
* @param {number} [limit] Limit num of the call.
|
|
|
|
* @return {string} Cache key.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
protected getActionEventsByTimesortCacheKey(afterEventId?: number, limit?: number): string {
|
2017-12-15 15:12:01 +01:00
|
|
|
afterEventId = afterEventId || 0;
|
|
|
|
limit = limit || 0;
|
2018-01-29 10:05:20 +01:00
|
|
|
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.getActionEventsByTimesortPrefixCacheKey() + afterEventId + ':' + limit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Invalidates get calendar action events for a given list of courses WS call.
|
|
|
|
*
|
|
|
|
* @param {string} [siteId] Site ID to invalidate. If not defined, use current site.
|
|
|
|
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
invalidateActionEventsByCourses(siteId?: string): Promise<any> {
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
|
|
|
return site.invalidateWsCacheForKeyStartingWith(this.getActionEventsByCoursesCacheKey());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Invalidates get calendar action events based on the timesort value WS call.
|
|
|
|
*
|
|
|
|
* @param {string} [siteId] Site ID to invalidate. If not defined, use current site.
|
|
|
|
* @return {Promise<any>} Promise resolved when the data is invalidated.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
invalidateActionEventsByTimesort(siteId?: string): Promise<any> {
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
|
|
|
return site.invalidateWsCacheForKeyStartingWith(this.getActionEventsByTimesortPrefixCacheKey());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns whether or not My Overview is available for a certain site.
|
|
|
|
*
|
|
|
|
* @param {string} [siteId] Site ID. If not defined, current site.
|
|
|
|
* @return {Promise<boolean>} Promise resolved with true if available, resolved with false or rejected otherwise.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
isAvailable(siteId?: string): Promise<boolean> {
|
2017-12-15 15:12:01 +01:00
|
|
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
|
|
|
return site.wsAvailable('core_calendar_get_action_events_by_courses');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if My Overview is disabled in a certain site.
|
|
|
|
*
|
|
|
|
* @param {CoreSite} [site] Site. If not defined, use current site.
|
|
|
|
* @return {boolean} Whether it's disabled.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
isDisabledInSite(site?: CoreSite): boolean {
|
2017-12-15 15:12:01 +01:00
|
|
|
site = site || this.sitesProvider.getCurrentSite();
|
2018-01-29 10:05:20 +01:00
|
|
|
|
2018-03-23 11:57:13 +01:00
|
|
|
return site.isFeatureDisabled('CoreMainMenuDelegate_CoreCourses');
|
2017-12-15 15:12:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if My Overview is available and not disabled.
|
|
|
|
*
|
|
|
|
* @return {Promise<boolean>} Promise resolved with true if enabled, resolved with false otherwise.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
isEnabled(): Promise<boolean> {
|
2017-12-15 15:12:01 +01:00
|
|
|
if (!this.isDisabledInSite()) {
|
|
|
|
return this.isAvailable().catch(() => {
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
2018-01-29 10:05:20 +01:00
|
|
|
|
2017-12-15 15:12:01 +01:00
|
|
|
return Promise.resolve(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles course events, filtering and treating if more can be loaded.
|
|
|
|
*
|
|
|
|
* @param {any} course Object containing response course events info.
|
|
|
|
* @param {number} timeFrom Current time to filter events from.
|
|
|
|
* @return {{events: any[], canLoadMore: number}} Object with course events and last loaded event id if more can be loaded.
|
|
|
|
*/
|
2018-01-29 10:05:20 +01:00
|
|
|
protected treatCourseEvents(course: any, timeFrom: number): { events: any[], canLoadMore: number } {
|
|
|
|
const canLoadMore: number =
|
2017-12-15 15:12:01 +01:00
|
|
|
course.events.length >= CoreCoursesMyOverviewProvider.EVENTS_LIMIT_PER_COURSE ? course.lastid : undefined;
|
|
|
|
|
|
|
|
// Filter events by time in case it uses cache.
|
|
|
|
course.events = course.events.filter((element) => {
|
|
|
|
return element.timesort >= timeFrom;
|
|
|
|
});
|
|
|
|
|
|
|
|
return {
|
|
|
|
events: course.events,
|
|
|
|
canLoadMore: canLoadMore
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|