MOBILE-2428 prefetch: Refactor prefetch base classes

main
Dani Palou 2018-06-15 14:55:50 +02:00
parent 0969b5cff1
commit c17534d69d
23 changed files with 829 additions and 646 deletions

View File

@ -12,11 +12,16 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 { CoreFilepoolProvider } from '@providers/filepool';
import { CoreGroupsProvider } from '@providers/groups'; import { CoreGroupsProvider } from '@providers/groups';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text'; 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 { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
@ -30,19 +35,21 @@ import { AddonModAssignSubmissionDelegate } from './submission-delegate';
* Handler to prefetch assigns. * Handler to prefetch assigns.
*/ */
@Injectable() @Injectable()
export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModAssign'; name = 'AddonModAssign';
modName = 'assign'; modName = 'assign';
component = AddonModAssignProvider.COMPONENT; component = AddonModAssignProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^submissions$|^grades$|^gradeitems$|^outcomes$|^comments$/; 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 textUtils: CoreTextUtilsProvider, protected feedbackDelegate: AddonModAssignFeedbackDelegate,
protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseProvider: CoreCourseProvider, protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseHelper: CoreCourseHelperProvider,
protected courseHelper: CoreCourseHelperProvider, protected filepoolProvider: CoreFilepoolProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider, protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider,
protected userProvider: CoreUserProvider, protected assignHelper: AddonModAssignHelperProvider) { 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// 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. * 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 {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -12,23 +12,32 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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'; import { AddonModBookProvider } from './book';
/** /**
* Handler to prefetch books. * Handler to prefetch books.
*/ */
@Injectable() @Injectable()
export class AddonModBookPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModBookPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModBook'; name = 'AddonModBook';
modName = 'book'; modName = 'book';
component = AddonModBookProvider.COMPONENT; component = AddonModBookProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^entries$/; updatesNames = /^configuration$|^.*files$|^entries$/;
isResource = true;
constructor(injector: Injector, protected bookProvider: AddonModBookProvider) { constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
super(injector); courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected bookProvider: AddonModBookProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
} }
/** /**

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { CoreUserProvider } from '@core/user/providers/user';
import { AddonModChoiceProvider } from './choice'; import { AddonModChoiceProvider } from './choice';
import { AddonModChoiceSyncProvider } from './sync'; import { AddonModChoiceSyncProvider } from './sync';
@ -22,28 +29,18 @@ import { AddonModChoiceSyncProvider } from './sync';
* Handler to prefetch choices. * Handler to prefetch choices.
*/ */
@Injectable() @Injectable()
export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModChoice'; name = 'AddonModChoice';
modName = 'choice'; modName = 'choice';
component = AddonModChoiceProvider.COMPONENT; component = AddonModChoiceProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^answers$/; 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) { protected syncProvider: AddonModChoiceSyncProvider, protected userProvider: CoreUserProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Same implementation for download or prefetch.
return this.prefetch(module, courseId, false, dirPath);
} }
/** /**
@ -52,7 +49,7 @@ export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandl
* @param {any} module Module. * @param {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
@ -137,13 +134,4 @@ export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandl
invalidateModule(module: any, courseId: number): Promise<any> { invalidateModule(module: any, courseId: number): Promise<any> {
return this.choiceProvider.invalidateChoiceData(courseId); return this.choiceProvider.invalidateChoiceData(courseId);
} }
/**
* Whether or not the handler is enabled on a site level.
*
* @return {boolean|Promise<boolean>} A boolean, or a promise resolved with a boolean, indicating if the handler is enabled.
*/
isEnabled(): boolean | Promise<boolean> {
return true;
}
} }

View File

