From 33003da29d1984e18bcec86141e7b0445fdbdd02 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 19 Feb 2021 12:47:16 +0100 Subject: [PATCH] MOBILE-3651 quiz: Implement missing handlers --- .../addon-block-recentlyaccesseditems.html | 2 +- src/addons/mod/quiz/quiz.module.ts | 15 ++++ .../mod/quiz/services/handlers/grade-link.ts | 35 ++++++++ .../mod/quiz/services/handlers/index-link.ts | 34 ++++++++ .../mod/quiz/services/handlers/list-link.ts | 34 ++++++++ .../mod/quiz/services/handlers/prefetch.ts | 2 +- .../mod/quiz/services/handlers/push-click.ts | 86 +++++++++++++++++++ .../mod/quiz/services/handlers/review-link.ts | 66 ++++++++++++++ .../mod/quiz/services/handlers/sync-cron.ts | 52 +++++++++++ src/addons/mod/quiz/services/quiz-helper.ts | 14 ++- src/addons/mod/quiz/services/quiz.ts | 10 --- .../section-selector/section-selector.html | 2 +- 12 files changed, 331 insertions(+), 21 deletions(-) create mode 100644 src/addons/mod/quiz/services/handlers/grade-link.ts create mode 100644 src/addons/mod/quiz/services/handlers/index-link.ts create mode 100644 src/addons/mod/quiz/services/handlers/list-link.ts create mode 100644 src/addons/mod/quiz/services/handlers/push-click.ts create mode 100644 src/addons/mod/quiz/services/handlers/review-link.ts create mode 100644 src/addons/mod/quiz/services/handlers/sync-cron.ts diff --git a/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html b/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html index 2008fbce0..f97b267b1 100644 --- a/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html +++ b/src/addons/block/recentlyaccesseditems/components/recentlyaccesseditems/addon-block-recentlyaccesseditems.html @@ -6,7 +6,7 @@
+ [title]="item.name" button>

