MOBILE-1979 sync: Sync activity logs
parent
56eaafdeda
commit
9143507284
|
@ -23,6 +23,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
|
|||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
|
||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
import { AddonModAssignProvider } from './assign';
|
||||
|
@ -61,7 +62,8 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
|
|||
private courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
|
||||
private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
@ -202,6 +204,9 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
|
|||
return [];
|
||||
}));
|
||||
|
||||
// Sync offline logs.
|
||||
promises.push(this.logHelper.syncIfNeeded(AddonModAssignProvider.COMPONENT, assignId, siteId));
|
||||
|
||||
syncPromise = Promise.all(promises).then((results) => {
|
||||
const submissions = results[0],
|
||||
grades = results[1];
|
||||
|
|
|
@ -25,6 +25,7 @@ import { AddonModChoiceProvider } from './choice';
|
|||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreSyncProvider } from '@providers/sync';
|
||||
|
||||
/**
|
||||
|
@ -40,7 +41,8 @@ export class AddonModChoiceSyncProvider extends CoreSyncBaseProvider {
|
|||
protected appProvider: CoreAppProvider, private choiceOffline: AddonModChoiceOfflineProvider,
|
||||
private eventsProvider: CoreEventsProvider, private choiceProvider: AddonModChoiceProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
||||
|
@ -137,10 +139,12 @@ export class AddonModChoiceSyncProvider extends CoreSyncBaseProvider {
|
|||
updated: false
|
||||
};
|
||||
|
||||
// Get offline responses to be sent.
|
||||
const syncPromise = this.choiceOffline.getResponse(choiceId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return {};
|
||||
// Sync offline logs.
|
||||
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.
|
||||
return {};
|
||||
});
|
||||
}).then((data) => {
|
||||
if (!data.choiceid) {
|
||||
// Nothing to sync.
|
||||
|
|
|
@ -26,6 +26,7 @@ import { AddonModDataHelperProvider } from './helper';
|
|||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreSyncProvider } from '@providers/sync';
|
||||
|
||||
/**
|
||||
|
@ -42,7 +43,7 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
|||
private eventsProvider: CoreEventsProvider, private dataProvider: AddonModDataProvider,
|
||||
protected translate: TranslateService, private utils: CoreUtilsProvider, courseProvider: CoreCourseProvider,
|
||||
syncProvider: CoreSyncProvider, protected textUtils: CoreTextUtilsProvider, timeUtils: CoreTimeUtilsProvider,
|
||||
private dataHelper: AddonModDataHelperProvider) {
|
||||
private dataHelper: AddonModDataHelperProvider, private logHelper: CoreCourseLogHelperProvider) {
|
||||
super('AddonModDataSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
|
||||
timeUtils);
|
||||
|
||||
|
@ -149,10 +150,13 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider {
|
|||
updated: false
|
||||
};
|
||||
|
||||
// Get answers to be sent.
|
||||
const syncPromise = this.dataOffline.getDatabaseEntries(dataId, siteId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return [];
|
||||
// Sync offline logs.
|
||||
const syncPromise = this.logHelper.syncIfNeeded(AddonModDataProvider.COMPONENT, dataId, siteId).finally(() => {
|
||||
// Get answers to be sent.
|
||||
return this.dataOffline.getDatabaseEntries(dataId, siteId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return [];
|
||||
});
|
||||
}).then((offlineActions) => {
|
||||
if (!offlineActions.length) {
|
||||
// Nothing to sync.
|
||||
|
|
|
@ -26,6 +26,7 @@ import { CoreEventsProvider } from '@providers/events';
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreSyncProvider } from '@providers/sync';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
|
||||
/**
|
||||
* Service to sync feedbacks.
|
||||
|
@ -40,7 +41,8 @@ export class AddonModFeedbackSyncProvider extends CoreSyncBaseProvider {
|
|||
protected appProvider: CoreAppProvider, private feedbackOffline: AddonModFeedbackOfflineProvider,
|
||||
private eventsProvider: CoreEventsProvider, private feedbackProvider: AddonModFeedbackProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
||||
|
@ -144,10 +146,13 @@ export class AddonModFeedbackSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
this.logger.debug(`Try to sync feedback '${feedbackId}' in site ${siteId}'`);
|
||||
|
||||
// Get offline responses to be sent.
|
||||
const syncPromise = this.feedbackOffline.getFeedbackResponses(feedbackId, siteId).catch(() => {
|
||||
// No offline data found, return empty array.
|
||||
return [];
|
||||
// Sync offline logs.
|
||||
const syncPromise = this.logHelper.syncIfNeeded(AddonModFeedbackProvider.COMPONENT, feedbackId, siteId).finally(() => {
|
||||
// Get offline responses to be sent.
|
||||
return this.feedbackOffline.getFeedbackResponses(feedbackId, siteId).catch(() => {
|
||||
// No offline data found, return empty array.
|
||||
return [];
|
||||
});
|
||||
}).then((responses) => {
|
||||
if (!responses.length) {
|
||||
// Nothing to sync.
|
||||
|
|
|
@ -299,7 +299,7 @@ export class AddonModForumDiscussionPage implements OnDestroy {
|
|||
|
||||
if (forceMarkAsRead || (hasUnreadPosts && this.trackPosts)) {
|
||||
// // Add log in Moodle and mark unread posts as readed.
|
||||
this.forumProvider.logDiscussionView(this.discussionId, this.forumId).catch(() => {
|
||||
this.forumProvider.logDiscussionView(this.discussionId, this.forumId || -1).catch(() => {
|
||||
// Ignore errors.
|
||||
}).finally(() => {
|
||||
// Trigger mark read posts.
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
|
@ -53,7 +54,8 @@ export class AddonModForumSyncProvider extends CoreSyncBaseProvider {
|
|||
private utils: CoreUtilsProvider,
|
||||
private forumProvider: AddonModForumProvider,
|
||||
private forumHelper: AddonModForumHelperProvider,
|
||||
private forumOffline: AddonModForumOfflineProvider) {
|
||||
private forumOffline: AddonModForumOfflineProvider,
|
||||
private logHelper: CoreCourseLogHelperProvider) {
|
||||
|
||||
super('AddonModForumSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
|
||||
timeUtils);
|
||||
|
@ -189,10 +191,13 @@ export class AddonModForumSyncProvider extends CoreSyncBaseProvider {
|
|||
updated: false
|
||||
};
|
||||
|
||||
// Get offline responses to be sent.
|
||||
const syncPromise = this.forumOffline.getNewDiscussions(forumId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return [];
|
||||
// Sync offline logs.
|
||||
const syncPromise = this.logHelper.syncIfNeeded(AddonModForumProvider.COMPONENT, forumId, siteId).finally(() => {
|
||||
// Get offline responses to be sent.
|
||||
return this.forumOffline.getNewDiscussions(forumId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return [];
|
||||
});
|
||||
}).then((discussions) => {
|
||||
if (!discussions.length) {
|
||||
// Nothing to sync.
|
||||
|
|
|
@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
||||
import { CoreAppProvider } from '@providers/app';
|
||||
import { CoreLoggerProvider } from '@providers/logger';
|
||||
|
@ -52,7 +53,8 @@ export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
|
|||
private utils: CoreUtilsProvider,
|
||||
private glossaryProvider: AddonModGlossaryProvider,
|
||||
private glossaryHelper: AddonModGlossaryHelperProvider,
|
||||
private glossaryOffline: AddonModGlossaryOfflineProvider) {
|
||||
private glossaryOffline: AddonModGlossaryOfflineProvider,
|
||||
private logHelper: CoreCourseLogHelperProvider) {
|
||||
|
||||
super('AddonModGlossarySyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
|
||||
timeUtils);
|
||||
|
@ -160,10 +162,13 @@ export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
|
|||
updated: false
|
||||
};
|
||||
|
||||
// Get offline responses to be sent.
|
||||
const syncPromise = this.glossaryOffline.getGlossaryNewEntries(glossaryId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return [];
|
||||
// Sync offline logs.
|
||||
const syncPromise = this.logHelper.syncIfNeeded(AddonModGlossaryProvider.COMPONENT, glossaryId, siteId).finally(() => {
|
||||
// Get offline responses to be sent.
|
||||
return this.glossaryOffline.getGlossaryNewEntries(glossaryId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return [];
|
||||
});
|
||||
}).then((entries) => {
|
||||
if (!entries.length) {
|
||||
// Nothing to sync.
|
||||
|
|
|
@ -24,6 +24,7 @@ import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
|||
import { CoreUrlUtilsProvider } from '@providers/utils/url';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
import { AddonModLessonProvider } from './lesson';
|
||||
import { AddonModLessonOfflineProvider } from './lesson-offline';
|
||||
|
@ -86,7 +87,8 @@ export class AddonModLessonSyncProvider extends CoreSyncBaseProvider {
|
|||
courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
|
||||
private lessonProvider: AddonModLessonProvider, private lessonOfflineProvider: AddonModLessonOfflineProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
@ -263,8 +265,11 @@ export class AddonModLessonSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
this.logger.debug('Try to sync lesson ' + lessonId + ' in site ' + siteId);
|
||||
|
||||
// Try to synchronize the attempts first.
|
||||
syncPromise = this.lessonOfflineProvider.getLessonAttempts(lessonId, siteId).then((attempts) => {
|
||||
// Sync offline logs.
|
||||
syncPromise = this.logHelper.syncIfNeeded(AddonModLessonProvider.COMPONENT, lessonId, siteId).finally(() => {
|
||||
// Try to synchronize the attempts first.
|
||||
return this.lessonOfflineProvider.getLessonAttempts(lessonId, siteId);
|
||||
}).then((attempts) => {
|
||||
if (!attempts.length) {
|
||||
return;
|
||||
} else if (!this.appProvider.isOnline()) {
|
||||
|
|
|
@ -428,8 +428,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy {
|
|||
});
|
||||
|
||||
// Mark the page as viewed. We'll ignore errors in this call.
|
||||
this.quizProvider.logViewAttempt(this.attempt.id, this.quizId, page, this.preflightData, this.offline)
|
||||
.catch((error) => {
|
||||
this.quizProvider.logViewAttempt(this.attempt.id, page, this.preflightData, this.offline).catch((error) => {
|
||||
// Ignore errors.
|
||||
});
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import { CoreSyncProvider } from '@providers/sync';
|
|||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreQuestionProvider } from '@core/question/providers/question';
|
||||
import { CoreQuestionDelegate } from '@core/question/providers/delegate';
|
||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
|
@ -61,7 +62,7 @@ export class AddonModQuizSyncProvider extends CoreSyncBaseProvider {
|
|||
courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider, timeUtils: CoreTimeUtilsProvider,
|
||||
private quizProvider: AddonModQuizProvider, private quizOfflineProvider: AddonModQuizOfflineProvider,
|
||||
private prefetchHandler: AddonModQuizPrefetchHandler, private questionProvider: CoreQuestionProvider,
|
||||
private questionDelegate: CoreQuestionDelegate) {
|
||||
private questionDelegate: CoreQuestionDelegate, private logHelper: CoreCourseLogHelperProvider) {
|
||||
|
||||
super('AddonModQuizSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
|
||||
timeUtils);
|
||||
|
@ -259,8 +260,11 @@ export class AddonModQuizSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
this.logger.debug('Try to sync quiz ' + quiz.id + ' in site ' + siteId);
|
||||
|
||||
// Get all the offline attempts for the quiz.
|
||||
syncPromise = this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId).then((attempts) => {
|
||||
// Sync offline logs.
|
||||
syncPromise = this.logHelper.syncIfNeeded(AddonModQuizProvider.COMPONENT, quiz.id, siteId).finally(() => {
|
||||
// Get all the offline attempts for the quiz.
|
||||
return this.quizOfflineProvider.getQuizAttempts(quiz.id, siteId);
|
||||
}).then((attempts) => {
|
||||
// Should return 0 or 1 attempt.
|
||||
if (!attempts.length) {
|
||||
return this.finishSync(siteId, quiz, courseId, warnings);
|
||||
|
@ -341,8 +345,8 @@ export class AddonModQuizSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
// Answers sent, now set the current page if the attempt isn't finished.
|
||||
if (!finish) {
|
||||
return this.quizProvider.logViewAttempt(onlineAttempt.id, quiz.id, offlineAttempt.currentpage,
|
||||
preflightData, false).catch(() => {
|
||||
return this.quizProvider.logViewAttempt(onlineAttempt.id, offlineAttempt.currentpage, preflightData,
|
||||
false).catch(() => {
|
||||
// Ignore errors.
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1518,31 +1518,31 @@ 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} [page=0] Page number.
|
||||
* @param {any} [preflightData] Preflight required data (like password).
|
||||
* @param {boolean} [offline] Whether attempt is offline.
|
||||
* @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.
|
||||
*/
|
||||
logViewAttempt(attemptId: number, quizId: number, page: number = 0, preflightData: any = {}, offline?: boolean,
|
||||
siteId?: string): Promise<any> {
|
||||
const params = {
|
||||
attemptid: attemptId,
|
||||
page: page,
|
||||
preflightdata: this.utils.objectToArrayOfObjects(preflightData, 'name', 'value', true)
|
||||
},
|
||||
promises = [];
|
||||
logViewAttempt(attemptId: number, page: number = 0, preflightData: any = {}, offline?: boolean, siteId?: string): Promise<any> {
|
||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const params = {
|
||||
attemptid: attemptId,
|
||||
page: page,
|
||||
preflightdata: this.utils.objectToArrayOfObjects(preflightData, 'name', 'value', true)
|
||||
},
|
||||
promises = [];
|
||||
|
||||
promises.push(this.logHelper.log('mod_quiz_view_attempt', params, AddonModQuizProvider.COMPONENT, quizId, siteId));
|
||||
if (offline) {
|
||||
promises.push(this.quizOfflineProvider.setAttemptCurrentPage(attemptId, page));
|
||||
}
|
||||
promises.push(site.write('mod_quiz_view_attempt', params));
|
||||
if (offline) {
|
||||
promises.push(this.quizOfflineProvider.setAttemptCurrentPage(attemptId, page, site.getId()));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
return Promise.all(promises);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
|
|||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
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 { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
import { AddonModScormProvider, AddonModScormAttemptCountResult } from './scorm';
|
||||
|
@ -67,7 +68,8 @@ export class AddonModScormSyncProvider extends CoreSyncBaseProvider {
|
|||
private eventsProvider: CoreEventsProvider, timeUtils: CoreTimeUtilsProvider,
|
||||
private scormProvider: AddonModScormProvider, private scormOfflineProvider: AddonModScormOfflineProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
@ -646,8 +648,11 @@ export class AddonModScormSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
this.logger.debug('Try to sync SCORM ' + scorm.id + ' in site ' + siteId);
|
||||
|
||||
// Get attempts data. We ignore cache for online attempts, so this call will fail if offline or server down.
|
||||
syncPromise = this.scormProvider.getAttemptCount(scorm.id, false, true, siteId).then((attemptsData) => {
|
||||
// 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.
|
||||
return this.scormProvider.getAttemptCount(scorm.id, false, true, siteId);
|
||||
}).then((attemptsData) => {
|
||||
if (!attemptsData.offline || !attemptsData.offline.length) {
|
||||
// Nothing to sync.
|
||||
return this.finishSync(siteId, scorm, warnings, lastOnline, lastOnlineWasFinished);
|
||||
|
|
|
@ -25,6 +25,7 @@ import { AddonModSurveyProvider } from './survey';
|
|||
import { CoreEventsProvider } from '@providers/events';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreSyncProvider } from '@providers/sync';
|
||||
|
||||
/**
|
||||
|
@ -40,7 +41,7 @@ export class AddonModSurveySyncProvider extends CoreSyncBaseProvider {
|
|||
syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService,
|
||||
courseProvider: CoreCourseProvider, private surveyOffline: AddonModSurveyOfflineProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
@ -141,10 +142,13 @@ export class AddonModSurveySyncProvider extends CoreSyncBaseProvider {
|
|||
answersSent: false
|
||||
};
|
||||
|
||||
// Get answers to be sent.
|
||||
const syncPromise = this.surveyOffline.getSurveyData(surveyId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return {};
|
||||
// Sync offline logs.
|
||||
const syncPromise = this.logHelper.syncIfNeeded(AddonModSurveyProvider.COMPONENT, surveyId, siteId).finally(() => {
|
||||
// Get answers to be sent.
|
||||
return this.surveyOffline.getSurveyData(surveyId, siteId, userId).catch(() => {
|
||||
// No offline data found, return empty object.
|
||||
return {};
|
||||
});
|
||||
}).then((data) => {
|
||||
if (!data.answers || !data.answers.length) {
|
||||
// Nothing to sync.
|
||||
|
|
|
@ -110,7 +110,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
// Ignore errors.
|
||||
});
|
||||
} else {
|
||||
this.wikiProvider.logPageView(this.pageId, this.wikiId).catch(() => {
|
||||
this.wikiProvider.logPageView(this.pageId, this.wiki.id).catch(() => {
|
||||
// Ignore errors.
|
||||
});
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
|
|||
this.currentPage = data.pageId;
|
||||
|
||||
this.showLoadingAndFetch(true, false).then(() => {
|
||||
this.wikiProvider.logPageView(this.currentPage, this.wikiId).catch(() => {
|
||||
this.wikiProvider.logPageView(this.currentPage, this.wiki.id).catch(() => {
|
||||
// Ignore errors.
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,6 +24,7 @@ import { CoreTextUtilsProvider } from '@providers/utils/text';
|
|||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreCourseProvider } from '@core/course/providers/course';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { CoreSyncBaseProvider } from '@classes/base-sync';
|
||||
import { AddonModWikiProvider } from './wiki';
|
||||
import { AddonModWikiOfflineProvider } from './wiki-offline';
|
||||
|
@ -104,7 +105,8 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider {
|
|||
syncProvider: CoreSyncProvider, textUtils: CoreTextUtilsProvider, translate: TranslateService,
|
||||
courseProvider: CoreCourseProvider, private eventsProvider: CoreEventsProvider,
|
||||
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,
|
||||
timeUtils);
|
||||
|
@ -336,8 +338,13 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider {
|
|||
syncWiki(wikiId: number, courseId?: number, cmId?: number, siteId?: string): Promise<AddonModWikiSyncWikiResult> {
|
||||
siteId = siteId || this.sitesProvider.getCurrentSiteId();
|
||||
|
||||
// Sync is done at subwiki level, get all the subwikis.
|
||||
return this.wikiProvider.getSubwikis(wikiId).then((subwikis) => {
|
||||
// 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.
|
||||
return this.wikiProvider.getSubwikis(wikiId);
|
||||
}).then((subwikis) => {
|
||||
const promises = [],
|
||||
result: AddonModWikiSyncWikiResult = {
|
||||
warnings: [],
|
||||
|
|
|
@ -24,6 +24,7 @@ import { CoreSyncProvider } from '@providers/sync';
|
|||
import { CoreTextUtilsProvider } from '@providers/utils/text';
|
||||
import { CoreTimeUtilsProvider } from '@providers/utils/time';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreCourseLogHelperProvider } from '@core/course/providers/log-helper';
|
||||
import { AddonModWorkshopProvider } from './workshop';
|
||||
import { AddonModWorkshopHelperProvider } from './helper';
|
||||
import { AddonModWorkshopOfflineProvider } from './offline';
|
||||
|
@ -51,7 +52,8 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
|
|||
private utils: CoreUtilsProvider,
|
||||
private workshopProvider: AddonModWorkshopProvider,
|
||||
private workshopHelper: AddonModWorkshopHelperProvider,
|
||||
private workshopOffline: AddonModWorkshopOfflineProvider) {
|
||||
private workshopOffline: AddonModWorkshopOfflineProvider,
|
||||
private logHelper: CoreCourseLogHelperProvider) {
|
||||
|
||||
super('AddonModWorkshopSyncProvider', loggerProvider, sitesProvider, appProvider, syncProvider, textUtils, translate,
|
||||
timeUtils);
|
||||
|
@ -172,6 +174,9 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
|
|||
return [];
|
||||
}));
|
||||
|
||||
// Sync offline logs.
|
||||
syncPromises.push(this.logHelper.syncIfNeeded(AddonModWorkshopProvider.COMPONENT, workshopId, siteId));
|
||||
|
||||
const result = {
|
||||
warnings: [],
|
||||
updated: false
|
||||
|
|
|
@ -67,7 +67,7 @@ export class CoreCourseLogHelperProvider {
|
|||
*
|
||||
* @param {string} component Component name.
|
||||
* @param {number} componentId Component 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 deleted, rejected if failure.
|
||||
*/
|
||||
protected deleteLogs(component: string, componentId: number, siteId?: string): Promise<any> {
|
||||
|
@ -78,19 +78,49 @@ export class CoreCourseLogHelperProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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: JSON.stringify(data)});
|
||||
{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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -99,7 +129,7 @@ export class CoreCourseLogHelperProvider {
|
|||
*
|
||||
* @param {string} component Component name.
|
||||
* @param {number} componentId Component 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 with the list of offline logs.
|
||||
*/
|
||||
protected getLogs(component: string, componentId: number, siteId?: string): Promise<any[]> {
|
||||
|
@ -117,7 +147,7 @@ export class CoreCourseLogHelperProvider {
|
|||
* @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.
|
||||
* @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> {
|
||||
|
@ -142,10 +172,10 @@ export class CoreCourseLogHelperProvider {
|
|||
/**
|
||||
* 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
|
||||
* @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> {
|
||||
|
@ -158,8 +188,6 @@ export class CoreCourseLogHelperProvider {
|
|||
// Remove all the logs performed.
|
||||
// TODO: Remove this lines when time is accepted in logs.
|
||||
return this.deleteWSLogs(ws, data);
|
||||
}).catch((error) => {
|
||||
return Promise.reject(this.utils.createFakeWSError(error));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -171,7 +199,7 @@ export class CoreCourseLogHelperProvider {
|
|||
* @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.
|
||||
* @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):
|
||||
|
@ -179,7 +207,7 @@ export class CoreCourseLogHelperProvider {
|
|||
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||
const log = {
|
||||
ws: ws,
|
||||
data: JSON.stringify(data),
|
||||
data: this.utils.sortAndStringify(data),
|
||||
component: component,
|
||||
componentid: componentId,
|
||||
time: this.timeUtils.timestamp()
|
||||
|
@ -189,12 +217,43 @@ export class CoreCourseLogHelperProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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> {
|
||||
|
@ -202,24 +261,37 @@ export class CoreCourseLogHelperProvider {
|
|||
const siteId = site.getId();
|
||||
|
||||
return this.getLogs(component, componentId, siteId).then((logs) => {
|
||||
const done = [];
|
||||
const unique = [];
|
||||
|
||||
// TODO: When time is accepted on log, do not discard same logs.
|
||||
return Promise.all(logs.map((log) => {
|
||||
logs.forEach((log) => {
|
||||
// Just perform unique syncs.
|
||||
const found = done.find((doneLog) => {
|
||||
const found = unique.find((doneLog) => {
|
||||
return log.ws == doneLog.ws && log.data == doneLog.data;
|
||||
});
|
||||
|
||||
if (found) {
|
||||
return Promise.resolve();
|
||||
if (!found) {
|
||||
unique.push(log);
|
||||
}
|
||||
});
|
||||
|
||||
done.push(log);
|
||||
|
||||
return this.logOnline(log.ws, this.textUtils.parseJSON(log.data), siteId);
|
||||
}));
|
||||
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 { CoreCronHandler } from '@providers/cron';
|
||||
import { CoreCourseSyncProvider } from './sync';
|
||||
import { CoreCourseLogHelperProvider } from './log-helper';
|
||||
|
||||
/**
|
||||
* Synchronization cron handler.
|
||||
|
@ -23,7 +24,7 @@ import { CoreCourseSyncProvider } from './sync';
|
|||
export class CoreCourseSyncCronHandler implements CoreCronHandler {
|
||||
name = 'CoreCourseSyncCronHandler';
|
||||
|
||||
constructor(private courseSync: CoreCourseSyncProvider) {}
|
||||
constructor(private courseSync: CoreCourseSyncProvider, private logHelper: CoreCourseLogHelperProvider) {}
|
||||
|
||||
/**
|
||||
* Execute the process.
|
||||
|
@ -33,7 +34,14 @@ export class CoreCourseSyncCronHandler implements CoreCronHandler {
|
|||
* @return {Promise<any>} Promise resolved when done, rejected if failure.
|
||||
*/
|
||||
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…
Reference in New Issue