@ -12,13 +12,18 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 { 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 { CoreGroupsProvider } from '@providers/groups';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreCommentsProvider } from '@core/comments/providers/comments'; import { CoreCommentsProvider } from '@core/comments/providers/comments';
import { CoreCourseProvider } from '@core/course/providers/course'; 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 { AddonModDataProvider } from './data';
import { AddonModDataHelperProvider } from './helper'; import { AddonModDataHelperProvider } from './helper';
@ -26,63 +31,19 @@ import { AddonModDataHelperProvider } from './helper';
* Handler to prefetch databases. * Handler to prefetch databases.
*/ */
@Injectable() @Injectable()
export class AddonModDataPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModData'; name = 'AddonModData';
modName = 'data'; modName = 'data';
component = AddonModDataProvider.COMPONENT; component = AddonModDataProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^entries$|^gradeitems$|^outcomes$|^comments$|^ratings/; updatesNames = /^configuration$|^.*files$|^entries$|^gradeitems$|^outcomes$|^comments$|^ratings/;
constructor(injector: Injector, protected dataProvider: AddonModDataProvider, protected timeUtils: CoreTimeUtilsProvider, constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider, protected dataHelper: AddonModDataHelperProvider, courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider, domUtils: CoreDomUtilsProvider, protected dataProvider: AddonModDataProvider,
protected courseProvider: CoreCourseProvider) { protected timeUtils: CoreTimeUtilsProvider, protected dataHelper: AddonModDataHelperProvider,
super(injector); protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider) {
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded. Data returned is not reliable.
*/
downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> {
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);
} }
/** /**
@ -282,4 +243,56 @@ export class AddonModDataPrefetchHandler extends CoreCourseModulePrefetchHandler
isEnabled(): boolean | Promise<boolean> { isEnabled(): boolean | Promise<boolean> {
return this.dataProvider.isPluginEnabled(); 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<any>} Promise resolved when done.
*/
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
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<any>} Promise resolved when done.
*/
protected prefetchDatabase(module: any, courseId: number, single: boolean, siteId: string): Promise<any> {
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);
});
}
} }

View File

@ -12,11 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { AddonModFeedbackProvider } from './feedback';
import { AddonModFeedbackHelperProvider } from './helper'; import { AddonModFeedbackHelperProvider } from './helper';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreGroupsProvider } from '@providers/groups'; import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
@ -25,101 +31,19 @@ import { CoreUserProvider } from '@core/user/providers/user';
* Handler to prefetch feedbacks. * Handler to prefetch feedbacks.
*/ */
@Injectable() @Injectable()
export class AddonModFeedbackPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModFeedback'; name = 'AddonModFeedback';
modName = 'feedback'; modName = 'feedback';
component = AddonModFeedbackProvider.COMPONENT; component = AddonModFeedbackProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^attemptsfinished|^attemptsunfinished$/; updatesNames = /^configuration$|^.*files$|^attemptsfinished|^attemptsunfinished$/;
constructor(injector: Injector, protected feedbackProvider: AddonModFeedbackProvider, protected userProvider: CoreUserProvider, constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider, protected feedbackHelper: AddonModFeedbackHelperProvider, courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected feedbackProvider: AddonModFeedbackProvider,
protected userProvider: CoreUserProvider, protected feedbackHelper: AddonModFeedbackHelperProvider,
protected timeUtils: CoreTimeUtilsProvider, protected groupsProvider: CoreGroupsProvider) { protected timeUtils: CoreTimeUtilsProvider, protected groupsProvider: CoreGroupsProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded. Data returned is not reliable.
*/
downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> {
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);
} }
/** /**
@ -224,4 +148,95 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseModulePrefetchHan
isEnabled(): boolean | Promise<boolean> { isEnabled(): boolean | Promise<boolean> {
return this.feedbackProvider.isPluginEnabled(); 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<any>} Promise resolved when done.
*/
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
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<any>} Promise resolved when done.
*/
protected prefetchFeedback(module: any, courseId: number, single: boolean, siteId: string): Promise<any> {
// 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);
});
}
} }

View File

