From 0669ba9592ca119e00d46c43b2d5fd32a739aa31 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 9 Mar 2018 09:00:43 +0100 Subject: [PATCH] MOBILE-2333 siteaddons: Improve logs and remove addon manager --- src/app/app.module.ts | 5 +- src/core/siteaddons/providers/helper.ts | 111 +++++++++++++++++++++-- src/core/siteaddons/siteaddons.module.ts | 6 +- src/providers/addonmanager.ts | 102 --------------------- src/providers/ws.ts | 5 + 5 files changed, 112 insertions(+), 117 deletions(-) delete mode 100644 src/providers/addonmanager.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e2efc6119..a6bee2732 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -49,7 +49,6 @@ import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreUpdateManagerProvider } from '@providers/update-manager'; import { CorePluginFileDelegate } from '@providers/plugin-file-delegate'; import { CoreSyncProvider } from '@providers/sync'; -import { CoreAddonManagerProvider } from '@providers/addonmanager'; import { CoreFileHelperProvider } from '@providers/file-helper'; // Core modules. @@ -110,7 +109,6 @@ export const CORE_PROVIDERS: any[] = [ CoreUpdateManagerProvider, CorePluginFileDelegate, CoreSyncProvider, - CoreAddonManagerProvider, CoreFileHelperProvider ]; @@ -170,8 +168,7 @@ export const CORE_PROVIDERS: any[] = [ }) export class AppModule { constructor(platform: Platform, initDelegate: CoreInitDelegate, updateManager: CoreUpdateManagerProvider, - sitesProvider: CoreSitesProvider, addonManagerProvider: CoreAddonManagerProvider) { - // Inject CoreAddonManagerProvider even if it's not used to make sure it's initialized. + sitesProvider: CoreSitesProvider) { // Register a handler for platform ready. initDelegate.registerProcess({ name: 'CorePlatformReady', diff --git a/src/core/siteaddons/providers/helper.ts b/src/core/siteaddons/providers/helper.ts index abf076fdb..015afa844 100644 --- a/src/core/siteaddons/providers/helper.ts +++ b/src/core/siteaddons/providers/helper.ts @@ -14,6 +14,7 @@ import { Injectable, Injector } from '@angular/core'; import { NavController, NavOptions } from 'ionic-angular'; +import { CoreEventsProvider } from '../../../providers/events'; import { CoreLangProvider } from '../../../providers/lang'; import { CoreLoggerProvider } from '../../../providers/logger'; import { CoreSite } from '../../../classes/site'; @@ -54,15 +55,39 @@ import { CoreCoursesProvider } from '../../courses/providers/courses'; @Injectable() export class CoreSiteAddonsHelperProvider { protected logger; + protected hasSiteAddonsLoaded = false; constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private injector: Injector, private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate, private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider, private siteAddonsProvider: CoreSiteAddonsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate, - private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider, + private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider, eventsProvider: CoreEventsProvider, private coursesProvider: CoreCoursesProvider, private courseOptionsDelegate: CoreCourseOptionsDelegate, private courseFormatDelegate: CoreCourseFormatDelegate, private profileFieldDelegate: CoreUserProfileFieldDelegate) { this.logger = logger.getInstance('CoreSiteAddonsHelperProvider'); + + // Fetch the addons on login. + eventsProvider.on(CoreEventsProvider.LOGIN, () => { + const siteId = this.sitesProvider.getCurrentSiteId(); + this.fetchSiteAddons(siteId).then((addons) => { + // Addons fetched, check that site hasn't changed. + if (siteId == this.sitesProvider.getCurrentSiteId() && addons.length) { + // Site is still the same. Load the addons and trigger the event. + this.loadSiteAddons(addons).then(() => { + eventsProvider.trigger(CoreEventsProvider.SITE_ADDONS_LOADED, {}, siteId); + }); + + } + }); + }); + + // Unload addons on logout if any. + eventsProvider.on(CoreEventsProvider.LOGOUT, () => { + if (this.hasSiteAddonsLoaded) { + // Temporary fix. Reload the page to unload all plugins. + window.location.reload(); + } + }); } /** @@ -116,6 +141,35 @@ export class CoreSiteAddonsHelperProvider { }); } + /** + * Fetch site addons. + * + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved when done. Returns the list of addons to load. + */ + fetchSiteAddons(siteId?: string): Promise { + const addons = []; + + return this.sitesProvider.getSite(siteId).then((site) => { + if (!this.siteAddonsProvider.isGetContentAvailable(site)) { + // Cannot load site addons, so there's no point to fetch them. + return addons; + } + + // Get the list of addons. Try not to use cache. + return site.read('tool_mobile_get_plugins_supporting_mobile', {}, { getFromCache: false }).then((data) => { + data.plugins.forEach((addon: any) => { + // Check if it's a site addon and it's enabled. + if (this.isSiteAddonEnabled(addon, site)) { + addons.push(addon); + } + }); + + return addons; + }); + }); + } + /** * Create a base handler for a site addon. * @@ -256,11 +310,15 @@ export class CoreSiteAddonsHelperProvider { loadSiteAddon(addon: any): Promise { const promises = []; + this.logger.debug('Load site addon:', addon); + try { if (!addon.parsedHandlers) { addon.parsedHandlers = JSON.parse(addon.handlers); } + this.hasSiteAddonsLoaded = true; + // Register all the handlers. for (const name in addon.parsedHandlers) { promises.push(this.registerHandler(addon, name, addon.parsedHandlers[name])); @@ -272,6 +330,22 @@ export class CoreSiteAddonsHelperProvider { return this.utils.allPromises(promises); } + /** + * Load site addons. + * + * @param {any[]} addons The addons to load. + * @return {Promise} Promise resolved when loaded. + */ + loadSiteAddons(addons: any[]): Promise { + const promises = []; + + addons.forEach((addon) => { + promises.push(this.loadSiteAddon(addon)); + }); + + return this.utils.allPromises(promises); + } + /** * Register a site addon handler in the right delegate. * @@ -343,10 +417,7 @@ export class CoreSiteAddonsHelperProvider { * @return {string} A string to identify the handler. */ protected registerCourseFormatHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string { - if (!handlerSchema) { - // Required data not provided, stop. - return; - } + this.logger.debug('Register site addon in course format delegate:', addon, handlerSchema, bootstrapResult); // Create the base handler. const formatName = addon.component.replace('format_', ''), @@ -386,11 +457,15 @@ export class CoreSiteAddonsHelperProvider { * @return {string} A string to identify the handler. */ protected registerCourseOptionHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string { - if (!handlerSchema || !handlerSchema.displaydata) { + if (!handlerSchema.displaydata) { // Required data not provided, stop. + this.logger.warn('Ignore site addon because it doesn\'t provide displaydata', addon, handlerSchema); + return; } + this.logger.debug('Register site addon in course option delegate:', addon, handlerSchema, bootstrapResult); + // Create the base handler. const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName), baseHandler = this.getBaseHandler(uniqueName), @@ -439,11 +514,15 @@ export class CoreSiteAddonsHelperProvider { * @return {string} A string to identify the handler. */ protected registerMainMenuHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string { - if (!handlerSchema || !handlerSchema.displaydata) { + if (!handlerSchema.displaydata) { // Required data not provided, stop. + this.logger.warn('Ignore site addon because it doesn\'t provide displaydata', addon, handlerSchema); + return; } + this.logger.debug('Register site addon in main menu delegate:', addon, handlerSchema, bootstrapResult); + // Create the base handler. const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName), baseHandler = this.getBaseHandler(uniqueName), @@ -484,11 +563,15 @@ export class CoreSiteAddonsHelperProvider { * @return {string} A string to identify the handler. */ protected registerModuleHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string { - if (!handlerSchema || !handlerSchema.displaydata) { + if (!handlerSchema.displaydata) { // Required data not provided, stop. + this.logger.warn('Ignore site addon because it doesn\'t provide displaydata', addon, handlerSchema); + return; } + this.logger.debug('Register site addon in module delegate:', addon, handlerSchema, bootstrapResult); + // Create the base handler. const modName = addon.component.replace('mod_', ''), baseHandler = this.getBaseHandler(modName), @@ -542,11 +625,15 @@ export class CoreSiteAddonsHelperProvider { * @return {string} A string to identify the handler. */ protected registerUserProfileHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string { - if (!handlerSchema || !handlerSchema.displaydata) { + if (!handlerSchema.displaydata) { // Required data not provided, stop. + this.logger.warn('Ignore site addon because it doesn\'t provide displaydata', addon, handlerSchema); + return; } + this.logger.debug('Register site addon in user profile delegate:', addon, handlerSchema, bootstrapResult); + // Create the base handler. const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName), baseHandler = this.getBaseHandler(uniqueName), @@ -614,11 +701,15 @@ export class CoreSiteAddonsHelperProvider { */ protected registerUserProfileFieldHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any) : string | Promise { - if (!handlerSchema || !handlerSchema.method) { + if (!handlerSchema.method) { // Required data not provided, stop. + this.logger.warn('Ignore site addon because it doesn\'t provide method', addon, handlerSchema); + return; } + this.logger.debug('Register site addon in user profile field delegate:', addon, handlerSchema, bootstrapResult); + // Execute the main method and its JS. The template returned will be used in the profile field component. return this.executeMethodAndJS(addon, handlerSchema.method).then((result) => { // Create the base handler. diff --git a/src/core/siteaddons/siteaddons.module.ts b/src/core/siteaddons/siteaddons.module.ts index 132e0d809..35493a853 100644 --- a/src/core/siteaddons/siteaddons.module.ts +++ b/src/core/siteaddons/siteaddons.module.ts @@ -31,4 +31,8 @@ export const CORE_SITEADDONS_PROVIDERS = [ ], providers: CORE_SITEADDONS_PROVIDERS }) -export class CoreSiteAddonsModule { } +export class CoreSiteAddonsModule { + constructor(helper: CoreSiteAddonsHelperProvider) { + // Inject the helper even if it isn't used so it's instantiated. + } +} diff --git a/src/providers/addonmanager.ts b/src/providers/addonmanager.ts deleted file mode 100644 index c03d74420..000000000 --- a/src/providers/addonmanager.ts +++ /dev/null @@ -1,102 +0,0 @@ -// (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 { CoreEventsProvider } from './events'; -import { CoreLoggerProvider } from './logger'; -import { CoreSitesProvider } from './sites'; -import { CoreSiteWSPreSets } from '../classes/site'; -import { CoreUtilsProvider } from './utils/utils'; -import { CoreSiteAddonsProvider } from '../core/siteaddons/providers/siteaddons'; -import { CoreSiteAddonsHelperProvider } from '../core/siteaddons/providers/helper'; - -/** - * Provider with some helper functions regarding addons. - */ -@Injectable() -export class CoreAddonManagerProvider { - - protected logger; - - constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, - private siteAddonsProvider: CoreSiteAddonsProvider, private siteAddonsHelperProvider: CoreSiteAddonsHelperProvider, - private utils: CoreUtilsProvider) { - logger = logger.getInstance('CoreAddonManagerProvider'); - - // Fetch the addons on login. - eventsProvider.on(CoreEventsProvider.LOGIN, () => { - const siteId = this.sitesProvider.getCurrentSiteId(); - this.fetchSiteAddons(siteId).then((addons) => { - // Addons fetched, check that site hasn't changed. - if (siteId == this.sitesProvider.getCurrentSiteId() && addons.length) { - // Site is still the same. Load the addons and trigger the event. - this.loadSiteAddons(addons).then(() => { - eventsProvider.trigger(CoreEventsProvider.SITE_ADDONS_LOADED, {}, siteId); - }); - - } - }); - }); - - // Unload addons on logout if any. - eventsProvider.on(CoreEventsProvider.LOGOUT, () => { - // @todo: Unload site addons. - }); - } - - /** - * Fetch site addons. - * - * @param {string} [siteId] Site ID. If not defined, current site. - * @return {Promise} Promise resolved when done. Returns the list of addons to load. - */ - fetchSiteAddons(siteId?: string): Promise { - const addons = []; - - return this.sitesProvider.getSite(siteId).then((site) => { - if (!this.siteAddonsProvider.isGetContentAvailable(site)) { - // Cannot load site addons, so there's no point to fetch them. - return addons; - } - - // Get the list of addons. Try not to use cache. - return site.read('tool_mobile_get_plugins_supporting_mobile', {}, { getFromCache: false }).then((data) => { - data.plugins.forEach((addon: any) => { - // Check if it's a site addon and it's enabled. - if (this.siteAddonsHelperProvider.isSiteAddonEnabled(addon, site)) { - addons.push(addon); - } - }); - - return addons; - }); - }); - } - - /** - * Load site addons. - * - * @param {any[]} addons The addons to load. - * @return {Promise} Promise resolved when loaded. - */ - loadSiteAddons(addons: any[]): Promise { - const promises = []; - - addons.forEach((addon) => { - promises.push(this.siteAddonsHelperProvider.loadSiteAddon(addon)); - }); - - return this.utils.allPromises(promises); - } -} diff --git a/src/providers/ws.ts b/src/providers/ws.ts index 462678683..01ccd7c71 100644 --- a/src/providers/ws.ts +++ b/src/providers/ws.ts @@ -523,6 +523,11 @@ export class CoreWSProvider { } if (typeof data.exception !== 'undefined') { + // Special debugging for site plugins, otherwise it's hard to debug errors if the data is cached. + if (method == 'tool_mobile_get_content') { + this.logger.error('Error calling WS', method, data); + } + return Promise.reject(data); }