From b2bd25fdcf20a7d540c1995921bba480734f3248 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Tue, 24 Apr 2018 16:50:15 +0200 Subject: [PATCH] MOBILE-2350 scorm: Implement handlers --- .../mod/scorm/providers/grade-link-handler.ts | 32 +++++++++ .../mod/scorm/providers/index-link-handler.ts | 29 ++++++++ .../mod/scorm/providers/module-handler.ts | 71 +++++++++++++++++++ .../mod/scorm/providers/pluginfile-handler.ts | 49 +++++++++++++ .../mod/scorm/providers/sync-cron-handler.ts | 47 ++++++++++++ src/addon/mod/scorm/scorm.module.ts | 30 +++++++- src/app/app.module.ts | 2 + 7 files changed, 258 insertions(+), 2 deletions(-) create mode 100644 src/addon/mod/scorm/providers/grade-link-handler.ts create mode 100644 src/addon/mod/scorm/providers/index-link-handler.ts create mode 100644 src/addon/mod/scorm/providers/module-handler.ts create mode 100644 src/addon/mod/scorm/providers/pluginfile-handler.ts create mode 100644 src/addon/mod/scorm/providers/sync-cron-handler.ts diff --git a/src/addon/mod/scorm/providers/grade-link-handler.ts b/src/addon/mod/scorm/providers/grade-link-handler.ts new file mode 100644 index 000000000..9d3dd8674 --- /dev/null +++ b/src/addon/mod/scorm/providers/grade-link-handler.ts @@ -0,0 +1,32 @@ +// (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 { Injectable } from '@angular/core'; +import { CoreSitesProvider } from '@providers/sites'; +import { CoreDomUtilsProvider } from '@providers/utils/dom'; +import { CoreContentLinksModuleGradeHandler } from '@core/contentlinks/classes/module-grade-handler'; +import { CoreCourseHelperProvider } from '@core/course/providers/helper'; + +/** + * Handler to treat links to SCORM grade. + */ +@Injectable() +export class AddonModScormGradeLinkHandler extends CoreContentLinksModuleGradeHandler { + name = 'AddonModScormGradeLinkHandler'; + canReview = false; + + constructor(courseHelper: CoreCourseHelperProvider, domUtils: CoreDomUtilsProvider, sitesProvider: CoreSitesProvider) { + super(courseHelper, domUtils, sitesProvider, 'AddonModScorm', 'scorm'); + } +} diff --git a/src/addon/mod/scorm/providers/index-link-handler.ts b/src/addon/mod/scorm/providers/index-link-handler.ts new file mode 100644 index 000000000..3ade9ccf3 --- /dev/null +++ b/src/addon/mod/scorm/providers/index-link-handler.ts @@ -0,0 +1,29 @@ +// (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 { Injectable } from '@angular/core'; +import { CoreContentLinksModuleIndexHandler } from '@core/contentlinks/classes/module-index-handler'; +import { CoreCourseHelperProvider } from '@core/course/providers/helper'; + +/** + * Handler to treat links to SCORM index. + */ +@Injectable() +export class AddonModScormIndexLinkHandler extends CoreContentLinksModuleIndexHandler { + name = 'AddonModScormIndexLinkHandler'; + + constructor(courseHelper: CoreCourseHelperProvider) { + super(courseHelper, 'AddonModScorm', 'scorm'); + } +} diff --git a/src/addon/mod/scorm/providers/module-handler.ts b/src/addon/mod/scorm/providers/module-handler.ts new file mode 100644 index 000000000..217c0c432 --- /dev/null +++ b/src/addon/mod/scorm/providers/module-handler.ts @@ -0,0 +1,71 @@ +// (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 { Injectable } from '@angular/core'; +import { NavController, NavOptions } from 'ionic-angular'; +import { AddonModScormIndexComponent } from '../components/index/index'; +import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate'; +import { CoreCourseProvider } from '@core/course/providers/course'; + +/** + * Handler to support SCORM modules. + */ +@Injectable() +export class AddonModScormModuleHandler implements CoreCourseModuleHandler { + name = 'AddonModScorm'; + modName = 'scorm'; + + constructor(private courseProvider: CoreCourseProvider) { } + + /** + * Check if the handler is enabled on a site level. + * + * @return {boolean} Whether or not the handler is enabled on a site level. + */ + isEnabled(): boolean { + return true; + } + + /** + * Get the data required to display the module in the course contents view. + * + * @param {any} module The module object. + * @param {number} courseId The course ID. + * @param {number} sectionId The section ID. + * @return {CoreCourseModuleHandlerData} Data to render the module. + */ + getData(module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData { + return { + icon: this.courseProvider.getModuleIconSrc('scorm'), + title: module.name, + class: 'addon-mod_scorm-handler', + showDownloadButton: true, + action(event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void { + navCtrl.push('AddonModScormIndexPage', {module: module, courseId: courseId}, options); + } + }; + } + + /** + * Get the component to render the module. This is needed to support singleactivity course format. + * The component returned must implement CoreCourseModuleMainComponent. + * + * @param {any} course The course object. + * @param {any} module The module object. + * @return {any} The component to use, undefined if not found. + */ + getMainComponent(course: any, module: any): any { + return AddonModScormIndexComponent; + } +} diff --git a/src/addon/mod/scorm/providers/pluginfile-handler.ts b/src/addon/mod/scorm/providers/pluginfile-handler.ts new file mode 100644 index 000000000..6910b67b4 --- /dev/null +++ b/src/addon/mod/scorm/providers/pluginfile-handler.ts @@ -0,0 +1,49 @@ +// (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 { Injectable } from '@angular/core'; +import { CorePluginFileHandler } from '@providers/plugin-file-delegate'; + +/** + * Handler to treat file URLs in SCORM. + */ +@Injectable() +export class AddonModScormPluginFileHandler implements CorePluginFileHandler { + name = 'AddonModScormPluginFileHandler'; + + /** + * Return the RegExp to match the revision on pluginfile URLs. + * + * @param {string[]} args Arguments of the pluginfile URL defining component and filearea at least. + * @return {RegExp} RegExp to match the revision on pluginfile URLs. + */ + getComponentRevisionRegExp(args: string[]): RegExp { + // Check filearea. + if (args[2] == 'content') { + // Component + Filearea + Revision + return new RegExp('/mod_resource/content/([0-9]+)/'); + } + } + + /** + * Should return the string to remove the revision on pluginfile url. + * + * @param {string[]} args Arguments of the pluginfile URL defining component and filearea at least. + * @return {string} String to remove the revision on pluginfile url. + */ + getComponentRevisionReplace(args: string[]): string { + // Component + Filearea + Revision + return '/mod_scorm/content/0/'; + } +} diff --git a/src/addon/mod/scorm/providers/sync-cron-handler.ts b/src/addon/mod/scorm/providers/sync-cron-handler.ts new file mode 100644 index 000000000..0d3acecd5 --- /dev/null +++ b/src/addon/mod/scorm/providers/sync-cron-handler.ts @@ -0,0 +1,47 @@ +// (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 { Injectable } from '@angular/core'; +import { CoreCronHandler } from '@providers/cron'; +import { AddonModScormSyncProvider } from './scorm-sync'; + +/** + * Synchronization cron handler. + */ +@Injectable() +export class AddonModScormSyncCronHandler implements CoreCronHandler { + name = 'AddonModScormSyncCronHandler'; + + constructor(private scormSync: AddonModScormSyncProvider) {} + + /** + * Execute the process. + * Receives the ID of the site affected, undefined for all sites. + * + * @param {string} [siteId] ID of the site affected, undefined for all sites. + * @return {Promise} Promise resolved when done, rejected if failure. + */ + execute(siteId?: string): Promise { + return this.scormSync.syncAllScorms(siteId); + } + + /** + * Get the time between consecutive executions. + * + * @return {number} Time between consecutive executions (in ms). + */ + getInterval(): number { + return AddonModScormSyncProvider.SYNC_TIME; + } +} diff --git a/src/addon/mod/scorm/scorm.module.ts b/src/addon/mod/scorm/scorm.module.ts index 7a9adc132..2d9e6c6b3 100644 --- a/src/addon/mod/scorm/scorm.module.ts +++ b/src/addon/mod/scorm/scorm.module.ts @@ -13,21 +13,47 @@ // limitations under the License. import { NgModule } from '@angular/core'; +import { CoreCronDelegate } from '@providers/cron'; +import { CoreCourseModuleDelegate } from '@core/course/providers/module-delegate'; +import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate'; +import { CoreContentLinksDelegate } from '@core/contentlinks/providers/delegate'; import { AddonModScormProvider } from './providers/scorm'; import { AddonModScormOfflineProvider } from './providers/scorm-offline'; +import { AddonModScormModuleHandler } from './providers/module-handler'; import { AddonModScormPrefetchHandler } from './providers/prefetch-handler'; +import { AddonModScormSyncCronHandler } from './providers/sync-cron-handler'; +import { AddonModScormIndexLinkHandler } from './providers/index-link-handler'; +import { AddonModScormGradeLinkHandler } from './providers/grade-link-handler'; import { AddonModScormSyncProvider } from './providers/scorm-sync'; +import { AddonModScormComponentsModule } from './components/components.module'; @NgModule({ declarations: [ ], imports: [ + AddonModScormComponentsModule ], providers: [ AddonModScormProvider, AddonModScormOfflineProvider, + AddonModScormSyncProvider, + AddonModScormModuleHandler, AddonModScormPrefetchHandler, - AddonModScormSyncProvider + AddonModScormSyncCronHandler, + AddonModScormIndexLinkHandler, + AddonModScormGradeLinkHandler ] }) -export class AddonModScormModule { } +export class AddonModScormModule { + constructor(moduleDelegate: CoreCourseModuleDelegate, moduleHandler: AddonModScormModuleHandler, + prefetchDelegate: CoreCourseModulePrefetchDelegate, prefetchHandler: AddonModScormPrefetchHandler, + cronDelegate: CoreCronDelegate, syncHandler: AddonModScormSyncCronHandler, linksDelegate: CoreContentLinksDelegate, + indexHandler: AddonModScormIndexLinkHandler, gradeHandler: AddonModScormGradeLinkHandler) { + + moduleDelegate.registerHandler(moduleHandler); + prefetchDelegate.registerHandler(prefetchHandler); + cronDelegate.register(syncHandler); + linksDelegate.registerHandler(indexHandler); + linksDelegate.registerHandler(gradeHandler); + } +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 90831a8a8..3f85cb6bf 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -86,6 +86,7 @@ import { AddonModFeedbackModule } from '@addon/mod/feedback/feedback.module'; import { AddonModFolderModule } from '@addon/mod/folder/folder.module'; import { AddonModPageModule } from '@addon/mod/page/page.module'; import { AddonModQuizModule } from '@addon/mod/quiz/quiz.module'; +import { AddonModScormModule } from '@addon/mod/scorm/scorm.module'; import { AddonModUrlModule } from '@addon/mod/url/url.module'; import { AddonModSurveyModule } from '@addon/mod/survey/survey.module'; import { AddonModImscpModule } from '@addon/mod/imscp/imscp.module'; @@ -185,6 +186,7 @@ export const CORE_PROVIDERS: any[] = [ AddonModFolderModule, AddonModPageModule, AddonModQuizModule, + AddonModScormModule, AddonModUrlModule, AddonModSurveyModule, AddonModImscpModule,