@ -12,22 +12,31 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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'; import { AddonModFolderProvider } from './folder';
/** /**
* Handler to prefetch folders. * Handler to prefetch folders.
*/ */
@Injectable() @Injectable()
export class AddonModFolderPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModFolderPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModFolder'; name = 'AddonModFolder';
modName = 'folder'; modName = 'folder';
component = AddonModFolderProvider.COMPONENT; component = AddonModFolderProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected folderProvider: AddonModFolderProvider) { constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
super(injector); courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected folderProvider: AddonModFolderProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
} }
/** /**

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModForumProvider } from './forum'; import { AddonModForumProvider } from './forum';
@ -22,30 +29,24 @@ import { AddonModForumProvider } from './forum';
* Handler to prefetch forums. * Handler to prefetch forums.
*/ */
@Injectable() @Injectable()
export class AddonModForumPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModForum'; name = 'AddonModForum';
modName = 'forum'; modName = 'forum';
component = AddonModForumProvider.COMPONENT; component = AddonModForumProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^discussions$/; 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 groupsProvider: CoreGroupsProvider,
private userProvider: CoreUserProvider, private userProvider: CoreUserProvider,
private forumProvider: AddonModForumProvider) { private forumProvider: AddonModForumProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Same implementation for download or prefetch.
return this.prefetch(module, courseId, false, dirPath);
} }
/** /**
@ -137,7 +138,7 @@ export class AddonModForumPrefetchHandler extends CoreCourseModulePrefetchHandle
* @param {any} module Module. * @param {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { CoreUserProvider } from '@core/user/providers/user';
import { AddonModGlossaryProvider } from './glossary'; import { AddonModGlossaryProvider } from './glossary';
@ -21,29 +28,23 @@ import { AddonModGlossaryProvider } from './glossary';
* Handler to prefetch forums. * Handler to prefetch forums.
*/ */
@Injectable() @Injectable()
export class AddonModGlossaryPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModGlossary'; name = 'AddonModGlossary';
modName = 'glossary'; modName = 'glossary';
component = AddonModGlossaryProvider.COMPONENT; component = AddonModGlossaryProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^entries$/; 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 userProvider: CoreUserProvider,
private glossaryProvider: AddonModGlossaryProvider) { private glossaryProvider: AddonModGlossaryProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Glossaries cannot be downloaded right away, only prefetched.
return this.prefetch(module, courseId);
} }
/** /**
@ -102,7 +103,7 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseModulePrefetchHan
* @param {any} module Module. * @param {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -12,36 +12,31 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; 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'; import { AddonModImscpProvider } from './imscp';
/** /**
* Handler to prefetch IMSCPs. * Handler to prefetch IMSCPs.
*/ */
@Injectable() @Injectable()
export class AddonModImscpPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModImscpPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModImscp'; name = 'AddonModImscp';
modName = 'imscp'; modName = 'imscp';
component = AddonModImscpProvider.COMPONENT; component = AddonModImscpProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected imscpProvider: AddonModImscpProvider, constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider) { courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
super(injector); domUtils: CoreDomUtilsProvider, protected imscpProvider: AddonModImscpProvider) {
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
return this.prefetch(module, courseId, false, dirPath);
} }
/** /**

View File

@ -12,26 +12,36 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { ModalController } from 'ionic-angular'; 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 { 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'; import { AddonModLessonProvider } from './lesson';
/** /**
* Handler to prefetch lessons. * Handler to prefetch lessons.
*/ */
@Injectable() @Injectable()
export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModLesson'; name = 'AddonModLesson';
modName = 'lesson'; modName = 'lesson';
component = AddonModLessonProvider.COMPONENT; component = AddonModLessonProvider.COMPONENT;
// Don't check timers to decrease positives. If a user performs some action it will be reflected in other items. // 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$/; 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) { 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Same implementation for download and prefetch.
return this.prefetch(module, courseId, false, dirPath);
}
/** /**
* Get the download size of a module. * 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<any[]>} Promise resolved with the list of files.
*/
getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> {
return Promise.resolve([]);
}
/** /**
* Get the lesson password if needed. If not stored, it can ask the user to enter it. * 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 {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -12,9 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { 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 { AddonModPageProvider } from './page';
import { AddonModPageHelperProvider } from './helper'; import { AddonModPageHelperProvider } from './helper';
@ -22,16 +28,18 @@ import { AddonModPageHelperProvider } from './helper';
* Handler to prefetch pages. * Handler to prefetch pages.
*/ */
@Injectable() @Injectable()
export class AddonModPagePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModPagePrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModPage'; name = 'AddonModPage';
modName = 'page'; modName = 'page';
component = AddonModPageProvider.COMPONENT; component = AddonModPageProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$/; 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) { protected pageHelper: AddonModPageHelperProvider) {
super(injector);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
} }
/** /**

View File

@ -13,9 +13,16 @@
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; 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 { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreQuestionHelperProvider } from '@core/question/providers/helper'; 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 { AddonModQuizProvider } from './quiz';
import { AddonModQuizHelperProvider } from './helper'; import { AddonModQuizHelperProvider } from './helper';
import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate'; import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate';
@ -26,7 +33,7 @@ import { CoreConstants } from '@core/constants';
* Handler to prefetch quizzes. * Handler to prefetch quizzes.
*/ */
@Injectable() @Injectable()
export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModQuizPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModQuiz'; name = 'AddonModQuiz';
modName = 'quiz'; modName = 'quiz';
component = AddonModQuizProvider.COMPONENT; component = AddonModQuizProvider.COMPONENT;
@ -34,23 +41,13 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler
protected syncProvider: AddonModQuizSyncProvider; // It will be injected later to prevent circular dependencies. 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 textUtils: CoreTextUtilsProvider, protected quizHelper: AddonModQuizHelperProvider,
protected accessRuleDelegate: AddonModQuizAccessRuleDelegate, protected questionHelper: CoreQuestionHelperProvider) { protected accessRuleDelegate: AddonModQuizAccessRuleDelegate, protected questionHelper: CoreQuestionHelperProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Same implementation for download or prefetch.
return this.prefetch(module, courseId, false, dirPath);
} }
/** /**
@ -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<any[]>} Promise resolved with the list of files.
*/
getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> {
return Promise.resolve([]);
}
/** /**
* Gather some preflight data for an attempt. This function will start a new attempt if needed. * 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 {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -12,25 +12,33 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { AddonModResourceProvider } from './resource';
import { AddonModResourceHelperProvider } from './helper'; import { AddonModResourceHelperProvider } from './helper';
import { CoreFilepoolProvider } from '@providers/filepool';
/** /**
* Handler to prefetch resources. * Handler to prefetch resources.
*/ */
@Injectable() @Injectable()
export class AddonModResourcePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModResourcePrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModResource'; name = 'AddonModResource';
modName = 'resource'; modName = 'resource';
component = AddonModResourceProvider.COMPONENT; component = AddonModResourceProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected resourceProvider: AddonModResourceProvider, constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider, protected resourceHelper: AddonModResourceHelperProvider) { courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
super(injector); domUtils: CoreDomUtilsProvider, protected resourceProvider: AddonModResourceProvider,
protected resourceHelper: AddonModResourceHelperProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
} }
/** /**

View File

@ -12,10 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 { CoreFileProvider } from '@providers/file';
import { CoreTextUtilsProvider } from '@providers/utils/text'; 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'; import { AddonModScormProvider } from './scorm';
/** /**
@ -45,15 +52,18 @@ export interface AddonModScormProgressEvent {
* Handler to prefetch SCORMs. * Handler to prefetch SCORMs.
*/ */
@Injectable() @Injectable()
export class AddonModScormPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModScorm'; name = 'AddonModScorm';
modName = 'scorm'; modName = 'scorm';
component = AddonModScormProvider.COMPONENT; component = AddonModScormProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^tracks$/; 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) { 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<boolean>} A boolean, or a promise resolved with a boolean, indicating if the handler is enabled.
*/
isEnabled(): boolean | Promise<boolean> {
return true;
}
/** /**
* Prefetch a module. * Prefetch a module.
* *

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { AddonModSurveyProvider } from './survey';
import { AddonModSurveyHelperProvider } from './helper'; import { AddonModSurveyHelperProvider } from './helper';
@ -21,40 +28,18 @@ import { AddonModSurveyHelperProvider } from './helper';
* Handler to prefetch surveys. * Handler to prefetch surveys.
*/ */
@Injectable() @Injectable()
export class AddonModSurveyPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModSurveyPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModSurvey'; name = 'AddonModSurvey';
modName = 'survey'; modName = 'survey';
component = AddonModSurveyProvider.COMPONENT; component = AddonModSurveyProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^answers$/; 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) { protected surveyHelper: AddonModSurveyHelperProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded. Data returned is not reliable.
*/
downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> {
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);
} }
/** /**
@ -102,4 +87,43 @@ export class AddonModSurveyPrefetchHandler extends CoreCourseModulePrefetchHandl
isEnabled(): boolean | Promise<boolean> { isEnabled(): boolean | Promise<boolean> {
return true; 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<any>} Promise resolved when done.
*/
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
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<any>} Promise resolved when done.
*/
protected prefetchSurvey(module: any, courseId: number, single: boolean, siteId: string): Promise<any> {
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);
});
}
} }

