MOBILE-2376 siteplugins: Support quiz access rules

main
Dani Palou 2018-05-09 12:33:06 +02:00
parent bf658df6b4
commit d7dd3acd8e
23 changed files with 281 additions and 50 deletions

View File

@ -24,6 +24,7 @@ import { FormGroup, FormBuilder } from '@angular/forms';
}) })
export class AddonModQuizAccessOfflineAttemptsComponent implements OnInit { export class AddonModQuizAccessOfflineAttemptsComponent implements OnInit {
@Input() rule: string; // The name of the rule.
@Input() quiz: any; // The quiz the rule belongs to. @Input() quiz: any; // The quiz the rule belongs to.
@Input() attempt: any; // The attempt being started/continued. @Input() attempt: any; // The attempt being started/continued.
@Input() prefetch: boolean; // Whether the user is prefetching the quiz. @Input() prefetch: boolean; // Whether the user is prefetching the quiz.

View File

@ -24,6 +24,7 @@ import { FormGroup, FormBuilder } from '@angular/forms';
}) })
export class AddonModQuizAccessPasswordComponent implements OnInit { export class AddonModQuizAccessPasswordComponent implements OnInit {
@Input() rule: string; // The name of the rule.
@Input() quiz: any; // The quiz the rule belongs to. @Input() quiz: any; // The quiz the rule belongs to.
@Input() attempt: any; // The attempt being started/continued. @Input() attempt: any; // The attempt being started/continued.
@Input() prefetch: boolean; // Whether the user is prefetching the quiz. @Input() prefetch: boolean; // Whether the user is prefetching the quiz.

View File

@ -24,6 +24,7 @@ import { FormGroup } from '@angular/forms';
}) })
export class AddonModQuizAccessTimeLimitComponent { export class AddonModQuizAccessTimeLimitComponent {
@Input() rule: string; // The name of the rule.
@Input() quiz: any; // The quiz the rule belongs to. @Input() quiz: any; // The quiz the rule belongs to.
@Input() attempt: any; // The attempt being started/continued. @Input() attempt: any; // The attempt being started/continued.
@Input() prefetch: boolean; // Whether the user is prefetching the quiz. @Input() prefetch: boolean; // Whether the user is prefetching the quiz.

View File

@ -12,8 +12,8 @@
<core-loading [hideUntil]="loaded"> <core-loading [hideUntil]="loaded">
<form ion-list [formGroup]="preflightForm" (ngSubmit)="sendData()"> <form ion-list [formGroup]="preflightForm" (ngSubmit)="sendData()">
<!-- Access rules. --> <!-- Access rules. -->
<ng-container *ngFor="let componentClass of accessRulesComponent; let last = last"> <ng-container *ngFor="let data of accessRulesData; let last = last">
<core-dynamic-component [component]="componentClass" [data]="data"> <core-dynamic-component [component]="data.component" [data]="data.data">
<p padding>Couldn't find the directive to render this access rule.</p> <p padding>Couldn't find the directive to render this access rule.</p>
</core-dynamic-component> </core-dynamic-component>
<ion-item-divider color="light" *ngIf="!last"></ion-item-divider> <ion-item-divider color="light" *ngIf="!last"></ion-item-divider>

View File

@ -34,8 +34,7 @@ export class AddonModQuizPreflightModalPage implements OnInit {
preflightForm: FormGroup; preflightForm: FormGroup;
title: string; title: string;
accessRulesComponent: any[] = []; accessRulesData: {component: any, data: any}[] = []; // Components and data for each access rule.
data: any;
loaded: boolean; loaded: boolean;
protected quiz: any; protected quiz: any;
@ -43,7 +42,6 @@ export class AddonModQuizPreflightModalPage implements OnInit {
protected prefetch: boolean; protected prefetch: boolean;
protected siteId: string; protected siteId: string;
protected rules: string[]; protected rules: string[];
protected renderedRules: string[] = [];
constructor(params: NavParams, fb: FormBuilder, translate: TranslateService, sitesProvider: CoreSitesProvider, constructor(params: NavParams, fb: FormBuilder, translate: TranslateService, sitesProvider: CoreSitesProvider,
protected viewCtrl: ViewController, protected accessRuleDelegate: AddonModQuizAccessRuleDelegate, protected viewCtrl: ViewController, protected accessRuleDelegate: AddonModQuizAccessRuleDelegate,
@ -58,15 +56,6 @@ export class AddonModQuizPreflightModalPage implements OnInit {
// Create an empty form group. The controls will be added by the access rules components. // Create an empty form group. The controls will be added by the access rules components.
this.preflightForm = fb.group({}); this.preflightForm = fb.group({});
// Create the data to pass to the access rules components.
this.data = {
quiz: this.quiz,
attempt: this.attempt,
prefetch: this.prefetch,
form: this.preflightForm,
siteId: this.siteId
};
} }
/** /**
@ -83,8 +72,17 @@ export class AddonModQuizPreflightModalPage implements OnInit {
if (required) { if (required) {
return this.accessRuleDelegate.getPreflightComponent(rule, this.injector).then((component) => { return this.accessRuleDelegate.getPreflightComponent(rule, this.injector).then((component) => {
if (component) { if (component) {
this.renderedRules.push(rule); this.accessRulesData.push({
this.accessRulesComponent.push(component); component: component,
data: {
rule: rule,
quiz: this.quiz,
attempt: this.attempt,
prefetch: this.prefetch,
form: this.preflightForm,
siteId: this.siteId
}
});
} }
}); });
} }

View File

@ -78,6 +78,7 @@ import { CoreSitePluginsCourseFormatComponent } from '@core/siteplugins/componen
import { CoreSitePluginsQuestionComponent } from '@core/siteplugins/components/question/question'; import { CoreSitePluginsQuestionComponent } from '@core/siteplugins/components/question/question';
import { CoreSitePluginsQuestionBehaviourComponent } from '@core/siteplugins/components/question-behaviour/question-behaviour'; import { CoreSitePluginsQuestionBehaviourComponent } from '@core/siteplugins/components/question-behaviour/question-behaviour';
import { CoreSitePluginsUserProfileFieldComponent } from '@core/siteplugins/components/user-profile-field/user-profile-field'; import { CoreSitePluginsUserProfileFieldComponent } from '@core/siteplugins/components/user-profile-field/user-profile-field';
import { CoreSitePluginsQuizAccessRuleComponent } from '@core/siteplugins/components/quiz-access-rule/quiz-access-rule';
/** /**
* Service to provide functionalities regarding compiling dynamic HTML and Javascript. * Service to provide functionalities regarding compiling dynamic HTML and Javascript.
@ -209,6 +210,7 @@ export class CoreCompileProvider {
instance['CoreSitePluginsQuestionComponent'] = CoreSitePluginsQuestionComponent; instance['CoreSitePluginsQuestionComponent'] = CoreSitePluginsQuestionComponent;
instance['CoreSitePluginsQuestionBehaviourComponent'] = CoreSitePluginsQuestionBehaviourComponent; instance['CoreSitePluginsQuestionBehaviourComponent'] = CoreSitePluginsQuestionBehaviourComponent;
instance['CoreSitePluginsUserProfileFieldComponent'] = CoreSitePluginsUserProfileFieldComponent; instance['CoreSitePluginsUserProfileFieldComponent'] = CoreSitePluginsUserProfileFieldComponent;
instance['CoreSitePluginsQuizAccessRuleComponent'] = CoreSitePluginsQuizAccessRuleComponent;
} }
/** /**

View File

@ -15,7 +15,7 @@
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { CoreCourseFormatHandler } from '@core/course/providers/format-delegate'; import { CoreCourseFormatHandler } from '@core/course/providers/format-delegate';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreSitePluginsCourseFormatComponent } from '../components/course-format/course-format'; import { CoreSitePluginsCourseFormatComponent } from '../../components/course-format/course-format';
/** /**
* Handler to support a course format using a site plugin. * Handler to support a course format using a site plugin.

View File

@ -13,10 +13,10 @@
// limitations under the License. // limitations under the License.
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { CoreSitePluginsProvider } from '../providers/siteplugins'; import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate'; import { CoreCourseOptionsHandler, CoreCourseOptionsHandlerData } from '@core/course/providers/options-delegate';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreSitePluginsCourseOptionComponent } from '../components/course-option/course-option'; import { CoreSitePluginsCourseOptionComponent } from '../../components/course-option/course-option';
/** /**
* Handler to display a site plugin in course options. * Handler to display a site plugin in course options.

View File

@ -16,7 +16,7 @@ import { Injector } from '@angular/core';
import { NavController, NavOptions } from 'ionic-angular'; import { NavController, NavOptions } from 'ionic-angular';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate'; import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@core/course/providers/module-delegate';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreSitePluginsModuleIndexComponent } from '../components/module-index/module-index'; import { CoreSitePluginsModuleIndexComponent } from '../../components/module-index/module-index';
/** /**
* Handler to support a module using a site plugin. * Handler to support a module using a site plugin.

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { CoreSitePluginsProvider } from '../providers/siteplugins'; import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler'; import { CoreCourseModulePrefetchHandlerBase } from '@core/course/classes/module-prefetch-handler';
/** /**

View File

@ -14,7 +14,7 @@
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { CoreQuestionBehaviourDefaultHandler } from '@core/question/providers/default-behaviour-handler'; import { CoreQuestionBehaviourDefaultHandler } from '@core/question/providers/default-behaviour-handler';
import { CoreSitePluginsQuestionBehaviourComponent } from '../components/question-behaviour/question-behaviour'; import { CoreSitePluginsQuestionBehaviourComponent } from '../../components/question-behaviour/question-behaviour';
import { CoreQuestionProvider } from '@core/question/providers/question'; import { CoreQuestionProvider } from '@core/question/providers/question';
/** /**

View File

@ -14,7 +14,7 @@
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { CoreQuestionDefaultHandler } from '@core/question/providers/default-question-handler'; import { CoreQuestionDefaultHandler } from '@core/question/providers/default-question-handler';
import { CoreSitePluginsQuestionComponent } from '../components/question/question'; import { CoreSitePluginsQuestionComponent } from '../../components/question/question';
/** /**
* Handler to display a question site plugin. * Handler to display a question site plugin.

View File

@ -0,0 +1,110 @@
// (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 { Injector } from '@angular/core';
import { CoreQuestionDefaultHandler } from '@core/question/providers/default-question-handler';
import { CoreSitePluginsQuizAccessRuleComponent } from '../../components/quiz-access-rule/quiz-access-rule';
/**
* Handler to display a quiz access rule site plugin.
*/
export class CoreSitePluginsQuizAccessRuleHandler extends CoreQuestionDefaultHandler {
constructor(public name: string, public ruleName: string, public hasTemplate: boolean) {
super();
}
/**
* Whether the rule requires a preflight check when prefetch/start/continue an attempt.
*
* @param {any} quiz The quiz the rule belongs to.
* @param {any} [attempt] The attempt started/continued. If not supplied, user is starting a new attempt.
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {boolean|Promise<boolean>} Whether the rule requires a preflight check.
*/
isPreflightCheckRequired(quiz: any, attempt?: any, prefetch?: boolean, siteId?: string): boolean | Promise<boolean> {
return this.hasTemplate;
}
/**
* Add preflight data that doesn't require user interaction. The data should be added to the preflightData param.
*
* @param {any} quiz The quiz the rule belongs to.
* @param {any} preflightData Object where to add the preflight data.
* @param {any} [attempt] The attempt started/continued. If not supplied, user is starting a new attempt.
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {void|Promise<any>} Promise resolved when done if async, void if it's synchronous.
*/
getFixedPreflightData(quiz: any, preflightData: any, attempt?: any, prefetch?: boolean, siteId?: string): void | Promise<any> {
// Nothing to do.
}
/**
* Return the Component to use to display the access rule preflight.
* Implement this if your access rule requires a preflight check with user interaction.
* It's recommended to return the class of the component, but you can also return an instance of the component.
*
* @param {Injector} injector Injector.
* @return {any|Promise<any>} The component (or promise resolved with component) to use, undefined if not found.
*/
getPreflightComponent(injector: Injector): any | Promise<any> {
if (this.hasTemplate) {
return CoreSitePluginsQuizAccessRuleComponent;
}
}
/**
* Function called when the preflight check has passed. This is a chance to record that fact in some way.
*
* @param {any} quiz The quiz the rule belongs to.
* @param {any} attempt The attempt started/continued.
* @param {any} preflightData Preflight data gathered.
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {void|Promise<any>} Promise resolved when done if async, void if it's synchronous.
*/
notifyPreflightCheckPassed(quiz: any, attempt: any, preflightData: any, prefetch?: boolean, siteId?: string)
: void | Promise<any> {
// Nothing to do.
}
/**
* Function called when the preflight check fails. This is a chance to record that fact in some way.
*
* @param {any} quiz The quiz the rule belongs to.
* @param {any} attempt The attempt started/continued.
* @param {any} preflightData Preflight data gathered.
* @param {boolean} [prefetch] Whether the user is prefetching the quiz.
* @param {string} [siteId] Site ID. If not defined, current site.
* @return {void|Promise<any>} Promise resolved when done if async, void if it's synchronous.
*/
notifyPreflightCheckFailed(quiz: any, attempt: any, preflightData: any, prefetch?: boolean, siteId?: string)
: void | Promise<any> {
// Nothing to do.
}
/**
* Whether or not the time left of an attempt should be displayed.
*
* @param {any} attempt The attempt.
* @param {number} endTime The attempt end time (in seconds).
* @param {number} timeNow The current time in seconds.
* @return {boolean} Whether it should be displayed.
*/
shouldShowTimeLeft(attempt: any, endTime: number, timeNow: number): boolean {
return false;
}
}

View File

@ -14,7 +14,7 @@
import { NavController } from 'ionic-angular'; import { NavController } from 'ionic-angular';
import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate'; import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate';
import { CoreSitePluginsProvider } from '../providers/siteplugins'; import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
/** /**

View File

@ -15,7 +15,7 @@
import { Injector } from '@angular/core'; import { Injector } from '@angular/core';
import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@core/user/providers/user-profile-field-delegate'; import { CoreUserProfileFieldHandler, CoreUserProfileFieldHandlerData } from '@core/user/providers/user-profile-field-delegate';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreSitePluginsUserProfileFieldComponent } from '../components/user-profile-field/user-profile-field'; import { CoreSitePluginsUserProfileFieldComponent } from '../../components/user-profile-field/user-profile-field';
/** /**
* Handler to display a site plugin in the user profile. * Handler to display a site plugin in the user profile.

View File

@ -25,6 +25,7 @@ import { CoreSitePluginsCourseFormatComponent } from './course-format/course-for
import { CoreSitePluginsUserProfileFieldComponent } from './user-profile-field/user-profile-field'; import { CoreSitePluginsUserProfileFieldComponent } from './user-profile-field/user-profile-field';
import { CoreSitePluginsQuestionComponent } from './question/question'; import { CoreSitePluginsQuestionComponent } from './question/question';
import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/question-behaviour'; import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/question-behaviour';
import { CoreSitePluginsQuizAccessRuleComponent } from './quiz-access-rule/quiz-access-rule';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -34,7 +35,8 @@ import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/
CoreSitePluginsCourseFormatComponent, CoreSitePluginsCourseFormatComponent,
CoreSitePluginsUserProfileFieldComponent, CoreSitePluginsUserProfileFieldComponent,
CoreSitePluginsQuestionComponent, CoreSitePluginsQuestionComponent,
CoreSitePluginsQuestionBehaviourComponent CoreSitePluginsQuestionBehaviourComponent,
CoreSitePluginsQuizAccessRuleComponent
], ],
imports: [ imports: [
CommonModule, CommonModule,
@ -52,7 +54,8 @@ import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/
CoreSitePluginsCourseFormatComponent, CoreSitePluginsCourseFormatComponent,
CoreSitePluginsUserProfileFieldComponent, CoreSitePluginsUserProfileFieldComponent,
CoreSitePluginsQuestionComponent, CoreSitePluginsQuestionComponent,
CoreSitePluginsQuestionBehaviourComponent CoreSitePluginsQuestionBehaviourComponent,
CoreSitePluginsQuizAccessRuleComponent
], ],
entryComponents: [ entryComponents: [
CoreSitePluginsModuleIndexComponent, CoreSitePluginsModuleIndexComponent,
@ -60,7 +63,8 @@ import { CoreSitePluginsQuestionBehaviourComponent } from './question-behaviour/
CoreSitePluginsCourseFormatComponent, CoreSitePluginsCourseFormatComponent,
CoreSitePluginsUserProfileFieldComponent, CoreSitePluginsUserProfileFieldComponent,
CoreSitePluginsQuestionComponent, CoreSitePluginsQuestionComponent,
CoreSitePluginsQuestionBehaviourComponent CoreSitePluginsQuestionBehaviourComponent,
CoreSitePluginsQuizAccessRuleComponent
] ]
}) })
export class CoreSitePluginsComponentsModule {} export class CoreSitePluginsComponentsModule {}

View File

@ -0,0 +1 @@
<core-compile-html [text]="content" [jsData]="jsData" (created)="componentCreated($event)"></core-compile-html>

View File

@ -0,0 +1,57 @@
// (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 { Component, OnInit, Input } from '@angular/core';
import { CoreSitePluginsProvider } from '../../providers/siteplugins';
import { CoreSitePluginsCompileInitComponent } from '../../classes/compile-init-component';
import { FormGroup } from '@angular/forms';
/**
* Component that displays a quiz access rule created using a site plugin.
*/
@Component({
selector: 'core-site-plugins-quiz-access-rule',
templateUrl: 'quiz-access-rule.html',
})
export class CoreSitePluginsQuizAccessRuleComponent extends CoreSitePluginsCompileInitComponent implements OnInit {
@Input() rule: string; // The name of the rule.
@Input() quiz: any; // The quiz the rule belongs to.
@Input() attempt: any; // The attempt being started/continued.
@Input() prefetch: boolean; // Whether the user is prefetching the quiz.
@Input() siteId: string; // Site ID.
@Input() form: FormGroup; // Form where to add the form control.
constructor(sitePluginsProvider: CoreSitePluginsProvider) {
super(sitePluginsProvider);
}
/**
* Component being initialized.
*/
ngOnInit(): void {
// Pass the input and output data to the component.
this.jsData = {
rule: this.rule,
quiz: this.quiz,
attempt: this.attempt,
prefetch: this.prefetch,
siteId: this.siteId,
form: this.form
};
if (this.rule) {
this.getHandlerData(this.rule);
}
}
}

View File

@ -39,19 +39,21 @@ import { CoreSettingsDelegate } from '@core/settings/providers/delegate';
import { CoreQuestionDelegate } from '@core/question/providers/delegate'; import { CoreQuestionDelegate } from '@core/question/providers/delegate';
import { CoreQuestionBehaviourDelegate } from '@core/question/providers/behaviour-delegate'; import { CoreQuestionBehaviourDelegate } from '@core/question/providers/behaviour-delegate';
import { AddonMessageOutputDelegate } from '@addon/messageoutput/providers/delegate'; import { AddonMessageOutputDelegate } from '@addon/messageoutput/providers/delegate';
import { AddonModQuizAccessRuleDelegate } from '@addon/mod/quiz/providers/access-rules-delegate';
// Handler classes. // Handler classes.
import { CoreSitePluginsCourseFormatHandler } from '../classes/course-format-handler'; import { CoreSitePluginsCourseFormatHandler } from '../classes/handlers/course-format-handler';
import { CoreSitePluginsCourseOptionHandler } from '../classes/course-option-handler'; import { CoreSitePluginsCourseOptionHandler } from '../classes/handlers/course-option-handler';
import { CoreSitePluginsModuleHandler } from '../classes/module-handler'; import { CoreSitePluginsModuleHandler } from '../classes/handlers/module-handler';
import { CoreSitePluginsModulePrefetchHandler } from '../classes/module-prefetch-handler'; import { CoreSitePluginsModulePrefetchHandler } from '../classes/handlers/module-prefetch-handler';
import { CoreSitePluginsMainMenuHandler } from '../classes/main-menu-handler'; import { CoreSitePluginsMainMenuHandler } from '../classes/handlers/main-menu-handler';
import { CoreSitePluginsUserProfileHandler } from '../classes/user-handler'; import { CoreSitePluginsUserProfileHandler } from '../classes/handlers/user-handler';
import { CoreSitePluginsUserProfileFieldHandler } from '../classes/user-profile-field-handler'; import { CoreSitePluginsUserProfileFieldHandler } from '../classes/handlers/user-profile-field-handler';
import { CoreSitePluginsSettingsHandler } from '../classes/settings-handler'; import { CoreSitePluginsSettingsHandler } from '../classes/handlers/settings-handler';
import { CoreSitePluginsQuestionHandler } from '../classes/question-handler'; import { CoreSitePluginsQuestionHandler } from '../classes/handlers/question-handler';
import { CoreSitePluginsQuestionBehaviourHandler } from '../classes/question-behaviour-handler'; import { CoreSitePluginsQuestionBehaviourHandler } from '../classes/handlers/question-behaviour-handler';
import { CoreSitePluginsMessageOutputHandler } from '../classes/message-output-handler'; import { CoreSitePluginsMessageOutputHandler } from '../classes/handlers/message-output-handler';
import { CoreSitePluginsQuizAccessRuleHandler } from '../classes/handlers/quiz-access-rule-handler';
/** /**
* Helper service to provide functionalities regarding site plugins. It basically has the features to load and register site * Helper service to provide functionalities regarding site plugins. It basically has the features to load and register site
@ -76,7 +78,8 @@ export class CoreSitePluginsHelperProvider {
private textUtils: CoreTextUtilsProvider, private filepoolProvider: CoreFilepoolProvider, private textUtils: CoreTextUtilsProvider, private filepoolProvider: CoreFilepoolProvider,
private settingsDelegate: CoreSettingsDelegate, private questionDelegate: CoreQuestionDelegate, private settingsDelegate: CoreSettingsDelegate, private questionDelegate: CoreQuestionDelegate,
private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider, private questionBehaviourDelegate: CoreQuestionBehaviourDelegate, private questionProvider: CoreQuestionProvider,
private messageOutputDelegate: AddonMessageOutputDelegate) { private messageOutputDelegate: AddonMessageOutputDelegate,
private accessRulesDelegate: AddonModQuizAccessRuleDelegate) {
this.logger = logger.getInstance('CoreSitePluginsHelperProvider'); this.logger = logger.getInstance('CoreSitePluginsHelperProvider');
@ -462,6 +465,10 @@ export class CoreSitePluginsHelperProvider {
promise = Promise.resolve(this.registerMessageOutputHandler(plugin, handlerName, handlerSchema, result)); promise = Promise.resolve(this.registerMessageOutputHandler(plugin, handlerName, handlerSchema, result));
break; break;
case 'AddonModQuizAccessRuleDelegate':
promise = Promise.resolve(this.registerQuizAccessRuleHandler(plugin, handlerName, handlerSchema, result));
break;
default: default:
// Nothing to do. // Nothing to do.
promise = Promise.resolve(); promise = Promise.resolve();
@ -504,7 +511,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the course options delegate. * Given a handler in a plugin, register it in the course options delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -533,7 +540,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the main menu delegate. * Given a handler in a plugin, register it in the main menu delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -562,7 +569,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the message output delegate. * Given a handler in a plugin, register it in the message output delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -592,7 +599,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the module delegate. * Given a handler in a plugin, register it in the module delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -626,7 +633,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the question delegate. * Given a handler in a plugin, register it in the question delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -675,7 +682,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the question behaviour delegate. * Given a handler in a plugin, register it in the question behaviour delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -721,12 +728,61 @@ export class CoreSitePluginsHelperProvider {
return plugin.component; return plugin.component;
}).catch((err) => { }).catch((err) => {
this.logger.error('Error executing main method for question', handlerSchema.method, err); this.logger.error('Error executing main method for question behaviour', handlerSchema.method, err);
}); });
} }
/** /**
* Given a handler in an plugin, register it in the settings delegate. * Given a handler in a plugin, register it in the quiz access rule delegate.
*
* @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin.
* @param {any} handlerSchema Data about the handler.
* @param {any} initResult Result of the init WS call.
* @return {string|Promise<string>} A string (or a promise resolved with a string) to identify the handler.
*/
protected registerQuizAccessRuleHandler(plugin: any, handlerName: string, handlerSchema: any, initResult: any)
: string | Promise<string> {
if (!handlerSchema.method) {
// Required data not provided, stop.
this.logger.warn('Ignore site plugin because it doesn\'t provide method', plugin, handlerSchema);
return;
}
this.logger.debug('Register site plugin in quiz access rule delegate:', plugin, handlerSchema, initResult);
// Execute the main method and its JS. The template returned will be used in the access rule component.
return this.executeMethodAndJS(plugin, handlerSchema.method).then((result) => {
// Create and register the handler.
const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
ruleName = plugin.component,
ruleHandler = new CoreSitePluginsQuizAccessRuleHandler(uniqueName, ruleName, result.templates.length);
// Store in handlerSchema some data required by the component.
handlerSchema.methodTemplates = result.templates;
handlerSchema.methodJSResult = result.jsResult;
if (result && result.jsResult) {
// Override default handler functions with the result of the method JS.
for (const property in ruleHandler) {
if (property != 'constructor' && typeof ruleHandler[property] == 'function' &&
typeof result.jsResult[property] == 'function') {
ruleHandler[property] = result.jsResult[property].bind(ruleHandler);
}
}
}
this.accessRulesDelegate.registerHandler(ruleHandler);
return ruleName;
}).catch((err) => {
this.logger.error('Error executing main method for quiz access rule', handlerSchema.method, err);
});
}
/**
* Given a handler in a plugin, register it in the settings delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -755,7 +811,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the user profile delegate. * Given a handler in a plugin, register it in the user profile delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.
@ -784,7 +840,7 @@ export class CoreSitePluginsHelperProvider {
} }
/** /**
* Given a handler in an plugin, register it in the user profile field delegate. * Given a handler in a plugin, register it in the user profile field delegate.
* *
* @param {any} plugin Data of the plugin. * @param {any} plugin Data of the plugin.
* @param {string} handlerName Name of the handler in the plugin. * @param {string} handlerName Name of the handler in the plugin.