From e3944a9e72355c526b959bbb1e05108f995c1608 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 24 Jul 2019 11:53:38 +0200 Subject: [PATCH] MOBILE-3055 core: Update site plugins init if course added --- src/core/course/providers/options-delegate.ts | 14 ++-- .../classes/handlers/course-option-handler.ts | 34 +++++++- .../classes/handlers/user-handler.ts | 25 +++++- src/core/siteplugins/providers/helper.ts | 82 +++++++++++++++++-- src/providers/events.ts | 1 + 5 files changed, 136 insertions(+), 20 deletions(-) diff --git a/src/core/course/providers/options-delegate.ts b/src/core/course/providers/options-delegate.ts index b99cc7760..8f0ac6124 100644 --- a/src/core/course/providers/options-delegate.ts +++ b/src/core/course/providers/options-delegate.ts @@ -552,16 +552,12 @@ export class CoreCourseOptionsDelegate extends CoreDelegate { /** * Update handlers for each course. - * - * @param {string} [siteId] Site ID. */ - updateData(siteId?: string): void { - if (this.sitesProvider.getCurrentSiteId() === siteId) { - // Update handlers for all courses. - for (const courseId in this.coursesHandlers) { - const handler = this.coursesHandlers[courseId]; - this.updateHandlersForCourse(parseInt(courseId, 10), handler.access, handler.navOptions, handler.admOptions); - } + updateData(): void { + // Update handlers for all courses. + for (const courseId in this.coursesHandlers) { + const handler = this.coursesHandlers[courseId]; + this.updateHandlersForCourse(parseInt(courseId, 10), handler.access, handler.navOptions, handler.admOptions); } } diff --git a/src/core/siteplugins/classes/handlers/course-option-handler.ts b/src/core/siteplugins/classes/handlers/course-option-handler.ts index e918ecf11..e3fde2bd2 100644 --- a/src/core/siteplugins/classes/handlers/course-option-handler.ts +++ b/src/core/siteplugins/classes/handlers/course-option-handler.ts @@ -19,6 +19,7 @@ import { } from '@core/course/providers/options-delegate'; import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsCourseOptionComponent } from '../../components/course-option/course-option'; +import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils'; /** * Handler to display a site plugin in course options. @@ -27,8 +28,11 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl priority: number; isMenuHandler: boolean; + protected updatingDefer: PromiseDefer; + constructor(name: string, protected title: string, protected plugin: any, protected handlerSchema: any, - protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider) { + protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider, + protected utils: CoreUtilsProvider) { super(name); this.priority = handlerSchema.priority; @@ -45,8 +49,13 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl * @return {boolean|Promise} True or promise resolved with true if enabled. */ isEnabledForCourse(courseId: number, accessData: any, navOptions?: any, admOptions?: any): boolean | Promise { - return this.sitePluginsProvider.isHandlerEnabledForCourse( - courseId, this.handlerSchema.restricttoenrolledcourses, this.initResult.restrict); + // Wait for "init" result to be updated. + const promise = this.updatingDefer ? this.updatingDefer.promise : Promise.resolve(); + + return promise.then(() => { + return this.sitePluginsProvider.isHandlerEnabledForCourse( + courseId, this.handlerSchema.restricttoenrolledcourses, this.initResult.restrict); + }); } /** @@ -108,4 +117,23 @@ export class CoreSitePluginsCourseOptionHandler extends CoreSitePluginsBaseHandl return this.sitePluginsProvider.prefetchFunctions(component, args, this.handlerSchema, course.id, undefined, true); } + + /** + * Set init result. + * + * @param {any} result Result to set. + */ + setInitResult(result: any): void { + this.initResult = result; + + this.updatingDefer.resolve(); + delete this.updatingDefer; + } + + /** + * Mark init being updated. + */ + updatingInit(): void { + this.updatingDefer = this.utils.promiseDefer(); + } } diff --git a/src/core/siteplugins/classes/handlers/user-handler.ts b/src/core/siteplugins/classes/handlers/user-handler.ts index 044fd2317..5bd01b063 100644 --- a/src/core/siteplugins/classes/handlers/user-handler.ts +++ b/src/core/siteplugins/classes/handlers/user-handler.ts @@ -16,6 +16,7 @@ import { NavController } from 'ionic-angular'; import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate'; import { CoreSitePluginsProvider } from '../../providers/siteplugins'; import { CoreSitePluginsBaseHandler } from './base-handler'; +import { CoreUtilsProvider, PromiseDefer } from '@providers/utils/utils'; /** * Handler to display a site plugin in the user profile. @@ -37,8 +38,11 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle */ type: string; + protected updatingDefer: PromiseDefer; + constructor(name: string, protected title: string, protected plugin: any, protected handlerSchema: any, - protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider) { + protected initResult: any, protected sitePluginsProvider: CoreSitePluginsProvider, + protected utils: CoreUtilsProvider) { super(name); this.priority = handlerSchema.priority; @@ -97,4 +101,23 @@ export class CoreSitePluginsUserProfileHandler extends CoreSitePluginsBaseHandle } }; } + + /** + * Set init result. + * + * @param {any} result Result to set. + */ + setInitResult(result: any): void { + this.initResult = result; + + this.updatingDefer.resolve(); + delete this.updatingDefer; + } + + /** + * Mark init being updated. + */ + updatingInit(): void { + this.updatingDefer = this.utils.promiseDefer(); + } } diff --git a/src/core/siteplugins/providers/helper.ts b/src/core/siteplugins/providers/helper.ts index 2b1242d85..ded88ec73 100644 --- a/src/core/siteplugins/providers/helper.ts +++ b/src/core/siteplugins/providers/helper.ts @@ -30,6 +30,7 @@ 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'; +import { CoreCoursesProvider } from '@core/courses/providers/courses'; // Delegates import { CoreMainMenuDelegate } from '@core/mainmenu/providers/delegate'; @@ -79,13 +80,14 @@ import { CoreSitePluginsBlockHandler } from '@core/siteplugins/classes/handlers/ @Injectable() export class CoreSitePluginsHelperProvider { protected logger; + protected courseRestrictHandlers = {}; 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, private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider, private urlUtils: CoreUrlUtilsProvider, - private courseOptionsDelegate: CoreCourseOptionsDelegate, eventsProvider: CoreEventsProvider, + private courseOptionsDelegate: CoreCourseOptionsDelegate, private eventsProvider: CoreEventsProvider, private courseFormatDelegate: CoreCourseFormatDelegate, private profileFieldDelegate: CoreUserProfileFieldDelegate, private textUtils: CoreTextUtilsProvider, private filepoolProvider: CoreFilepoolProvider, private settingsDelegate: CoreSettingsDelegate, private questionDelegate: CoreQuestionDelegate, @@ -122,6 +124,13 @@ export class CoreSitePluginsHelperProvider { window.location.reload(); } }); + + // Re-load plugins restricted for courses when the list of user courses changes. + eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_CHANGED, (data) => { + if (data && data.siteId && data.siteId == this.sitesProvider.getCurrentSiteId() && data.added && data.added.length) { + this.reloadCourseRestrictHandlers(); + } + }); } /** @@ -375,6 +384,7 @@ export class CoreSitePluginsHelperProvider { */ loadSitePlugins(plugins: any[]): Promise { const promises = []; + this.courseRestrictHandlers = {}; plugins.forEach((plugin) => { const pluginPromise = this.loadSitePlugin(plugin); @@ -683,10 +693,21 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName), - prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); + prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title), + handler = new CoreSitePluginsCourseOptionHandler(uniqueName, prefixedTitle, plugin, + handlerSchema, initResult, this.sitePluginsProvider, this.utils); - this.courseOptionsDelegate.registerHandler(new CoreSitePluginsCourseOptionHandler(uniqueName, prefixedTitle, plugin, - handlerSchema, initResult, this.sitePluginsProvider)); + this.courseOptionsDelegate.registerHandler(handler); + + if (initResult && initResult.restrict && initResult.restrict.courses) { + // This handler is restricted to certan courses, store it in the list. + this.courseRestrictHandlers[uniqueName] = { + plugin: plugin, + handlerName: handlerName, + handlerSchema: handlerSchema, + handler: handler + }; + } return uniqueName; } @@ -889,10 +910,21 @@ export class CoreSitePluginsHelperProvider { // Create and register the handler. const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName), - prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title); + prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title), + handler = new CoreSitePluginsUserProfileHandler(uniqueName, prefixedTitle, plugin, handlerSchema, + initResult, this.sitePluginsProvider, this.utils); - this.userDelegate.registerHandler(new CoreSitePluginsUserProfileHandler(uniqueName, prefixedTitle, plugin, handlerSchema, - initResult, this.sitePluginsProvider)); + this.userDelegate.registerHandler(handler); + + if (initResult && initResult.restrict && initResult.restrict.courses) { + // This handler is restricted to certan courses, store it in the list. + this.courseRestrictHandlers[uniqueName] = { + plugin: plugin, + handlerName: handlerName, + handlerSchema: handlerSchema, + handler: handler + }; + } return uniqueName; } @@ -935,4 +967,40 @@ export class CoreSitePluginsHelperProvider { return new CoreSitePluginsWorkshopAssessmentStrategyHandler(uniqueName, strategyName); }); } + + /** + * Reload the handlers that are restricted to certain courses. + * + * @return {Promise} Promise resolved when done. + */ + protected reloadCourseRestrictHandlers(): Promise { + if (!Object.keys(this.courseRestrictHandlers).length) { + // No course restrict handlers, nothing to do. + return Promise.resolve(); + } + + const promises = []; + + for (const name in this.courseRestrictHandlers) { + const data = this.courseRestrictHandlers[name]; + + if (!data.handler || !data.handler.setInitResult) { + // No handler or it doesn't implement a required function, ignore it. + continue; + } + + // Mark the handler as being updated. + data.handler.updatingInit && data.handler.updatingInit(); + + promises.push(this.executeHandlerInit(data.plugin, data.handlerSchema).then((initResult) => { + data.handler.setInitResult(initResult); + }).catch((error) => { + this.logger.error('Error reloading course restrict handler', error, data.plugin); + })); + } + + return Promise.all(promises).then(() => { + this.eventsProvider.trigger(CoreEventsProvider.SITE_PLUGINS_COURSE_RESTRICT_UPDATED, {}); + }); + } } diff --git a/src/providers/events.ts b/src/providers/events.ts index fe75a177a..48f3dcf32 100644 --- a/src/providers/events.ts +++ b/src/providers/events.ts @@ -48,6 +48,7 @@ export class CoreEventsProvider { static COURSE_STATUS_CHANGED = 'course_status_changed'; static SECTION_STATUS_CHANGED = 'section_status_changed'; static SITE_PLUGINS_LOADED = 'site_plugins_loaded'; + static SITE_PLUGINS_COURSE_RESTRICT_UPDATED = 'site_plugins_course_restrict_updated'; static LOGIN_SITE_CHECKED = 'login_site_checked'; static LOGIN_SITE_UNCHECKED = 'login_site_unchecked'; static IAB_LOAD_START = 'inappbrowser_load_start';