View File

@ -12,12 +12,17 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 { 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 { CoreGroupsProvider } from '@providers/groups';
import { CoreTextUtilsProvider } from '@providers/utils/text'; 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 { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseHelperProvider } from '@core/course/providers/helper'; import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper'; import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
@ -27,31 +32,19 @@ import { AddonModWikiProvider } from './wiki';
* Handler to prefetch wikis. * Handler to prefetch wikis.
*/ */
@Injectable() @Injectable()
export class AddonModWikiPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModWiki'; name = 'AddonModWiki';
modName = 'wiki'; modName = 'wiki';
component = AddonModWikiProvider.COMPONENT; component = AddonModWikiProvider.COMPONENT;
updatesNames = /^.*files$|^pages$/; updatesNames = /^.*files$|^pages$/;
constructor(protected injector: Injector, protected wikiProvider: AddonModWikiProvider, constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
protected textUtils: CoreTextUtilsProvider, protected courseProvider: CoreCourseProvider, courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
protected courseHelper: CoreCourseHelperProvider, protected filepoolProvider: CoreFilepoolProvider, domUtils: CoreDomUtilsProvider, protected wikiProvider: AddonModWikiProvider, protected userProvider: CoreUserProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider, protected textUtils: CoreTextUtilsProvider, protected courseHelper: CoreCourseHelperProvider,
protected userProvider: CoreUserProvider) { protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Same implementation for download or prefetch.
return this.prefetch(module, courseId, false, dirPath);
} }
/** /**
@ -156,7 +149,7 @@ export class AddonModWikiPrefetchHandler extends CoreCourseModulePrefetchHandler
* @param {any} module Module. * @param {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; 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 { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModWorkshopProvider } from './workshop'; import { AddonModWorkshopProvider } from './workshop';
@ -23,32 +30,26 @@ import { AddonModWorkshopHelperProvider } from './helper';
* Handler to prefetch workshops. * Handler to prefetch workshops.
*/ */
@Injectable() @Injectable()
export class AddonModWorkshopPrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModWorkshop'; name = 'AddonModWorkshop';
modName = 'workshop'; modName = 'workshop';
component = AddonModWorkshopProvider.COMPONENT; component = AddonModWorkshopProvider.COMPONENT;
updatesNames = new RegExp('^configuration$|^.*files$|^completion|^gradeitems$|^outcomes$|^submissions$|^assessments$' + updatesNames = new RegExp('^configuration$|^.*files$|^completion|^gradeitems$|^outcomes$|^submissions$|^assessments$' +
'|^assessmentgrades$|^usersubmissions$|^userassessments$|^userassessmentgrades$|^userassessmentgrades$'); '|^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 groupsProvider: CoreGroupsProvider,
private userProvider: CoreUserProvider, private userProvider: CoreUserProvider,
private workshopProvider: AddonModWorkshopProvider, private workshopProvider: AddonModWorkshopProvider,
private workshopHelper: AddonModWorkshopHelperProvider) { private workshopHelper: AddonModWorkshopHelperProvider) {
super(injector);
}
/** super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// Workshop cannot be downloaded right away, only prefetched.
return this.prefetch(module, courseId, false, dirPath);
} }
/** /**
@ -210,7 +211,7 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseModulePrefetchHan
* @param {any} module Module. * @param {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {

View File

@ -56,7 +56,8 @@ import { CoreDelegate } from '@classes/delegate';
import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler'; import { CoreContentLinksHandlerBase } from '@core/contentlinks/classes/base-handler';
import { CoreContentLinksModuleGradeHandler } from '@core/contentlinks/classes/module-grade-handler'; import { CoreContentLinksModuleGradeHandler } from '@core/contentlinks/classes/module-grade-handler';
import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-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 all core modules that define components, directives and pipes.
import { CoreComponentsModule } from '@components/components.module'; import { CoreComponentsModule } from '@components/components.module';
@ -257,7 +258,8 @@ export class CoreCompileProvider {
instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase; instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase;
instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler; instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler;
instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler; instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler;
instance['CoreCourseModulePrefetchHandlerBase'] = CoreCourseModulePrefetchHandlerBase; instance['CoreCourseActivityPrefetchHandlerBase'] = CoreCourseActivityPrefetchHandlerBase;
instance['CoreCourseResourcePrefetchHandlerBase'] = CoreCourseResourcePrefetchHandlerBase;
instance['CoreCourseUnsupportedModuleComponent'] = CoreCourseUnsupportedModuleComponent; instance['CoreCourseUnsupportedModuleComponent'] = CoreCourseUnsupportedModuleComponent;
instance['CoreCourseFormatSingleActivityComponent'] = CoreCourseFormatSingleActivityComponent; instance['CoreCourseFormatSingleActivityComponent'] = CoreCourseFormatSingleActivityComponent;
instance['CoreSitePluginsModuleIndexComponent'] = CoreSitePluginsModuleIndexComponent; instance['CoreSitePluginsModuleIndexComponent'] = CoreSitePluginsModuleIndexComponent;

View File

@ -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<string>} 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<string>;
/**
* 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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
// 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<any>} Promise resolved when done.
*/
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
// 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<any>} 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<any> {
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<any>} Promise resolved when done.
*/
setDownloaded(id: number, siteId?: string, extra?: string): Promise<any> {
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<any>} Promise resolved when done.
*/
setDownloading(id: number, siteId?: string): Promise<any> {
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<never>} Rejected promise.
*/
setPreviousStatusAndReject(id: number, error?: any, siteId?: string): Promise<never> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
return this.filepoolProvider.setPackagePreviousStatus(siteId, this.component, id).then(() => {
return Promise.reject(error);
});
}
}