diff --git a/src/addons/mod/quiz/quiz.module.ts b/src/addons/mod/quiz/quiz.module.ts index 3dcf54d19..c39a6deb3 100644 --- a/src/addons/mod/quiz/quiz.module.ts +++ b/src/addons/mod/quiz/quiz.module.ts @@ -14,16 +14,25 @@ import { APP_INITIALIZER, NgModule } from '@angular/core'; import { Routes } from '@angular/router'; +import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate'; import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate'; import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate'; import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module'; +import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate'; +import { CoreCronDelegate } from '@services/cron'; import { CORE_SITE_SCHEMAS } from '@services/sites'; import { AddonModQuizAccessRulesModule } from './accessrules/accessrules.module'; import { AddonModQuizComponentsModule } from './components/components.module'; import { SITE_SCHEMA } from './services/database/quiz'; +import { AddonModQuizGradeLinkHandler } from './services/handlers/grade-link'; +import { AddonModQuizIndexLinkHandler } from './services/handlers/index-link'; +import { AddonModQuizListLinkHandler } from './services/handlers/list-link'; import { AddonModQuizModuleHandler, AddonModQuizModuleHandlerService } from './services/handlers/module'; import { AddonModQuizPrefetchHandler } from './services/handlers/prefetch'; +import { AddonModQuizPushClickHandler } from './services/handlers/push-click'; +import { AddonModQuizReviewLinkHandler } from './services/handlers/review-link'; +import { AddonModQuizSyncCronHandler } from './services/handlers/sync-cron'; const routes: Routes = [ { @@ -51,6 +60,12 @@ const routes: Routes = [ useFactory: () => () => { CoreCourseModuleDelegate.instance.registerHandler(AddonModQuizModuleHandler.instance); CoreCourseModulePrefetchDelegate.instance.registerHandler(AddonModQuizPrefetchHandler.instance); + CoreContentLinksDelegate.instance.registerHandler(AddonModQuizGradeLinkHandler.instance); + CoreContentLinksDelegate.instance.registerHandler(AddonModQuizIndexLinkHandler.instance); + CoreContentLinksDelegate.instance.registerHandler(AddonModQuizListLinkHandler.instance); + CoreContentLinksDelegate.instance.registerHandler(AddonModQuizReviewLinkHandler.instance); + CorePushNotificationsDelegate.instance.registerClickHandler(AddonModQuizPushClickHandler.instance); + CoreCronDelegate.instance.register(AddonModQuizSyncCronHandler.instance); }, }, ], diff --git a/src/addons/mod/quiz/services/handlers/grade-link.ts b/src/addons/mod/quiz/services/handlers/grade-link.ts new file mode 100644 index 000000000..06557f770 --- /dev/null +++ b/src/addons/mod/quiz/services/handlers/grade-link.ts @@ -0,0 +1,35 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// 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 { CoreContentLinksModuleGradeHandler } from '@features/contentlinks/classes/module-grade-handler'; +import { makeSingleton } from '@singletons'; + +/** + * Handler to treat links to quiz grade. + */ +@Injectable({ providedIn: 'root' }) +export class AddonModQuizGradeLinkHandlerService extends CoreContentLinksModuleGradeHandler { + + name = 'AddonModQuizGradeLinkHandler'; + canReview = false; + + constructor() { + super('AddonModQuiz', 'quiz'); + } + +} + +export class AddonModQuizGradeLinkHandler extends makeSingleton(AddonModQuizGradeLinkHandlerService) {} diff --git a/src/addons/mod/quiz/services/handlers/index-link.ts b/src/addons/mod/quiz/services/handlers/index-link.ts new file mode 100644 index 000000000..a59d0924e --- /dev/null +++ b/src/addons/mod/quiz/services/handlers/index-link.ts @@ -0,0 +1,34 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Injectable } from '@angular/core'; + +import { CoreContentLinksModuleIndexHandler } from '@features/contentlinks/classes/module-index-handler'; +import { makeSingleton } from '@singletons'; + +/** + * Handler to treat links to quiz index. + */ +@Injectable({ providedIn: 'root' }) +export class AddonModQuizIndexLinkHandlerService extends CoreContentLinksModuleIndexHandler { + + name = 'AddonModQuizIndexLinkHandler'; + + constructor() { + super('AddonModQuiz', 'quiz', 'q'); + } + +} + +export class AddonModQuizIndexLinkHandler extends makeSingleton(AddonModQuizIndexLinkHandlerService) {} diff --git a/src/addons/mod/quiz/services/handlers/list-link.ts b/src/addons/mod/quiz/services/handlers/list-link.ts new file mode 100644 index 000000000..1158d1beb --- /dev/null +++ b/src/addons/mod/quiz/services/handlers/list-link.ts @@ -0,0 +1,34 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// 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 { CoreContentLinksModuleListHandler } from '@features/contentlinks/classes/module-list-handler'; +import { makeSingleton } from '@singletons'; + +/** + * Handler to treat links to quiz list page. + */ +@Injectable({ providedIn: 'root' }) +export class AddonModQuizListLinkHandlerService extends CoreContentLinksModuleListHandler { + + name = 'AddonModQuizListLinkHandler'; + + constructor() { + super('AddonModQuiz', 'quiz'); + } + +} + +export class AddonModQuizListLinkHandler extends makeSingleton(AddonModQuizListLinkHandlerService) {} diff --git a/src/addons/mod/quiz/services/handlers/prefetch.ts b/src/addons/mod/quiz/services/handlers/prefetch.ts index e138fe936..251a5e5ed 100644 --- a/src/addons/mod/quiz/services/handlers/prefetch.ts +++ b/src/addons/mod/quiz/services/handlers/prefetch.ts @@ -254,7 +254,7 @@ export class AddonModQuizPrefetchHandlerService extends CoreCourseActivityPrefet * @return A boolean, or a promise resolved with a boolean, indicating if the handler is enabled. */ async isEnabled(): Promise { - return AddonModQuiz.instance.isPluginEnabled(); + return true; } /** diff --git a/src/addons/mod/quiz/services/handlers/push-click.ts b/src/addons/mod/quiz/services/handlers/push-click.ts new file mode 100644 index 000000000..b969577ef --- /dev/null +++ b/src/addons/mod/quiz/services/handlers/push-click.ts @@ -0,0 +1,86 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// 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 { CoreCourseHelper } from '@features/course/services/course-helper'; +import { CorePushNotificationsClickHandler } from '@features/pushnotifications/services/push-delegate'; +import { CorePushNotificationsNotificationBasicData } from '@features/pushnotifications/services/pushnotifications'; +import { CoreUrlUtils } from '@services/utils/url'; +import { CoreUtils } from '@services/utils/utils'; +import { makeSingleton } from '@singletons'; +import { AddonModQuiz } from '../quiz'; +import { AddonModQuizHelper } from '../quiz-helper'; + +/** + * Handler for quiz push notifications clicks. + */ +@Injectable({ providedIn: 'root' }) +export class AddonModQuizPushClickHandlerService implements CorePushNotificationsClickHandler { + + name = 'AddonModQuizPushClickHandler'; + priority = 200; + featureName = 'CoreCourseModuleDelegate_AddonModQuiz'; + + protected readonly SUPPORTED_NAMES = ['submission', 'confirmation', 'attempt_overdue']; + + /** + * Check if a notification click is handled by this handler. + * + * @param notification The notification to check. + * @return Whether the notification click is handled by this handler + */ + async handles(notification: AddonModQuizPushNotificationData): Promise { + return CoreUtils.instance.isTrueOrOne(notification.notif) && notification.moodlecomponent == 'mod_quiz' && + this.SUPPORTED_NAMES.indexOf(notification.name!) != -1; + } + + /** + * Handle the notification click. + * + * @param notification The notification to check. + * @return Promise resolved when done. + */ + async handleClick(notification: AddonModQuizPushNotificationData): Promise { + const contextUrlParams = CoreUrlUtils.instance.extractUrlParams(notification.contexturl || ''); + const data = notification.customdata || {}; + const courseId = Number(notification.courseid); + + if (notification.name == 'submission') { + // A student made a submission, go to view the attempt. + return AddonModQuizHelper.instance.handleReviewLink( + Number(contextUrlParams.attempt), + Number(contextUrlParams.page), + courseId, + Number(data.instance), + notification.site, + ); + } + + // Open the activity. + const moduleId = Number(contextUrlParams.id); + + await CoreUtils.instance.ignoreErrors(AddonModQuiz.instance.invalidateContent(moduleId, courseId, notification.site)); + + return CoreCourseHelper.instance.navigateToModule(moduleId, notification.site, courseId); + } + +} + +export class AddonModQuizPushClickHandler extends makeSingleton(AddonModQuizPushClickHandlerService) {} + +type AddonModQuizPushNotificationData = CorePushNotificationsNotificationBasicData & { + contexturl?: string; + courseid?: number | string; +}; diff --git a/src/addons/mod/quiz/services/handlers/review-link.ts b/src/addons/mod/quiz/services/handlers/review-link.ts new file mode 100644 index 000000000..7c9f40a63 --- /dev/null +++ b/src/addons/mod/quiz/services/handlers/review-link.ts @@ -0,0 +1,66 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// 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 { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base-handler'; +import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate'; +import { makeSingleton } from '@singletons'; +import { AddonModQuizHelper } from '../quiz-helper'; + +/** + * Handler to treat links to quiz review. + */ +@Injectable({ providedIn: 'root' }) +export class AddonModQuizReviewLinkHandlerService extends CoreContentLinksHandlerBase { + + name = 'AddonModQuizReviewLinkHandler'; + featureName = 'CoreCourseModuleDelegate_AddonModQuiz'; + pattern = /\/mod\/quiz\/review\.php.*([&?]attempt=\d+)/; + + /** + * Get the list of actions for a link (url). + * + * @param siteIds List of sites the URL belongs to. + * @param url The URL to treat. + * @param params The params of the URL. E.g. 'mysite.com?id=1' -> {id: 1} + * @param courseId Course ID related to the URL. Optional but recommended. + * @param data Extra data to handle the URL. + * @return List of (or promise resolved with list of) actions. + */ + + getActions( + siteIds: string[], + url: string, + params: Record, + courseId?: number, + data?: Record, + ): CoreContentLinksAction[] | Promise { + + courseId = Number(courseId || params.courseid || params.cid); + data = data || {}; + + return [{ + action: (siteId): void => { + const attemptId = parseInt(params.attempt, 10); + const page = parseInt(params.page, 10); + const quizId = data!.instance ? Number(data!.instance) : undefined; + + AddonModQuizHelper.instance.handleReviewLink(attemptId, page, courseId, quizId, siteId); + }, + }]; + } + +} + +export class AddonModQuizReviewLinkHandler extends makeSingleton(AddonModQuizReviewLinkHandlerService) {} diff --git a/src/addons/mod/quiz/services/handlers/sync-cron.ts b/src/addons/mod/quiz/services/handlers/sync-cron.ts new file mode 100644 index 000000000..9477bbf5e --- /dev/null +++ b/src/addons/mod/quiz/services/handlers/sync-cron.ts @@ -0,0 +1,52 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Injectable } from '@angular/core'; + +import { CoreCronHandler } from '@services/cron'; +import { makeSingleton } from '@singletons'; +import { AddonModQuizSync } from '../quiz-sync'; + +/** + * Synchronization cron handler. + */ +@Injectable({ providedIn: 'root' }) +export class AddonModQuizSyncCronHandlerService implements CoreCronHandler { + + name = 'AddonModQuizSyncCronHandler'; + + /** + * Execute the process. + * Receives the ID of the site affected, undefined for all sites. + * + * @param siteId ID of the site affected, undefined for all sites. + * @param force Wether the execution is forced (manual sync). + * @return Promise resolved when done, rejected if failure. + */ + execute(siteId?: string, force?: boolean): Promise { + return AddonModQuizSync.instance.syncAllQuizzes(siteId, force); + } + + /** + * Get the time between consecutive executions. + * + * @return Time between consecutive executions (in ms). + */ + getInterval(): number { + return AddonModQuizSync.instance.syncInterval; + } + +} + +export class AddonModQuizSyncCronHandler extends makeSingleton(AddonModQuizSyncCronHandlerService) {} diff --git a/src/addons/mod/quiz/services/quiz-helper.ts b/src/addons/mod/quiz/services/quiz-helper.ts index 74967b107..6fb0851c3 100644 --- a/src/addons/mod/quiz/services/quiz-helper.ts +++ b/src/addons/mod/quiz/services/quiz-helper.ts @@ -237,14 +237,12 @@ export class AddonModQuizHelperProvider { } // Go to the review page. - const pageParams = { - quizId, - attemptId, - courseId, - page: page == undefined || isNaN(page) ? -1 : page, - }; - - await CoreNavigator.instance.navigateToSitePath('@todo AddonModQuizReviewPage', { params: pageParams, siteId }); + await CoreNavigator.instance.navigateToSitePath(`mod_quiz/review/${courseId}/${quizId}/${attemptId}`, { + params: { + page: page == undefined || isNaN(page) ? -1 : page, + }, + siteId, + }); } catch (error) { CoreDomUtils.instance.showErrorModalDefault(error, 'An error occurred while loading the required data.'); } finally { diff --git a/src/addons/mod/quiz/services/quiz.ts b/src/addons/mod/quiz/services/quiz.ts index 86fd2e27e..7b40b3252 100644 --- a/src/addons/mod/quiz/services/quiz.ts +++ b/src/addons/mod/quiz/services/quiz.ts @@ -1496,16 +1496,6 @@ export class AddonModQuizProvider { return quiz.navmethod == 'sequential'; } - /** - * Return whether or not the plugin is enabled in a certain site. Plugin is enabled if the quiz WS are available. - * - * @return Whether the plugin is enabled. - */ - isPluginEnabled(): boolean { - // Quiz WebServices were introduced in 3.1, it will always be enabled. - return true; - } - /** * Check if a question is blocked. * diff --git a/src/core/features/course/components/section-selector/section-selector.html b/src/core/features/course/components/section-selector/section-selector.html index f0997453a..9eb4b28dd 100644 --- a/src/core/features/course/components/section-selector/section-selector.html +++ b/src/core/features/course/components/section-selector/section-selector.html @@ -14,7 +14,7 @@ + [attr.aria-hidden]="section.uservisible === false" button>