From c17534d69dec4f6902bf30169f770b465cdfa91d Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 15 Jun 2018 14:55:50 +0200 Subject: [PATCH] MOBILE-2428 prefetch: Refactor prefetch base classes --- .../mod/assign/providers/prefetch-handler.ts | 36 ++- .../mod/book/providers/prefetch-handler.ts | 21 +- .../mod/choice/providers/prefetch-handler.ts | 42 ++-- .../mod/data/providers/prefetch-handler.ts | 119 +++++---- .../feedback/providers/prefetch-handler.ts | 197 ++++++++------- .../mod/folder/providers/prefetch-handler.ts | 21 +- .../mod/forum/providers/prefetch-handler.ts | 37 +-- .../glossary/providers/prefetch-handler.ts | 37 +-- .../mod/imscp/providers/prefetch-handler.ts | 31 +-- .../mod/lesson/providers/prefetch-handler.ts | 47 ++-- .../mod/page/providers/prefetch-handler.ts | 20 +- .../mod/quiz/providers/prefetch-handler.ts | 43 ++-- .../resource/providers/prefetch-handler.ts | 24 +- .../mod/scorm/providers/prefetch-handler.ts | 29 +-- .../mod/survey/providers/prefetch-handler.ts | 82 ++++--- .../mod/wiki/providers/prefetch-handler.ts | 39 ++- .../workshop/providers/prefetch-handler.ts | 37 +-- src/core/compile/providers/compile.ts | 6 +- .../classes/activity-prefetch-handler.ts | 165 +++++++++++++ .../course/classes/module-prefetch-handler.ts | 231 ++---------------- .../classes/resource-prefetch-handler.ts | 151 ++++++++++++ .../handlers/module-prefetch-handler.ts | 43 +++- src/core/siteplugins/providers/helper.ts | 17 +- 23 files changed, 829 insertions(+), 646 deletions(-) create mode 100644 src/core/course/classes/activity-prefetch-handler.ts create mode 100644 src/core/course/classes/resource-prefetch-handler.ts diff --git a/src/addon/mod/assign/providers/prefetch-handler.ts b/src/addon/mod/assign/providers/prefetch-handler.ts index b409fb1ec..4abdb881c 100644 --- a/src/addon/mod/assign/providers/prefetch-handler.ts +++ b/src/addon/mod/assign/providers/prefetch-handler.ts @@ -12,11 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreGroupsProvider } from '@providers/groups'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; @@ -30,19 +35,21 @@ import { AddonModAssignSubmissionDelegate } from './submission-delegate'; * Handler to prefetch assigns. */ @Injectable() -export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModAssign'; modName = 'assign'; component = AddonModAssignProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^submissions$|^grades$|^gradeitems$|^outcomes$|^comments$/; - constructor(protected injector: Injector, protected assignProvider: AddonModAssignProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected assignProvider: AddonModAssignProvider, protected textUtils: CoreTextUtilsProvider, protected feedbackDelegate: AddonModAssignFeedbackDelegate, - protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseProvider: CoreCourseProvider, - protected courseHelper: CoreCourseHelperProvider, protected filepoolProvider: CoreFilepoolProvider, + protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseHelper: CoreCourseHelperProvider, protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider, protected userProvider: CoreUserProvider, protected assignHelper: AddonModAssignHelperProvider) { - super(injector); + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -65,19 +72,6 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl }); } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Same implementation for download or prefetch. - return this.prefetch(module, courseId, false, dirPath); - } - /** * Get list of files. If not defined, we'll assume they're in module.contents. * @@ -207,7 +201,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/addon/mod/book/providers/prefetch-handler.ts b/src/addon/mod/book/providers/prefetch-handler.ts index aa0b5d8a5..0289370cd 100644 --- a/src/addon/mod/book/providers/prefetch-handler.ts +++ b/src/addon/mod/book/providers/prefetch-handler.ts @@ -12,23 +12,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; import { AddonModBookProvider } from './book'; /** * Handler to prefetch books. */ @Injectable() -export class AddonModBookPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModBookPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase { name = 'AddonModBook'; modName = 'book'; component = AddonModBookProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^entries$/; - isResource = true; - constructor(injector: Injector, protected bookProvider: AddonModBookProvider) { - super(injector); + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected bookProvider: AddonModBookProvider) { + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** diff --git a/src/addon/mod/choice/providers/prefetch-handler.ts b/src/addon/mod/choice/providers/prefetch-handler.ts index 8aee0ec61..fb3680e4c 100644 --- a/src/addon/mod/choice/providers/prefetch-handler.ts +++ b/src/addon/mod/choice/providers/prefetch-handler.ts @@ -12,8 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreUserProvider } from '@core/user/providers/user'; import { AddonModChoiceProvider } from './choice'; import { AddonModChoiceSyncProvider } from './sync'; @@ -22,28 +29,18 @@ import { AddonModChoiceSyncProvider } from './sync'; * Handler to prefetch choices. */ @Injectable() -export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModChoice'; modName = 'choice'; component = AddonModChoiceProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^answers$/; - constructor(protected injector: Injector, protected choiceProvider: AddonModChoiceProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected choiceProvider: AddonModChoiceProvider, protected syncProvider: AddonModChoiceSyncProvider, protected userProvider: CoreUserProvider) { - super(injector); - } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Same implementation for download or prefetch. - return this.prefetch(module, courseId, false, dirPath); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -52,7 +49,7 @@ export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandl * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { @@ -137,13 +134,4 @@ export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandl invalidateModule(module: any, courseId: number): Promise { return this.choiceProvider.invalidateChoiceData(courseId); } - - /** - * Whether or not the handler is enabled on a site level. - * - * @return {boolean|Promise} A boolean, or a promise resolved with a boolean, indicating if the handler is enabled. - */ - isEnabled(): boolean | Promise { - return true; - } } diff --git a/src/addon/mod/data/providers/prefetch-handler.ts b/src/addon/mod/data/providers/prefetch-handler.ts index 81413449f..b39b6b204 100644 --- a/src/addon/mod/data/providers/prefetch-handler.ts +++ b/src/addon/mod/data/providers/prefetch-handler.ts @@ -12,13 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreGroupsProvider } from '@providers/groups'; import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreCommentsProvider } from '@core/comments/providers/comments'; import { CoreCourseProvider } from '@core/course/providers/course'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { AddonModDataProvider } from './data'; import { AddonModDataHelperProvider } from './helper'; @@ -26,63 +31,19 @@ import { AddonModDataHelperProvider } from './helper'; * Handler to prefetch databases. */ @Injectable() -export class AddonModDataPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModData'; modName = 'data'; component = AddonModDataProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^entries$|^gradeitems$|^outcomes$|^comments$|^ratings/; - constructor(injector: Injector, protected dataProvider: AddonModDataProvider, protected timeUtils: CoreTimeUtilsProvider, - protected filepoolProvider: CoreFilepoolProvider, protected dataHelper: AddonModDataHelperProvider, - protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider, - protected courseProvider: CoreCourseProvider) { - super(injector); - } + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected dataProvider: AddonModDataProvider, + protected timeUtils: CoreTimeUtilsProvider, protected dataHelper: AddonModDataHelperProvider, + protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider) { - /** - * Download or prefetch the content. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {boolean} [prefetch] True to prefetch, false to download right away. - * @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files - * relative paths and make the package work in an iframe. Undefined to download the files - * in the filepool root data. - * @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable. - */ - downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise { - const promises = [], - siteId = this.sitesProvider.getCurrentSiteId(); - - promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); - promises.push(this.getDatabaseInfoHelper(module, courseId, false, false, true, siteId).then((info) => { - // Prefetch the database data. - const database = info.database, - promises = []; - - promises.push(this.dataProvider.getFields(database.id, false, true, siteId)); - - promises.push(this.filepoolProvider.addFilesToQueue(siteId, info.files, this.component, module.id)); - - info.groups.forEach((group) => { - promises.push(this.dataProvider.getDatabaseAccessInformation(database.id, group.id, false, true, siteId)); - }); - - info.entries.forEach((entry) => { - promises.push(this.dataProvider.getEntry(database.id, entry.id, siteId)); - if (database.comments) { - promises.push(this.commentsProvider.getComments('module', database.coursemodule, 'mod_data', entry.id, - 'database_entry', 0, siteId)); - } - }); - - // Add Basic Info to manage links. - promises.push(this.courseProvider.getModuleBasicInfoByInstance(database.id, 'data', siteId)); - - return Promise.all(promises); - })); - - return Promise.all(promises); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -282,4 +243,56 @@ export class AddonModDataPrefetchHandler extends CoreCourseModulePrefetchHandler isEnabled(): boolean | Promise { return this.dataProvider.isPluginEnabled(); } + + /** + * Prefetch a module. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when done. + */ + prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { + return this.prefetchPackage(module, courseId, single, this.prefetchDatabase.bind(this)); + } + + /** + * Prefetch a database. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} single True if we're downloading a single module, false if we're downloading a whole section. + * @param {String} siteId Site ID. + * @return {Promise} Promise resolved when done. + */ + protected prefetchDatabase(module: any, courseId: number, single: boolean, siteId: string): Promise { + + return this.getDatabaseInfoHelper(module, courseId, false, false, true, siteId).then((info) => { + // Prefetch the database data. + const database = info.database, + promises = []; + + promises.push(this.dataProvider.getFields(database.id, false, true, siteId)); + + promises.push(this.filepoolProvider.addFilesToQueue(siteId, info.files, this.component, module.id)); + + info.groups.forEach((group) => { + promises.push(this.dataProvider.getDatabaseAccessInformation(database.id, group.id, false, true, siteId)); + }); + + info.entries.forEach((entry) => { + promises.push(this.dataProvider.getEntry(database.id, entry.id, siteId)); + if (database.comments) { + promises.push(this.commentsProvider.getComments('module', database.coursemodule, 'mod_data', entry.id, + 'database_entry', 0, siteId)); + } + }); + + // Add Basic Info to manage links. + promises.push(this.courseProvider.getModuleBasicInfoByInstance(database.id, 'data', siteId)); + + return Promise.all(promises); + }); + } } diff --git a/src/addon/mod/feedback/providers/prefetch-handler.ts b/src/addon/mod/feedback/providers/prefetch-handler.ts index 31b2ba45a..73a9dfc6b 100644 --- a/src/addon/mod/feedback/providers/prefetch-handler.ts +++ b/src/addon/mod/feedback/providers/prefetch-handler.ts @@ -12,11 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { AddonModFeedbackProvider } from './feedback'; import { AddonModFeedbackHelperProvider } from './helper'; -import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreGroupsProvider } from '@providers/groups'; import { CoreUserProvider } from '@core/user/providers/user'; @@ -25,101 +31,19 @@ import { CoreUserProvider } from '@core/user/providers/user'; * Handler to prefetch feedbacks. */ @Injectable() -export class AddonModFeedbackPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModFeedback'; modName = 'feedback'; component = AddonModFeedbackProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^attemptsfinished|^attemptsunfinished$/; - constructor(injector: Injector, protected feedbackProvider: AddonModFeedbackProvider, protected userProvider: CoreUserProvider, - protected filepoolProvider: CoreFilepoolProvider, protected feedbackHelper: AddonModFeedbackHelperProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected feedbackProvider: AddonModFeedbackProvider, + protected userProvider: CoreUserProvider, protected feedbackHelper: AddonModFeedbackHelperProvider, protected timeUtils: CoreTimeUtilsProvider, protected groupsProvider: CoreGroupsProvider) { - super(injector); - } - /** - * Download or prefetch the content. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {boolean} [prefetch] True to prefetch, false to download right away. - * @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files - * relative paths and make the package work in an iframe. Undefined to download the files - * in the filepool root feedback. - * @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable. - */ - downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise { - const promises = [], - siteId = this.sitesProvider.getCurrentSiteId(); - - promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); - promises.push(this.feedbackProvider.getFeedback(courseId, module.id).then((feedback) => { - const p1 = []; - - p1.push(this.getFiles(module, courseId).then((files) => { - return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); - })); - - p1.push(this.feedbackProvider.getFeedbackAccessInformation(feedback.id, false, true, siteId).then((accessData) => { - const p2 = []; - if (accessData.canedititems || accessData.canviewreports) { - // Get all groups analysis. - p2.push(this.feedbackProvider.getAnalysis(feedback.id, undefined, siteId)); - p2.push(this.groupsProvider.getActivityGroupInfo(feedback.coursemodule, true, undefined, siteId) - .then((groupInfo) => { - const p3 = [], - userIds = []; - - if (!groupInfo.groups || groupInfo.groups.length == 0) { - groupInfo.groups = [{id: 0}]; - } - groupInfo.groups.forEach((group) => { - p3.push(this.feedbackProvider.getAnalysis(feedback.id, group.id, siteId)); - p3.push(this.feedbackProvider.getAllResponsesAnalysis(feedback.id, group.id, siteId) - .then((responses) => { - responses.attempts.forEach((attempt) => { - userIds.push(attempt.userid); - }); - })); - - if (!accessData.isanonymous) { - p3.push(this.feedbackProvider.getAllNonRespondents(feedback.id, group.id, siteId) - .then((responses) => { - responses.users.forEach((user) => { - userIds.push(user.userid); - }); - })); - } - }); - - return Promise.all(p3).then(() => { - // Prefetch user profiles. - return this.userProvider.prefetchProfiles(userIds, courseId, siteId); - }); - })); - } - - p2.push(this.feedbackProvider.getItems(feedback.id, siteId)); - - if (accessData.cancomplete && accessData.cansubmit && !accessData.isempty) { - // Send empty data, so it will recover last completed feedback attempt values. - p2.push(this.feedbackProvider.processPageOnline(feedback.id, 0, {}, undefined, siteId).finally(() => { - const p4 = []; - - p4.push(this.feedbackProvider.getCurrentValues(feedback.id, false, true, siteId)); - p4.push(this.feedbackProvider.getResumePage(feedback.id, false, true, siteId)); - - return Promise.all(p4); - })); - } - - return Promise.all(p2); - })); - - return Promise.all(p1); - })); - - return Promise.all(promises); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -224,4 +148,95 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseModulePrefetchHan isEnabled(): boolean | Promise { return this.feedbackProvider.isPluginEnabled(); } + + /** + * Prefetch a module. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when done. + */ + prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { + return this.prefetchPackage(module, courseId, single, this.prefetchFeedback.bind(this)); + } + + /** + * Prefetch a feedback. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} single True if we're downloading a single module, false if we're downloading a whole section. + * @param {String} siteId Site ID. + * @return {Promise} Promise resolved when done. + */ + protected prefetchFeedback(module: any, courseId: number, single: boolean, siteId: string): Promise { + // Prefetch the feedback data. + return this.feedbackProvider.getFeedback(courseId, module.id).then((feedback) => { + const p1 = []; + + p1.push(this.getFiles(module, courseId).then((files) => { + return this.filepoolProvider.addFilesToQueue(siteId, files, this.component, module.id); + })); + + p1.push(this.feedbackProvider.getFeedbackAccessInformation(feedback.id, false, true, siteId).then((accessData) => { + const p2 = []; + if (accessData.canedititems || accessData.canviewreports) { + // Get all groups analysis. + p2.push(this.feedbackProvider.getAnalysis(feedback.id, undefined, siteId)); + p2.push(this.groupsProvider.getActivityGroupInfo(feedback.coursemodule, true, undefined, siteId) + .then((groupInfo) => { + const p3 = [], + userIds = []; + + if (!groupInfo.groups || groupInfo.groups.length == 0) { + groupInfo.groups = [{id: 0}]; + } + groupInfo.groups.forEach((group) => { + p3.push(this.feedbackProvider.getAnalysis(feedback.id, group.id, siteId)); + p3.push(this.feedbackProvider.getAllResponsesAnalysis(feedback.id, group.id, siteId) + .then((responses) => { + responses.attempts.forEach((attempt) => { + userIds.push(attempt.userid); + }); + })); + + if (!accessData.isanonymous) { + p3.push(this.feedbackProvider.getAllNonRespondents(feedback.id, group.id, siteId) + .then((responses) => { + responses.users.forEach((user) => { + userIds.push(user.userid); + }); + })); + } + }); + + return Promise.all(p3).then(() => { + // Prefetch user profiles. + return this.userProvider.prefetchProfiles(userIds, courseId, siteId); + }); + })); + } + + p2.push(this.feedbackProvider.getItems(feedback.id, siteId)); + + if (accessData.cancomplete && accessData.cansubmit && !accessData.isempty) { + // Send empty data, so it will recover last completed feedback attempt values. + p2.push(this.feedbackProvider.processPageOnline(feedback.id, 0, {}, undefined, siteId).finally(() => { + const p4 = []; + + p4.push(this.feedbackProvider.getCurrentValues(feedback.id, false, true, siteId)); + p4.push(this.feedbackProvider.getResumePage(feedback.id, false, true, siteId)); + + return Promise.all(p4); + })); + } + + return Promise.all(p2); + })); + + return Promise.all(p1); + }); + } } diff --git a/src/addon/mod/folder/providers/prefetch-handler.ts b/src/addon/mod/folder/providers/prefetch-handler.ts index 2b443ae83..77197e136 100644 --- a/src/addon/mod/folder/providers/prefetch-handler.ts +++ b/src/addon/mod/folder/providers/prefetch-handler.ts @@ -12,22 +12,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; import { AddonModFolderProvider } from './folder'; /** * Handler to prefetch folders. */ @Injectable() -export class AddonModFolderPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModFolderPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase { name = 'AddonModFolder'; modName = 'folder'; component = AddonModFolderProvider.COMPONENT; - isResource = true; - constructor(injector: Injector, protected folderProvider: AddonModFolderProvider) { - super(injector); + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected folderProvider: AddonModFolderProvider) { + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** diff --git a/src/addon/mod/forum/providers/prefetch-handler.ts b/src/addon/mod/forum/providers/prefetch-handler.ts index 89da20694..81ba80633 100644 --- a/src/addon/mod/forum/providers/prefetch-handler.ts +++ b/src/addon/mod/forum/providers/prefetch-handler.ts @@ -12,8 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreGroupsProvider } from '@providers/groups'; import { CoreUserProvider } from '@core/user/providers/user'; import { AddonModForumProvider } from './forum'; @@ -22,30 +29,24 @@ import { AddonModForumProvider } from './forum'; * Handler to prefetch forums. */ @Injectable() -export class AddonModForumPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModForum'; modName = 'forum'; component = AddonModForumProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^discussions$/; - constructor(injector: Injector, + constructor(translate: TranslateService, + appProvider: CoreAppProvider, + utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, + filepoolProvider: CoreFilepoolProvider, + sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, private groupsProvider: CoreGroupsProvider, private userProvider: CoreUserProvider, private forumProvider: AddonModForumProvider) { - super(injector); - } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Same implementation for download or prefetch. - return this.prefetch(module, courseId, false, dirPath); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -137,7 +138,7 @@ export class AddonModForumPrefetchHandler extends CoreCourseModulePrefetchHandle * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/addon/mod/glossary/providers/prefetch-handler.ts b/src/addon/mod/glossary/providers/prefetch-handler.ts index dc3dcad35..24ac9d4c9 100644 --- a/src/addon/mod/glossary/providers/prefetch-handler.ts +++ b/src/addon/mod/glossary/providers/prefetch-handler.ts @@ -12,8 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreUserProvider } from '@core/user/providers/user'; import { AddonModGlossaryProvider } from './glossary'; @@ -21,29 +28,23 @@ import { AddonModGlossaryProvider } from './glossary'; * Handler to prefetch forums. */ @Injectable() -export class AddonModGlossaryPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModGlossary'; modName = 'glossary'; component = AddonModGlossaryProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^entries$/; - constructor(injector: Injector, + constructor(translate: TranslateService, + appProvider: CoreAppProvider, + utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, + filepoolProvider: CoreFilepoolProvider, + sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, private userProvider: CoreUserProvider, private glossaryProvider: AddonModGlossaryProvider) { - super(injector); - } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Glossaries cannot be downloaded right away, only prefetched. - return this.prefetch(module, courseId); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -102,7 +103,7 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseModulePrefetchHan * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/addon/mod/imscp/providers/prefetch-handler.ts b/src/addon/mod/imscp/providers/prefetch-handler.ts index b82877731..6f8a10c9e 100644 --- a/src/addon/mod/imscp/providers/prefetch-handler.ts +++ b/src/addon/mod/imscp/providers/prefetch-handler.ts @@ -12,36 +12,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; import { AddonModImscpProvider } from './imscp'; /** * Handler to prefetch IMSCPs. */ @Injectable() -export class AddonModImscpPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModImscpPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase { name = 'AddonModImscp'; modName = 'imscp'; component = AddonModImscpProvider.COMPONENT; - isResource = true; - constructor(injector: Injector, protected imscpProvider: AddonModImscpProvider, - protected filepoolProvider: CoreFilepoolProvider) { - super(injector); - } + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected imscpProvider: AddonModImscpProvider) { - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - return this.prefetch(module, courseId, false, dirPath); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** diff --git a/src/addon/mod/lesson/providers/prefetch-handler.ts b/src/addon/mod/lesson/providers/prefetch-handler.ts index 4a1dc83c9..30fbc8a1d 100644 --- a/src/addon/mod/lesson/providers/prefetch-handler.ts +++ b/src/addon/mod/lesson/providers/prefetch-handler.ts @@ -12,26 +12,36 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { ModalController } from 'ionic-angular'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreGroupsProvider } from '@providers/groups'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { AddonModLessonProvider } from './lesson'; /** * Handler to prefetch lessons. */ @Injectable() -export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModLesson'; modName = 'lesson'; component = AddonModLessonProvider.COMPONENT; // Don't check timers to decrease positives. If a user performs some action it will be reflected in other items. updatesNames = /^configuration$|^.*files$|^grades$|^gradeitems$|^pages$|^answers$|^questionattempts$|^pagesviewed$/; - constructor(protected injector: Injector, protected modalCtrl: ModalController, protected groupsProvider: CoreGroupsProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected modalCtrl: ModalController, protected groupsProvider: CoreGroupsProvider, protected lessonProvider: AddonModLessonProvider) { - super(injector); + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -58,19 +68,6 @@ export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandl }); } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Same implementation for download and prefetch. - return this.prefetch(module, courseId, false, dirPath); - } - /** * Get the download size of a module. * @@ -112,18 +109,6 @@ export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandl }); } - /** - * Get list of files. If not defined, we'll assume they're in module.contents. - * - * @param {any} module Module. - * @param {Number} courseId Course ID the module belongs to. - * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @return {Promise} Promise resolved with the list of files. - */ - getFiles(module: any, courseId: number, single?: boolean): Promise { - return Promise.resolve([]); - } - /** * Get the lesson password if needed. If not stored, it can ask the user to enter it. * @@ -254,7 +239,7 @@ export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandl * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/addon/mod/page/providers/prefetch-handler.ts b/src/addon/mod/page/providers/prefetch-handler.ts index 32f6627e6..87000313c 100644 --- a/src/addon/mod/page/providers/prefetch-handler.ts +++ b/src/addon/mod/page/providers/prefetch-handler.ts @@ -12,9 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; import { AddonModPageProvider } from './page'; import { AddonModPageHelperProvider } from './helper'; @@ -22,16 +28,18 @@ import { AddonModPageHelperProvider } from './helper'; * Handler to prefetch pages. */ @Injectable() -export class AddonModPagePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModPagePrefetchHandler extends CoreCourseResourcePrefetchHandlerBase { name = 'AddonModPage'; modName = 'page'; component = AddonModPageProvider.COMPONENT; updatesNames = /^configuration$|^.*files$/; - isResource = true; - constructor(injector: Injector, protected pageProvider: AddonModPageProvider, protected utils: CoreUtilsProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected pageProvider: AddonModPageProvider, protected pageHelper: AddonModPageHelperProvider) { - super(injector); + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** diff --git a/src/addon/mod/quiz/providers/prefetch-handler.ts b/src/addon/mod/quiz/providers/prefetch-handler.ts index 2c932a59a..69ec84506 100644 --- a/src/addon/mod/quiz/providers/prefetch-handler.ts +++ b/src/addon/mod/quiz/providers/prefetch-handler.ts @@ -13,9 +13,16 @@ // limitations under the License. import { Injectable, Injector } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreQuestionHelperProvider } from '@core/question/providers/helper'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { AddonModQuizProvider } from './quiz'; import { AddonModQuizHelperProvider } from './helper'; import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate'; @@ -26,7 +33,7 @@ import { CoreConstants } from '@core/constants'; * Handler to prefetch quizzes. */ @Injectable() -export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModQuizPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModQuiz'; modName = 'quiz'; component = AddonModQuizProvider.COMPONENT; @@ -34,23 +41,13 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler protected syncProvider: AddonModQuizSyncProvider; // It will be injected later to prevent circular dependencies. - constructor(protected injector: Injector, protected quizProvider: AddonModQuizProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected injector: Injector, protected quizProvider: AddonModQuizProvider, protected textUtils: CoreTextUtilsProvider, protected quizHelper: AddonModQuizHelperProvider, protected accessRuleDelegate: AddonModQuizAccessRuleDelegate, protected questionHelper: CoreQuestionHelperProvider) { - super(injector); - } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Same implementation for download or prefetch. - return this.prefetch(module, courseId, false, dirPath); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -69,18 +66,6 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler }); } - /** - * Get list of files. If not defined, we'll assume they're in module.contents. - * - * @param {any} module Module. - * @param {Number} courseId Course ID the module belongs to. - * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @return {Promise} Promise resolved with the list of files. - */ - getFiles(module: any, courseId: number, single?: boolean): Promise { - return Promise.resolve([]); - } - /** * Gather some preflight data for an attempt. This function will start a new attempt if needed. * @@ -190,7 +175,7 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/addon/mod/resource/providers/prefetch-handler.ts b/src/addon/mod/resource/providers/prefetch-handler.ts index d6d9db96f..93b675a0e 100644 --- a/src/addon/mod/resource/providers/prefetch-handler.ts +++ b/src/addon/mod/resource/providers/prefetch-handler.ts @@ -12,25 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; import { AddonModResourceProvider } from './resource'; import { AddonModResourceHelperProvider } from './helper'; -import { CoreFilepoolProvider } from '@providers/filepool'; /** * Handler to prefetch resources. */ @Injectable() -export class AddonModResourcePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModResourcePrefetchHandler extends CoreCourseResourcePrefetchHandlerBase { name = 'AddonModResource'; modName = 'resource'; component = AddonModResourceProvider.COMPONENT; - isResource = true; - constructor(injector: Injector, protected resourceProvider: AddonModResourceProvider, - protected filepoolProvider: CoreFilepoolProvider, protected resourceHelper: AddonModResourceHelperProvider) { - super(injector); + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected resourceProvider: AddonModResourceProvider, + protected resourceHelper: AddonModResourceHelperProvider) { + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** diff --git a/src/addon/mod/scorm/providers/prefetch-handler.ts b/src/addon/mod/scorm/providers/prefetch-handler.ts index de95bd520..c6f19e138 100644 --- a/src/addon/mod/scorm/providers/prefetch-handler.ts +++ b/src/addon/mod/scorm/providers/prefetch-handler.ts @@ -12,10 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreFileProvider } from '@providers/file'; import { CoreTextUtilsProvider } from '@providers/utils/text'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { AddonModScormProvider } from './scorm'; /** @@ -45,15 +52,18 @@ export interface AddonModScormProgressEvent { * Handler to prefetch SCORMs. */ @Injectable() -export class AddonModScormPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModScorm'; modName = 'scorm'; component = AddonModScormProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^tracks$/; - constructor(injector: Injector, protected fileProvider: CoreFileProvider, protected textUtils: CoreTextUtilsProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected fileProvider: CoreFileProvider, protected textUtils: CoreTextUtilsProvider, protected scormProvider: AddonModScormProvider) { - super(injector); + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -359,15 +369,6 @@ export class AddonModScormPrefetchHandler extends CoreCourseModulePrefetchHandle }); } - /** - * Whether or not the handler is enabled on a site level. - * - * @return {boolean|Promise} A boolean, or a promise resolved with a boolean, indicating if the handler is enabled. - */ - isEnabled(): boolean | Promise { - return true; - } - /** * Prefetch a module. * diff --git a/src/addon/mod/survey/providers/prefetch-handler.ts b/src/addon/mod/survey/providers/prefetch-handler.ts index 6b1c998dc..b3ac45ea6 100644 --- a/src/addon/mod/survey/providers/prefetch-handler.ts +++ b/src/addon/mod/survey/providers/prefetch-handler.ts @@ -12,8 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { AddonModSurveyProvider } from './survey'; import { AddonModSurveyHelperProvider } from './helper'; @@ -21,40 +28,18 @@ import { AddonModSurveyHelperProvider } from './helper'; * Handler to prefetch surveys. */ @Injectable() -export class AddonModSurveyPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModSurveyPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModSurvey'; modName = 'survey'; component = AddonModSurveyProvider.COMPONENT; updatesNames = /^configuration$|^.*files$|^answers$/; - constructor(injector: Injector, protected surveyProvider: AddonModSurveyProvider, + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected surveyProvider: AddonModSurveyProvider, protected surveyHelper: AddonModSurveyHelperProvider) { - super(injector); - } - /** - * Download or prefetch the content. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {boolean} [prefetch] True to prefetch, false to download right away. - * @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files - * relative paths and make the package work in an iframe. Undefined to download the files - * in the filepool root survey. - * @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable. - */ - downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise { - const promises = []; - - promises.push(super.downloadOrPrefetch(module, courseId, prefetch)); - promises.push(this.surveyProvider.getSurvey(courseId, module.id).then((survey) => { - // If survey isn't answered, prefetch the questions. - if (!survey.surveydone) { - promises.push(this.surveyProvider.getQuestions(survey.id)); - } - })); - - return Promise.all(promises); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -102,4 +87,43 @@ export class AddonModSurveyPrefetchHandler extends CoreCourseModulePrefetchHandl isEnabled(): boolean | Promise { return true; } + + /** + * Prefetch a module. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when done. + */ + prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { + return this.prefetchPackage(module, courseId, single, this.prefetchSurvey.bind(this)); + } + + /** + * Prefetch a survey. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} single True if we're downloading a single module, false if we're downloading a whole section. + * @param {String} siteId Site ID. + * @return {Promise} Promise resolved when done. + */ + protected prefetchSurvey(module: any, courseId: number, single: boolean, siteId: string): Promise { + return this.surveyProvider.getSurvey(courseId, module.id).then((survey) => { + const promises = [], + files = this.getIntroFilesFromInstance(module, survey); + + // Prefetch files. + promises.push(this.filepoolProvider.addFilesToQueue(siteId, files, AddonModSurveyProvider.COMPONENT, module.id)); + + // If survey isn't answered, prefetch the questions. + if (!survey.surveydone) { + promises.push(this.surveyProvider.getQuestions(survey.id)); + } + + return Promise.all(promises); + }); + } } diff --git a/src/addon/mod/wiki/providers/prefetch-handler.ts b/src/addon/mod/wiki/providers/prefetch-handler.ts index b275bfe9f..6f131ab58 100644 --- a/src/addon/mod/wiki/providers/prefetch-handler.ts +++ b/src/addon/mod/wiki/providers/prefetch-handler.ts @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreGroupsProvider } from '@providers/groups'; import { CoreTextUtilsProvider } from '@providers/utils/text'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; -import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; import { CoreUserProvider } from '@core/user/providers/user'; @@ -27,31 +32,19 @@ import { AddonModWikiProvider } from './wiki'; * Handler to prefetch wikis. */ @Injectable() -export class AddonModWikiPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModWiki'; modName = 'wiki'; component = AddonModWikiProvider.COMPONENT; updatesNames = /^.*files$|^pages$/; - constructor(protected injector: Injector, protected wikiProvider: AddonModWikiProvider, - protected textUtils: CoreTextUtilsProvider, protected courseProvider: CoreCourseProvider, - protected courseHelper: CoreCourseHelperProvider, protected filepoolProvider: CoreFilepoolProvider, - protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider, - protected userProvider: CoreUserProvider) { - super(injector); - } + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected wikiProvider: AddonModWikiProvider, protected userProvider: CoreUserProvider, + protected textUtils: CoreTextUtilsProvider, protected courseHelper: CoreCourseHelperProvider, + protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider) { - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Same implementation for download or prefetch. - return this.prefetch(module, courseId, false, dirPath); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -156,7 +149,7 @@ export class AddonModWikiPrefetchHandler extends CoreCourseModulePrefetchHandler * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/addon/mod/workshop/providers/prefetch-handler.ts b/src/addon/mod/workshop/providers/prefetch-handler.ts index 0dc4f488e..6c5762737 100644 --- a/src/addon/mod/workshop/providers/prefetch-handler.ts +++ b/src/addon/mod/workshop/providers/prefetch-handler.ts @@ -12,8 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; import { CoreGroupsProvider } from '@providers/groups'; import { CoreUserProvider } from '@core/user/providers/user'; import { AddonModWorkshopProvider } from './workshop'; @@ -23,32 +30,26 @@ import { AddonModWorkshopHelperProvider } from './helper'; * Handler to prefetch workshops. */ @Injectable() -export class AddonModWorkshopPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { name = 'AddonModWorkshop'; modName = 'workshop'; component = AddonModWorkshopProvider.COMPONENT; updatesNames = new RegExp('^configuration$|^.*files$|^completion|^gradeitems$|^outcomes$|^submissions$|^assessments$' + '|^assessmentgrades$|^usersubmissions$|^userassessments$|^userassessmentgrades$|^userassessmentgrades$'); - constructor(injector: Injector, + constructor(translate: TranslateService, + appProvider: CoreAppProvider, + utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, + filepoolProvider: CoreFilepoolProvider, + sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, private groupsProvider: CoreGroupsProvider, private userProvider: CoreUserProvider, private workshopProvider: AddonModWorkshopProvider, private workshopHelper: AddonModWorkshopHelperProvider) { - super(injector); - } - /** - * Download the module. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. - * @return {Promise} Promise resolved when all content is downloaded. - */ - download(module: any, courseId: number, dirPath?: string): Promise { - // Workshop cannot be downloaded right away, only prefetched. - return this.prefetch(module, courseId, false, dirPath); + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); } /** @@ -210,7 +211,7 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseModulePrefetchHan * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { diff --git a/src/core/compile/providers/compile.ts b/src/core/compile/providers/compile.ts index 8b96eaf10..d49667352 100644 --- a/src/core/compile/providers/compile.ts +++ b/src/core/compile/providers/compile.ts @@ -56,7 +56,8 @@ import { CoreDelegate } from '@classes/delegate'; import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; import { CoreContentLinksModuleGradeHandler } from '@core/contentlinks/classes/module-grade-handler'; import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; +import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler'; // Import all core modules that define components, directives and pipes. import { CoreComponentsModule } from '@components/components.module'; @@ -257,7 +258,8 @@ export class CoreCompileProvider { instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase; instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler; instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler; - instance['CoreCourseModulePrefetchHandlerBase'] = CoreCourseModulePrefetchHandlerBase; + instance['CoreCourseActivityPrefetchHandlerBase'] = CoreCourseActivityPrefetchHandlerBase; + instance['CoreCourseResourcePrefetchHandlerBase'] = CoreCourseResourcePrefetchHandlerBase; instance['CoreCourseUnsupportedModuleComponent'] = CoreCourseUnsupportedModuleComponent; instance['CoreCourseFormatSingleActivityComponent'] = CoreCourseFormatSingleActivityComponent; instance['CoreSitePluginsModuleIndexComponent'] = CoreSitePluginsModuleIndexComponent; diff --git a/src/core/course/classes/activity-prefetch-handler.ts b/src/core/course/classes/activity-prefetch-handler.ts new file mode 100644 index 000000000..72805ca21 --- /dev/null +++ b/src/core/course/classes/activity-prefetch-handler.ts @@ -0,0 +1,165 @@ +// (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 { CoreConstants } from '../../constants'; +import { CoreCourseModulePrefetchHandlerBase } from './module-prefetch-handler'; + +/** + * A prefetch function to be passed to prefetchPackage. + * This function should NOT call storePackageStatus, downloadPackage or prefetchPakage from filepool. + * It receives the same params as prefetchPackage except the function itself. This includes all extra parameters sent after siteId. + * The string returned by this function will be stored as "extra" data in the filepool package. If you don't need to store + * extra data, don't return anything. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} single True if we're downloading a single module, false if we're downloading a whole section. + * @param {string} siteId Site ID. If not defined, current site. + * @return {Promise} Promise resolved when the prefetch finishes. The string returned will be stored as "extra" data in the + * filepool package. If you don't need to store extra data, don't return anything. + */ +export type prefetchFunction = (module: any, courseId: number, single: boolean, siteId: string, ...args: any[]) => Promise; + +/** + * Base prefetch handler to be registered in CoreCourseModulePrefetchDelegate. It is useful to minimize the amount of + * functions that handlers need to implement. It also provides some helper features like preventing a module to be + * downloaded twice at the same time. + * + * If your handler inherits from this service, you just need to override the functions that you want to change. + * + * This class should be used for ACTIVITIES. You must override the prefetch function, and it's recommended to call + * prefetchPackage in there since it handles the package status. + */ +export class CoreCourseActivityPrefetchHandlerBase extends CoreCourseModulePrefetchHandlerBase { + + /** + * Download the module. + * + * @param {any} module The module object returned by WS. + * @param {number} courseId Course ID. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when all content is downloaded. + */ + download(module: any, courseId: number, dirPath?: string): Promise { + // Same implementation for download and prefetch. + return this.prefetch(module, courseId, false, dirPath); + } + + /** + * Prefetch a module. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when done. + */ + prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { + // To be overridden. It should call prefetchPackage + return Promise.resolve(); + } + + /** + * Prefetch the module, setting package status at start and finish. + * + * Example usage from a child instance: + * return this.prefetchPackage(module, courseId, single, this.prefetchModule.bind(this), siteId, someParam, anotherParam); + * + * Then the function "prefetchModule" will receive params: + * prefetchModule(module, courseId, single, siteId, someParam, anotherParam) + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @param {prefetchFunction} downloadFn Function to perform the prefetch. Please check the documentation of prefetchFunction. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved when the module has been downloaded. Data returned is not reliable. + */ + prefetchPackage(module: any, courseId: number, single: boolean, downloadFn: prefetchFunction, siteId?: string, ...args: any[]) + : Promise { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + if (!this.appProvider.isOnline()) { + // Cannot prefetch in offline. + return Promise.reject(this.translate.instant('core.networkerrormsg')); + } + + if (this.isDownloading(module.id, siteId)) { + // There's already a download ongoing for this module, return the promise. + return this.getOngoingDownload(module.id, siteId); + } + + const prefetchPromise = this.setDownloading(module.id, siteId).then(() => { + // Package marked as downloading, call the download function. + // Send all the params except downloadFn. This includes all params passed after siteId. + return downloadFn.apply(downloadFn, [module, courseId, single, siteId].concat(args)); + }).then((extra: any) => { + // Only accept string types. + if (typeof extra != 'string') { + extra = ''; + } + + // Prefetch finished, mark as downloaded. + return this.setDownloaded(module.id, siteId, extra); + }).catch((error) => { + // Error prefetching, go back to previous status and reject the promise. + return this.setPreviousStatusAndReject(module.id, error, siteId); + }); + + return this.addOngoingDownload(module.id, prefetchPromise, siteId); + } + + /** + * Mark the module as downloaded. + * + * @param {number} id Unique identifier per component. + * @param {string} [siteId] Site ID. If not defined, current site. + * @param {string} [extra] Extra data to store. + * @return {Promise} Promise resolved when done. + */ + setDownloaded(id: number, siteId?: string, extra?: string): Promise { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + return this.filepoolProvider.storePackageStatus(siteId, CoreConstants.DOWNLOADED, this.component, id, extra); + } + + /** + * Mark the module as downloading. + * + * @param {number} id Unique identifier per component. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved when done. + */ + setDownloading(id: number, siteId?: string): Promise { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + return this.filepoolProvider.storePackageStatus(siteId, CoreConstants.DOWNLOADING, this.component, id); + } + + /** + * Set previous status and return a rejected promise. + * + * @param {number} id Unique identifier per component. + * @param {any} [error] Error to return. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Rejected promise. + */ + setPreviousStatusAndReject(id: number, error?: any, siteId?: string): Promise { + siteId = siteId || this.sitesProvider.getCurrentSiteId(); + + return this.filepoolProvider.setPackagePreviousStatus(siteId, this.component, id).then(() => { + return Promise.reject(error); + }); + } +} diff --git a/src/core/course/classes/module-prefetch-handler.ts b/src/core/course/classes/module-prefetch-handler.ts index a663354f4..49ae7e6c4 100644 --- a/src/core/course/classes/module-prefetch-handler.ts +++ b/src/core/course/classes/module-prefetch-handler.ts @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injector } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; import { CoreAppProvider } from '@providers/app'; import { CoreFilepoolProvider } from '@providers/filepool'; @@ -21,36 +20,11 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreCourseProvider } from '../providers/course'; import { CoreCourseModulePrefetchHandler } from '../providers/module-prefetch-delegate'; -import { CoreConstants } from '../../constants'; /** - * A prefetch function to be passed to prefetchPackage. - * This function should NOT call storePackageStatus, downloadPackage or prefetchPakage from filepool. - * It receives the same params as prefetchPackage except the function itself. This includes all extra parameters sent after siteId. - * The string returned by this function will be stored as "extra" data in the filepool package. If you don't need to store - * extra data, don't return anything. - * - * @param {any} module Module. - * @param {number} courseId Course ID the module belongs to. - * @param {boolean} single True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} siteId Site ID. If not defined, current site. - * @return {Promise} Promise resolved when the prefetch finishes. The string returned will be stored as "extra" data in the - * filepool package. If you don't need to store extra data, don't return anything. - */ -export type prefetchFunction = (module: any, courseId: number, single: boolean, siteId: string, ...args: any[]) => Promise; - -/** - * Base prefetch handler to be registered in CoreCourseModulePrefetchDelegate. It is useful to minimize the amount of - * functions that handlers need to implement. It also provides some helper features like preventing a module to be - * downloaded twice at the same time. - * - * If your handler inherits from this service, you just need to override the functions that you want to change. - * - * The implementation of this default handler is aimed for resources that only need to prefetch files, not WebService calls. - * - * By default, prefetching a module will only download its files (downloadOrPrefetch). This might be enough for resources. - * If you need to prefetch WebServices, then you need to override the "download" and "prefetch" functions. In this case, it's - * recommended to call the prefetchPackage function since it'll handle changing the status of the module. + * Base prefetch handler to be registered in CoreCourseModulePrefetchDelegate. Prefetch handlers should inherit either + * from CoreCourseModuleActivityPrefetchHandlerBase or CoreCourseModuleResourcePrefetchHandlerBase, depending on whether + * they are an activity or a resource. It's not recommended to inherit from this class directly. */ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePrefetchHandler { /** @@ -78,37 +52,15 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref */ updatesNames = /^.*files$/; - /** - * Whether the module is a resource (true) or an activity (false). - * @type {boolean} - */ - isResource: boolean; - /** * List of download promises to prevent downloading the module twice at the same time. * @type {{[s: string]: {[s: string]: Promise}}} */ protected downloadPromises: { [s: string]: { [s: string]: Promise } } = {}; - // List of services that will be injected using injector. - // It's done like this so subclasses don't have to send all the services to the parent in the constructor. - protected translate: TranslateService; - protected appProvider: CoreAppProvider; - protected courseProvider: CoreCourseProvider; - protected filepoolProvider: CoreFilepoolProvider; - protected sitesProvider: CoreSitesProvider; - protected domUtils: CoreDomUtilsProvider; - protected utils: CoreUtilsProvider; - - constructor(injector: Injector) { - this.translate = injector.get(TranslateService); - this.appProvider = injector.get(CoreAppProvider); - this.courseProvider = injector.get(CoreCourseProvider); - this.filepoolProvider = injector.get(CoreFilepoolProvider); - this.sitesProvider = injector.get(CoreSitesProvider); - this.domUtils = injector.get(CoreDomUtilsProvider); - this.utils = injector.get(CoreUtilsProvider); - } + constructor(protected translate: TranslateService, protected appProvider: CoreAppProvider, protected utils: CoreUtilsProvider, + protected courseProvider: CoreCourseProvider, protected filepoolProvider: CoreFilepoolProvider, + protected sitesProvider: CoreSitesProvider, protected domUtils: CoreDomUtilsProvider) { } /** * Add an ongoing download to the downloadPromises list. When the promise finishes it will be removed. @@ -139,57 +91,12 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref * * @param {any} module The module object returned by WS. * @param {number} courseId Course ID. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when all content is downloaded. */ download(module: any, courseId: number, dirPath?: string): Promise { - return this.downloadOrPrefetch(module, courseId, false, dirPath); - } - - /** - * Download or prefetch the content. - * - * @param {any} module The module object returned by WS. - * @param {number} courseId Course ID. - * @param {boolean} [prefetch] True to prefetch, false to download right away. - * @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files - * relative paths and make the package work in an iframe. Undefined to download the files - * in the filepool root folder. - * @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable. - */ - downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise { - if (!this.appProvider.isOnline()) { - // Cannot download in offline. - return Promise.reject(this.translate.instant('core.networkerrormsg')); - } - - const siteId = this.sitesProvider.getCurrentSiteId(); - - // Load module contents (ignore cache so we always have the latest data). - return this.loadContents(module, courseId, true).then(() => { - // Get the intro files. - return this.getIntroFiles(module, courseId); - }).then((introFiles) => { - const downloadFn = prefetch ? this.filepoolProvider.prefetchPackage.bind(this.filepoolProvider) : - this.filepoolProvider.downloadPackage.bind(this.filepoolProvider), - contentFiles = this.getContentDownloadableFiles(module), - promises = []; - - if (dirPath) { - // Download intro files in filepool root folder. - promises.push(this.filepoolProvider.downloadOrPrefetchFiles(siteId, introFiles, prefetch, false, - this.component, module.id)); - - // Download content files inside dirPath. - promises.push(downloadFn(siteId, contentFiles, this.component, module.id, undefined, dirPath)); - } else { - // No dirPath, download everything in filepool root folder. - const files = introFiles.concat(contentFiles); - promises.push(downloadFn(siteId, files, this.component, module.id)); - } - - return Promise.all(promises); - }); + // To be overridden. + return Promise.resolve(); } /** @@ -251,12 +158,8 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref * @return {Promise} Promise resolved with the list of files. */ getFiles(module: any, courseId: number, single?: boolean): Promise { - // Load module contents if needed. - return this.loadContents(module, courseId).then(() => { - return this.getIntroFiles(module, courseId).then((files) => { - return files.concat(this.getContentDownloadableFiles(module)); - }); - }); + // To be overridden. + return Promise.resolve([]); } /** @@ -329,13 +232,8 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref * @return {Promise} Promise resolved when the data is invalidated. */ invalidateContent(moduleId: number, courseId: number): Promise { - const promises = [], - siteId = this.sitesProvider.getCurrentSiteId(); - - promises.push(this.courseProvider.invalidateModule(moduleId)); - promises.push(this.filepoolProvider.invalidateFilesByComponent(siteId, this.component, moduleId)); - - return Promise.all(promises); + // To be overridden. + return Promise.resolve(); } /** @@ -403,10 +301,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref * @return {Promise} Promise resolved when loaded. */ loadContents(module: any, courseId: number, ignoreCache?: boolean): Promise { - if (this.isResource) { - return this.courseProvider.loadModuleContents(module, courseId, undefined, false, ignoreCache); - } - + // To be overridden. return Promise.resolve(); } @@ -416,104 +311,12 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref * @param {any} module Module. * @param {number} courseId Course ID the module belongs to. * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { - return this.downloadOrPrefetch(module, courseId, true, dirPath); - } - - /** - * Prefetch the module, setting package status at start and finish. - * - * Example usage from a child instance: - * return this.prefetchPackage(module, courseId, single, this.prefetchModule.bind(this), siteId, someParam, anotherParam); - * - * Then the function "prefetchModule" will receive params: - * prefetchModule(module, courseId, single, siteId, someParam, anotherParam) - * - * @param {any} module Module. - * @param {number} courseId Course ID the module belongs to. - * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. - * @param {prefetchFunction} downloadFn Function to perform the prefetch. Please check the documentation of prefetchFunction. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when the module has been downloaded. Data returned is not reliable. - */ - prefetchPackage(module: any, courseId: number, single: boolean, downloadFn: prefetchFunction, siteId?: string, ...args: any[]) - : Promise { - siteId = siteId || this.sitesProvider.getCurrentSiteId(); - - if (!this.appProvider.isOnline()) { - // Cannot prefetch in offline. - return Promise.reject(this.translate.instant('core.networkerrormsg')); - } - - if (this.isDownloading(module.id, siteId)) { - // There's already a download ongoing for this module, return the promise. - return this.getOngoingDownload(module.id, siteId); - } - - const prefetchPromise = this.setDownloading(module.id, siteId).then(() => { - // Package marked as downloading, call the download function. - // Send all the params except downloadFn. This includes all params passed after siteId. - return downloadFn.apply(downloadFn, [module, courseId, single, siteId].concat(args)); - }).then((extra: any) => { - // Only accept string types. - if (typeof extra != 'string') { - extra = ''; - } - - // Prefetch finished, mark as downloaded. - return this.setDownloaded(module.id, siteId, extra); - }).catch((error) => { - // Error prefetching, go back to previous status and reject the promise. - return this.setPreviousStatusAndReject(module.id, error, siteId); - }); - - return this.addOngoingDownload(module.id, prefetchPromise, siteId); - } - - /** - * Mark the module as downloaded. - * - * @param {number} id Unique identifier per component. - * @param {string} [siteId] Site ID. If not defined, current site. - * @param {string} [extra] Extra data to store. - * @return {Promise} Promise resolved when done. - */ - setDownloaded(id: number, siteId?: string, extra?: string): Promise { - siteId = siteId || this.sitesProvider.getCurrentSiteId(); - - return this.filepoolProvider.storePackageStatus(siteId, CoreConstants.DOWNLOADED, this.component, id, extra); - } - - /** - * Mark the module as downloading. - * - * @param {number} id Unique identifier per component. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when done. - */ - setDownloading(id: number, siteId?: string): Promise { - siteId = siteId || this.sitesProvider.getCurrentSiteId(); - - return this.filepoolProvider.storePackageStatus(siteId, CoreConstants.DOWNLOADING, this.component, id); - } - - /** - * Set previous status and return a rejected promise. - * - * @param {number} id Unique identifier per component. - * @param {any} [error] Error to return. - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Rejected promise. - */ - setPreviousStatusAndReject(id: number, error?: any, siteId?: string): Promise { - siteId = siteId || this.sitesProvider.getCurrentSiteId(); - - return this.filepoolProvider.setPackagePreviousStatus(siteId, this.component, id).then(() => { - return Promise.reject(error); - }); + // To be overridden. + return Promise.resolve(); } /** diff --git a/src/core/course/classes/resource-prefetch-handler.ts b/src/core/course/classes/resource-prefetch-handler.ts new file mode 100644 index 000000000..b707e2086 --- /dev/null +++ b/src/core/course/classes/resource-prefetch-handler.ts @@ -0,0 +1,151 @@ +// (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 { CoreCourseModulePrefetchHandlerBase } from './module-prefetch-handler'; + +/** + * Base prefetch handler to be registered in CoreCourseModulePrefetchDelegate. It is useful to minimize the amount of + * functions that handlers need to implement. It also provides some helper features like preventing a module to be + * downloaded twice at the same time. + * + * If your handler inherits from this service, you just need to override the functions that you want to change. + * + * This class should be used for RESOURCES whose main purpose is downloading files present in module.contents. + */ +export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefetchHandlerBase { + + /** + * Download the module. + * + * @param {any} module The module object returned by WS. + * @param {number} courseId Course ID. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when all content is downloaded. + */ + download(module: any, courseId: number, dirPath?: string): Promise { + return this.downloadOrPrefetch(module, courseId, false, dirPath); + } + + /** + * Download or prefetch the content. + * + * @param {any} module The module object returned by WS. + * @param {number} courseId Course ID. + * @param {boolean} [prefetch] True to prefetch, false to download right away. + * @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files + * relative paths and make the package work in an iframe. Undefined to download the files + * in the filepool root folder. + * @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable. + */ + downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise { + if (!this.appProvider.isOnline()) { + // Cannot download in offline. + return Promise.reject(this.translate.instant('core.networkerrormsg')); + } + + const siteId = this.sitesProvider.getCurrentSiteId(); + + if (this.isDownloading(module.id, siteId)) { + // There's already a download ongoing for this module, return the promise. + return this.getOngoingDownload(module.id, siteId); + } + + // Load module contents (ignore cache so we always have the latest data). + const prefetchPromise = this.loadContents(module, courseId, true).then(() => { + // Get the intro files. + return this.getIntroFiles(module, courseId); + }).then((introFiles) => { + const downloadFn = prefetch ? this.filepoolProvider.prefetchPackage.bind(this.filepoolProvider) : + this.filepoolProvider.downloadPackage.bind(this.filepoolProvider), + contentFiles = this.getContentDownloadableFiles(module), + promises = []; + + if (dirPath) { + // Download intro files in filepool root folder. + promises.push(this.filepoolProvider.downloadOrPrefetchFiles(siteId, introFiles, prefetch, false, + this.component, module.id)); + + // Download content files inside dirPath. + promises.push(downloadFn(siteId, contentFiles, this.component, module.id, undefined, dirPath)); + } else { + // No dirPath, download everything in filepool root folder. + const files = introFiles.concat(contentFiles); + promises.push(downloadFn(siteId, files, this.component, module.id)); + } + + return Promise.all(promises); + }); + + return this.addOngoingDownload(module.id, prefetchPromise, siteId); + } + + /** + * Get list of files. If not defined, we'll assume they're in module.contents. + * + * @param {any} module Module. + * @param {Number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @return {Promise} Promise resolved with the list of files. + */ + getFiles(module: any, courseId: number, single?: boolean): Promise { + // Load module contents if needed. + return this.loadContents(module, courseId).then(() => { + return this.getIntroFiles(module, courseId).then((files) => { + return files.concat(this.getContentDownloadableFiles(module)); + }); + }); + } + + /** + * Invalidate the prefetched content. + * + * @param {number} moduleId The module ID. + * @param {number} courseId The course ID the module belongs to. + * @return {Promise} Promise resolved when the data is invalidated. + */ + invalidateContent(moduleId: number, courseId: number): Promise { + const promises = [], + siteId = this.sitesProvider.getCurrentSiteId(); + + promises.push(this.courseProvider.invalidateModule(moduleId)); + promises.push(this.filepoolProvider.invalidateFilesByComponent(siteId, this.component, moduleId)); + + return Promise.all(promises); + } + + /** + * Load module contents into module.contents if they aren't loaded already. + * + * @param {any} module Module to load the contents. + * @param {number} [courseId] The course ID. Recommended to speed up the process and minimize data usage. + * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). + * @return {Promise} Promise resolved when loaded. + */ + loadContents(module: any, courseId: number, ignoreCache?: boolean): Promise { + return this.courseProvider.loadModuleContents(module, courseId, undefined, false, ignoreCache); + } + + /** + * Prefetch a module. + * + * @param {any} module Module. + * @param {number} courseId Course ID the module belongs to. + * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. + * @param {string} [dirPath] Path of the directory where to store all the content files. + * @return {Promise} Promise resolved when done. + */ + prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise { + return this.downloadOrPrefetch(module, courseId, true, dirPath); + } +} diff --git a/src/core/siteplugins/classes/handlers/module-prefetch-handler.ts b/src/core/siteplugins/classes/handlers/module-prefetch-handler.ts index df289cc97..a9db53e91 100644 --- a/src/core/siteplugins/classes/handlers/module-prefetch-handler.ts +++ b/src/core/siteplugins/classes/handlers/module-prefetch-handler.ts @@ -12,19 +12,30 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injector } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; +import { CoreFilepoolProvider } from '@providers/filepool'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreUtilsProvider } from '@providers/utils/utils'; +import { CoreCourseProvider } from '@core/course/providers/course'; import { CoreSitePluginsProvider } from '../../providers/siteplugins'; -import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; +import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler'; /** * Handler to prefetch a module site plugin. */ -export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { +export class CoreSitePluginsModulePrefetchHandler extends CoreCourseActivityPrefetchHandlerBase { protected ROOT_CACHE_KEY = 'CoreSitePluginsModulePrefetchHandler:'; - constructor(injector: Injector, protected sitePluginsProvider: CoreSitePluginsProvider, component: string, name: string, - modName: string, protected handlerSchema: any) { - super(injector); + protected isResource: boolean; + + constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider, + courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider, + domUtils: CoreDomUtilsProvider, protected sitePluginsProvider: CoreSitePluginsProvider, component: string, + name: string, modName: string, protected handlerSchema: any) { + + super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils); this.component = component; this.name = name; @@ -63,7 +74,7 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet * @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section. * @param {string} [siteId] Site ID. If not defined, current site. * @param {boolean} [prefetch] True to prefetch, false to download right away. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ protected downloadPrefetchPlugin(module: any, courseId: number, single?: boolean, siteId?: string, prefetch?: boolean, @@ -94,7 +105,7 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet * @param {any} module The module object returned by WS. * @param {number} courseId Course ID. * @param {boolean} [prefetch] True to prefetch, false to download right away. - * @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch. + * @param {string} [dirPath] Path of the directory where to store all the content files. * @return {Promise} Promise resolved when done. */ protected downloadOrPrefetchFiles(siteId: string, module: any, courseId: number, prefetch?: boolean, dirPath?: string) @@ -169,4 +180,20 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet isEnabled(): boolean | Promise { return true; } + + /** + * Load module contents into module.contents if they aren't loaded already. + * + * @param {any} module Module to load the contents. + * @param {number} [courseId] The course ID. Recommended to speed up the process and minimize data usage. + * @param {boolean} [ignoreCache] True if it should ignore cached data (it will always fail in offline or server down). + * @return {Promise} Promise resolved when loaded. + */ + loadContents(module: any, courseId: number, ignoreCache?: boolean): Promise { + if (this.isResource) { + return this.courseProvider.loadModuleContents(module, courseId, undefined, false, ignoreCache); + } + + return Promise.resolve(); + } } diff --git a/src/core/siteplugins/providers/helper.ts b/src/core/siteplugins/providers/helper.ts index 040d3379a..7aa65b72d 100644 --- a/src/core/siteplugins/providers/helper.ts +++ b/src/core/siteplugins/providers/helper.ts @@ -12,21 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable, Injector } from '@angular/core'; +import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { TranslateService } from '@ngx-translate/core'; +import { CoreAppProvider } from '@providers/app'; import { CoreEventsProvider } from '@providers/events'; import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreLangProvider } from '@providers/lang'; import { CoreLoggerProvider } from '@providers/logger'; import { CoreSite } from '@classes/site'; import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreSitePluginsProvider } from './siteplugins'; import { CoreCompileProvider } from '@core/compile/providers/compile'; import { CoreQuestionProvider } from '@core/question/providers/question'; +import { CoreCourseProvider } from '@core/course/providers/course'; // Delegates import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate'; @@ -75,7 +78,7 @@ import { CoreSitePluginsWorkshopAssessmentStrategyHandler } from '../classes/han export class CoreSitePluginsHelperProvider { protected logger; - constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private injector: Injector, + constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider, private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate, private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider, private http: Http, private sitePluginsProvider: CoreSitePluginsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate, @@ -87,8 +90,9 @@ export class CoreSitePluginsHelperProvider { private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider, private messageOutputDelegate: AddonMessageOutputDelegate, private accessRulesDelegate: AddonModQuizAccessRuleDelegate, private assignSubmissionDelegate: AddonModAssignSubmissionDelegate, private translate: TranslateService, - private assignFeedbackDelegate: AddonModAssignFeedbackDelegate, - private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate) { + private assignFeedbackDelegate: AddonModAssignFeedbackDelegate, private appProvider: CoreAppProvider, + private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate, + private courseProvider: CoreCourseProvider) { this.logger = logger.getInstance('CoreSitePluginsHelperProvider'); @@ -735,8 +739,9 @@ export class CoreSitePluginsHelperProvider { if (handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length) { // Register the prefetch handler. - this.prefetchDelegate.registerHandler(new CoreSitePluginsModulePrefetchHandler( - this.injector, this.sitePluginsProvider, plugin.component, uniqueName, modName, handlerSchema)); + this.prefetchDelegate.registerHandler(new CoreSitePluginsModulePrefetchHandler(this.translate, this.appProvider, + this.utils, this.courseProvider, this.filepoolProvider, this.sitesProvider, this.domUtils, + this.sitePluginsProvider, plugin.component, uniqueName, modName, handlerSchema)); } return modName;