Merge pull request #1765 from crazyserver/MOBILE-1979

Mobile 1979
main
Juan Leyva 2019-02-18 12:09:19 +01:00 committed by GitHub
commit 8ecf48caa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 594 additions and 190 deletions

View File

@ -23,6 +23,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
import { AddonModAssignProvider } from './assign'; import { AddonModAssignProvider } from './assign';
@ -61,7 +62,8 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider, private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
private utils: CoreUtilsProvider, private submissionDelegate: AddonModAssignSubmissionDelegate, private utils: CoreUtilsProvider, private submissionDelegate: AddonModAssignSubmissionDelegate,
private gradesHelper: CoreGradesHelperProvider, timeUtils: CoreTimeUtilsProvider) { private gradesHelper: CoreGradesHelperProvider, timeUtils: CoreTimeUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModAssignSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModAssignSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -202,6 +204,9 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
return []; return [];
})); }));
// Sync offline logs.
promises.push(this.logHelper.syncIfNeeded(AddonModAssignProvider.COMPONENT, assignId, siteId));
syncPromise = Promise.all(promises).then((results) => { syncPromise = Promise.all(promises).then((results) => {
const submissions = results[0], const submissions = results[0],
grades = results[1]; grades = results[1];

View File

@ -23,6 +23,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCommentsProvider } from '@core/comments/providers/comments'; import { CoreCommentsProvider } from '@core/comments/providers/comments';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
import { CoreGradesProvider } from '@core/grades/providers/grades'; import { CoreGradesProvider } from '@core/grades/providers/grades';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModAssignSubmissionDelegate } from './submission-delegate'; import { AddonModAssignSubmissionDelegate } from './submission-delegate';
import { AddonModAssignOfflineProvider } from './assign-offline'; import { AddonModAssignOfflineProvider } from './assign-offline';
import { CoreSiteWSPreSets } from '@classes/site'; import { CoreSiteWSPreSets } from '@classes/site';
@ -68,7 +69,8 @@ export class AddonModAssignProvider {
private timeUtils: CoreTimeUtilsProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private timeUtils: CoreTimeUtilsProvider, private appProvider: CoreAppProvider, private utils: CoreUtilsProvider,
private userProvider: CoreUserProvider, private submissionDelegate: AddonModAssignSubmissionDelegate, private userProvider: CoreUserProvider, private submissionDelegate: AddonModAssignSubmissionDelegate,
private gradesProvider: CoreGradesProvider, private filepoolProvider: CoreFilepoolProvider, private gradesProvider: CoreGradesProvider, private filepoolProvider: CoreFilepoolProvider,
private assignOffline: AddonModAssignOfflineProvider, private commentsProvider: CoreCommentsProvider) { private assignOffline: AddonModAssignOfflineProvider, private commentsProvider: CoreCommentsProvider,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModAssignProvider'); this.logger = logger.getInstance('AddonModAssignProvider');
} }
@ -976,13 +978,11 @@ export class AddonModAssignProvider {
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logGradingView(assignId: number, siteId?: string): Promise<any> { logGradingView(assignId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { assignid: assignId
assignid: assignId };
};
return site.write('mod_assign_view_grading_table', params); return this.logHelper.log('mod_assign_view_grading_table', params, AddonModAssignProvider.COMPONENT, assignId, siteId);
});
} }
/** /**
@ -993,13 +993,11 @@ export class AddonModAssignProvider {
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(assignId: number, siteId?: string): Promise<any> { logView(assignId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { assignid: assignId
assignid: assignId };
};
return site.write('mod_assign_view_assign', params); return this.logHelper.log('mod_assign_view_assign', params, AddonModAssignProvider.COMPONENT, assignId, siteId);
});
} }
/** /**

View File

@ -22,6 +22,7 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
/** /**
* A book chapter inside the toc list. * A book chapter inside the toc list.
@ -64,7 +65,8 @@ export class AddonModBookProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider,
private fileProvider: CoreFileProvider, private filepoolProvider: CoreFilepoolProvider, private http: Http, private fileProvider: CoreFileProvider, private filepoolProvider: CoreFilepoolProvider, private http: Http,
private utils: CoreUtilsProvider, private courseProvider: CoreCourseProvider, private domUtils: CoreDomUtilsProvider) { private utils: CoreUtilsProvider, private courseProvider: CoreCourseProvider, private domUtils: CoreDomUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModBookProvider'); this.logger = logger.getInstance('AddonModBookProvider');
} }
@ -378,14 +380,15 @@ export class AddonModBookProvider {
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} chapterId Chapter ID. * @param {string} chapterId Chapter ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number, chapterId: string): Promise<any> { logView(id: number, chapterId: string, siteId?: string): Promise<any> {
const params = { const params = {
bookid: id, bookid: id,
chapterid: chapterId chapterid: chapterId
}; };
return this.sitesProvider.getCurrentSite().write('mod_book_view_book', params); return this.logHelper.log('mod_book_view_book', params, AddonModBookProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -15,6 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
/** /**
* Service that provides some features for chats. * Service that provides some features for chats.
@ -24,7 +25,8 @@ export class AddonModChatProvider {
static COMPONENT = 'mmaModChat'; static COMPONENT = 'mmaModChat';
static POLL_INTERVAL = 4000; static POLL_INTERVAL = 4000;
constructor(private sitesProvider: CoreSitesProvider, private userProvider: CoreUserProvider) {} constructor(private sitesProvider: CoreSitesProvider, private userProvider: CoreUserProvider,
private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Get a chat. * Get a chat.
@ -77,15 +79,16 @@ export class AddonModChatProvider {
/** /**
* Report a chat as being viewed. * Report a chat as being viewed.
* *
* @param {number} chatId Chat instance ID. * @param {number} id Chat instance ID.
* @return {Promise<any>} Promise resolved when the WS call is executed. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(chatId: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
chatid: chatId chatid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_chat_view_chat', params); return this.logHelper.log('mod_chat_view_chat', params, AddonModChatProvider.COMPONENT, id, siteId);
} }
/** /**

View File

@ -17,6 +17,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModChoiceOfflineProvider } from './offline'; import { AddonModChoiceOfflineProvider } from './offline';
/** /**
@ -38,7 +39,7 @@ export class AddonModChoiceProvider {
constructor(private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, constructor(private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider,
private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider, private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider,
private choiceOffline: AddonModChoiceOfflineProvider) {} private choiceOffline: AddonModChoiceOfflineProvider, private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Check if results can be seen by a student. The student can see the results if: * Check if results can be seen by a student. The student can see the results if:
@ -346,14 +347,15 @@ export class AddonModChoiceProvider {
* Report the choice as being viewed. * Report the choice as being viewed.
* *
* @param {string} id Choice ID. * @param {string} id Choice ID.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: string): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
choiceid: id choiceid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_choice_view_choice', params); return this.logHelper.log('mod_choice_view_choice', params, AddonModChoiceProvider.COMPONENT, id, siteId);
} }
/** /**

View File

@ -25,6 +25,7 @@ import { AddonModChoiceProvider } from './choice';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreSyncProvider } from '@providers/sync'; import { CoreSyncProvider } from '@providers/sync';
/** /**
@ -40,7 +41,8 @@ export class AddonModChoiceSyncProvider extends CoreSyncBaseProvider {
protected appProvider: CoreAppProvider, private choiceOffline: AddonModChoiceOfflineProvider, protected appProvider: CoreAppProvider, private choiceOffline: AddonModChoiceOfflineProvider,
private eventsProvider: CoreEventsProvider, private choiceProvider: AddonModChoiceProvider, private eventsProvider: CoreEventsProvider, private choiceProvider: AddonModChoiceProvider,
translate: TranslateService, private utils: CoreUtilsProvider, protected textUtils: CoreTextUtilsProvider, translate: TranslateService, private utils: CoreUtilsProvider, protected textUtils: CoreTextUtilsProvider,
courseProvider: CoreCourseProvider, syncProvider: CoreSyncProvider, timeUtils: CoreTimeUtilsProvider) { courseProvider: CoreCourseProvider, syncProvider: CoreSyncProvider, timeUtils: CoreTimeUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModChoiceSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModChoiceSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -137,10 +139,12 @@ export class AddonModChoiceSyncProvider extends CoreSyncBaseProvider {
updated: false updated: false
}; };
// Get offline responses to be sent. // Sync offline logs.
const syncPromise = this.choiceOffline.getResponse(choiceId, siteId, userId).catch(() => { const syncPromise = this.logHelper.syncIfNeeded(AddonModChoiceProvider.COMPONENT, choiceId, siteId).finally(() => {
// No offline data found, return empty object. return this.choiceOffline.getResponse(choiceId, siteId, userId).catch(() => {
return {}; // No offline data found, return empty object.
return {};
});
}).then((data) => { }).then((data) => {
if (!data.choiceid) { if (!data.choiceid) {
// Nothing to sync. // Nothing to sync.

View File

@ -18,6 +18,7 @@ import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModDataOfflineProvider } from './offline'; import { AddonModDataOfflineProvider } from './offline';
import { AddonModDataFieldsDelegate } from './fields-delegate'; import { AddonModDataFieldsDelegate } from './fields-delegate';
@ -35,7 +36,8 @@ export class AddonModDataProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
private filepoolProvider: CoreFilepoolProvider, private dataOffline: AddonModDataOfflineProvider, private filepoolProvider: CoreFilepoolProvider, private dataOffline: AddonModDataOfflineProvider,
private appProvider: CoreAppProvider, private fieldsDelegate: AddonModDataFieldsDelegate) { private appProvider: CoreAppProvider, private fieldsDelegate: AddonModDataFieldsDelegate,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModDataProvider'); this.logger = logger.getInstance('AddonModDataProvider');
} }
@ -846,14 +848,15 @@ export class AddonModDataProvider {
* Report the database as being viewed. * Report the database as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
databaseid: id databaseid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_data_view_database', params); return this.logHelper.log('mod_data_view_database', params, AddonModDataProvider.COMPONENT, id, siteId);
} }
/** /**

View File

@ -26,6 +26,7 @@ import { AddonModDataHelperProvider } from './helper';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreSyncProvider } from '@providers/sync'; import { CoreSyncProvider } from '@providers/sync';
/** /**
@ -42,7 +43,7 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
private eventsProvider: CoreEventsProvider, private dataProvider: AddonModDataProvider, private eventsProvider: CoreEventsProvider, private dataProvider: AddonModDataProvider,
protected translate: TranslateService, private utils: CoreUtilsProvider, courseProvider: CoreCourseProvider, protected translate: TranslateService, private utils: CoreUtilsProvider, courseProvider: CoreCourseProvider,
syncProvider: CoreSyncProvider, protected textUtils: CoreTextUtilsProvider, timeUtils: CoreTimeUtilsProvider, syncProvider: CoreSyncProvider, protected textUtils: CoreTextUtilsProvider, timeUtils: CoreTimeUtilsProvider,
private dataHelper: AddonModDataHelperProvider) { private dataHelper: AddonModDataHelperProvider, private logHelper: CoreCourseLogHelperProvider) {
super('AddonModDataSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModDataSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -149,10 +150,13 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
updated: false updated: false
}; };
// Get answers to be sent. // Sync offline logs.
const syncPromise = this.dataOffline.getDatabaseEntries(dataId, siteId).catch(() => { const syncPromise = this.logHelper.syncIfNeeded(AddonModDataProvider.COMPONENT, dataId, siteId).finally(() => {
// No offline data found, return empty object. // Get answers to be sent.
return []; return this.dataOffline.getDatabaseEntries(dataId, siteId).catch(() => {
// No offline data found, return empty object.
return [];
});
}).then((offlineActions) => { }).then((offlineActions) => {
if (!offlineActions.length) { if (!offlineActions.length) {
// Nothing to sync. // Nothing to sync.

View File

@ -18,6 +18,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModFeedbackOfflineProvider } from './offline'; import { AddonModFeedbackOfflineProvider } from './offline';
/** /**
@ -38,7 +39,7 @@ export class AddonModFeedbackProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
private filepoolProvider: CoreFilepoolProvider, private feedbackOffline: AddonModFeedbackOfflineProvider, private filepoolProvider: CoreFilepoolProvider, private feedbackOffline: AddonModFeedbackOfflineProvider,
private appProvider: CoreAppProvider) { private appProvider: CoreAppProvider, private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModFeedbackProvider'); this.logger = logger.getInstance('AddonModFeedbackProvider');
} }
@ -1071,15 +1072,16 @@ export class AddonModFeedbackProvider {
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {boolean} [formViewed=false] True if form was viewed. * @param {boolean} [formViewed=false] True if form was viewed.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number, formViewed: boolean = false): Promise<any> { logView(id: number, formViewed: boolean = false, siteId?: string): Promise<any> {
const params = { const params = {
feedbackid: id, feedbackid: id,
moduleviewed: formViewed ? 1 : 0 moduleviewed: formViewed ? 1 : 0
}; };
return this.sitesProvider.getCurrentSite().write('mod_feedback_view_feedback', params); return this.logHelper.log('mod_feedback_view_feedback', params, AddonModFeedbackProvider.COMPONENT, id, siteId);
} }
/** /**

View File

@ -26,6 +26,7 @@ import { CoreEventsProvider } from '@providers/events';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreSyncProvider } from '@providers/sync'; import { CoreSyncProvider } from '@providers/sync';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
/** /**
* Service to sync feedbacks. * Service to sync feedbacks.
@ -40,7 +41,8 @@ export class AddonModFeedbackSyncProvider extends CoreSyncBaseProvider {
protected appProvider: CoreAppProvider, private feedbackOffline: AddonModFeedbackOfflineProvider, protected appProvider: CoreAppProvider, private feedbackOffline: AddonModFeedbackOfflineProvider,
private eventsProvider: CoreEventsProvider, private feedbackProvider: AddonModFeedbackProvider, private eventsProvider: CoreEventsProvider, private feedbackProvider: AddonModFeedbackProvider,
protected translate: TranslateService, private utils: CoreUtilsProvider, protected textUtils: CoreTextUtilsProvider, protected translate: TranslateService, private utils: CoreUtilsProvider, protected textUtils: CoreTextUtilsProvider,
courseProvider: CoreCourseProvider, syncProvider: CoreSyncProvider, timeUtils: CoreTimeUtilsProvider) { courseProvider: CoreCourseProvider, syncProvider: CoreSyncProvider, timeUtils: CoreTimeUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModFeedbackSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModFeedbackSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -144,10 +146,13 @@ export class AddonModFeedbackSyncProvider extends CoreSyncBaseProvider {
this.logger.debug(`Try to sync feedback '${feedbackId}' in site ${siteId}'`); this.logger.debug(`Try to sync feedback '${feedbackId}' in site ${siteId}'`);
// Get offline responses to be sent. // Sync offline logs.
const syncPromise = this.feedbackOffline.getFeedbackResponses(feedbackId, siteId).catch(() => { const syncPromise = this.logHelper.syncIfNeeded(AddonModFeedbackProvider.COMPONENT, feedbackId, siteId).finally(() => {
// No offline data found, return empty array. // Get offline responses to be sent.
return []; return this.feedbackOffline.getFeedbackResponses(feedbackId, siteId).catch(() => {
// No offline data found, return empty array.
return [];
});
}).then((responses) => { }).then((responses) => {
if (!responses.length) { if (!responses.length) {
// Nothing to sync. // Nothing to sync.

View File

@ -17,6 +17,7 @@ import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
/** /**
* Service that provides some features for folder. * Service that provides some features for folder.
@ -29,7 +30,7 @@ export class AddonModFolderProvider {
protected logger; protected logger;
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider,
private utils: CoreUtilsProvider) { private utils: CoreUtilsProvider, private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModFolderProvider'); this.logger = logger.getInstance('AddonModFolderProvider');
} }
@ -132,13 +133,14 @@ export class AddonModFolderProvider {
* Report a folder as being viewed. * Report a folder as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
folderid: id folderid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_folder_view_folder', params); return this.logHelper.log('mod_folder_view_folder', params, AddonModFolderProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -299,7 +299,7 @@ export class AddonModForumDiscussionPage implements OnDestroy {
if (forceMarkAsRead || (hasUnreadPosts && this.trackPosts)) { if (forceMarkAsRead || (hasUnreadPosts && this.trackPosts)) {
// // Add log in Moodle and mark unread posts as readed. // // Add log in Moodle and mark unread posts as readed.
this.forumProvider.logDiscussionView(this.discussionId).catch(() => { this.forumProvider.logDiscussionView(this.discussionId, this.forumId || -1).catch(() => {
// Ignore errors. // Ignore errors.
}).finally(() => { }).finally(() => {
// Trigger mark read posts. // Trigger mark read posts.

View File

@ -20,6 +20,7 @@ import { CoreGroupsProvider } from '@providers/groups';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModForumOfflineProvider } from './offline'; import { AddonModForumOfflineProvider } from './offline';
/** /**
@ -43,7 +44,8 @@ export class AddonModForumProvider {
private userProvider: CoreUserProvider, private userProvider: CoreUserProvider,
private translate: TranslateService, private translate: TranslateService,
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private forumOffline: AddonModForumOfflineProvider) {} private forumOffline: AddonModForumOfflineProvider,
private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Get cache key for can add discussion WS calls. * Get cache key for can add discussion WS calls.
@ -596,28 +598,31 @@ export class AddonModForumProvider {
* Report a forum as being viewed. * Report a forum as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
forumid: id forumid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_forum_view_forum', params); return this.logHelper.log('mod_forum_view_forum', params, AddonModForumProvider.COMPONENT, id, siteId);
} }
/** /**
* Report a forum discussion as being viewed. * Report a forum discussion as being viewed.
* *
* @param {number} id Discussion ID. * @param {number} id Discussion ID.
* @param {number} forumId Forum ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logDiscussionView(id: number): Promise<any> { logDiscussionView(id: number, forumId: number, siteId?: string): Promise<any> {
const params = { const params = {
discussionid: id discussionid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_forum_view_forum_discussion', params); return this.logHelper.log('mod_forum_view_forum_discussion', params, AddonModForumProvider.COMPONENT, forumId, siteId);
} }
/** /**

View File

@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
@ -53,7 +54,8 @@ export class AddonModForumSyncProvider extends CoreSyncBaseProvider {
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private forumProvider: AddonModForumProvider, private forumProvider: AddonModForumProvider,
private forumHelper: AddonModForumHelperProvider, private forumHelper: AddonModForumHelperProvider,
private forumOffline: AddonModForumOfflineProvider) { private forumOffline: AddonModForumOfflineProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModForumSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModForumSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -189,10 +191,13 @@ export class AddonModForumSyncProvider extends CoreSyncBaseProvider {
updated: false updated: false
}; };
// Get offline responses to be sent. // Sync offline logs.
const syncPromise = this.forumOffline.getNewDiscussions(forumId, siteId, userId).catch(() => { const syncPromise = this.logHelper.syncIfNeeded(AddonModForumProvider.COMPONENT, forumId, siteId).finally(() => {
// No offline data found, return empty object. // Get offline responses to be sent.
return []; return this.forumOffline.getNewDiscussions(forumId, siteId, userId).catch(() => {
// No offline data found, return empty object.
return [];
});
}).then((discussions) => { }).then((discussions) => {
if (!discussions.length) { if (!discussions.length) {
// Nothing to sync. // Nothing to sync.

View File

@ -48,7 +48,7 @@ export class AddonModGlossaryEntryPage {
*/ */
ionViewDidLoad(): void { ionViewDidLoad(): void {
this.fetchEntry().then(() => { this.fetchEntry().then(() => {
this.glossaryProvider.logEntryView(this.entry.id).catch(() => { this.glossaryProvider.logEntryView(this.entry.id, this.componentId).catch(() => {
// Ignore errors. // Ignore errors.
}); });
}).finally(() => { }).finally(() => {

View File

@ -20,6 +20,7 @@ import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModGlossaryOfflineProvider } from './offline'; import { AddonModGlossaryOfflineProvider } from './offline';
/** /**
@ -43,7 +44,8 @@ export class AddonModGlossaryProvider {
private translate: TranslateService, private translate: TranslateService,
private textUtils: CoreTextUtilsProvider, private textUtils: CoreTextUtilsProvider,
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private glossaryOffline: AddonModGlossaryOfflineProvider) {} private glossaryOffline: AddonModGlossaryOfflineProvider,
private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Get the course glossary cache key. * Get the course glossary cache key.
@ -860,28 +862,31 @@ export class AddonModGlossaryProvider {
* *
* @param {number} glossaryId Glossary ID. * @param {number} glossaryId Glossary ID.
* @param {string} mode The mode in which the glossary was viewed. * @param {string} mode The mode in which the glossary was viewed.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(glossaryId: number, mode: string): Promise<any> { logView(glossaryId: number, mode: string, siteId?: string): Promise<any> {
const params = { const params = {
id: glossaryId, id: glossaryId,
mode: mode mode: mode
}; };
return this.sitesProvider.getCurrentSite().write('mod_glossary_view_glossary', params); return this.logHelper.log('mod_glossary_view_glossary', params, AddonModGlossaryProvider.COMPONENT, glossaryId, siteId);
} }
/** /**
* Report a glossary entry as being viewed. * Report a glossary entry as being viewed.
* *
* @param {number} entryId Entry ID. * @param {number} entryId Entry ID.
* @param {number} glossaryId Glossary ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logEntryView(entryId: number): Promise<any> { logEntryView(entryId: number, glossaryId: number, siteId?: string): Promise<any> {
const params = { const params = {
id: entryId id: entryId
}; };
return this.sitesProvider.getCurrentSite().write('mod_glossary_view_entry', params); return this.logHelper.log('mod_glossary_view_entry', params, AddonModGlossaryProvider.COMPONENT, glossaryId, siteId);
} }
} }

View File

@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
@ -52,7 +53,8 @@ export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private glossaryProvider: AddonModGlossaryProvider, private glossaryProvider: AddonModGlossaryProvider,
private glossaryHelper: AddonModGlossaryHelperProvider, private glossaryHelper: AddonModGlossaryHelperProvider,
private glossaryOffline: AddonModGlossaryOfflineProvider) { private glossaryOffline: AddonModGlossaryOfflineProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModGlossarySyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModGlossarySyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -160,10 +162,13 @@ export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
updated: false updated: false
}; };
// Get offline responses to be sent. // Sync offline logs.
const syncPromise = this.glossaryOffline.getGlossaryNewEntries(glossaryId, siteId, userId).catch(() => { const syncPromise = this.logHelper.syncIfNeeded(AddonModGlossaryProvider.COMPONENT, glossaryId, siteId).finally(() => {
// No offline data found, return empty object. // Get offline responses to be sent.
return []; return this.glossaryOffline.getGlossaryNewEntries(glossaryId, siteId, userId).catch(() => {
// No offline data found, return empty object.
return [];
});
}).then((entries) => { }).then((entries) => {
if (!entries.length) { if (!entries.length) {
// Nothing to sync. // Nothing to sync.

View File

@ -19,6 +19,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
/** /**
* Service that provides some features for IMSCP. * Service that provides some features for IMSCP.
@ -31,7 +32,8 @@ export class AddonModImscpProvider {
constructor(private appProvider: CoreAppProvider, private courseProvider: CoreCourseProvider, constructor(private appProvider: CoreAppProvider, private courseProvider: CoreCourseProvider,
private filepoolProvider: CoreFilepoolProvider, private sitesProvider: CoreSitesProvider, private filepoolProvider: CoreFilepoolProvider, private sitesProvider: CoreSitesProvider,
private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider) {} private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Get the IMSCP toc as an array. * Get the IMSCP toc as an array.
@ -307,13 +309,14 @@ export class AddonModImscpProvider {
* Report a IMSCP as being viewed. * Report a IMSCP as being viewed.
* *
* @param {string} id Module ID. * @param {string} id Module ID.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: string): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
imscpid: id imscpid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_imscp_view_imscp', params); return this.logHelper.log('mod_imscp_view_imscp', params, AddonModImscpProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -24,6 +24,7 @@ import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
import { AddonModLessonProvider } from './lesson'; import { AddonModLessonProvider } from './lesson';
import { AddonModLessonOfflineProvider } from './lesson-offline'; import { AddonModLessonOfflineProvider } from './lesson-offline';
@ -92,7 +93,8 @@ export class AddonModLessonSyncProvider extends CoreSyncBaseProvider {
courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
private lessonProvider: AddonModLessonProvider, private lessonOfflineProvider: AddonModLessonOfflineProvider, private lessonProvider: AddonModLessonProvider, private lessonOfflineProvider: AddonModLessonOfflineProvider,
private prefetchHandler: AddonModLessonPrefetchHandler, timeUtils: CoreTimeUtilsProvider, private prefetchHandler: AddonModLessonPrefetchHandler, timeUtils: CoreTimeUtilsProvider,
private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider) { private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModLessonSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModLessonSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -269,8 +271,11 @@ export class AddonModLessonSyncProvider extends CoreSyncBaseProvider {
this.logger.debug('Try to sync lesson ' + lessonId + ' in site ' + siteId); this.logger.debug('Try to sync lesson ' + lessonId + ' in site ' + siteId);
// Try to synchronize the attempts first. // Sync offline logs.
syncPromise = this.lessonOfflineProvider.getLessonAttempts(lessonId, siteId).then((attempts) => { syncPromise = this.logHelper.syncIfNeeded(AddonModLessonProvider.COMPONENT, lessonId, siteId).finally(() => {
// Try to synchronize the attempts first.
return this.lessonOfflineProvider.getLessonAttempts(lessonId, siteId);
}).then((attempts) => {
if (!attempts.length) { if (!attempts.length) {
return; return;
} else if (!this.appProvider.isOnline()) { } else if (!this.appProvider.isOnline()) {

View File

@ -20,6 +20,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreGradesProvider } from '@core/grades/providers/grades'; import { CoreGradesProvider } from '@core/grades/providers/grades';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreSiteWSPreSets } from '@classes/site'; import { CoreSiteWSPreSets } from '@classes/site';
import { AddonModLessonOfflineProvider } from './lesson-offline'; import { AddonModLessonOfflineProvider } from './lesson-offline';
@ -185,7 +186,7 @@ export class AddonModLessonProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private utils: CoreUtilsProvider,
private translate: TranslateService, private textUtils: CoreTextUtilsProvider, private domUtils: CoreDomUtilsProvider, private translate: TranslateService, private textUtils: CoreTextUtilsProvider, private domUtils: CoreDomUtilsProvider,
private lessonOfflineProvider: AddonModLessonOfflineProvider) { private lessonOfflineProvider: AddonModLessonOfflineProvider, private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModLessonProvider'); this.logger = logger.getInstance('AddonModLessonProvider');
this.sitesProvider.registerSiteSchema(this.siteSchema); this.sitesProvider.registerSiteSchema(this.siteSchema);
@ -2966,14 +2967,9 @@ export class AddonModLessonProvider {
params.password = password; params.password = password;
} }
return site.write('mod_lesson_view_lesson', params).then((result) => { return this.logHelper.log('mod_lesson_view_lesson', params, AddonModLessonProvider.COMPONENT, id, siteId);
if (!result.status) {
return Promise.reject(null);
}
return result;
});
}); });
} }
/** /**

View File

@ -20,6 +20,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
export interface AddonModLtiParam { export interface AddonModLtiParam {
name: string; name: string;
@ -42,7 +43,8 @@ export class AddonModLtiProvider {
private urlUtils: CoreUrlUtilsProvider, private urlUtils: CoreUrlUtilsProvider,
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private translate: TranslateService, private translate: TranslateService,
private appProvider: CoreAppProvider) {} private appProvider: CoreAppProvider,
private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Delete launcher. * Delete launcher.
@ -211,13 +213,14 @@ export class AddonModLtiProvider {
* Report the LTI as being viewed. * Report the LTI as being viewed.
* *
* @param {string} id LTI id. * @param {string} id LTI id.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: string): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params: any = { const params: any = {
ltiid: id ltiid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_lti_view_lti', params); return this.logHelper.log('mod_lti_view_lti', params, AddonModLtiProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -17,6 +17,7 @@ import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
/** /**
@ -30,7 +31,8 @@ export class AddonModPageProvider {
protected logger; protected logger;
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider,
private utils: CoreUtilsProvider, private filepoolProvider: CoreFilepoolProvider) { private utils: CoreUtilsProvider, private filepoolProvider: CoreFilepoolProvider,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModPageProvider'); this.logger = logger.getInstance('AddonModPageProvider');
} }
@ -146,13 +148,14 @@ export class AddonModPageProvider {
* Report a page as being viewed. * Report a page as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
pageid: id pageid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_page_view_page', params); return this.logHelper.log('mod_page_view_page', params, AddonModPageProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -455,7 +455,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
this.attempt.dueDateWarning = this.quizProvider.getAttemptDueDateWarning(this.quiz, this.attempt); this.attempt.dueDateWarning = this.quizProvider.getAttemptDueDateWarning(this.quiz, this.attempt);
// Log summary as viewed. // Log summary as viewed.
this.quizProvider.logViewAttemptSummary(this.attempt.id, this.preflightData).catch((error) => { this.quizProvider.logViewAttemptSummary(this.attempt.id, this.preflightData, this.quizId).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
}); });

View File

@ -77,7 +77,7 @@ export class AddonModQuizReviewPage implements OnInit {
*/ */
ngOnInit(): void { ngOnInit(): void {
this.fetchData().then(() => { this.fetchData().then(() => {
this.quizProvider.logViewAttemptReview(this.attemptId).catch((error) => { this.quizProvider.logViewAttemptReview(this.attemptId, this.quizId).catch((error) => {
// Ignore errors. // Ignore errors.
}); });
}).finally(() => { }).finally(() => {

View File

@ -22,6 +22,7 @@ import { CoreSyncProvider } from '@providers/sync';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreQuestionProvider } from '@core/question/providers/question'; import { CoreQuestionProvider } from '@core/question/providers/question';
import { CoreQuestionDelegate } from '@core/question/providers/delegate'; import { CoreQuestionDelegate } from '@core/question/providers/delegate';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
@ -61,7 +62,7 @@ export class AddonModQuizSyncProvider extends CoreSyncBaseProvider {
courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, timeUtils: CoreTimeUtilsProvider, courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, timeUtils: CoreTimeUtilsProvider,
private quizProvider: AddonModQuizProvider, private quizOfflineProvider: AddonModQuizOfflineProvider, private quizProvider: AddonModQuizProvider, private quizOfflineProvider: AddonModQuizOfflineProvider,
private prefetchHandler: AddonModQuizPrefetchHandler, private questionProvider: CoreQuestionProvider, private prefetchHandler: AddonModQuizPrefetchHandler, private questionProvider: CoreQuestionProvider,
private questionDelegate: CoreQuestionDelegate) { private questionDelegate: CoreQuestionDelegate, private logHelper: CoreCourseLogHelperProvider) {
super('AddonModQuizSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModQuizSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -259,8 +260,11 @@ export class AddonModQuizSyncProvider extends CoreSyncBaseProvider {
this.logger.debug('Try to sync quiz ' + quiz.id + ' in site ' + siteId); this.logger.debug('Try to sync quiz ' + quiz.id + ' in site ' + siteId);
// Get all the offline attempts for the quiz. // Sync offline logs.
syncPromise = this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId).then((attempts) => { syncPromise = this.logHelper.syncIfNeeded(AddonModQuizProvider.COMPONENT, quiz.id, siteId).finally(() => {
// Get all the offline attempts for the quiz.
return this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId);
}).then((attempts) => {
// Should return 0 or 1 attempt. // Should return 0 or 1 attempt.
if (!attempts.length) { if (!attempts.length) {
return this.finishSync(siteId, quiz, courseId, warnings); return this.finishSync(siteId, quiz, courseId, warnings);

View File

@ -24,6 +24,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreSiteWSPreSets } from '@classes/site'; import { CoreSiteWSPreSets } from '@classes/site';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { CoreQuestionDelegate } from '@core/question/providers/delegate'; import { CoreQuestionDelegate } from '@core/question/providers/delegate';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate'; import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate';
import { AddonModQuizOfflineProvider } from './quiz-offline'; import { AddonModQuizOfflineProvider } from './quiz-offline';
@ -62,7 +63,7 @@ export class AddonModQuizProvider {
private gradesHelper: CoreGradesHelperProvider, private questionDelegate: CoreQuestionDelegate, private gradesHelper: CoreGradesHelperProvider, private questionDelegate: CoreQuestionDelegate,
private filepoolProvider: CoreFilepoolProvider, private timeUtils: CoreTimeUtilsProvider, private filepoolProvider: CoreFilepoolProvider, private timeUtils: CoreTimeUtilsProvider,
private accessRulesDelegate: AddonModQuizAccessRuleDelegate, private quizOfflineProvider: AddonModQuizOfflineProvider, private accessRulesDelegate: AddonModQuizAccessRuleDelegate, private quizOfflineProvider: AddonModQuizOfflineProvider,
private domUtils: CoreDomUtilsProvider) { private domUtils: CoreDomUtilsProvider, private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModQuizProvider'); this.logger = logger.getInstance('AddonModQuizProvider');
} }
@ -1517,42 +1518,47 @@ export class AddonModQuizProvider {
} }
/** /**
* Report an attempt as being viewed. * Report an attempt as being viewed. It did not store logs offline because order of the log is important.
* *
* @param {number} attemptId Attempt ID. * @param {number} attemptId Attempt ID.
* @param {number} [page=0] Page number. * @param {number} [page=0] Page number.
* @param {any} [preflightData] Preflight required data (like password). * @param {any} [preflightData] Preflight required data (like password).
* @param {boolean} [offline] Whether attempt is offline. * @param {boolean} [offline] Whether attempt is offline.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logViewAttempt(attemptId: number, page: number = 0, preflightData: any = {}, offline?: boolean): Promise<any> { logViewAttempt(attemptId: number, page: number = 0, preflightData: any = {}, offline?: boolean, siteId?: string): Promise<any> {
const params = { return this.sitesProvider.getSite(siteId).then((site) => {
attemptid: attemptId, const params = {
page: page, attemptid: attemptId,
preflightdata: this.utils.objectToArrayOfObjects(preflightData, 'name', 'value', true) page: page,
}, preflightdata: this.utils.objectToArrayOfObjects(preflightData, 'name', 'value', true)
promises = []; },
promises = [];
promises.push(this.sitesProvider.getCurrentSite().write('mod_quiz_view_attempt', params)); promises.push(site.write('mod_quiz_view_attempt', params));
if (offline) { if (offline) {
promises.push(this.quizOfflineProvider.setAttemptCurrentPage(attemptId, page)); promises.push(this.quizOfflineProvider.setAttemptCurrentPage(attemptId, page, site.getId()));
} }
return Promise.all(promises); return Promise.all(promises);
});
} }
/** /**
* Report an attempt's review as being viewed. * Report an attempt's review as being viewed.
* *
* @param {number} attemptId Attempt ID. * @param {number} attemptId Attempt ID.
* @param {number} quizId Quiz ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logViewAttemptReview(attemptId: number): Promise<any> { logViewAttemptReview(attemptId: number, quizId: number, siteId?: string): Promise<any> {
const params = { const params = {
attemptid: attemptId attemptid: attemptId
}; };
return this.sitesProvider.getCurrentSite().write('mod_quiz_view_attempt_review', params); return this.logHelper.log('mod_quiz_view_attempt_review', params, AddonModQuizProvider.COMPONENT, quizId, siteId);
} }
/** /**
@ -1560,29 +1566,32 @@ export class AddonModQuizProvider {
* *
* @param {number} attemptId Attempt ID. * @param {number} attemptId Attempt ID.
* @param {any} preflightData Preflight required data (like password). * @param {any} preflightData Preflight required data (like password).
* @param {number} quizId Quiz ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logViewAttemptSummary(attemptId: number, preflightData: any): Promise<any> { logViewAttemptSummary(attemptId: number, preflightData: any, quizId: number, siteId?: string): Promise<any> {
const params = { const params = {
attemptid: attemptId, attemptid: attemptId,
preflightdata: this.utils.objectToArrayOfObjects(preflightData, 'name', 'value', true) preflightdata: this.utils.objectToArrayOfObjects(preflightData, 'name', 'value', true)
}; };
return this.sitesProvider.getCurrentSite().write('mod_quiz_view_attempt_summary', params); return this.logHelper.log('mod_quiz_view_attempt_summary', params, AddonModQuizProvider.COMPONENT, quizId, siteId);
} }
/** /**
* Report a quiz as being viewed. * Report a quiz as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logViewQuiz(id: number): Promise<any> { logViewQuiz(id: number, siteId?: string): Promise<any> {
const params = { const params = {
quizid: id quizid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_quiz_view_quiz', params); return this.logHelper.log('mod_quiz_view_quiz', params, AddonModQuizProvider.COMPONENT, id, siteId);
} }
/** /**

View File

@ -17,6 +17,7 @@ import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
/** /**
@ -30,7 +31,8 @@ export class AddonModResourceProvider {
protected logger; protected logger;
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider,
private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider) { private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModResourceProvider'); this.logger = logger.getInstance('AddonModResourceProvider');
} }
@ -148,13 +150,14 @@ export class AddonModResourceProvider {
* Report the resource as being viewed. * Report the resource as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
resourceid: id resourceid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_resource_view_resource', params); return this.logHelper.log('mod_resource_view_resource', params, AddonModResourceProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -23,6 +23,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate'; import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
import { AddonModScormProvider, AddonModScormAttemptCountResult } from './scorm'; import { AddonModScormProvider, AddonModScormAttemptCountResult } from './scorm';
@ -67,7 +68,8 @@ export class AddonModScormSyncProvider extends CoreSyncBaseProvider {
private eventsProvider: CoreEventsProvider, timeUtils: CoreTimeUtilsProvider, private eventsProvider: CoreEventsProvider, timeUtils: CoreTimeUtilsProvider,
private scormProvider: AddonModScormProvider, private scormOfflineProvider: AddonModScormOfflineProvider, private scormProvider: AddonModScormProvider, private scormOfflineProvider: AddonModScormOfflineProvider,
private prefetchHandler: AddonModScormPrefetchHandler, private utils: CoreUtilsProvider, private prefetchHandler: AddonModScormPrefetchHandler, private utils: CoreUtilsProvider,
private prefetchDelegate: CoreCourseModulePrefetchDelegate, private courseProvider: CoreCourseProvider) { private prefetchDelegate: CoreCourseModulePrefetchDelegate, private courseProvider: CoreCourseProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModScormSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModScormSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -646,8 +648,11 @@ export class AddonModScormSyncProvider extends CoreSyncBaseProvider {
this.logger.debug('Try to sync SCORM ' + scorm.id + ' in site ' + siteId); this.logger.debug('Try to sync SCORM ' + scorm.id + ' in site ' + siteId);
// Get attempts data. We ignore cache for online attempts, so this call will fail if offline or server down. // Sync offline logs.
syncPromise = this.scormProvider.getAttemptCount(scorm.id, false, true, siteId).then((attemptsData) => { syncPromise = this.logHelper.syncIfNeeded(AddonModScormProvider.COMPONENT, scorm.id, siteId).finally(() => {
// Get attempts data. We ignore cache for online attempts, so this call will fail if offline or server down.
return this.scormProvider.getAttemptCount(scorm.id, false, true, siteId);
}).then((attemptsData) => {
if (!attemptsData.offline || !attemptsData.offline.length) { if (!attemptsData.offline || !attemptsData.offline.length) {
// Nothing to sync. // Nothing to sync.
return this.finishSync(siteId, scorm, warnings, lastOnline, lastOnlineWasFinished); return this.finishSync(siteId, scorm, warnings, lastOnline, lastOnlineWasFinished);

View File

@ -26,6 +26,7 @@ import { CoreUtilsProvider } from '@providers/utils/utils';
import { AddonModScormOfflineProvider } from './scorm-offline'; import { AddonModScormOfflineProvider } from './scorm-offline';
import { CoreSiteWSPreSets } from '@classes/site'; import { CoreSiteWSPreSets } from '@classes/site';
import { CoreConstants } from '@core/constants'; import { CoreConstants } from '@core/constants';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
/** /**
* Result of getAttemptCount. * Result of getAttemptCount.
@ -113,7 +114,7 @@ export class AddonModScormProvider {
private wsProvider: CoreWSProvider, private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider, private wsProvider: CoreWSProvider, private textUtils: CoreTextUtilsProvider, private utils: CoreUtilsProvider,
private filepoolProvider: CoreFilepoolProvider, private scormOfflineProvider: AddonModScormOfflineProvider, private filepoolProvider: CoreFilepoolProvider, private scormOfflineProvider: AddonModScormOfflineProvider,
private timeUtils: CoreTimeUtilsProvider, private syncProvider: CoreSyncProvider, private timeUtils: CoreTimeUtilsProvider, private syncProvider: CoreSyncProvider,
private eventsProvider: CoreEventsProvider) { private eventsProvider: CoreEventsProvider, private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModScormProvider'); this.logger = logger.getInstance('AddonModScormProvider');
} }
@ -1446,18 +1447,12 @@ export class AddonModScormProvider {
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number, siteId?: string): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { scormid: id
scormid: id };
};
return site.write('mod_scorm_view_scorm', params).then((response) => { return this.logHelper.log('mod_scorm_view_scorm', params, AddonModScormProvider.COMPONENT, id, siteId);
if (!response || !response.status) { }
return Promise.reject(null);
}
});
});
}
/** /**
* Saves a SCORM tracking record. * Saves a SCORM tracking record.

View File

@ -18,6 +18,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModSurveyOfflineProvider } from './offline'; import { AddonModSurveyOfflineProvider } from './offline';
/** /**
@ -32,7 +33,7 @@ export class AddonModSurveyProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider,
private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider, private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider,
private surveyOffline: AddonModSurveyOfflineProvider) { private surveyOffline: AddonModSurveyOfflineProvider, private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModSurveyProvider'); this.logger = logger.getInstance('AddonModSurveyProvider');
} }
@ -197,14 +198,15 @@ export class AddonModSurveyProvider {
* Report the survey as being viewed. * Report the survey as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
surveyid: id surveyid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_survey_view_survey', params); return this.logHelper.log('mod_survey_view_survey', params, AddonModSurveyProvider.COMPONENT, id, siteId);
} }
/** /**

View File

@ -25,6 +25,7 @@ import { AddonModSurveyProvider } from './survey';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreSyncProvider } from '@providers/sync'; import { CoreSyncProvider } from '@providers/sync';
/** /**
@ -40,7 +41,7 @@ export class AddonModSurveySyncProvider extends CoreSyncBaseProvider {
syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService, syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService,
courseProvider: CoreCourseProvider, private surveyOffline: AddonModSurveyOfflineProvider, courseProvider: CoreCourseProvider, private surveyOffline: AddonModSurveyOfflineProvider,
private eventsProvider: CoreEventsProvider, private surveyProvider: AddonModSurveyProvider, private eventsProvider: CoreEventsProvider, private surveyProvider: AddonModSurveyProvider,
private utils: CoreUtilsProvider, timeUtils: CoreTimeUtilsProvider) { private utils: CoreUtilsProvider, timeUtils: CoreTimeUtilsProvider, private logHelper: CoreCourseLogHelperProvider) {
super('AddonModSurveySyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModSurveySyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -141,10 +142,13 @@ export class AddonModSurveySyncProvider extends CoreSyncBaseProvider {
answersSent: false answersSent: false
}; };
// Get answers to be sent. // Sync offline logs.
const syncPromise = this.surveyOffline.getSurveyData(surveyId, siteId, userId).catch(() => { const syncPromise = this.logHelper.syncIfNeeded(AddonModSurveyProvider.COMPONENT, surveyId, siteId).finally(() => {
// No offline data found, return empty object. // Get answers to be sent.
return {}; return this.surveyOffline.getSurveyData(surveyId, siteId, userId).catch(() => {
// No offline data found, return empty object.
return {};
});
}).then((data) => { }).then((data) => {
if (!data.answers || !data.answers.length) { if (!data.answers || !data.answers.length) {
// Nothing to sync. // Nothing to sync.

View File

@ -18,6 +18,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype'; import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreConstants } from '@core/constants'; import { CoreConstants } from '@core/constants';
/** /**
@ -31,7 +32,8 @@ export class AddonModUrlProvider {
protected logger; protected logger;
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private courseProvider: CoreCourseProvider,
private utils: CoreUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider) { private utils: CoreUtilsProvider, private mimeUtils: CoreMimetypeUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModUrlProvider'); this.logger = logger.getInstance('AddonModUrlProvider');
} }
@ -215,13 +217,14 @@ export class AddonModUrlProvider {
* Report the url as being viewed. * Report the url as being viewed.
* *
* @param {number} id Module ID. * @param {number} id Module ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
const params = { const params = {
urlid: id urlid: id
}; };
return this.sitesProvider.getCurrentSite().write('mod_url_view_url', params); return this.logHelper.log('mod_url_view_url', params, AddonModUrlProvider.COMPONENT, id, siteId);
} }
} }

View File

@ -110,7 +110,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
// Ignore errors. // Ignore errors.
}); });
} else { } else {
this.wikiProvider.logPageView(this.pageId).catch(() => { this.wikiProvider.logPageView(this.pageId, this.wiki.id).catch(() => {
// Ignore errors. // Ignore errors.
}); });
} }
@ -341,7 +341,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
this.currentPage = data.pageId; this.currentPage = data.pageId;
this.showLoadingAndFetch(true, false).then(() => { this.showLoadingAndFetch(true, false).then(() => {
this.wikiProvider.logPageView(this.currentPage).catch(() => { this.wikiProvider.logPageView(this.currentPage, this.wiki.id).catch(() => {
// Ignore errors. // Ignore errors.
}); });
}); });

View File

@ -24,6 +24,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreSyncBaseProvider } from '@classes/base-sync';
import { AddonModWikiProvider } from './wiki'; import { AddonModWikiProvider } from './wiki';
import { AddonModWikiOfflineProvider } from './wiki-offline'; import { AddonModWikiOfflineProvider } from './wiki-offline';
@ -104,7 +105,8 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider {
syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService, syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService,
courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
private wikiProvider: AddonModWikiProvider, private wikiOfflineProvider: AddonModWikiOfflineProvider, private wikiProvider: AddonModWikiProvider, private wikiOfflineProvider: AddonModWikiOfflineProvider,
private utils: CoreUtilsProvider, private groupsProvider: CoreGroupsProvider, timeUtils: CoreTimeUtilsProvider) { private utils: CoreUtilsProvider, private groupsProvider: CoreGroupsProvider, timeUtils: CoreTimeUtilsProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModWikiSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModWikiSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -336,8 +338,13 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider {
syncWiki(wikiId: number, courseId?: number, cmId?: number, siteId?: string): Promise<AddonModWikiSyncWikiResult> { syncWiki(wikiId: number, courseId?: number, cmId?: number, siteId?: string): Promise<AddonModWikiSyncWikiResult> {
siteId = siteId || this.sitesProvider.getCurrentSiteId(); siteId = siteId || this.sitesProvider.getCurrentSiteId();
// Sync is done at subwiki level, get all the subwikis. // Sync offline logs.
return this.wikiProvider.getSubwikis(wikiId).then((subwikis) => { return this.logHelper.syncIfNeeded(AddonModWikiProvider.COMPONENT, wikiId, siteId).catch(() => {
// Ignore errors.
}).then(() => {
// Sync is done at subwiki level, get all the subwikis.
return this.wikiProvider.getSubwikis(wikiId);
}).then((subwikis) => {
const promises = [], const promises = [],
result: AddonModWikiSyncWikiResult = { result: AddonModWikiSyncWikiResult = {
warnings: [], warnings: [],

View File

@ -20,6 +20,7 @@ import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModWikiOfflineProvider } from './wiki-offline'; import { AddonModWikiOfflineProvider } from './wiki-offline';
import { CoreSiteWSPreSets } from '@classes/site'; import { CoreSiteWSPreSets } from '@classes/site';
@ -70,7 +71,8 @@ export class AddonModWikiProvider {
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider,
private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider, private translate: TranslateService, private filepoolProvider: CoreFilepoolProvider, private utils: CoreUtilsProvider, private translate: TranslateService,
private wikiOffline: AddonModWikiOfflineProvider, eventsProvider: CoreEventsProvider) { private wikiOffline: AddonModWikiOfflineProvider, eventsProvider: CoreEventsProvider,
private logHelper: CoreCourseLogHelperProvider) {
this.logger = logger.getInstance('AddonModWikiProvider'); this.logger = logger.getInstance('AddonModWikiProvider');
// Clear subwiki lists cache on logout. // Clear subwiki lists cache on logout.
@ -651,18 +653,17 @@ export class AddonModWikiProvider {
/** /**
* Report a wiki page as being viewed. * Report a wiki page as being viewed.
* *
* @param {string} id Page ID. * @param {number} id Page ID.
* @param {number} wikiId Wiki ID.
* @param {string} [siteId] Site ID. If not defined, current site. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logPageView(id: number, siteId?: string): Promise<any> { logPageView(id: number, wikiId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { pageid: id
pageid: id };
};
return site.write('mod_wiki_view_page', params); return this.logHelper.log('mod_wiki_view_page', params, AddonModWikiProvider.COMPONENT, wikiId, siteId);
});
} }
/** /**
@ -673,13 +674,11 @@ export class AddonModWikiProvider {
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number, siteId?: string): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { wikiid: id
wikiid: id };
};
return site.write('mod_wiki_view_wiki', params); return this.logHelper.log('mod_wiki_view_wiki', params, AddonModWikiProvider.COMPONENT, id, siteId);
});
} }
/** /**

View File

@ -130,7 +130,7 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
*/ */
ngOnInit(): void { ngOnInit(): void {
this.fetchSubmissionData().then(() => { this.fetchSubmissionData().then(() => {
this.workshopProvider.logViewSubmission(this.submissionId).then(() => { this.workshopProvider.logViewSubmission(this.submissionId, this.workshopId).then(() => {
this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata); this.courseProvider.checkModuleCompletion(this.courseId, this.module.completiondata);
}).catch(() => { }).catch(() => {
// Ignore errors. // Ignore errors.

View File

@ -24,6 +24,7 @@ import { CoreSyncProvider } from '@providers/sync';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModWorkshopProvider } from './workshop'; import { AddonModWorkshopProvider } from './workshop';
import { AddonModWorkshopHelperProvider } from './helper'; import { AddonModWorkshopHelperProvider } from './helper';
import { AddonModWorkshopOfflineProvider } from './offline'; import { AddonModWorkshopOfflineProvider } from './offline';
@ -51,7 +52,8 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private workshopProvider: AddonModWorkshopProvider, private workshopProvider: AddonModWorkshopProvider,
private workshopHelper: AddonModWorkshopHelperProvider, private workshopHelper: AddonModWorkshopHelperProvider,
private workshopOffline: AddonModWorkshopOfflineProvider) { private workshopOffline: AddonModWorkshopOfflineProvider,
private logHelper: CoreCourseLogHelperProvider) {
super('AddonModWorkshopSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate, super('AddonModWorkshopSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
timeUtils); timeUtils);
@ -172,6 +174,9 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
return []; return [];
})); }));
// Sync offline logs.
syncPromises.push(this.logHelper.syncIfNeeded(AddonModWorkshopProvider.COMPONENT, workshopId, siteId));
const result = { const result = {
warnings: [], warnings: [],
updated: false updated: false

View File

@ -17,6 +17,7 @@ import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
import { AddonModWorkshopOfflineProvider } from './offline'; import { AddonModWorkshopOfflineProvider } from './offline';
/** /**
@ -49,7 +50,8 @@ export class AddonModWorkshopProvider {
private filepoolProvider: CoreFilepoolProvider, private filepoolProvider: CoreFilepoolProvider,
private sitesProvider: CoreSitesProvider, private sitesProvider: CoreSitesProvider,
private utils: CoreUtilsProvider, private utils: CoreUtilsProvider,
private workshopOffline: AddonModWorkshopOfflineProvider) {} private workshopOffline: AddonModWorkshopOfflineProvider,
private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Get cache key for workshop data WS calls. * Get cache key for workshop data WS calls.
@ -1359,34 +1361,31 @@ export class AddonModWorkshopProvider {
/** /**
* Report the workshop as being viewed. * Report the workshop as being viewed.
* *
* @param {string} id Workshop ID. * @param {number} id Workshop ID.
* @param {string} [siteId] Site ID. If not defined, current site. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logView(id: number, siteId?: string): Promise<any> { logView(id: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { workshopid: id
workshopid: id };
};
return site.write('mod_workshop_view_workshop', params); return this.logHelper.log('mod_workshop_view_workshop', params, AddonModWorkshopProvider.COMPONENT, id, siteId);
});
} }
/** /**
* Report the workshop submission as being viewed. * Report the workshop submission as being viewed.
* *
* @param {string} id Submission ID. * @param {number} id Submission ID.
* @param {number} workshopId Workshop ID.
* @param {string} [siteId] Site ID. If not defined, current site. * @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when the WS call is successful. * @return {Promise<any>} Promise resolved when the WS call is successful.
*/ */
logViewSubmission(id: number, siteId?: string): Promise<any> { logViewSubmission(id: number, workshopId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { const params = {
const params = { submissionid: id
submissionid: id };
};
return site.write('mod_workshop_view_submission', params); return this.logHelper.log('mod_workshop_view_submission', params, AddonModWorkshopProvider.COMPONENT, workshopId, siteId);
});
} }
} }

View File

@ -18,6 +18,7 @@ import { CoreCronDelegate } from '@providers/cron';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { CoreCourseProvider } from './providers/course'; import { CoreCourseProvider } from './providers/course';
import { CoreCourseHelperProvider } from './providers/helper'; import { CoreCourseHelperProvider } from './providers/helper';
import { CoreCourseLogHelperProvider } from './providers/log-helper';
import { CoreCourseFormatDelegate } from './providers/format-delegate'; import { CoreCourseFormatDelegate } from './providers/format-delegate';
import { CoreCourseModuleDelegate } from './providers/module-delegate'; import { CoreCourseModuleDelegate } from './providers/module-delegate';
import { CoreCourseOfflineProvider } from './providers/course-offline'; import { CoreCourseOfflineProvider } from './providers/course-offline';
@ -37,6 +38,7 @@ import { CoreCourseLogCronHandler } from './providers/log-cron-handler';
export const CORE_COURSE_PROVIDERS: any[] = [ export const CORE_COURSE_PROVIDERS: any[] = [
CoreCourseProvider, CoreCourseProvider,
CoreCourseHelperProvider, CoreCourseHelperProvider,
CoreCourseLogHelperProvider,
CoreCourseFormatDelegate, CoreCourseFormatDelegate,
CoreCourseModuleDelegate, CoreCourseModuleDelegate,
CoreCourseModulePrefetchDelegate, CoreCourseModulePrefetchDelegate,
@ -56,6 +58,7 @@ export const CORE_COURSE_PROVIDERS: any[] = [
providers: [ providers: [
CoreCourseProvider, CoreCourseProvider,
CoreCourseHelperProvider, CoreCourseHelperProvider,
CoreCourseLogHelperProvider,
CoreCourseFormatDelegate, CoreCourseFormatDelegate,
CoreCourseModuleDelegate, CoreCourseModuleDelegate,
CoreCourseModulePrefetchDelegate, CoreCourseModulePrefetchDelegate,

View File

@ -0,0 +1,297 @@
// (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';
import { CoreSitesProvider } from '@providers/sites';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreAppProvider } from '@providers/app';
/**
* Helper to manage logging to Moodle.
*/
@Injectable()
export class CoreCourseLogHelperProvider {
// Variables for database.
static ACTIVITY_LOG_TABLE = 'course_activity_log';
protected tablesSchema = [
{
name: CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
columns: [
{
name: 'component',
type: 'TEXT'
},
{
name: 'componentid',
type: 'INTEGER'
},
{
name: 'ws',
type: 'TEXT'
},
{
name: 'data',
type: 'TEXT'
},
{
name: 'time',
type: 'INTEGER'
}
],
primaryKeys: ['component', 'componentid', 'ws', 'time']
}
];
constructor(protected sitesProvider: CoreSitesProvider, protected timeUtils: CoreTimeUtilsProvider,
protected textUtils: CoreTextUtilsProvider, protected utils: CoreUtilsProvider,
protected appProvider: CoreAppProvider) {
this.sitesProvider.createTablesFromSchema(this.tablesSchema);
}
/**
* Delete the offline saved activity logs.
*
* @param {string} component Component name.
* @param {number} componentId Component ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when deleted, rejected if failure.
*/
protected deleteLogs(component: string, componentId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.getDb().deleteRecords(CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
{component: component, componentid: componentId});
});
}
/**
* Delete a WS based log.
*
* @param {string} component Component name.
* @param {number} componentId Component ID.
* @param {string} ws WS name.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when deleted, rejected if failure.
*/
protected deleteWSLogsByComponent(component: string, componentId: number, ws: string, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.getDb().deleteRecords(CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
{component: component, componentid: componentId, ws: ws});
});
}
/**
* Delete the offline saved activity logs using call data.
*
* @param {string} ws WS name.
* @param {any} data Data to send to the WS.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when deleted, rejected if failure.
*/
protected deleteWSLogs(ws: string, data: any, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.getDb().deleteRecords(CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
{ws: ws, data: this.utils.sortAndStringify(data)});
});
}
/**
* Get all the offline saved activity logs.
*
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any[]>} Promise resolved with the list of offline logs.
*/
protected getAllLogs(siteId?: string): Promise<any[]> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.getDb().getAllRecords(CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE);
});
}
/**
* Get the offline saved activity logs.
*
* @param {string} component Component name.
* @param {number} componentId Component ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any[]>} Promise resolved with the list of offline logs.
*/
protected getLogs(component: string, componentId: number, siteId?: string): Promise<any[]> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.getDb().getRecords(CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE,
{component: component, componentid: componentId});
});
}
/**
* Perform log online. Data will be saved offline for syncing.
*
* @param {string} ws WS name.
* @param {any} data Data to send to the WS.
* @param {string} component Component name.
* @param {number} componentId Component ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
log(ws: string, data: any, component: string, componentId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
if (!this.appProvider.isOnline()) {
// App is offline, store the action.
return this.storeOffline(ws, data, component, componentId, site.getId());
}
return this.logOnline(ws, data, site.getId()).catch((error) => {
if (this.utils.isWebServiceError(error)) {
// The WebService has thrown an error, this means that responses cannot be submitted.
return Promise.reject(error);
}
// Couldn't connect to server, store in offline.
return this.storeOffline(ws, data, component, componentId, site.getId());
});
});
}
/**
* Perform the log online.
*
* @param {string} ws WS name.
* @param {any} data Data to send to the WS.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when log is successfully submitted. Rejected with object containing
* the error message (if any) and a boolean indicating if the error was returned by WS.
*/
protected logOnline(ws: string, data: any, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
return site.write(ws, data).then((response) => {
if (!response.status) {
return Promise.reject(this.utils.createFakeWSError(''));
}
// Remove all the logs performed.
// TODO: Remove this lines when time is accepted in logs.
return this.deleteWSLogs(ws, data);
});
});
}
/**
* Save activity log for offline sync.
*
* @param {string} ws WS name.
* @param {any} data Data to send to the WS.
* @param {string} component Component name.
* @param {number} componentId Component ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<number>} Resolved with the inserted rowId field.
*/
protected storeOffline(ws: string, data: any, component: string, componentId: number, siteId?: string):
Promise<number> {
return this.sitesProvider.getSite(siteId).then((site) => {
const log = {
ws: ws,
data: this.utils.sortAndStringify(data),
component: component,
componentid: componentId,
time: this.timeUtils.timestamp()
};
return site.getDb().insertRecord(CoreCourseLogHelperProvider.ACTIVITY_LOG_TABLE, log);
});
}
/**
* Sync all the offline saved activity logs.
*
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
syncAll(siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
const siteId = site.getId();
return this.getAllLogs(siteId).then((logs) => {
const unique = [];
// TODO: When time is accepted on log, do not discard same logs.
logs.forEach((log) => {
// Just perform unique syncs.
const found = unique.find((doneLog) => {
return log.component == doneLog.component && log.componentid == doneLog.componentid &&
log.ws == doneLog.ws && log.data == doneLog.data;
});
if (!found) {
unique.push(log);
}
});
return this.syncLogs(unique, siteId);
});
});
}
/**
* Sync the offline saved activity logs.
*
* @param {string} component Component name.
* @param {number} componentId Component ID.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<any>} Promise resolved when done.
*/
syncIfNeeded(component: string, componentId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
const siteId = site.getId();
return this.getLogs(component, componentId, siteId).then((logs) => {
const unique = [];
// TODO: When time is accepted on log, do not discard same logs.
logs.forEach((log) => {
// Just perform unique syncs.
const found = unique.find((doneLog) => {
return log.ws == doneLog.ws && log.data == doneLog.data;
});
if (!found) {
unique.push(log);
}
});
return this.syncLogs(unique, siteId);
});
});
}
/**
* Sync and delete given logs.
*
* @param {any[]} logs Array of log objects.
* @param {string} siteId Site Id.
* @return {Promise<any>} Promise resolved when done.
*/
protected syncLogs(logs: any[], siteId: string): Promise<any> {
return Promise.all(logs.map((log) => {
return this.logOnline(log.ws, this.textUtils.parseJSON(log.data), siteId).then(() => {
return this.deleteWSLogsByComponent(log.component, log.componentid, log.ws);
});
}));
}
}

View File

@ -15,6 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCronHandler } from '@providers/cron'; import { CoreCronHandler } from '@providers/cron';
import { CoreCourseSyncProvider } from './sync'; import { CoreCourseSyncProvider } from './sync';
import { CoreCourseLogHelperProvider } from './log-helper';
/** /**
* Synchronization cron handler. * Synchronization cron handler.
@ -23,7 +24,7 @@ import { CoreCourseSyncProvider } from './sync';
export class CoreCourseSyncCronHandler implements CoreCronHandler { export class CoreCourseSyncCronHandler implements CoreCronHandler {
name = 'CoreCourseSyncCronHandler'; name = 'CoreCourseSyncCronHandler';
constructor(private courseSync: CoreCourseSyncProvider) {} constructor(private courseSync: CoreCourseSyncProvider, private logHelper: CoreCourseLogHelperProvider) {}
/** /**
* Execute the process. * Execute the process.
@ -33,7 +34,14 @@ export class CoreCourseSyncCronHandler implements CoreCronHandler {
* @return {Promise<any>} Promise resolved when done, rejected if failure. * @return {Promise<any>} Promise resolved when done, rejected if failure.
*/ */
execute(siteId?: string): Promise<any> { execute(siteId?: string): Promise<any> {
return this.courseSync.syncAllCourses(siteId); const promises = [];
// Sync activity logs even if the activity does not have sync handler.
// This will sync all the activity logs even if there's nothing else to sync and also recources.
promises.push(this.logHelper.syncAll(siteId));
promises.push(this.courseSync.syncAllCourses(siteId));
return Promise.all(promises);
} }
/** /**