View File

@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
@ -21,36 +20,11 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '../providers/course'; import { CoreCourseProvider } from '../providers/course';
import { CoreCourseModulePrefetchHandler } from '../providers/module-prefetch-delegate'; import { CoreCourseModulePrefetchHandler } from '../providers/module-prefetch-delegate';
import { CoreConstants } from '../../constants';
/** /**
* A prefetch function to be passed to prefetchPackage. * Base prefetch handler to be registered in CoreCourseModulePrefetchDelegate. Prefetch handlers should inherit either
* This function should NOT call storePackageStatus, downloadPackage or prefetchPakage from filepool. * from CoreCourseModuleActivityPrefetchHandlerBase or CoreCourseModuleResourcePrefetchHandlerBase, depending on whether
* It receives the same params as prefetchPackage except the function itself. This includes all extra parameters sent after siteId. * they are an activity or a resource. It's not recommended to inherit from this class directly.
* 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<string>} 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<string>;
/**
* 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.
*/ */
export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePrefetchHandler { export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePrefetchHandler {
/** /**
@ -78,37 +52,15 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
*/ */
updatesNames = /^.*files$/; 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. * List of download promises to prevent downloading the module twice at the same time.
* @type {{[s: string]: {[s: string]: Promise<any>}}} * @type {{[s: string]: {[s: string]: Promise<any>}}}
*/ */
protected downloadPromises: { [s: string]: { [s: string]: Promise<any> } } = {}; protected downloadPromises: { [s: string]: { [s: string]: Promise<any> } } = {};
// List of services that will be injected using injector. constructor(protected translate: TranslateService, protected appProvider: CoreAppProvider, protected utils: CoreUtilsProvider,
// It's done like this so subclasses don't have to send all the services to the parent in the constructor. protected courseProvider: CoreCourseProvider, protected filepoolProvider: CoreFilepoolProvider,
protected translate: TranslateService; protected sitesProvider: CoreSitesProvider, protected domUtils: CoreDomUtilsProvider) { }
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);
}
/** /**
* Add an ongoing download to the downloadPromises list. When the promise finishes it will be removed. * 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 {any} module The module object returned by WS.
* @param {number} courseId Course ID. * @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<any>} Promise resolved when all content is downloaded. * @return {Promise<any>} Promise resolved when all content is downloaded.
*/ */
download(module: any, courseId: number, dirPath?: string): Promise<any> { download(module: any, courseId: number, dirPath?: string): Promise<any> {
return this.downloadOrPrefetch(module, courseId, false, dirPath); // To be overridden.
} return Promise.resolve();
/**
* 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<any>} Promise resolved when all content is downloaded. Data returned is not reliable.
*/
downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> {
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);
});
} }
/** /**
@ -251,12 +158,8 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @return {Promise<any[]>} Promise resolved with the list of files. * @return {Promise<any[]>} Promise resolved with the list of files.
*/ */
getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> { getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> {
// Load module contents if needed. // To be overridden.
return this.loadContents(module, courseId).then(() => { return Promise.resolve([]);
return this.getIntroFiles(module, courseId).then((files) => {
return files.concat(this.getContentDownloadableFiles(module));
});
});
} }
/** /**
@ -329,13 +232,8 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @return {Promise<any>} Promise resolved when the data is invalidated. * @return {Promise<any>} Promise resolved when the data is invalidated.
*/ */
invalidateContent(moduleId: number, courseId: number): Promise<any> { invalidateContent(moduleId: number, courseId: number): Promise<any> {
const promises = [], // To be overridden.
siteId = this.sitesProvider.getCurrentSiteId(); return Promise.resolve();
promises.push(this.courseProvider.invalidateModule(moduleId));
promises.push(this.filepoolProvider.invalidateFilesByComponent(siteId, this.component, moduleId));
return Promise.all(promises);
} }
/** /**
@ -403,10 +301,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @return {Promise} Promise resolved when loaded. * @return {Promise} Promise resolved when loaded.
*/ */
loadContents(module: any, courseId: number, ignoreCache?: boolean): Promise<void> { loadContents(module: any, courseId: number, ignoreCache?: boolean): Promise<void> {
if (this.isResource) { // To be overridden.
return this.courseProvider.loadModuleContents(module, courseId, undefined, false, ignoreCache);
}
return Promise.resolve(); return Promise.resolve();
} }
@ -416,104 +311,12 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @param {any} module Module. * @param {any} module Module.
* @param {number} courseId Course ID the module belongs to. * @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 {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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> { prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
return this.downloadOrPrefetch(module, courseId, true, dirPath); // To be overridden.
} 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<any>} 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<any> {
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<any>} Promise resolved when done.
*/
setDownloaded(id: number, siteId?: string, extra?: string): Promise<any> {
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<any>} Promise resolved when done.
*/
setDownloading(id: number, siteId?: string): Promise<any> {
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<never>} Rejected promise.
*/
setPreviousStatusAndReject(id: number, error?: any, siteId?: string): Promise<never> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
return this.filepoolProvider.setPackagePreviousStatus(siteId, this.component, id).then(() => {
return Promise.reject(error);
});
} }
/** /**

View File

@ -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<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
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<any>} Promise resolved when all content is downloaded. Data returned is not reliable.
*/
downloadOrPrefetch(module: any, courseId: number, prefetch?: boolean, dirPath?: string): Promise<any> {
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<any[]>} Promise resolved with the list of files.
*/
getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> {
// 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<any>} Promise resolved when the data is invalidated.
*/
invalidateContent(moduleId: number, courseId: number): Promise<any> {
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<void> {
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<any>} Promise resolved when done.
*/
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
return this.downloadOrPrefetch(module, courseId, true, dirPath);
}
}

