commit
						8ecf48caa4
					
				| @ -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]; | ||||||
|  | |||||||
| @ -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); | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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. | ||||||
|  |      * @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: 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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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(() => { | ||||||
|  |             return this.choiceOffline.getResponse(choiceId, siteId, userId).catch(() => { | ||||||
|                 // No offline data found, return empty object.
 |                 // No offline data found, return empty object.
 | ||||||
|                 return {}; |                 return {}; | ||||||
|  |             }); | ||||||
|         }).then((data) => { |         }).then((data) => { | ||||||
|             if (!data.choiceid) { |             if (!data.choiceid) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         const syncPromise = this.logHelper.syncIfNeeded(AddonModDataProvider.COMPONENT, dataId, siteId).finally(() => { | ||||||
|             // Get answers to be sent.
 |             // Get answers to be sent.
 | ||||||
|         const syncPromise = this.dataOffline.getDatabaseEntries(dataId, siteId).catch(() => { |             return this.dataOffline.getDatabaseEntries(dataId, siteId).catch(() => { | ||||||
|                 // No offline data found, return empty object.
 |                 // No offline data found, return empty object.
 | ||||||
|                 return []; |                 return []; | ||||||
|  |             }); | ||||||
|         }).then((offlineActions) => { |         }).then((offlineActions) => { | ||||||
|             if (!offlineActions.length) { |             if (!offlineActions.length) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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}'`); | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         const syncPromise = this.logHelper.syncIfNeeded(AddonModFeedbackProvider.COMPONENT, feedbackId, siteId).finally(() => { | ||||||
|             // Get offline responses to be sent.
 |             // Get offline responses to be sent.
 | ||||||
|         const syncPromise = this.feedbackOffline.getFeedbackResponses(feedbackId, siteId).catch(() => { |             return this.feedbackOffline.getFeedbackResponses(feedbackId, siteId).catch(() => { | ||||||
|                 // No offline data found, return empty array.
 |                 // No offline data found, return empty array.
 | ||||||
|                 return []; |                 return []; | ||||||
|  |             }); | ||||||
|         }).then((responses) => { |         }).then((responses) => { | ||||||
|             if (!responses.length) { |             if (!responses.length) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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.
 | ||||||
|  | |||||||
| @ -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. | ||||||
|  |      * @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 = { | ||||||
|             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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         const syncPromise = this.logHelper.syncIfNeeded(AddonModForumProvider.COMPONENT, forumId, siteId).finally(() => { | ||||||
|             // Get offline responses to be sent.
 |             // Get offline responses to be sent.
 | ||||||
|         const syncPromise = this.forumOffline.getNewDiscussions(forumId, siteId, userId).catch(() => { |             return this.forumOffline.getNewDiscussions(forumId, siteId, userId).catch(() => { | ||||||
|                 // No offline data found, return empty object.
 |                 // No offline data found, return empty object.
 | ||||||
|                 return []; |                 return []; | ||||||
|  |             }); | ||||||
|         }).then((discussions) => { |         }).then((discussions) => { | ||||||
|             if (!discussions.length) { |             if (!discussions.length) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|  | |||||||
| @ -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(() => { | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         const syncPromise = this.logHelper.syncIfNeeded(AddonModGlossaryProvider.COMPONENT, glossaryId, siteId).finally(() => { | ||||||
|             // Get offline responses to be sent.
 |             // Get offline responses to be sent.
 | ||||||
|         const syncPromise = this.glossaryOffline.getGlossaryNewEntries(glossaryId, siteId, userId).catch(() => { |             return this.glossaryOffline.getGlossaryNewEntries(glossaryId, siteId, userId).catch(() => { | ||||||
|                 // No offline data found, return empty object.
 |                 // No offline data found, return empty object.
 | ||||||
|                 return []; |                 return []; | ||||||
|  |             }); | ||||||
|         }).then((entries) => { |         }).then((entries) => { | ||||||
|             if (!entries.length) { |             if (!entries.length) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|  | |||||||
| @ -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. | ||||||
|  |      * @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: 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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         syncPromise = this.logHelper.syncIfNeeded(AddonModLessonProvider.COMPONENT, lessonId, siteId).finally(() => { | ||||||
|             // Try to synchronize the attempts first.
 |             // Try to synchronize the attempts first.
 | ||||||
|         syncPromise = this.lessonOfflineProvider.getLessonAttempts(lessonId, siteId).then((attempts) => { |             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()) { | ||||||
|  | |||||||
| @ -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; |  | ||||||
|             }); |  | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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. | ||||||
|  |      * @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: 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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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.
 | ||||||
|             }); |             }); | ||||||
|         }); |         }); | ||||||
|  | |||||||
| @ -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(() => { | ||||||
|  | |||||||
| @ -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); | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         syncPromise = this.logHelper.syncIfNeeded(AddonModQuizProvider.COMPONENT, quiz.id, siteId).finally(() => { | ||||||
|             // Get all the offline attempts for the quiz.
 |             // Get all the offline attempts for the quiz.
 | ||||||
|         syncPromise = this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId).then((attempts) => { |             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); | ||||||
|  | |||||||
| @ -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,15 +1518,17 @@ 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> { | ||||||
|  |         return this.sitesProvider.getSite(siteId).then((site) => { | ||||||
|             const params = { |             const params = { | ||||||
|                     attemptid: attemptId, |                     attemptid: attemptId, | ||||||
|                     page: page, |                     page: page, | ||||||
| @ -1533,26 +1536,29 @@ export class AddonModQuizProvider { | |||||||
|                 }, |                 }, | ||||||
|                 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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         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.
 |             // Get attempts data. We ignore cache for online attempts, so this call will fail if offline or server down.
 | ||||||
|         syncPromise = this.scormProvider.getAttemptCount(scorm.id, false, true, siteId).then((attemptsData) => { |             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); | ||||||
|  | |||||||
| @ -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. | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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 | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  |         // Sync offline logs.
 | ||||||
|  |         const syncPromise = this.logHelper.syncIfNeeded(AddonModSurveyProvider.COMPONENT, surveyId, siteId).finally(() => { | ||||||
|             // Get answers to be sent.
 |             // Get answers to be sent.
 | ||||||
|         const syncPromise = this.surveyOffline.getSurveyData(surveyId, siteId, userId).catch(() => { |             return this.surveyOffline.getSurveyData(surveyId, siteId, userId).catch(() => { | ||||||
|                 // No offline data found, return empty object.
 |                 // No offline data found, return empty object.
 | ||||||
|                 return {}; |                 return {}; | ||||||
|  |             }); | ||||||
|         }).then((data) => { |         }).then((data) => { | ||||||
|             if (!data.answers || !data.answers.length) { |             if (!data.answers || !data.answers.length) { | ||||||
|                 // Nothing to sync.
 |                 // Nothing to sync.
 | ||||||
|  | |||||||
| @ -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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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.
 | ||||||
|                                 }); |                                 }); | ||||||
|                             }); |                             }); | ||||||
|  | |||||||
| @ -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 offline logs.
 | ||||||
|  |         return this.logHelper.syncIfNeeded(AddonModWikiProvider.COMPONENT, wikiId, siteId).catch(() => { | ||||||
|  |             // Ignore errors.
 | ||||||
|  |          }).then(() => { | ||||||
|             // Sync is done at subwiki level, get all the subwikis.
 |             // Sync is done at subwiki level, get all the subwikis.
 | ||||||
|         return this.wikiProvider.getSubwikis(wikiId).then((subwikis) => { |             return this.wikiProvider.getSubwikis(wikiId); | ||||||
|  |         }).then((subwikis) => { | ||||||
|             const promises = [], |             const promises = [], | ||||||
|                 result: AddonModWikiSyncWikiResult = { |                 result: AddonModWikiSyncWikiResult = { | ||||||
|                     warnings: [], |                     warnings: [], | ||||||
|  | |||||||
| @ -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); | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -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.
 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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); | ||||||
|         }); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
							
								
								
									
										297
									
								
								src/core/course/providers/log-helper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										297
									
								
								src/core/course/providers/log-helper.ts
									
									
									
									
									
										Normal 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); | ||||||
|  |             }); | ||||||
|  |         })); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user