From d767b7514e82e52454eaf2e6892c60d902ed501a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Fri, 8 Mar 2019 10:24:25 +0100 Subject: [PATCH] MOBILE-2873 sync: Sync fixes --- src/addon/mod/assign/providers/assign-sync.ts | 4 +- .../mod/assign/providers/prefetch-handler.ts | 3 +- .../mod/choice/providers/prefetch-handler.ts | 3 +- src/addon/mod/choice/providers/sync.ts | 166 +++++++++--------- src/addon/mod/data/components/index/index.ts | 2 +- .../mod/data/providers/prefetch-handler.ts | 3 +- src/addon/mod/data/providers/sync.ts | 2 +- .../feedback/providers/prefetch-handler.ts | 3 +- src/addon/mod/feedback/providers/sync.ts | 2 +- src/addon/mod/forum/components/index/index.ts | 2 +- .../mod/forum/providers/prefetch-handler.ts | 3 +- .../mod/glossary/components/index/index.ts | 2 +- .../glossary/providers/prefetch-handler.ts | 3 +- .../mod/lesson/providers/prefetch-handler.ts | 3 +- src/addon/mod/quiz/providers/helper.ts | 2 +- .../mod/quiz/providers/prefetch-handler.ts | 4 +- .../mod/scorm/providers/prefetch-handler.ts | 3 +- src/addon/mod/scorm/providers/scorm-sync.ts | 2 +- .../mod/survey/providers/prefetch-handler.ts | 3 +- src/addon/mod/survey/providers/sync.ts | 148 ++++++++-------- .../mod/wiki/providers/prefetch-handler.ts | 3 +- .../workshop/providers/prefetch-handler.ts | 3 +- src/core/course/providers/helper.ts | 2 +- .../providers/module-prefetch-delegate.ts | 15 +- 24 files changed, 203 insertions(+), 183 deletions(-) diff --git a/src/addon/mod/assign/providers/assign-sync.ts b/src/addon/mod/assign/providers/assign-sync.ts index f65b2f393..049b44ba3 100644 --- a/src/addon/mod/assign/providers/assign-sync.ts +++ b/src/addon/mod/assign/providers/assign-sync.ts @@ -109,8 +109,8 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { /** * Try to synchronize all the assignments in a certain site or in all sites. * - * @param {boolean} force Wether to force sync not depending on last execution. * @param {string} [siteId] Site ID to sync. If not defined, sync all sites. + * @param {boolean} force Wether to force sync not depending on last execution. * @return {Promise} Promise resolved if sync is successful, rejected if sync fails. */ syncAllAssignments(siteId?: string, force?: boolean): Promise { @@ -120,8 +120,8 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider { /** * Sync all assignments on a site. * - * @param {boolean} [force] Wether to force sync not depending on last execution. * @param {string} [siteId] Site ID to sync. If not defined, sync all sites. + * @param {boolean} [force] Wether to force sync not depending on last execution. * @param {Promise} Promise resolved if sync is successful, rejected if sync fails. */ protected syncAllAssignmentsFunc(siteId?: string, force?: boolean): Promise { diff --git a/src/addon/mod/assign/providers/prefetch-handler.ts b/src/addon/mod/assign/providers/prefetch-handler.ts index 1cc2a6faa..2bac491cc 100644 --- a/src/addon/mod/assign/providers/prefetch-handler.ts +++ b/src/addon/mod/assign/providers/prefetch-handler.ts @@ -461,10 +461,11 @@ export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHan * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { return this.syncProvider.syncAssign(module.instance, siteId); } } diff --git a/src/addon/mod/choice/providers/prefetch-handler.ts b/src/addon/mod/choice/providers/prefetch-handler.ts index c12bf6902..eb8a72d4b 100644 --- a/src/addon/mod/choice/providers/prefetch-handler.ts +++ b/src/addon/mod/choice/providers/prefetch-handler.ts @@ -141,10 +141,11 @@ export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHan * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { if (!this.syncProvider) { this.syncProvider = this.injector.get(AddonModChoiceSyncProvider); } diff --git a/src/addon/mod/choice/providers/sync.ts b/src/addon/mod/choice/providers/sync.ts index 5d7e82d7f..965a1b06d 100644 --- a/src/addon/mod/choice/providers/sync.ts +++ b/src/addon/mod/choice/providers/sync.ts @@ -67,8 +67,8 @@ export class AddonModChoiceSyncProvider extends CoreCourseActivitySyncBaseProvid /** * Try to synchronize all the choices in a certain site or in all sites. * - * @param {boolean} force Wether to force sync not depending on last execution. * @param {string} [siteId] Site ID to sync. If not defined, sync all sites. + * @param {boolean} force Wether to force sync not depending on last execution. * @return {Promise} Promise resolved if sync is successful, rejected if sync fails. */ syncAllChoices(siteId?: string, force?: boolean): Promise { @@ -132,94 +132,96 @@ export class AddonModChoiceSyncProvider extends CoreCourseActivitySyncBaseProvid * @return {Promise} Promise resolved if sync is successful, rejected otherwise. */ syncChoice(choiceId: number, userId?: number, siteId?: string): Promise { - siteId = siteId || this.sitesProvider.getCurrentSiteId(); - userId = userId || this.sitesProvider.getCurrentSiteUserId(); + return this.sitesProvider.getSite(siteId).then((site) => { + userId = userId || site.getUserId(); + siteId = site.getId(); - const syncId = this.getSyncId(choiceId, userId); - if (this.isSyncing(syncId, siteId)) { - // There's already a sync ongoing for this discussion, return the promise. - return this.getOngoingSync(syncId, siteId); - } - - this.logger.debug(`Try to sync choice '${choiceId}' for user '${userId}'`); - - let courseId; - const result = { - warnings: [], - updated: false - }; - - // Sync offline logs. - const syncPromise = this.logHelper.syncIfNeeded(AddonModChoiceProvider.COMPONENT, choiceId, siteId).catch(() => { - // Ignore errors. - }).then(() => { - return this.choiceOffline.getResponse(choiceId, siteId, userId).catch(() => { - // No offline data found, return empty object. - return {}; - }); - }).then((data) => { - if (!data.choiceid) { - // Nothing to sync. - return; + const syncId = this.getSyncId(choiceId, userId); + if (this.isSyncing(syncId, siteId)) { + // There's already a sync ongoing for this discussion, return the promise. + return this.getOngoingSync(syncId, siteId); } - if (!this.appProvider.isOnline()) { - // Cannot sync in offline. - return Promise.reject(null); - } + this.logger.debug(`Try to sync choice '${choiceId}' for user '${userId}'`); - courseId = data.courseid; + let courseId; + const result = { + warnings: [], + updated: false + }; - // Send the responses. - let promise; - - if (data.deleting) { - // A user has deleted some responses. - promise = this.choiceProvider.deleteResponsesOnline(choiceId, data.responses, siteId); - } else { - // A user has added some responses. - promise = this.choiceProvider.submitResponseOnline(choiceId, data.responses, siteId); - } - - return promise.then(() => { - result.updated = true; - - return this.choiceOffline.deleteResponse(choiceId, siteId, userId); - }).catch((error) => { - if (this.utils.isWebServiceError(error)) { - // The WebService has thrown an error, this means that responses cannot be submitted. Delete them. - result.updated = true; - - return this.choiceOffline.deleteResponse(choiceId, siteId, userId).then(() => { - // Responses deleted, add a warning. - result.warnings.push(this.translate.instant('core.warningofflinedatadeleted', { - component: this.componentTranslate, - name: data.name, - error: this.textUtils.getErrorMessageFromError(error) - })); - }); + // Sync offline logs. + const syncPromise = this.logHelper.syncIfNeeded(AddonModChoiceProvider.COMPONENT, choiceId, siteId).catch(() => { + // Ignore errors. + }).then(() => { + return this.choiceOffline.getResponse(choiceId, siteId, userId).catch(() => { + // No offline data found, return empty object. + return {}; + }); + }).then((data) => { + if (!data.choiceid) { + // Nothing to sync. + return; } - // Couldn't connect to server, reject. - return Promise.reject(error); - }); - }).then(() => { - if (courseId) { - // Data has been sent to server, prefetch choice if needed. - return this.courseProvider.getModuleBasicInfoByInstance(choiceId, 'choice', siteId).then((module) => { - return this.prefetchAfterUpdate(module, courseId, undefined, siteId); - }).catch(() => { - // Ignore errors. - }); - } - }).then(() => { - // Sync finished, set sync time. - return this.setSyncTime(syncId, siteId); - }).then(() => { - // All done, return the warnings. - return result; - }); + if (!this.appProvider.isOnline()) { + // Cannot sync in offline. + return Promise.reject(null); + } - return this.addOngoingSync(syncId, syncPromise, siteId); + courseId = data.courseid; + + // Send the responses. + let promise; + + if (data.deleting) { + // A user has deleted some responses. + promise = this.choiceProvider.deleteResponsesOnline(choiceId, data.responses, siteId); + } else { + // A user has added some responses. + promise = this.choiceProvider.submitResponseOnline(choiceId, data.responses, siteId); + } + + return promise.then(() => { + result.updated = true; + + return this.choiceOffline.deleteResponse(choiceId, siteId, userId); + }).catch((error) => { + if (this.utils.isWebServiceError(error)) { + // The WebService has thrown an error, this means that responses cannot be submitted. Delete them. + result.updated = true; + + return this.choiceOffline.deleteResponse(choiceId, siteId, userId).then(() => { + // Responses deleted, add a warning. + result.warnings.push(this.translate.instant('core.warningofflinedatadeleted', { + component: this.componentTranslate, + name: data.name, + error: this.textUtils.getErrorMessageFromError(error) + })); + }); + } + + // Couldn't connect to server, reject. + return Promise.reject(error); + }); + }).then(() => { + if (courseId) { + // Data has been sent to server, prefetch choice if needed. + return this.courseProvider.getModuleBasicInfoByInstance(choiceId, 'choice', siteId).then((module) => { + return this.prefetchAfterUpdate(module, courseId, undefined, siteId); + }).catch(() => { + // Ignore errors. + }); + } + }).then(() => { + // Sync finished, set sync time. + return this.setSyncTime(syncId, siteId); + }).then(() => { + // All done, return the warnings. + return result; + }); + + return this.addOngoingSync(syncId, syncPromise, siteId); + }); } } diff --git a/src/addon/mod/data/components/index/index.ts b/src/addon/mod/data/components/index/index.ts index caaae195f..54c6d61cd 100644 --- a/src/addon/mod/data/components/index/index.ts +++ b/src/addon/mod/data/components/index/index.ts @@ -521,7 +521,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp * @return {Promise} Promise resolved when done. */ protected sync(): Promise { - return this.prefetchHandler.sync(this.module); + return this.prefetchHandler.sync(this.module, this.courseId); } /** diff --git a/src/addon/mod/data/providers/prefetch-handler.ts b/src/addon/mod/data/providers/prefetch-handler.ts index 8ac16c797..5586ef558 100644 --- a/src/addon/mod/data/providers/prefetch-handler.ts +++ b/src/addon/mod/data/providers/prefetch-handler.ts @@ -307,10 +307,11 @@ export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandl * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { const promises = [ this.syncProvider.syncDatabase(module.instance, siteId), this.syncProvider.syncRatings(module.id, true, siteId) diff --git a/src/addon/mod/data/providers/sync.ts b/src/addon/mod/data/providers/sync.ts index cb1465820..5bfe991bd 100644 --- a/src/addon/mod/data/providers/sync.ts +++ b/src/addon/mod/data/providers/sync.ts @@ -66,8 +66,8 @@ export class AddonModDataSyncProvider extends CoreSyncBaseProvider { /** * Try to synchronize all the databases in a certain site or in all sites. * - * @param {boolean} force Wether to force sync not depending on last execution. * @param {string} [siteId] Site ID to sync. If not defined, sync all sites. + * @param {boolean} force Wether to force sync not depending on last execution. * @return {Promise} Promise resolved if sync is successful, rejected if sync fails. */ syncAllDatabases(siteId?: string, force?: boolean): Promise { diff --git a/src/addon/mod/feedback/providers/prefetch-handler.ts b/src/addon/mod/feedback/providers/prefetch-handler.ts index 2e6d0ed7a..b6ab91297 100644 --- a/src/addon/mod/feedback/providers/prefetch-handler.ts +++ b/src/addon/mod/feedback/providers/prefetch-handler.ts @@ -248,10 +248,11 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchH * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { if (!this.syncProvider) { this.syncProvider = this.injector.get(AddonModFeedbackSyncProvider); } diff --git a/src/addon/mod/feedback/providers/sync.ts b/src/addon/mod/feedback/providers/sync.ts index 08604869a..c643f237b 100644 --- a/src/addon/mod/feedback/providers/sync.ts +++ b/src/addon/mod/feedback/providers/sync.ts @@ -71,8 +71,8 @@ export class AddonModFeedbackSyncProvider extends CoreCourseActivitySyncBaseProv /** * Try to synchronize all the feedbacks in a certain site or in all sites. * - * @param {boolean} force Wether to force sync not depending on last execution. * @param {string} [siteId] Site ID to sync. If not defined, sync all sites. + * @param {boolean} force Wether to force sync not depending on last execution. * @return {Promise} Promise resolved if sync is successful, rejected if sync fails. */ syncAllFeedbacks(siteId?: string, force?: boolean): Promise { diff --git a/src/addon/mod/forum/components/index/index.ts b/src/addon/mod/forum/components/index/index.ts index 38551d2ff..999974f31 100644 --- a/src/addon/mod/forum/components/index/index.ts +++ b/src/addon/mod/forum/components/index/index.ts @@ -376,7 +376,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom * @return {Promise} Promise resolved when done. */ protected sync(): Promise { - return this.prefetchHandler.sync(this.module); + return this.prefetchHandler.sync(this.module, this.courseId); } /** diff --git a/src/addon/mod/forum/providers/prefetch-handler.ts b/src/addon/mod/forum/providers/prefetch-handler.ts index 1da5e7b71..2b03e2525 100644 --- a/src/addon/mod/forum/providers/prefetch-handler.ts +++ b/src/addon/mod/forum/providers/prefetch-handler.ts @@ -271,10 +271,11 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { const promises = []; promises.push(this.syncProvider.syncForumDiscussions(module.instance, undefined, siteId)); diff --git a/src/addon/mod/glossary/components/index/index.ts b/src/addon/mod/glossary/components/index/index.ts index f44df70c6..1f473e081 100644 --- a/src/addon/mod/glossary/components/index/index.ts +++ b/src/addon/mod/glossary/components/index/index.ts @@ -220,7 +220,7 @@ export class AddonModGlossaryIndexComponent extends CoreCourseModuleMainActivity * @return {Promise} Promise resolved when done. */ protected sync(): Promise { - return this.prefetchHandler.sync(this.module); + return this.prefetchHandler.sync(this.module, this.courseId); } /** diff --git a/src/addon/mod/glossary/providers/prefetch-handler.ts b/src/addon/mod/glossary/providers/prefetch-handler.ts index 2436dd1b8..fb283d9b4 100644 --- a/src/addon/mod/glossary/providers/prefetch-handler.ts +++ b/src/addon/mod/glossary/providers/prefetch-handler.ts @@ -194,10 +194,11 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchH * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { const promises = [ this.syncProvider.syncGlossaryEntries(module.instance, undefined, siteId), this.syncProvider.syncRatings(module.id, undefined, siteId) diff --git a/src/addon/mod/lesson/providers/prefetch-handler.ts b/src/addon/mod/lesson/providers/prefetch-handler.ts index cdc03d516..01eed6fa3 100644 --- a/src/addon/mod/lesson/providers/prefetch-handler.ts +++ b/src/addon/mod/lesson/providers/prefetch-handler.ts @@ -437,10 +437,11 @@ export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHan * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { if (!this.syncProvider) { this.syncProvider = this.injector.get(AddonModLessonSyncProvider); } diff --git a/src/addon/mod/quiz/providers/helper.ts b/src/addon/mod/quiz/providers/helper.ts index af9d466a8..fbf0d5f61 100644 --- a/src/addon/mod/quiz/providers/helper.ts +++ b/src/addon/mod/quiz/providers/helper.ts @@ -49,7 +49,7 @@ export class AddonModQuizHelperProvider { getAndCheckPreflightData(quiz: any, accessInfo: any, preflightData: any, attempt: any, offline?: boolean, prefetch?: boolean, title?: string, siteId?: string, retrying?: boolean): Promise { - const rules = accessInfo.activerulenames; + const rules = accessInfo && accessInfo.activerulenames; let isPreflightCheckRequired = false; // Check if the user needs to input preflight data. diff --git a/src/addon/mod/quiz/providers/prefetch-handler.ts b/src/addon/mod/quiz/providers/prefetch-handler.ts index 7a4387058..9c9c65704 100644 --- a/src/addon/mod/quiz/providers/prefetch-handler.ts +++ b/src/addon/mod/quiz/providers/prefetch-handler.ts @@ -567,6 +567,8 @@ export class AddonModQuizPrefetchHandler extends CoreCourseActivityPrefetchHandl this.syncProvider = this.injector.get(AddonModQuizSyncProvider); } - return this.syncProvider.syncQuiz(module.instance, false, siteId); + return this.quizProvider.getQuiz(module.course, module.id).then((quiz) => { + return this.syncProvider.syncQuiz(quiz, false, siteId); + }); } } diff --git a/src/addon/mod/scorm/providers/prefetch-handler.ts b/src/addon/mod/scorm/providers/prefetch-handler.ts index 161f3243c..d64ad764b 100644 --- a/src/addon/mod/scorm/providers/prefetch-handler.ts +++ b/src/addon/mod/scorm/providers/prefetch-handler.ts @@ -431,10 +431,11 @@ export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHand * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { if (!this.syncProvider) { this.syncProvider = this.injector.get(AddonModScormSyncProvider); } diff --git a/src/addon/mod/scorm/providers/scorm-sync.ts b/src/addon/mod/scorm/providers/scorm-sync.ts index 163c4cd7a..bb6074179 100644 --- a/src/addon/mod/scorm/providers/scorm-sync.ts +++ b/src/addon/mod/scorm/providers/scorm-sync.ts @@ -443,8 +443,8 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide /** * Try to synchronize all the SCORMs in a certain site or in all sites. * - * @param {boolean} force Wether to force sync not depending on last execution. * @param {string} [siteId] Site ID to sync. If not defined, sync all sites. + * @param {boolean} force Wether to force sync not depending on last execution. * @return {Promise} Promise resolved if sync is successful, rejected if sync fails. */ syncAllScorms(siteId?: string, force?: boolean): Promise { diff --git a/src/addon/mod/survey/providers/prefetch-handler.ts b/src/addon/mod/survey/providers/prefetch-handler.ts index c1ffba84a..83945c844 100644 --- a/src/addon/mod/survey/providers/prefetch-handler.ts +++ b/src/addon/mod/survey/providers/prefetch-handler.ts @@ -134,10 +134,11 @@ export class AddonModSurveyPrefetchHandler extends CoreCourseActivityPrefetchHan * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { if (!this.syncProvider) { this.syncProvider = this.injector.get(AddonModSurveySyncProvider); } diff --git a/src/addon/mod/survey/providers/sync.ts b/src/addon/mod/survey/providers/sync.ts index e2e459a18..0a57a0258 100644 --- a/src/addon/mod/survey/providers/sync.ts +++ b/src/addon/mod/survey/providers/sync.ts @@ -135,87 +135,89 @@ export class AddonModSurveySyncProvider extends CoreCourseActivitySyncBaseProvid * @return {Promise} Promise resolved if sync is successful, rejected otherwise. */ syncSurvey(surveyId: number, userId?: number, siteId?: string): Promise { - siteId = siteId || this.sitesProvider.getCurrentSiteId(); - userId = userId || this.sitesProvider.getCurrentSiteUserId(); + return this.sitesProvider.getSite(siteId).then((site) => { + userId = userId || site.getUserId(); + siteId = site.getId(); - const syncId = this.getSyncId(surveyId, userId); - if (this.isSyncing(syncId, siteId)) { - // There's already a sync ongoing for this survey and user, return the promise. - return this.getOngoingSync(syncId, siteId); - } - - this.logger.debug(`Try to sync survey '${surveyId}' for user '${userId}'`); - - let courseId; - const result = { - warnings: [], - answersSent: false - }; - - // Sync offline logs. - const syncPromise = this.logHelper.syncIfNeeded(AddonModSurveyProvider.COMPONENT, surveyId, siteId).catch(() => { - // Ignore errors. - }).then(() => { - // 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. - return; + const syncId = this.getSyncId(surveyId, userId); + if (this.isSyncing(syncId, siteId)) { + // There's already a sync ongoing for this survey and user, return the promise. + return this.getOngoingSync(syncId, siteId); } - if (!this.appProvider.isOnline()) { - // Cannot sync in offline. - return Promise.reject(null); - } + this.logger.debug(`Try to sync survey '${surveyId}' for user '${userId}'`); - courseId = data.courseid; + let courseId; + const result = { + warnings: [], + answersSent: false + }; - // Send the answers. - return this.surveyProvider.submitAnswersOnline(surveyId, data.answers, siteId).then(() => { - result.answersSent = true; - - // Answers sent, delete them. - return this.surveyOffline.deleteSurveyAnswers(surveyId, siteId, userId); - }).catch((error) => { - if (this.utils.isWebServiceError(error)) { - - // The WebService has thrown an error, this means that answers cannot be submitted. Delete them. - result.answersSent = true; - - return this.surveyOffline.deleteSurveyAnswers(surveyId, siteId, userId).then(() => { - // Answers deleted, add a warning. - result.warnings.push(this.translate.instant('core.warningofflinedatadeleted', { - component: this.componentTranslate, - name: data.name, - error: this.textUtils.getErrorMessageFromError(error) - })); - }); + // Sync offline logs. + const syncPromise = this.logHelper.syncIfNeeded(AddonModSurveyProvider.COMPONENT, surveyId, siteId).catch(() => { + // Ignore errors. + }).then(() => { + // 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. + return; } - // Couldn't connect to server, reject. - return Promise.reject(error); - }); - }).then(() => { - if (courseId) { - // Data has been sent to server, update survey data. - return this.courseProvider.getModuleBasicInfoByInstance(surveyId, 'survey', siteId).then((module) => { - return this.prefetchAfterUpdate(module, courseId, undefined, siteId); - }).catch(() => { - // Ignore errors. - }); - } - }).then(() => { - // Sync finished, set sync time. - return this.setSyncTime(syncId, siteId); - }).then(() => { - return result; - }); + if (!this.appProvider.isOnline()) { + // Cannot sync in offline. + return Promise.reject(null); + } - return this.addOngoingSync(syncId, syncPromise, siteId); + courseId = data.courseid; + + // Send the answers. + return this.surveyProvider.submitAnswersOnline(surveyId, data.answers, siteId).then(() => { + result.answersSent = true; + + // Answers sent, delete them. + return this.surveyOffline.deleteSurveyAnswers(surveyId, siteId, userId); + }).catch((error) => { + if (this.utils.isWebServiceError(error)) { + + // The WebService has thrown an error, this means that answers cannot be submitted. Delete them. + result.answersSent = true; + + return this.surveyOffline.deleteSurveyAnswers(surveyId, siteId, userId).then(() => { + // Answers deleted, add a warning. + result.warnings.push(this.translate.instant('core.warningofflinedatadeleted', { + component: this.componentTranslate, + name: data.name, + error: this.textUtils.getErrorMessageFromError(error) + })); + }); + } + + // Couldn't connect to server, reject. + return Promise.reject(error); + }); + }).then(() => { + if (courseId) { + // Data has been sent to server, update survey data. + return this.courseProvider.getModuleBasicInfoByInstance(surveyId, 'survey', siteId).then((module) => { + return this.prefetchAfterUpdate(module, courseId, undefined, siteId); + }).catch(() => { + // Ignore errors. + }); + } + }).then(() => { + // Sync finished, set sync time. + return this.setSyncTime(syncId, siteId); + }).then(() => { + return result; + }); + + return this.addOngoingSync(syncId, syncPromise, siteId); + }); } } diff --git a/src/addon/mod/wiki/providers/prefetch-handler.ts b/src/addon/mod/wiki/providers/prefetch-handler.ts index 02762895c..5aaa5d158 100644 --- a/src/addon/mod/wiki/providers/prefetch-handler.ts +++ b/src/addon/mod/wiki/providers/prefetch-handler.ts @@ -217,10 +217,11 @@ export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandl * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { return this.syncProvider.syncWiki(module.instance, module.course, module.id, siteId); } } diff --git a/src/addon/mod/workshop/providers/prefetch-handler.ts b/src/addon/mod/workshop/providers/prefetch-handler.ts index b6da65262..9ec409fa3 100644 --- a/src/addon/mod/workshop/providers/prefetch-handler.ts +++ b/src/addon/mod/workshop/providers/prefetch-handler.ts @@ -372,10 +372,11 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchH * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync(module: any, siteId?: string): Promise { + sync(module: any, courseId: number, siteId?: any): Promise { return this.syncProvider.syncWorkshop(module.instance, siteId); } } diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index aca768b0d..fa1fd33f5 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -1319,7 +1319,7 @@ export class CoreCourseHelperProvider { section.isDownloading = true; // Sync the modules first. - promises.push(this.prefetchDelegate.syncModules(section.modules).then(() => { + promises.push(this.prefetchDelegate.syncModules(section.modules, courseId).then(() => { // Validate the section needs to be downloaded and calculate amount of modules that need to be downloaded. return this.prefetchDelegate.getModulesStatus(section.modules, courseId, section.id).then((result) => { if (result.status == CoreConstants.DOWNLOADED || result.status == CoreConstants.NOT_DOWNLOADABLE) { diff --git a/src/core/course/providers/module-prefetch-delegate.ts b/src/core/course/providers/module-prefetch-delegate.ts index 7691f5276..25aae46ab 100644 --- a/src/core/course/providers/module-prefetch-delegate.ts +++ b/src/core/course/providers/module-prefetch-delegate.ts @@ -211,10 +211,11 @@ export interface CoreCourseModulePrefetchHandler extends CoreDelegateHandler { * Sync a module. * * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when done. */ - sync?(module: any, siteId?: any): Promise; + sync?(module: any, courseId: number, siteId?: any): Promise; } /** @@ -1148,7 +1149,7 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { // Check if the module has a prefetch handler. if (handler) { - return this.syncModule(module).then(() => { + return this.syncModule(module, courseId).then(() => { return handler.prefetch(module, courseId, single); }); } @@ -1160,11 +1161,12 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { * Sync a group of modules. * * @param {any[]} modules Array of modules to sync. + * @param {number} courseId Course ID the module belongs to. * @return {Promise} Promise resolved when finished. */ - syncModules(modules: any[]): Promise { + syncModules(modules: any[], courseId: number): Promise { return Promise.all(modules.map((module) => { - return this.syncModule(module); + return this.syncModule(module, courseId); })); } @@ -1172,12 +1174,13 @@ export class CoreCourseModulePrefetchDelegate extends CoreDelegate { * Sync a module. * * @param {any} module Module to sync. + * @param {number} courseId Course ID the module belongs to. * @return {Promise} Promise resolved when finished. */ - syncModule(module: any): Promise { + syncModule(module: any, courseId: number): Promise { const handler = this.getPrefetchHandlerFor(module); - const promise = handler && handler.sync ? handler.sync(module) : Promise.resolve(); + const promise = handler && handler.sync ? handler.sync(module, courseId) : Promise.resolve(); return promise.catch(() => { // Ignore errors.