View File

@ -12,19 +12,30 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // 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 { 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. * Handler to prefetch a module site plugin.
*/ */
export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefetchHandlerBase { export class CoreSitePluginsModulePrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
protected ROOT_CACHE_KEY = 'CoreSitePluginsModulePrefetchHandler:'; protected ROOT_CACHE_KEY = 'CoreSitePluginsModulePrefetchHandler:';
constructor(injector: Injector, protected sitePluginsProvider: CoreSitePluginsProvider, component: string, name: string, protected isResource: boolean;
modName: string, protected handlerSchema: any) {
super(injector); 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.component = component;
this.name = name; 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 {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 {string} [siteId] Site ID. If not defined, current site.
* @param {boolean} [prefetch] True to prefetch, false to download right away. * @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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
protected downloadPrefetchPlugin(module: any, courseId: number, single?: boolean, siteId?: string, prefetch?: boolean, 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 {any} module The module object returned by WS.
* @param {number} courseId Course ID. * @param {number} courseId Course ID.
* @param {boolean} [prefetch] True to prefetch, false to download right away. * @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<any>} Promise resolved when done. * @return {Promise<any>} Promise resolved when done.
*/ */
protected downloadOrPrefetchFiles(siteId: string, module: any, courseId: number, prefetch?: boolean, dirPath?: string) protected downloadOrPrefetchFiles(siteId: string, module: any, courseId: number, prefetch?: boolean, dirPath?: string)
@ -169,4 +180,20 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet
isEnabled(): boolean | Promise<boolean> { isEnabled(): boolean | Promise<boolean> {
return true; 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<void> {
if (this.isResource) {
return this.courseProvider.loadModuleContents(module, courseId, undefined, false, ignoreCache);
}
return Promise.resolve();
}
} }

View File

@ -12,21 +12,24 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http } from '@angular/http'; import { Http } from '@angular/http';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreLangProvider } from '@providers/lang'; import { CoreLangProvider } from '@providers/lang';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
import { CoreSite } from '@classes/site'; import { CoreSite } from '@classes/site';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreSitePluginsProvider } from './siteplugins'; import { CoreSitePluginsProvider } from './siteplugins';
import { CoreCompileProvider } from '@core/compile/providers/compile'; import { CoreCompileProvider } from '@core/compile/providers/compile';
import { CoreQuestionProvider } from '@core/question/providers/question'; import { CoreQuestionProvider } from '@core/question/providers/question';
import { CoreCourseProvider } from '@core/course/providers/course';
// Delegates // Delegates
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate'; import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
@ -75,7 +78,7 @@ import { CoreSitePluginsWorkshopAssessmentStrategyHandler } from '../classes/han
export class CoreSitePluginsHelperProvider { export class CoreSitePluginsHelperProvider {
protected logger; 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 mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider, private http: Http, private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider, private http: Http,
private sitePluginsProvider: CoreSitePluginsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate, private sitePluginsProvider: CoreSitePluginsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate,
@ -87,8 +90,9 @@ export class CoreSitePluginsHelperProvider {
private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider, private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider,
private messageOutputDelegate: AddonMessageOutputDelegate, private accessRulesDelegate: AddonModQuizAccessRuleDelegate, private messageOutputDelegate: AddonMessageOutputDelegate, private accessRulesDelegate: AddonModQuizAccessRuleDelegate,
private assignSubmissionDelegate: AddonModAssignSubmissionDelegate, private translate: TranslateService, private assignSubmissionDelegate: AddonModAssignSubmissionDelegate, private translate: TranslateService,
private assignFeedbackDelegate: AddonModAssignFeedbackDelegate, private assignFeedbackDelegate: AddonModAssignFeedbackDelegate, private appProvider: CoreAppProvider,
private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate) { private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate,
private courseProvider: CoreCourseProvider) {
this.logger = logger.getInstance('CoreSitePluginsHelperProvider'); this.logger = logger.getInstance('CoreSitePluginsHelperProvider');
@ -735,8 +739,9 @@ export class CoreSitePluginsHelperProvider {
if (handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length) { if (handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length) {
// Register the prefetch handler. // Register the prefetch handler.
this.prefetchDelegate.registerHandler(new CoreSitePluginsModulePrefetchHandler( this.prefetchDelegate.registerHandler(new CoreSitePluginsModulePrefetchHandler(this.translate, this.appProvider,
this.injector, this.sitePluginsProvider, plugin.component, uniqueName, modName, handlerSchema)); this.utils, this.courseProvider, this.filepoolProvider, this.sitesProvider, this.domUtils,
this.sitePluginsProvider, plugin.component, uniqueName, modName, handlerSchema));
} }
return modName; return modName;