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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
@ -30,19 +35,21 @@ import { AddonModAssignSubmissionDelegate } from './submission-delegate';
* Handler to prefetch assigns.
*/
@Injectable()
export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModAssignPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModAssign';
modName = 'assign';
component = AddonModAssignProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^submissions$|^grades$|^gradeitems$|^outcomes$|^comments$/;
constructor(protected injector: Injector, protected assignProvider: AddonModAssignProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected assignProvider: AddonModAssignProvider,
protected textUtils: CoreTextUtilsProvider, protected feedbackDelegate: AddonModAssignFeedbackDelegate,
protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseProvider: CoreCourseProvider,
protected courseHelper: CoreCourseHelperProvider, protected filepoolProvider: CoreFilepoolProvider,
protected submissionDelegate: AddonModAssignSubmissionDelegate, protected courseHelper: CoreCourseHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider,
protected userProvider: CoreUserProvider, protected assignHelper: AddonModAssignHelperProvider) {
super(injector);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -65,19 +72,6 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
});
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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.
*
@ -207,7 +201,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
import { AddonModBookProvider } from './book';
/**
* Handler to prefetch books.
*/
@Injectable()
export class AddonModBookPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModBookPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModBook';
modName = 'book';
component = AddonModBookProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^entries$/;
isResource = true;
constructor(injector: Injector, protected bookProvider: AddonModBookProvider) {
super(injector);
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected bookProvider: AddonModBookProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModChoiceProvider } from './choice';
import { AddonModChoiceSyncProvider } from './sync';
@ -22,28 +29,18 @@ import { AddonModChoiceSyncProvider } from './sync';
* Handler to prefetch choices.
*/
@Injectable()
export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModChoicePrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModChoice';
modName = 'choice';
component = AddonModChoiceProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^answers$/;
constructor(protected injector: Injector, protected choiceProvider: AddonModChoiceProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected choiceProvider: AddonModChoiceProvider,
protected syncProvider: AddonModChoiceSyncProvider, protected userProvider: CoreUserProvider) {
super(injector);
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -52,7 +49,7 @@ export class AddonModChoicePrefetchHandler extends CoreCourseModulePrefetchHandl
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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> {
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreCommentsProvider } from '@core/comments/providers/comments';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModDataProvider } from './data';
import { AddonModDataHelperProvider } from './helper';
@ -26,63 +31,19 @@ import { AddonModDataHelperProvider } from './helper';
* Handler to prefetch databases.
*/
@Injectable()
export class AddonModDataPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModDataPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModData';
modName = 'data';
component = AddonModDataProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^entries$|^gradeitems$|^outcomes$|^comments$|^ratings/;
constructor(injector: Injector, protected dataProvider: AddonModDataProvider, protected timeUtils: CoreTimeUtilsProvider,
protected filepoolProvider: CoreFilepoolProvider, protected dataHelper: AddonModDataHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider,
protected courseProvider: CoreCourseProvider) {
super(injector);
}
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected dataProvider: AddonModDataProvider,
protected timeUtils: CoreTimeUtilsProvider, protected dataHelper: AddonModDataHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected commentsProvider: CoreCommentsProvider) {
/**
* Download or prefetch the content.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {boolean} [prefetch] True to prefetch, false to download right away.
* @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files
* relative paths and make the package work in an iframe. Undefined to download the files
* in the filepool root data.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -282,4 +243,56 @@ export class AddonModDataPrefetchHandler extends CoreCourseModulePrefetchHandler
isEnabled(): boolean | Promise<boolean> {
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModFeedbackProvider } from './feedback';
import { AddonModFeedbackHelperProvider } from './helper';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreTimeUtilsProvider } from '@providers/utils/time';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user';
@ -25,101 +31,19 @@ import { CoreUserProvider } from '@core/user/providers/user';
* Handler to prefetch feedbacks.
*/
@Injectable()
export class AddonModFeedbackPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModFeedback';
modName = 'feedback';
component = AddonModFeedbackProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^attemptsfinished|^attemptsunfinished$/;
constructor(injector: Injector, protected feedbackProvider: AddonModFeedbackProvider, protected userProvider: CoreUserProvider,
protected filepoolProvider: CoreFilepoolProvider, protected feedbackHelper: AddonModFeedbackHelperProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected feedbackProvider: AddonModFeedbackProvider,
protected userProvider: CoreUserProvider, protected feedbackHelper: AddonModFeedbackHelperProvider,
protected timeUtils: CoreTimeUtilsProvider, protected groupsProvider: CoreGroupsProvider) {
super(injector);
}
/**
* Download or prefetch the content.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {boolean} [prefetch] True to prefetch, false to download right away.
* @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files
* relative paths and make the package work in an iframe. Undefined to download the files
* in the filepool root feedback.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -224,4 +148,95 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseModulePrefetchHan
isEnabled(): boolean | Promise<boolean> {
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
import { AddonModFolderProvider } from './folder';
/**
* Handler to prefetch folders.
*/
@Injectable()
export class AddonModFolderPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModFolderPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModFolder';
modName = 'folder';
component = AddonModFolderProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected folderProvider: AddonModFolderProvider) {
super(injector);
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected folderProvider: AddonModFolderProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModForumProvider } from './forum';
@ -22,30 +29,24 @@ import { AddonModForumProvider } from './forum';
* Handler to prefetch forums.
*/
@Injectable()
export class AddonModForumPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModForum';
modName = 'forum';
component = AddonModForumProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^discussions$/;
constructor(injector: Injector,
constructor(translate: TranslateService,
appProvider: CoreAppProvider,
utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider,
filepoolProvider: CoreFilepoolProvider,
sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider,
private groupsProvider: CoreGroupsProvider,
private userProvider: CoreUserProvider,
private forumProvider: AddonModForumProvider) {
super(injector);
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -137,7 +138,7 @@ export class AddonModForumPrefetchHandler extends CoreCourseModulePrefetchHandle
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModGlossaryProvider } from './glossary';
@ -21,29 +28,23 @@ import { AddonModGlossaryProvider } from './glossary';
* Handler to prefetch forums.
*/
@Injectable()
export class AddonModGlossaryPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModGlossaryPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModGlossary';
modName = 'glossary';
component = AddonModGlossaryProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^entries$/;
constructor(injector: Injector,
constructor(translate: TranslateService,
appProvider: CoreAppProvider,
utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider,
filepoolProvider: CoreFilepoolProvider,
sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider,
private userProvider: CoreUserProvider,
private glossaryProvider: AddonModGlossaryProvider) {
super(injector);
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -102,7 +103,7 @@ export class AddonModGlossaryPrefetchHandler extends CoreCourseModulePrefetchHan
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
import { AddonModImscpProvider } from './imscp';
/**
* Handler to prefetch IMSCPs.
*/
@Injectable()
export class AddonModImscpPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModImscpPrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModImscp';
modName = 'imscp';
component = AddonModImscpProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected imscpProvider: AddonModImscpProvider,
protected filepoolProvider: CoreFilepoolProvider) {
super(injector);
}
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected imscpProvider: AddonModImscpProvider) {
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<any>} Promise resolved when all content is downloaded.
*/
download(module: any, courseId: number, dirPath?: string): Promise<any> {
return this.prefetch(module, courseId, false, dirPath);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**

View File

@ -12,26 +12,36 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { ModalController } from 'ionic-angular';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModLessonProvider } from './lesson';
/**
* Handler to prefetch lessons.
*/
@Injectable()
export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModLesson';
modName = 'lesson';
component = AddonModLessonProvider.COMPONENT;
// Don't check timers to decrease positives. If a user performs some action it will be reflected in other items.
updatesNames = /^configuration$|^.*files$|^grades$|^gradeitems$|^pages$|^answers$|^questionattempts$|^pagesviewed$/;
constructor(protected injector: Injector, protected modalCtrl: ModalController, protected groupsProvider: CoreGroupsProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected modalCtrl: ModalController, protected groupsProvider: CoreGroupsProvider,
protected lessonProvider: AddonModLessonProvider) {
super(injector);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -58,19 +68,6 @@ export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandl
});
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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.
*
@ -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.
*
@ -254,7 +239,7 @@ export class AddonModLessonPrefetchHandler extends CoreCourseModulePrefetchHandl
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
import { AddonModPageProvider } from './page';
import { AddonModPageHelperProvider } from './helper';
@ -22,16 +28,18 @@ import { AddonModPageHelperProvider } from './helper';
* Handler to prefetch pages.
*/
@Injectable()
export class AddonModPagePrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModPagePrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModPage';
modName = 'page';
component = AddonModPageProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$/;
isResource = true;
constructor(injector: Injector, protected pageProvider: AddonModPageProvider, protected utils: CoreUtilsProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected pageProvider: AddonModPageProvider,
protected pageHelper: AddonModPageHelperProvider) {
super(injector);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**

View File

@ -13,9 +13,16 @@
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreQuestionHelperProvider } from '@core/question/providers/helper';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModQuizProvider } from './quiz';
import { AddonModQuizHelperProvider } from './helper';
import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate';
@ -26,7 +33,7 @@ import { CoreConstants } from '@core/constants';
* Handler to prefetch quizzes.
*/
@Injectable()
export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModQuizPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModQuiz';
modName = 'quiz';
component = AddonModQuizProvider.COMPONENT;
@ -34,23 +41,13 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler
protected syncProvider: AddonModQuizSyncProvider; // It will be injected later to prevent circular dependencies.
constructor(protected injector: Injector, protected quizProvider: AddonModQuizProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected injector: Injector, protected quizProvider: AddonModQuizProvider,
protected textUtils: CoreTextUtilsProvider, protected quizHelper: AddonModQuizHelperProvider,
protected accessRuleDelegate: AddonModQuizAccessRuleDelegate, protected questionHelper: CoreQuestionHelperProvider) {
super(injector);
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -69,18 +66,6 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler
});
}
/**
* Get list of files. If not defined, we'll assume they're in module.contents.
*
* @param {any} module Module.
* @param {Number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @return {Promise<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.
*
@ -190,7 +175,7 @@ export class AddonModQuizPrefetchHandler extends CoreCourseModulePrefetchHandler
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
import { AddonModResourceProvider } from './resource';
import { AddonModResourceHelperProvider } from './helper';
import { CoreFilepoolProvider } from '@providers/filepool';
/**
* Handler to prefetch resources.
*/
@Injectable()
export class AddonModResourcePrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModResourcePrefetchHandler extends CoreCourseResourcePrefetchHandlerBase {
name = 'AddonModResource';
modName = 'resource';
component = AddonModResourceProvider.COMPONENT;
isResource = true;
constructor(injector: Injector, protected resourceProvider: AddonModResourceProvider,
protected filepoolProvider: CoreFilepoolProvider, protected resourceHelper: AddonModResourceHelperProvider) {
super(injector);
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected resourceProvider: AddonModResourceProvider,
protected resourceHelper: AddonModResourceHelperProvider) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**

View File

@ -12,10 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreFileProvider } from '@providers/file';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModScormProvider } from './scorm';
/**
@ -45,15 +52,18 @@ export interface AddonModScormProgressEvent {
* Handler to prefetch SCORMs.
*/
@Injectable()
export class AddonModScormPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModScorm';
modName = 'scorm';
component = AddonModScormProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^tracks$/;
constructor(injector: Injector, protected fileProvider: CoreFileProvider, protected textUtils: CoreTextUtilsProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected fileProvider: CoreFileProvider, protected textUtils: CoreTextUtilsProvider,
protected scormProvider: AddonModScormProvider) {
super(injector);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -359,15 +369,6 @@ export class AddonModScormPrefetchHandler extends CoreCourseModulePrefetchHandle
});
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return {boolean|Promise<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.
*

View File

@ -12,8 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { AddonModSurveyProvider } from './survey';
import { AddonModSurveyHelperProvider } from './helper';
@ -21,40 +28,18 @@ import { AddonModSurveyHelperProvider } from './helper';
* Handler to prefetch surveys.
*/
@Injectable()
export class AddonModSurveyPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModSurveyPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModSurvey';
modName = 'survey';
component = AddonModSurveyProvider.COMPONENT;
updatesNames = /^configuration$|^.*files$|^answers$/;
constructor(injector: Injector, protected surveyProvider: AddonModSurveyProvider,
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected surveyProvider: AddonModSurveyProvider,
protected surveyHelper: AddonModSurveyHelperProvider) {
super(injector);
}
/**
* Download or prefetch the content.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {boolean} [prefetch] True to prefetch, false to download right away.
* @param {string} [dirPath] Path of the directory where to store all the content files. This is to keep the files
* relative paths and make the package work in an iframe. Undefined to download the files
* in the filepool root survey.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -102,4 +87,43 @@ export class AddonModSurveyPrefetchHandler extends CoreCourseModulePrefetchHandl
isEnabled(): boolean | Promise<boolean> {
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
import { CoreGradesHelperProvider } from '@core/grades/providers/helper';
import { CoreUserProvider } from '@core/user/providers/user';
@ -27,31 +32,19 @@ import { AddonModWikiProvider } from './wiki';
* Handler to prefetch wikis.
*/
@Injectable()
export class AddonModWikiPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModWiki';
modName = 'wiki';
component = AddonModWikiProvider.COMPONENT;
updatesNames = /^.*files$|^pages$/;
constructor(protected injector: Injector, protected wikiProvider: AddonModWikiProvider,
protected textUtils: CoreTextUtilsProvider, protected courseProvider: CoreCourseProvider,
protected courseHelper: CoreCourseHelperProvider, protected filepoolProvider: CoreFilepoolProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider,
protected userProvider: CoreUserProvider) {
super(injector);
}
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected wikiProvider: AddonModWikiProvider, protected userProvider: CoreUserProvider,
protected textUtils: CoreTextUtilsProvider, protected courseHelper: CoreCourseHelperProvider,
protected groupsProvider: CoreGroupsProvider, protected gradesHelper: CoreGradesHelperProvider) {
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -156,7 +149,7 @@ export class AddonModWikiPrefetchHandler extends CoreCourseModulePrefetchHandler
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModWorkshopProvider } from './workshop';
@ -23,32 +30,26 @@ import { AddonModWorkshopHelperProvider } from './helper';
* Handler to prefetch workshops.
*/
@Injectable()
export class AddonModWorkshopPrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class AddonModWorkshopPrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
name = 'AddonModWorkshop';
modName = 'workshop';
component = AddonModWorkshopProvider.COMPONENT;
updatesNames = new RegExp('^configuration$|^.*files$|^completion|^gradeitems$|^outcomes$|^submissions$|^assessments$' +
'|^assessmentgrades$|^usersubmissions$|^userassessments$|^userassessmentgrades$|^userassessmentgrades$');
constructor(injector: Injector,
constructor(translate: TranslateService,
appProvider: CoreAppProvider,
utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider,
filepoolProvider: CoreFilepoolProvider,
sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider,
private groupsProvider: CoreGroupsProvider,
private userProvider: CoreUserProvider,
private workshopProvider: AddonModWorkshopProvider,
private workshopHelper: AddonModWorkshopHelperProvider) {
super(injector);
}
/**
* Download the module.
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @return {Promise<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);
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
}
/**
@ -210,7 +211,7 @@ export class AddonModWorkshopPrefetchHandler extends CoreCourseModulePrefetchHan
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
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 { CoreContentLinksModuleGradeHandler } from '@core/contentlinks/classes/module-grade-handler';
import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
import { CoreCourseResourcePrefetchHandlerBase } from '@core/course/classes/resource-prefetch-handler';
// Import all core modules that define components, directives and pipes.
import { CoreComponentsModule } from '@components/components.module';
@ -257,7 +258,8 @@ export class CoreCompileProvider {
instance['CoreContentLinksHandlerBase'] = CoreContentLinksHandlerBase;
instance['CoreContentLinksModuleGradeHandler'] = CoreContentLinksModuleGradeHandler;
instance['CoreContentLinksModuleIndexHandler'] = CoreContentLinksModuleIndexHandler;
instance['CoreCourseModulePrefetchHandlerBase'] = CoreCourseModulePrefetchHandlerBase;
instance['CoreCourseActivityPrefetchHandlerBase'] = CoreCourseActivityPrefetchHandlerBase;
instance['CoreCourseResourcePrefetchHandlerBase'] = CoreCourseResourcePrefetchHandlerBase;
instance['CoreCourseUnsupportedModuleComponent'] = CoreCourseUnsupportedModuleComponent;
instance['CoreCourseFormatSingleActivityComponent'] = CoreCourseFormatSingleActivityComponent;
instance['CoreSitePluginsModuleIndexComponent'] = CoreSitePluginsModuleIndexComponent;

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
// limitations under the License.
import { Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
@ -21,36 +20,11 @@ import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '../providers/course';
import { CoreCourseModulePrefetchHandler } from '../providers/module-prefetch-delegate';
import { CoreConstants } from '../../constants';
/**
* A prefetch function to be passed to prefetchPackage.
* This function should NOT call storePackageStatus, downloadPackage or prefetchPakage from filepool.
* It receives the same params as prefetchPackage except the function itself. This includes all extra parameters sent after siteId.
* The string returned by this function will be stored as "extra" data in the filepool package. If you don't need to store
* extra data, don't return anything.
*
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} single True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} siteId Site ID. If not defined, current site.
* @return {Promise<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.
* Base prefetch handler to be registered in CoreCourseModulePrefetchDelegate. Prefetch handlers should inherit either
* from CoreCourseModuleActivityPrefetchHandlerBase or CoreCourseModuleResourcePrefetchHandlerBase, depending on whether
* they are an activity or a resource. It's not recommended to inherit from this class directly.
*/
export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePrefetchHandler {
/**
@ -78,37 +52,15 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
*/
updatesNames = /^.*files$/;
/**
* Whether the module is a resource (true) or an activity (false).
* @type {boolean}
*/
isResource: boolean;
/**
* List of download promises to prevent downloading the module twice at the same time.
* @type {{[s: string]: {[s: string]: Promise<any>}}}
*/
protected downloadPromises: { [s: string]: { [s: string]: Promise<any> } } = {};
// List of services that will be injected using injector.
// It's done like this so subclasses don't have to send all the services to the parent in the constructor.
protected translate: TranslateService;
protected appProvider: CoreAppProvider;
protected courseProvider: CoreCourseProvider;
protected filepoolProvider: CoreFilepoolProvider;
protected sitesProvider: CoreSitesProvider;
protected domUtils: CoreDomUtilsProvider;
protected utils: CoreUtilsProvider;
constructor(injector: Injector) {
this.translate = injector.get(TranslateService);
this.appProvider = injector.get(CoreAppProvider);
this.courseProvider = injector.get(CoreCourseProvider);
this.filepoolProvider = injector.get(CoreFilepoolProvider);
this.sitesProvider = injector.get(CoreSitesProvider);
this.domUtils = injector.get(CoreDomUtilsProvider);
this.utils = injector.get(CoreUtilsProvider);
}
constructor(protected translate: TranslateService, protected appProvider: CoreAppProvider, protected utils: CoreUtilsProvider,
protected courseProvider: CoreCourseProvider, protected filepoolProvider: CoreFilepoolProvider,
protected sitesProvider: CoreSitesProvider, protected domUtils: CoreDomUtilsProvider) { }
/**
* Add an ongoing download to the downloadPromises list. When the promise finishes it will be removed.
@ -139,57 +91,12 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
*
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<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();
// Load module contents (ignore cache so we always have the latest data).
return this.loadContents(module, courseId, true).then(() => {
// Get the intro files.
return this.getIntroFiles(module, courseId);
}).then((introFiles) => {
const downloadFn = prefetch ? this.filepoolProvider.prefetchPackage.bind(this.filepoolProvider) :
this.filepoolProvider.downloadPackage.bind(this.filepoolProvider),
contentFiles = this.getContentDownloadableFiles(module),
promises = [];
if (dirPath) {
// Download intro files in filepool root folder.
promises.push(this.filepoolProvider.downloadOrPrefetchFiles(siteId, introFiles, prefetch, false,
this.component, module.id));
// Download content files inside dirPath.
promises.push(downloadFn(siteId, contentFiles, this.component, module.id, undefined, dirPath));
} else {
// No dirPath, download everything in filepool root folder.
const files = introFiles.concat(contentFiles);
promises.push(downloadFn(siteId, files, this.component, module.id));
}
return Promise.all(promises);
});
// To be overridden.
return Promise.resolve();
}
/**
@ -251,12 +158,8 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @return {Promise<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));
});
});
// To be overridden.
return Promise.resolve([]);
}
/**
@ -329,13 +232,8 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @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);
// To be overridden.
return Promise.resolve();
}
/**
@ -403,10 +301,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @return {Promise} Promise resolved when loaded.
*/
loadContents(module: any, courseId: number, ignoreCache?: boolean): Promise<void> {
if (this.isResource) {
return this.courseProvider.loadModuleContents(module, courseId, undefined, false, ignoreCache);
}
// To be overridden.
return Promise.resolve();
}
@ -416,104 +311,12 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
prefetch(module: any, courseId?: number, single?: boolean, dirPath?: string): Promise<any> {
return this.downloadOrPrefetch(module, courseId, true, dirPath);
}
/**
* Prefetch the module, setting package status at start and finish.
*
* Example usage from a child instance:
* return this.prefetchPackage(module, courseId, single, this.prefetchModule.bind(this), siteId, someParam, anotherParam);
*
* Then the function "prefetchModule" will receive params:
* prefetchModule(module, courseId, single, siteId, someParam, anotherParam)
*
* @param {any} module Module.
* @param {number} courseId Course ID the module belongs to.
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {prefetchFunction} downloadFn Function to perform the prefetch. Please check the documentation of prefetchFunction.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {Promise<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);
});
// To be overridden.
return Promise.resolve();
}
/**

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
// limitations under the License.
import { Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreCourseProvider } from '@core/course/providers/course';
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
import { CoreCourseActivityPrefetchHandlerBase } from '@core/course/classes/activity-prefetch-handler';
/**
* Handler to prefetch a module site plugin.
*/
export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefetchHandlerBase {
export class CoreSitePluginsModulePrefetchHandler extends CoreCourseActivityPrefetchHandlerBase {
protected ROOT_CACHE_KEY = 'CoreSitePluginsModulePrefetchHandler:';
constructor(injector: Injector, protected sitePluginsProvider: CoreSitePluginsProvider, component: string, name: string,
modName: string, protected handlerSchema: any) {
super(injector);
protected isResource: boolean;
constructor(translate: TranslateService, appProvider: CoreAppProvider, utils: CoreUtilsProvider,
courseProvider: CoreCourseProvider, filepoolProvider: CoreFilepoolProvider, sitesProvider: CoreSitesProvider,
domUtils: CoreDomUtilsProvider, protected sitePluginsProvider: CoreSitePluginsProvider, component: string,
name: string, modName: string, protected handlerSchema: any) {
super(translate, appProvider, utils, courseProvider, filepoolProvider, sitesProvider, domUtils);
this.component = component;
this.name = name;
@ -63,7 +74,7 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet
* @param {boolean} [single] True if we're downloading a single module, false if we're downloading a whole section.
* @param {string} [siteId] Site ID. If not defined, current site.
* @param {boolean} [prefetch] True to prefetch, false to download right away.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
protected downloadPrefetchPlugin(module: any, courseId: number, single?: boolean, siteId?: string, prefetch?: boolean,
@ -94,7 +105,7 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet
* @param {any} module The module object returned by WS.
* @param {number} courseId Course ID.
* @param {boolean} [prefetch] True to prefetch, false to download right away.
* @param {string} [dirPath] Path of the directory where to store all the content files. @see downloadOrPrefetch.
* @param {string} [dirPath] Path of the directory where to store all the content files.
* @return {Promise<any>} Promise resolved when done.
*/
protected downloadOrPrefetchFiles(siteId: string, module: any, courseId: number, prefetch?: boolean, dirPath?: string)
@ -169,4 +180,20 @@ export class CoreSitePluginsModulePrefetchHandler extends CoreCourseModulePrefet
isEnabled(): boolean | Promise<boolean> {
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
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { TranslateService } from '@ngx-translate/core';
import { CoreAppProvider } from '@providers/app';
import { CoreEventsProvider } from '@providers/events';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreLangProvider } from '@providers/lang';
import { CoreLoggerProvider } from '@providers/logger';
import { CoreSite } from '@classes/site';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreSitePluginsProvider } from './siteplugins';
import { CoreCompileProvider } from '@core/compile/providers/compile';
import { CoreQuestionProvider } from '@core/question/providers/question';
import { CoreCourseProvider } from '@core/course/providers/course';
// Delegates
import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate';
@ -75,7 +78,7 @@ import { CoreSitePluginsWorkshopAssessmentStrategyHandler } from '../classes/han
export class CoreSitePluginsHelperProvider {
protected logger;
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private injector: Injector,
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider, private http: Http,
private sitePluginsProvider: CoreSitePluginsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate,
@ -87,8 +90,9 @@ export class CoreSitePluginsHelperProvider {
private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider,
private messageOutputDelegate: AddonMessageOutputDelegate, private accessRulesDelegate: AddonModQuizAccessRuleDelegate,
private assignSubmissionDelegate: AddonModAssignSubmissionDelegate, private translate: TranslateService,
private assignFeedbackDelegate: AddonModAssignFeedbackDelegate,
private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate) {
private assignFeedbackDelegate: AddonModAssignFeedbackDelegate, private appProvider: CoreAppProvider,
private workshopAssessmentStrategyDelegate: AddonWorkshopAssessmentStrategyDelegate,
private courseProvider: CoreCourseProvider) {
this.logger = logger.getInstance('CoreSitePluginsHelperProvider');
@ -735,8 +739,9 @@ export class CoreSitePluginsHelperProvider {
if (handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length) {
// Register the prefetch handler.
this.prefetchDelegate.registerHandler(new CoreSitePluginsModulePrefetchHandler(
this.injector, this.sitePluginsProvider, plugin.component, uniqueName, modName, handlerSchema));
this.prefetchDelegate.registerHandler(new CoreSitePluginsModulePrefetchHandler(this.translate, this.appProvider,
this.utils, this.courseProvider, this.filepoolProvider, this.sitesProvider, this.domUtils,
this.sitePluginsProvider, plugin.component, uniqueName, modName, handlerSchema));
}
return modName;