2018-02-15 14:57:18 +01:00
|
|
|
// (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.
|
|
|
|
|
2018-02-16 11:34:29 +01:00
|
|
|
import { Injectable, Injector } from '@angular/core';
|
2018-02-15 14:57:18 +01:00
|
|
|
import { NavController, NavOptions } from 'ionic-angular';
|
|
|
|
import { CoreLangProvider } from '../../../providers/lang';
|
|
|
|
import { CoreLoggerProvider } from '../../../providers/logger';
|
|
|
|
import { CoreSite } from '../../../classes/site';
|
|
|
|
import { CoreSitesProvider } from '../../../providers/sites';
|
2018-02-21 16:18:03 +01:00
|
|
|
import { CoreUtilsProvider } from '../../../providers/utils/utils';
|
|
|
|
import { CoreMainMenuDelegate, CoreMainMenuHandler, CoreMainMenuHandlerData } from '../../mainmenu/providers/delegate';
|
2018-02-15 14:57:18 +01:00
|
|
|
import {
|
|
|
|
CoreCourseModuleDelegate, CoreCourseModuleHandler, CoreCourseModuleHandlerData
|
2018-02-21 16:18:03 +01:00
|
|
|
} from '../../course/providers/module-delegate';
|
|
|
|
import { CoreCourseModulePrefetchDelegate } from '../../course/providers/module-prefetch-delegate';
|
2018-02-23 15:53:45 +01:00
|
|
|
import {
|
|
|
|
CoreCourseOptionsDelegate, CoreCourseOptionsHandler, CoreCourseOptionsHandlerData
|
|
|
|
} from '../../course/providers/options-delegate';
|
2018-02-28 16:14:37 +01:00
|
|
|
import { CoreCourseFormatDelegate, CoreCourseFormatHandler } from '../../course/providers/format-delegate';
|
2018-02-21 16:18:03 +01:00
|
|
|
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '../../user/providers/user-delegate';
|
2018-03-08 15:42:44 +01:00
|
|
|
import {
|
|
|
|
CoreUserProfileFieldDelegate, CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData
|
|
|
|
} from '../../user/providers/user-profile-field-delegate';
|
2018-02-15 14:57:18 +01:00
|
|
|
import { CoreDelegateHandler } from '../../../classes/delegate';
|
|
|
|
import { CoreSiteAddonsModuleIndexComponent } from '../components/module-index/module-index';
|
2018-02-23 15:53:45 +01:00
|
|
|
import { CoreSiteAddonsCourseOptionComponent } from '../components/course-option/course-option';
|
2018-02-28 16:14:37 +01:00
|
|
|
import { CoreSiteAddonsCourseFormatComponent } from '../components/course-format/course-format';
|
2018-03-08 15:42:44 +01:00
|
|
|
import { CoreSiteAddonsUserProfileFieldComponent } from '../components/user-profile-field/user-profile-field';
|
2018-02-15 14:57:18 +01:00
|
|
|
import { CoreSiteAddonsProvider } from './siteaddons';
|
2018-02-16 11:34:29 +01:00
|
|
|
import { CoreSiteAddonsModulePrefetchHandler } from '../classes/module-prefetch-handler';
|
2018-02-21 16:18:03 +01:00
|
|
|
import { CoreCompileProvider } from '../../compile/providers/compile';
|
2018-02-23 12:28:36 +01:00
|
|
|
import { CoreCoursesProvider } from '../../courses/providers/courses';
|
2018-02-15 14:57:18 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper service to provide functionalities regarding site addons. It basically has the features to load and register site
|
|
|
|
* addons.
|
|
|
|
*
|
|
|
|
* This code is split from CoreSiteAddonsProvider to prevent circular dependencies.
|
2018-03-02 15:25:00 +01:00
|
|
|
*
|
|
|
|
* @todo: Support ViewChild and similar in site addons. Possible solution: make components and directives inject the instance
|
|
|
|
* inside the host DOM element?
|
2018-02-15 14:57:18 +01:00
|
|
|
*/
|
|
|
|
@Injectable()
|
|
|
|
export class CoreSiteAddonsHelperProvider {
|
|
|
|
protected logger;
|
|
|
|
|
2018-02-16 11:34:29 +01:00
|
|
|
constructor(logger: CoreLoggerProvider, private sitesProvider: CoreSitesProvider, private injector: Injector,
|
2018-02-15 14:57:18 +01:00
|
|
|
private mainMenuDelegate: CoreMainMenuDelegate, private moduleDelegate: CoreCourseModuleDelegate,
|
|
|
|
private userDelegate: CoreUserDelegate, private langProvider: CoreLangProvider,
|
2018-02-21 16:18:03 +01:00
|
|
|
private siteAddonsProvider: CoreSiteAddonsProvider, private prefetchDelegate: CoreCourseModulePrefetchDelegate,
|
2018-02-23 12:28:36 +01:00
|
|
|
private compileProvider: CoreCompileProvider, private utils: CoreUtilsProvider,
|
2018-02-28 16:14:37 +01:00
|
|
|
private coursesProvider: CoreCoursesProvider, private courseOptionsDelegate: CoreCourseOptionsDelegate,
|
2018-03-08 15:42:44 +01:00
|
|
|
private courseFormatDelegate: CoreCourseFormatDelegate, private profileFieldDelegate: CoreUserProfileFieldDelegate) {
|
2018-02-15 14:57:18 +01:00
|
|
|
this.logger = logger.getInstance('CoreSiteAddonsHelperProvider');
|
|
|
|
}
|
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
/**
|
2018-02-23 12:28:36 +01:00
|
|
|
* Bootstrap a handler if it has some bootstrap method.
|
2018-02-21 16:18:03 +01:00
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-03-01 13:08:27 +01:00
|
|
|
* @return {Promise<any>} Promise resolved when done. It returns the results of the getContent call and the data returned by
|
|
|
|
* the bootstrap JS (if any).
|
2018-02-21 16:18:03 +01:00
|
|
|
*/
|
2018-03-08 15:42:44 +01:00
|
|
|
protected bootstrapHandler(addon: any, handlerSchema: any): Promise<any> {
|
2018-02-21 16:18:03 +01:00
|
|
|
if (!handlerSchema.bootstrap) {
|
2018-02-23 12:28:36 +01:00
|
|
|
return Promise.resolve({});
|
2018-02-21 16:18:03 +01:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:42:44 +01:00
|
|
|
return this.executeMethodAndJS(addon, handlerSchema.bootstrap);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a get_content method and run its javascript (if any).
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} method The method to call.
|
|
|
|
* @return {Promise<any>} Promise resolved when done. It returns the results of the getContent call and the data returned by
|
|
|
|
* the JS (if any).
|
|
|
|
*/
|
|
|
|
protected executeMethodAndJS(addon: any, method: string): Promise<any> {
|
2018-02-21 16:18:03 +01:00
|
|
|
const siteId = this.sitesProvider.getCurrentSiteId(),
|
|
|
|
preSets = {getFromCache: false}; // Try to ignore cache.
|
|
|
|
|
2018-03-08 15:42:44 +01:00
|
|
|
return this.siteAddonsProvider.getContent(addon.component, method, {}, preSets).then((result) => {
|
2018-02-21 16:18:03 +01:00
|
|
|
if (!result.javascript || this.sitesProvider.getCurrentSiteId() != siteId) {
|
|
|
|
// No javascript or site has changed, stop.
|
2018-03-01 13:08:27 +01:00
|
|
|
return result;
|
2018-02-21 16:18:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create a "fake" instance to hold all the libraries.
|
|
|
|
const instance = {};
|
|
|
|
this.compileProvider.injectLibraries(instance);
|
|
|
|
|
2018-03-01 13:08:27 +01:00
|
|
|
// Add some data of the WS call result.
|
|
|
|
const jsData = this.siteAddonsProvider.createDataForJS(result);
|
|
|
|
for (const name in jsData) {
|
|
|
|
instance[name] = jsData[name];
|
|
|
|
}
|
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
// Now execute the javascript using this instance.
|
2018-03-01 13:08:27 +01:00
|
|
|
result.jsResult = this.compileProvider.executeJavascript(instance, result.javascript);
|
2018-02-23 12:28:36 +01:00
|
|
|
|
2018-03-01 13:08:27 +01:00
|
|
|
return result;
|
2018-02-21 16:18:03 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-02-15 14:57:18 +01:00
|
|
|
/**
|
|
|
|
* Create a base handler for a site addon.
|
|
|
|
*
|
|
|
|
* @param {string} name Name of the handler.
|
|
|
|
* @return {CoreDelegateHandler} The base handler.
|
|
|
|
*/
|
|
|
|
protected getBaseHandler(name: string): CoreDelegateHandler {
|
|
|
|
return {
|
|
|
|
name: name,
|
|
|
|
isEnabled: (): boolean => {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a handler's unique name, return the prefix to add to its string keys.
|
|
|
|
*
|
|
|
|
* @param {string} handlerName Handler's unique name (result of getHandlerUniqueName).
|
|
|
|
* @return {string} Prefix.
|
|
|
|
*/
|
|
|
|
protected getHandlerPrefixForStrings(handlerName: string): string {
|
|
|
|
if (handlerName) {
|
|
|
|
return 'addon.' + handlerName + '.';
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a handler's unique name and the key of a string, return the full string key (prefixed).
|
|
|
|
*
|
|
|
|
* @param {string} handlerName Handler's unique name (result of getHandlerUniqueName).
|
|
|
|
* @param {string} key The key of the string.
|
|
|
|
* @return {string} Full string key.
|
|
|
|
*/
|
|
|
|
protected getHandlerPrefixedString(handlerName: string, key: string): string {
|
|
|
|
return this.getHandlerPrefixForStrings(handlerName) + key;
|
|
|
|
}
|
|
|
|
|
2018-02-23 15:53:45 +01:00
|
|
|
/**
|
|
|
|
* Check if a handler is enabled for a certain course.
|
|
|
|
*
|
|
|
|
* @param {number} courseId Course ID to check.
|
|
|
|
* @param {boolean} [restrictEnrolled] If true or undefined, handler is only enabled for courses the user is enrolled in.
|
|
|
|
* @param {any} [restrict] Users and courses the handler is restricted to.
|
|
|
|
* @return {boolean | Promise<boolean>} Whether the handler is enabled.
|
|
|
|
*/
|
|
|
|
protected isHandlerEnabledForCourse(courseId: number, restrictEnrolled?: boolean, restrict?: any): boolean | Promise<boolean> {
|
|
|
|
if (restrict && restrict.courses && restrict.courses.indexOf(courseId) == -1) {
|
|
|
|
// Course is not in the list of restricted courses.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (restrictEnrolled || typeof restrictEnrolled == 'undefined') {
|
|
|
|
// Only enabled for courses the user is enrolled to. Check if the user is enrolled in the course.
|
|
|
|
return this.coursesProvider.getUserCourse(courseId, true).then(() => {
|
|
|
|
return true;
|
|
|
|
}).catch(() => {
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a handler is enabled for a certain user.
|
|
|
|
*
|
|
|
|
* @param {number} userId User ID to check.
|
|
|
|
* @param {boolean} [restrictCurrent] Whether handler is only enabled for current user.
|
|
|
|
* @param {any} [restrict] Users and courses the handler is restricted to.
|
|
|
|
* @return {boolean} Whether the handler is enabled.
|
|
|
|
*/
|
|
|
|
protected isHandlerEnabledForUser(userId: number, restrictCurrent?: boolean, restrict?: any): boolean {
|
|
|
|
if (restrictCurrent && userId != this.sitesProvider.getCurrentSite().getUserId()) {
|
|
|
|
// Only enabled for current user.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (restrict && restrict.users && restrict.users.indexOf(userId) == -1) {
|
|
|
|
// User is not in the list of restricted users.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-02-15 14:57:18 +01:00
|
|
|
/**
|
|
|
|
* Check if a certain addon is a site addon and it's enabled in a certain site.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {CoreSite} site Site affected.
|
|
|
|
* @return {boolean} Whether it's a site addon and it's enabled.
|
|
|
|
*/
|
|
|
|
isSiteAddonEnabled(addon: any, site: CoreSite): boolean {
|
|
|
|
if (!site.isFeatureDisabled('siteAddOn_' + addon.component + '_' + addon.addon) && addon.handlers) {
|
|
|
|
// Site addon not disabled. Check if it has handlers.
|
|
|
|
try {
|
|
|
|
if (!addon.parsedHandlers) {
|
|
|
|
addon.parsedHandlers = JSON.parse(addon.handlers);
|
|
|
|
}
|
|
|
|
|
|
|
|
return !!(addon.parsedHandlers && Object.keys(addon.parsedHandlers).length);
|
|
|
|
} catch (ex) {
|
|
|
|
this.logger.warn('Error parsing site addon', ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load the lang strings for a handler.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
|
|
|
*/
|
|
|
|
loadHandlerLangStrings(addon: any, handlerName: string, handlerSchema: any): void {
|
|
|
|
if (!handlerSchema.lang) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const lang in handlerSchema.lang) {
|
2018-02-21 16:18:03 +01:00
|
|
|
const prefix = this.getHandlerPrefixForStrings(this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName));
|
2018-02-15 14:57:18 +01:00
|
|
|
|
|
|
|
this.langProvider.addSiteAddonsStrings(lang, handlerSchema.lang[lang], prefix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load a site addon.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
2018-02-21 16:18:03 +01:00
|
|
|
* @return {Promise<any>} Promise resolved when loaded.
|
2018-02-15 14:57:18 +01:00
|
|
|
*/
|
2018-02-21 16:18:03 +01:00
|
|
|
loadSiteAddon(addon: any): Promise<any> {
|
|
|
|
const promises = [];
|
|
|
|
|
2018-02-15 14:57:18 +01:00
|
|
|
try {
|
|
|
|
if (!addon.parsedHandlers) {
|
|
|
|
addon.parsedHandlers = JSON.parse(addon.handlers);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register all the handlers.
|
|
|
|
for (const name in addon.parsedHandlers) {
|
2018-02-21 16:18:03 +01:00
|
|
|
promises.push(this.registerHandler(addon, name, addon.parsedHandlers[name]));
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
|
|
|
} catch (ex) {
|
|
|
|
this.logger.warn('Error parsing site addon', ex);
|
|
|
|
}
|
2018-02-21 16:18:03 +01:00
|
|
|
|
|
|
|
return this.utils.allPromises(promises);
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register a site addon handler in the right delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-02-21 16:18:03 +01:00
|
|
|
* @return {Promise<any>} Promise resolved when done.
|
2018-02-15 14:57:18 +01:00
|
|
|
*/
|
2018-02-21 16:18:03 +01:00
|
|
|
registerHandler(addon: any, handlerName: string, handlerSchema: any): Promise<any> {
|
2018-02-15 14:57:18 +01:00
|
|
|
this.loadHandlerLangStrings(addon, handlerName, handlerSchema);
|
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
// Wait for the bootstrap JS to be executed.
|
2018-03-08 15:42:44 +01:00
|
|
|
return this.bootstrapHandler(addon, handlerSchema).then((result) => {
|
|
|
|
let promise;
|
2018-02-15 14:57:18 +01:00
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
switch (handlerSchema.delegate) {
|
|
|
|
case 'CoreMainMenuDelegate':
|
2018-03-08 15:42:44 +01:00
|
|
|
promise = Promise.resolve(this.registerMainMenuHandler(addon, handlerName, handlerSchema, result));
|
2018-02-21 16:18:03 +01:00
|
|
|
break;
|
2018-02-15 14:57:18 +01:00
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
case 'CoreCourseModuleDelegate':
|
2018-03-08 15:42:44 +01:00
|
|
|
promise = Promise.resolve(this.registerModuleHandler(addon, handlerName, handlerSchema, result));
|
2018-02-21 16:18:03 +01:00
|
|
|
break;
|
2018-02-15 14:57:18 +01:00
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
case 'CoreUserDelegate':
|
2018-03-08 15:42:44 +01:00
|
|
|
promise = Promise.resolve(this.registerUserProfileHandler(addon, handlerName, handlerSchema, result));
|
2018-02-21 16:18:03 +01:00
|
|
|
break;
|
|
|
|
|
2018-02-23 15:53:45 +01:00
|
|
|
case 'CoreCourseOptionsDelegate':
|
2018-03-08 15:42:44 +01:00
|
|
|
promise = Promise.resolve(this.registerCourseOptionHandler(addon, handlerName, handlerSchema, result));
|
2018-02-23 15:53:45 +01:00
|
|
|
break;
|
|
|
|
|
2018-02-28 16:14:37 +01:00
|
|
|
case 'CoreCourseFormatDelegate':
|
2018-03-08 15:42:44 +01:00
|
|
|
promise = Promise.resolve(this.registerCourseFormatHandler(addon, handlerName, handlerSchema, result));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'CoreUserProfileFieldDelegate':
|
|
|
|
promise = Promise.resolve(this.registerUserProfileFieldHandler(addon, handlerName, handlerSchema, result));
|
2018-02-28 16:14:37 +01:00
|
|
|
break;
|
|
|
|
|
2018-02-21 16:18:03 +01:00
|
|
|
default:
|
|
|
|
// Nothing to do.
|
2018-03-08 15:42:44 +01:00
|
|
|
promise = Promise.resolve();
|
2018-02-21 16:18:03 +01:00
|
|
|
}
|
|
|
|
|
2018-03-08 15:42:44 +01:00
|
|
|
return promise.then((uniqueName) => {
|
|
|
|
if (uniqueName) {
|
|
|
|
// Store the handler data.
|
|
|
|
this.siteAddonsProvider.setSiteAddonHandler(uniqueName, {
|
|
|
|
addon: addon,
|
|
|
|
handlerName: handlerName,
|
|
|
|
handlerSchema: handlerSchema,
|
|
|
|
bootstrapResult: result
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}).catch((err) => {
|
|
|
|
this.logger.error('Error executing bootstrap method', handlerSchema.bootstrap, err);
|
2018-02-21 16:18:03 +01:00
|
|
|
});
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
|
|
|
|
2018-02-28 16:14:37 +01:00
|
|
|
/**
|
|
|
|
* Given a handler in an addon, register it in the course format delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-03-01 13:08:27 +01:00
|
|
|
* @param {any} bootstrapResult Result of the bootstrap WS call.
|
2018-02-28 16:14:37 +01:00
|
|
|
* @return {string} A string to identify the handler.
|
|
|
|
*/
|
2018-03-01 13:08:27 +01:00
|
|
|
protected registerCourseFormatHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string {
|
2018-02-28 16:14:37 +01:00
|
|
|
if (!handlerSchema) {
|
|
|
|
// Required data not provided, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the base handler.
|
|
|
|
const formatName = addon.component.replace('format_', ''),
|
|
|
|
baseHandler = this.getBaseHandler(formatName);
|
|
|
|
let handler: CoreCourseFormatHandler;
|
|
|
|
|
|
|
|
// Extend the base handler, adding the properties required by the delegate.
|
|
|
|
handler = Object.assign(baseHandler, {
|
|
|
|
canViewAllSections: (course: any): boolean => {
|
|
|
|
return typeof handlerSchema.canviewallsections != 'undefined' ? handlerSchema.canviewallsections : true;
|
|
|
|
},
|
|
|
|
displayEnableDownload: (course: any): boolean => {
|
|
|
|
return typeof handlerSchema.displayenabledownload != 'undefined' ? handlerSchema.displayenabledownload : true;
|
|
|
|
},
|
|
|
|
displaySectionSelector: (course: any): boolean => {
|
|
|
|
return typeof handlerSchema.displaysectionselector != 'undefined' ? handlerSchema.displaysectionselector : true;
|
|
|
|
},
|
2018-03-02 15:25:00 +01:00
|
|
|
getCourseFormatComponent: (injector: Injector, course: any): any | Promise<any> => {
|
2018-02-28 16:14:37 +01:00
|
|
|
if (handlerSchema.method) {
|
|
|
|
return CoreSiteAddonsCourseFormatComponent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.courseFormatDelegate.registerHandler(handler);
|
|
|
|
|
|
|
|
return formatName;
|
|
|
|
}
|
|
|
|
|
2018-02-23 15:53:45 +01:00
|
|
|
/**
|
|
|
|
* Given a handler in an addon, register it in the course options delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-03-01 13:08:27 +01:00
|
|
|
* @param {any} bootstrapResult Result of the bootstrap WS call.
|
2018-02-23 15:53:45 +01:00
|
|
|
* @return {string} A string to identify the handler.
|
|
|
|
*/
|
2018-03-01 13:08:27 +01:00
|
|
|
protected registerCourseOptionHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string {
|
2018-02-23 15:53:45 +01:00
|
|
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
|
|
|
// Required data not provided, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the base handler.
|
|
|
|
const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName),
|
|
|
|
baseHandler = this.getBaseHandler(uniqueName),
|
|
|
|
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
|
|
|
|
let handler: CoreCourseOptionsHandler;
|
|
|
|
|
|
|
|
// Extend the base handler, adding the properties required by the delegate.
|
|
|
|
handler = Object.assign(baseHandler, {
|
|
|
|
priority: handlerSchema.priority,
|
|
|
|
isEnabledForCourse: (courseId: number, accessData: any, navOptions?: any, admOptions?: any)
|
|
|
|
: boolean | Promise<boolean> => {
|
2018-03-01 13:08:27 +01:00
|
|
|
return this.isHandlerEnabledForCourse(courseId, handlerSchema.restricttoenrolledcourses, bootstrapResult.restrict);
|
2018-02-23 15:53:45 +01:00
|
|
|
},
|
2018-03-02 15:25:00 +01:00
|
|
|
getDisplayData: (injector: Injector, courseId: number):
|
|
|
|
CoreCourseOptionsHandlerData | Promise<CoreCourseOptionsHandlerData> => {
|
2018-02-23 15:53:45 +01:00
|
|
|
return {
|
|
|
|
title: prefixedTitle,
|
|
|
|
class: handlerSchema.displaydata.class,
|
|
|
|
component: CoreSiteAddonsCourseOptionComponent,
|
|
|
|
componentData: {
|
|
|
|
handlerUniqueName: uniqueName
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
|
|
|
prefetch: (course: any): Promise<any> => {
|
|
|
|
const args = {
|
|
|
|
courseid: course.id,
|
|
|
|
};
|
|
|
|
|
|
|
|
return this.siteAddonsProvider.prefetchFunctions(addon.component, args, handlerSchema, course.id, undefined, true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.courseOptionsDelegate.registerHandler(handler);
|
|
|
|
|
|
|
|
return uniqueName;
|
|
|
|
}
|
|
|
|
|
2018-02-15 14:57:18 +01:00
|
|
|
/**
|
|
|
|
* Given a handler in an addon, register it in the main menu delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-03-01 13:08:27 +01:00
|
|
|
* @param {any} bootstrapResult Result of the bootstrap WS call.
|
2018-02-21 16:18:03 +01:00
|
|
|
* @return {string} A string to identify the handler.
|
2018-02-15 14:57:18 +01:00
|
|
|
*/
|
2018-03-01 13:08:27 +01:00
|
|
|
protected registerMainMenuHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string {
|
2018-02-15 14:57:18 +01:00
|
|
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
|
|
|
// Required data not provided, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the base handler.
|
2018-02-21 16:18:03 +01:00
|
|
|
const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName),
|
|
|
|
baseHandler = this.getBaseHandler(uniqueName),
|
2018-02-15 14:57:18 +01:00
|
|
|
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
|
|
|
|
let mainMenuHandler: CoreMainMenuHandler;
|
|
|
|
|
|
|
|
// Extend the base handler, adding the properties required by the delegate.
|
|
|
|
mainMenuHandler = Object.assign(baseHandler, {
|
|
|
|
priority: handlerSchema.priority,
|
|
|
|
getDisplayData: (): CoreMainMenuHandlerData => {
|
|
|
|
return {
|
|
|
|
title: prefixedTitle,
|
|
|
|
icon: handlerSchema.displaydata.icon,
|
|
|
|
class: handlerSchema.displaydata.class,
|
|
|
|
page: 'CoreSiteAddonsAddonPage',
|
|
|
|
pageParams: {
|
|
|
|
title: prefixedTitle,
|
|
|
|
component: addon.component,
|
|
|
|
method: handlerSchema.method,
|
2018-02-21 16:18:03 +01:00
|
|
|
bootstrapResult: bootstrapResult
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.mainMenuDelegate.registerHandler(mainMenuHandler);
|
2018-02-21 16:18:03 +01:00
|
|
|
|
|
|
|
return uniqueName;
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a handler in an addon, register it in the module delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-03-01 13:08:27 +01:00
|
|
|
* @param {any} bootstrapResult Result of the bootstrap WS call.
|
2018-02-21 16:18:03 +01:00
|
|
|
* @return {string} A string to identify the handler.
|
2018-02-15 14:57:18 +01:00
|
|
|
*/
|
2018-03-01 13:08:27 +01:00
|
|
|
protected registerModuleHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string {
|
2018-02-15 14:57:18 +01:00
|
|
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
|
|
|
// Required data not provided, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the base handler.
|
|
|
|
const modName = addon.component.replace('mod_', ''),
|
2018-02-16 11:34:29 +01:00
|
|
|
baseHandler = this.getBaseHandler(modName),
|
2018-02-21 16:18:03 +01:00
|
|
|
hasOfflineFunctions = !!(handlerSchema.offlinefunctions && Object.keys(handlerSchema.offlinefunctions).length),
|
|
|
|
showDowloadButton = handlerSchema.downloadbutton;
|
2018-02-15 14:57:18 +01:00
|
|
|
let moduleHandler: CoreCourseModuleHandler;
|
|
|
|
|
|
|
|
// Extend the base handler, adding the properties required by the delegate.
|
|
|
|
moduleHandler = Object.assign(baseHandler, {
|
|
|
|
getData: (module: any, courseId: number, sectionId: number): CoreCourseModuleHandlerData => {
|
|
|
|
return {
|
|
|
|
title: module.name,
|
|
|
|
icon: handlerSchema.displaydata.icon,
|
|
|
|
class: handlerSchema.displaydata.class,
|
2018-02-21 16:18:03 +01:00
|
|
|
showDownloadButton: typeof showDowloadButton != 'undefined' ? showDowloadButton : hasOfflineFunctions,
|
2018-02-15 14:57:18 +01:00
|
|
|
action: (event: Event, navCtrl: NavController, module: any, courseId: number, options: NavOptions): void => {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
|
2018-02-19 15:58:39 +01:00
|
|
|
navCtrl.push('CoreSiteAddonsModuleIndexPage', {
|
2018-02-15 14:57:18 +01:00
|
|
|
title: module.name,
|
2018-02-19 15:58:39 +01:00
|
|
|
module: module,
|
|
|
|
courseId: courseId
|
2018-02-15 14:57:18 +01:00
|
|
|
}, options);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
},
|
2018-03-02 15:25:00 +01:00
|
|
|
getMainComponent: (injector: Injector, course: any, module: any): any | Promise<any> => {
|
2018-02-15 14:57:18 +01:00
|
|
|
return CoreSiteAddonsModuleIndexComponent;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-02-16 11:34:29 +01:00
|
|
|
if (hasOfflineFunctions) {
|
|
|
|
// Register the prefetch handler.
|
|
|
|
this.prefetchDelegate.registerHandler(new CoreSiteAddonsModulePrefetchHandler(
|
|
|
|
this.injector, this.siteAddonsProvider, addon.component, modName, handlerSchema));
|
|
|
|
}
|
|
|
|
|
2018-02-15 14:57:18 +01:00
|
|
|
this.moduleDelegate.registerHandler(moduleHandler);
|
2018-02-21 16:18:03 +01:00
|
|
|
|
|
|
|
return modName;
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a handler in an addon, register it in the user profile delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
2018-03-01 13:08:27 +01:00
|
|
|
* @param {any} bootstrapResult Result of the bootstrap WS call.
|
2018-02-21 16:18:03 +01:00
|
|
|
* @return {string} A string to identify the handler.
|
2018-02-15 14:57:18 +01:00
|
|
|
*/
|
2018-03-01 13:08:27 +01:00
|
|
|
protected registerUserProfileHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any): string {
|
2018-02-15 14:57:18 +01:00
|
|
|
if (!handlerSchema || !handlerSchema.displaydata) {
|
|
|
|
// Required data not provided, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the base handler.
|
2018-02-21 16:18:03 +01:00
|
|
|
const uniqueName = this.siteAddonsProvider.getHandlerUniqueName(addon, handlerName),
|
|
|
|
baseHandler = this.getBaseHandler(uniqueName),
|
2018-02-15 14:57:18 +01:00
|
|
|
prefixedTitle = this.getHandlerPrefixedString(baseHandler.name, handlerSchema.displaydata.title);
|
2018-03-08 15:42:44 +01:00
|
|
|
let userHandler: CoreUserProfileHandler,
|
|
|
|
type = handlerSchema.type;
|
|
|
|
|
|
|
|
// Only support TYPE_COMMUNICATION and TYPE_NEW_PAGE.
|
|
|
|
if (type != CoreUserDelegate.TYPE_COMMUNICATION) {
|
|
|
|
type = CoreUserDelegate.TYPE_NEW_PAGE;
|
|
|
|
}
|
2018-02-15 14:57:18 +01:00
|
|
|
|
|
|
|
// Extend the base handler, adding the properties required by the delegate.
|
|
|
|
userHandler = Object.assign(baseHandler, {
|
|
|
|
priority: handlerSchema.priority,
|
2018-03-08 15:42:44 +01:00
|
|
|
type: type,
|
2018-02-23 12:28:36 +01:00
|
|
|
isEnabledForUser: (user: any, courseId: number, navOptions?: any, admOptions?: any): boolean | Promise<boolean> => {
|
2018-02-23 15:53:45 +01:00
|
|
|
// First check if it's enabled for the user.
|
2018-03-01 13:08:27 +01:00
|
|
|
const enabledForUser = this.isHandlerEnabledForUser(user.id, handlerSchema.restricttocurrentuser,
|
|
|
|
bootstrapResult.restrict);
|
2018-02-23 15:53:45 +01:00
|
|
|
if (!enabledForUser) {
|
2018-02-15 14:57:18 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-02-23 15:53:45 +01:00
|
|
|
// Enabled for user, check if it's enabled for the course.
|
2018-03-01 13:08:27 +01:00
|
|
|
return this.isHandlerEnabledForCourse(courseId, handlerSchema.restricttoenrolledcourses, bootstrapResult.restrict);
|
2018-02-15 14:57:18 +01:00
|
|
|
},
|
|
|
|
getDisplayData: (user: any, courseId: number): CoreUserProfileHandlerData => {
|
|
|
|
return {
|
|
|
|
title: prefixedTitle,
|
|
|
|
icon: handlerSchema.displaydata.icon,
|
|
|
|
class: handlerSchema.displaydata.class,
|
|
|
|
action: (event: Event, navCtrl: NavController, user: any, courseId?: number): void => {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
|
|
navCtrl.push('CoreSiteAddonsAddonPage', {
|
|
|
|
title: prefixedTitle,
|
|
|
|
component: addon.component,
|
|
|
|
method: handlerSchema.method,
|
|
|
|
args: {
|
|
|
|
courseid: courseId,
|
|
|
|
userid: user.id
|
2018-02-21 16:18:03 +01:00
|
|
|
},
|
|
|
|
bootstrapResult: bootstrapResult
|
2018-02-15 14:57:18 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.userDelegate.registerHandler(userHandler);
|
2018-02-21 16:18:03 +01:00
|
|
|
|
|
|
|
return uniqueName;
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|
2018-03-08 15:42:44 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Given a handler in an addon, register it in the user profile field delegate.
|
|
|
|
*
|
|
|
|
* @param {any} addon Data of the addon.
|
|
|
|
* @param {string} handlerName Name of the handler in the addon.
|
|
|
|
* @param {any} handlerSchema Data about the handler.
|
|
|
|
* @param {any} bootstrapResult Result of the bootstrap WS call.
|
|
|
|
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
|
|
|
|
*/
|
|
|
|
protected registerUserProfileFieldHandler(addon: any, handlerName: string, handlerSchema: any, bootstrapResult: any)
|
|
|
|
: string | Promise<string> {
|
|
|
|
if (!handlerSchema || !handlerSchema.method) {
|
|
|
|
// Required data not provided, stop.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
const fieldType = addon.component.replace('profilefield_', ''),
|
|
|
|
baseHandler = this.getBaseHandler(fieldType);
|
|
|
|
let fieldHandler: CoreUserProfileFieldHandler;
|
|
|
|
|
|
|
|
// Store in handlerSchema some data required by the component.
|
|
|
|
handlerSchema.methodTemplates = result.templates;
|
|
|
|
handlerSchema.methodJSResult = result.jsResult;
|
|
|
|
|
|
|
|
// Extend the base handler, adding the properties required by the delegate.
|
|
|
|
fieldHandler = Object.assign(baseHandler, {
|
|
|
|
getData: (field: any, signup: boolean, registerAuth: string, formValues: any):
|
|
|
|
Promise<CoreUserProfileFieldHandlerData> | CoreUserProfileFieldHandlerData => {
|
|
|
|
if (result && result.jsResult && result.jsResult.getData) {
|
|
|
|
// The JS of the main method implements the getData function, use it.
|
|
|
|
return result.jsResult.getData();
|
|
|
|
}
|
|
|
|
|
|
|
|
// No getData function implemented, use a default behaviour.
|
|
|
|
const name = 'profile_field_' + field.shortname;
|
|
|
|
|
|
|
|
return {
|
|
|
|
type: field.type || field.datatype,
|
|
|
|
name: name,
|
|
|
|
value: formValues[name]
|
|
|
|
};
|
|
|
|
},
|
|
|
|
getComponent: (injector: Injector): any | Promise<any> => {
|
|
|
|
return CoreSiteAddonsUserProfileFieldComponent;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.profileFieldDelegate.registerHandler(fieldHandler);
|
|
|
|
|
|
|
|
return fieldType;
|
|
|
|
}).catch((err) => {
|
|
|
|
this.logger.error('Error executing main method', handlerSchema.method, err);
|
|
|
|
});
|
|
|
|
}
|
2018-02-15 14:57:18 +01:00
|
|
|
}
|