commit
9ba630c02a
|
@ -14,8 +14,8 @@ jobs:
|
|||
with:
|
||||
node-version: '12.x'
|
||||
- run: npm ci
|
||||
- run: result=$(find src -type f -iname '*.html' -exec sh -c 'cat {} | tr "\n" " " | grep -Eo "class=\"[^\"]+\"[^>]+class=\"" ' \; | wc -l); test $result -eq 0
|
||||
- run: npm run lint
|
||||
- run: npx tslint -c ionic-migration.json -p tsconfig.json
|
||||
- run: npm run test:ci
|
||||
- run: npm run build:prod
|
||||
- run: result=$(find src -type f -iname '*.html' -exec sh -c 'cat {} | tr "\n" " " | grep -Eo "class=\"[^\"]+\"[^>]+class=\"" ' \; | wc -l); test $result -eq 0
|
||||
|
|
|
@ -376,13 +376,13 @@ export class AddonModBookProvider {
|
|||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the WS call is successful.
|
||||
*/
|
||||
logView(id: number, chapterId?: number, name?: string, siteId?: string): Promise<void> {
|
||||
async logView(id: number, chapterId?: number, name?: string, siteId?: string): Promise<void> {
|
||||
const params: AddonModBookViewBookWSParams = {
|
||||
bookid: id,
|
||||
chapterid: chapterId,
|
||||
};
|
||||
|
||||
return CoreCourseLogHelper.instance.logSingle(
|
||||
await CoreCourseLogHelper.instance.logSingle(
|
||||
'mod_book_view_book',
|
||||
params,
|
||||
AddonModBookProvider.COMPONENT,
|
||||
|
|
|
@ -16,12 +16,14 @@ import { NgModule } from '@angular/core';
|
|||
|
||||
import { AddonModBookModule } from './book/book.module';
|
||||
import { AddonModLessonModule } from './lesson/lesson.module';
|
||||
import { AddonModPageModule } from './page/page.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
AddonModBookModule,
|
||||
AddonModLessonModule,
|
||||
AddonModPageModule,
|
||||
],
|
||||
providers: [],
|
||||
exports: [],
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { CoreSharedModule } from '@/core/shared.module';
|
||||
import { CoreCourseComponentsModule } from '@features/course/components/components.module';
|
||||
|
||||
import { AddonModPageIndexComponent } from './index/index';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AddonModPageIndexComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
FormsModule,
|
||||
CoreSharedModule,
|
||||
CoreCourseComponentsModule,
|
||||
],
|
||||
exports: [
|
||||
AddonModPageIndexComponent,
|
||||
],
|
||||
})
|
||||
export class AddonModPageComponentsModule {}
|
|
@ -0,0 +1,47 @@
|
|||
<!-- Buttons to add to the header. -->
|
||||
<core-navbar-buttons slot="end">
|
||||
<core-context-menu>
|
||||
<core-context-menu-item *ngIf="externalUrl" [priority]="900" [content]="'core.openinbrowser' | translate"
|
||||
[href]="externalUrl" iconAction="fas-external-link-alt">
|
||||
</core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="description" [priority]="800" [content]="'core.moduleintro' | translate"
|
||||
(action)="expandDescription()" iconAction="fas-arrow-right">
|
||||
</core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="blog" [priority]="750" content="{{'addon.blog.blog' | translate}}"
|
||||
iconAction="far-newspaper" (action)="gotoBlog()">
|
||||
</core-context-menu-item>
|
||||
<core-context-menu-item [priority]="700" [content]="'core.refresh' | translate" (action)="doRefresh(null, $event)"
|
||||
[iconAction]="refreshIcon" [closeOnClick]="false">
|
||||
</core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="prefetchStatusIcon" [priority]="600" [content]="prefetchText" (action)="prefetch($event)"
|
||||
[iconAction]="prefetchStatusIcon" [closeOnClick]="false">
|
||||
</core-context-menu-item>
|
||||
<core-context-menu-item *ngIf="size" [priority]="500" [content]="'core.clearstoreddata' | translate:{$a: size}"
|
||||
iconDescription="fas-archive" (action)="removeFiles($event)" iconAction="fas-trash" [closeOnClick]="false">
|
||||
</core-context-menu-item>
|
||||
</core-context-menu>
|
||||
</core-navbar-buttons>
|
||||
|
||||
<!-- Content. -->
|
||||
<core-loading [hideUntil]="loaded" class="core-loading-center safe-area-page">
|
||||
|
||||
<core-course-module-description *ngIf="displayDescription" [description]="description" [component]="component"
|
||||
[componentId]="componentId" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
|
||||
</core-course-module-description>
|
||||
|
||||
<ion-card class="core-warning-card" *ngIf="warning">
|
||||
<ion-icon name="fas-exclamation-triangle" slot="start"></ion-icon>
|
||||
<span [innerHTML]="warning"></span>
|
||||
</ion-card>
|
||||
|
||||
<div class="ion-padding">
|
||||
<core-format-text [component]="component" [componentId]="componentId" [text]="contents" contextLevel="module"
|
||||
[contextInstanceId]="module?.id" [courseId]="courseId">
|
||||
</core-format-text>
|
||||
|
||||
<p class="ion-padding-bottom addon-mod_page-timemodified" *ngIf="displayTimemodified && timemodified">
|
||||
{{ 'core.lastmodified' | translate}}: {{ timemodified! * 1000 | coreFormatDate }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</core-loading>
|
|
@ -0,0 +1,8 @@
|
|||
/* Solves iframe height */
|
||||
.core-loading-content > div[padding] {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
core-format-text > .no-overflow {
|
||||
display: inline;
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
// (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 { Component, OnInit, Optional } from '@angular/core';
|
||||
import {
|
||||
CoreCourseModuleMainResourceComponent,
|
||||
} from '@features/course/classes/main-resource-component';
|
||||
import { CoreCourseContentsPage } from '@features/course/pages/contents/contents';
|
||||
import { CoreCourse, CoreCourseWSModule } from '@features/course/services/course';
|
||||
import { CoreTextUtils } from '@services/utils/text';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { AddonModPageProvider, AddonModPagePage, AddonModPage } from '../../services/page';
|
||||
import { AddonModPageHelper } from '../../services/page-helper';
|
||||
|
||||
/**
|
||||
* Component that displays a page.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'addon-mod-page-index',
|
||||
templateUrl: 'addon-mod-page-index.html',
|
||||
styleUrls: ['index.scss'],
|
||||
})
|
||||
export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComponent implements OnInit {
|
||||
|
||||
component = AddonModPageProvider.COMPONENT;
|
||||
canGetPage = false;
|
||||
contents?: string;
|
||||
displayDescription = true;
|
||||
displayTimemodified = true;
|
||||
timemodified?: number;
|
||||
page?: CoreCourseWSModule | AddonModPagePage;
|
||||
warning?: string;
|
||||
|
||||
protected fetchContentDefaultError = 'addon.mod_page.errorwhileloadingthepage';
|
||||
|
||||
constructor(@Optional() courseContentsPage?: CoreCourseContentsPage) {
|
||||
super('AddonModPageIndexComponent', courseContentsPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
super.ngOnInit();
|
||||
|
||||
this.canGetPage = AddonModPage.instance.isGetPageWSAvailable();
|
||||
|
||||
await this.loadContent();
|
||||
|
||||
try {
|
||||
await AddonModPage.instance.logView(this.module!.instance!, this.module!.name);
|
||||
CoreCourse.instance.checkModuleCompletion(this.courseId!, this.module!.completiondata);
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the invalidate content function.
|
||||
*
|
||||
* @return Resolved when done.
|
||||
*/
|
||||
protected async invalidateContent(): Promise<void> {
|
||||
await AddonModPage.instance.invalidateContent(this.module!.id, this.courseId!);
|
||||
}
|
||||
|
||||
/**
|
||||
* Download page contents.
|
||||
*
|
||||
* @param refresh Whether we're refreshing data.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
protected async fetchContent(refresh?: boolean): Promise<void> {
|
||||
// Download the resource if it needs to be downloaded.
|
||||
try {
|
||||
const downloadResult = await this.downloadResourceIfNeeded(refresh);
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
let getPagePromise: Promise<CoreCourseWSModule | AddonModPagePage>;
|
||||
|
||||
// Get the module to get the latest title and description. Data should've been updated in download.
|
||||
if (this.canGetPage) {
|
||||
getPagePromise = AddonModPage.instance.getPageData(this.courseId!, this.module!.id);
|
||||
} else {
|
||||
getPagePromise = CoreCourse.instance.getModule(this.module!.id, this.courseId!);
|
||||
}
|
||||
|
||||
promises.push(getPagePromise.then((page) => {
|
||||
if (!page) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.description = 'intro' in page ? page.intro : page.description;
|
||||
this.dataRetrieved.emit(page);
|
||||
|
||||
if (!this.canGetPage) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.page = page;
|
||||
|
||||
// Check if description and timemodified should be displayed.
|
||||
if ('displayoptions' in this.page) {
|
||||
const options: Record<string, string | boolean> =
|
||||
CoreTextUtils.instance.unserialize(this.page.displayoptions) || {};
|
||||
|
||||
this.displayDescription = typeof options.printintro == 'undefined' ||
|
||||
CoreUtils.instance.isTrueOrOne(options.printintro);
|
||||
this.displayTimemodified = typeof options.printlastmodified == 'undefined' ||
|
||||
CoreUtils.instance.isTrueOrOne(options.printlastmodified);
|
||||
} else {
|
||||
this.displayDescription = true;
|
||||
this.displayTimemodified = true;
|
||||
}
|
||||
|
||||
this.timemodified = 'timemodified' in this.page ? this.page.timemodified : undefined;
|
||||
|
||||
return;
|
||||
}).catch(() => {
|
||||
// Ignore errors.
|
||||
}));
|
||||
|
||||
// Get the page HTML.
|
||||
promises.push(AddonModPageHelper.instance.getPageHtml(this.module!.contents, this.module!.id).then((content) => {
|
||||
|
||||
this.contents = content;
|
||||
this.warning = downloadResult?.failed ? this.getErrorDownloadingSomeFilesMessage(downloadResult.error!) : '';
|
||||
|
||||
return;
|
||||
}));
|
||||
|
||||
await Promise.all(promises);
|
||||
} finally {
|
||||
this.fillContextMenu(refresh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"errorwhileloadingthepage": "Error while loading the page content.",
|
||||
"modulenameplural": "Pages"
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: ':courseId/:cmdId',
|
||||
loadChildren: () => import('./pages/index/index.module').then( m => m.AddonModPageIndexPageModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
})
|
||||
export class AddonModPageLazyModule {}
|
|
@ -0,0 +1,56 @@
|
|||
// (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 { 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 { CorePluginFileDelegate } from '@services/plugin-file-delegate';
|
||||
import { AddonModPageComponentsModule } from './components/components.module';
|
||||
import { AddonModPageIndexLinkHandler } from './services/handlers/index-link';
|
||||
import { AddonModPageListLinkHandler } from './services/handlers/list-link';
|
||||
import { AddonModPageModuleHandler, AddonModPageModuleHandlerService } from './services/handlers/module';
|
||||
import { AddonModPagePluginFileHandler } from './services/handlers/pluginfile';
|
||||
import { AddonModPagePrefetchHandler } from './services/handlers/prefetch';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: AddonModPageModuleHandlerService.PAGE_NAME,
|
||||
loadChildren: () => import('./page-lazy.module').then(m => m.AddonModPageLazyModule),
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CoreMainMenuTabRoutingModule.forChild(routes),
|
||||
AddonModPageComponentsModule,
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
multi: true,
|
||||
deps: [],
|
||||
useFactory: () => () => {
|
||||
CoreCourseModuleDelegate.instance.registerHandler(AddonModPageModuleHandler.instance);
|
||||
CoreContentLinksDelegate.instance.registerHandler(AddonModPageIndexLinkHandler.instance);
|
||||
CoreContentLinksDelegate.instance.registerHandler(AddonModPageListLinkHandler.instance);
|
||||
CoreCourseModulePrefetchDelegate.instance.registerHandler(AddonModPagePrefetchHandler.instance);
|
||||
CorePluginFileDelegate.instance.registerHandler(AddonModPagePluginFileHandler.instance);
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
export class AddonModPageModule {}
|
|
@ -0,0 +1,22 @@
|
|||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module?.id" [courseId]="courseId">
|
||||
</core-format-text>
|
||||
</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<!-- The buttons defined by the component will be added in here. -->
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-refresher slot="fixed" [disabled]="!pageComponent?.loaded" (ionRefresh)="pageComponent?.doRefresh($event)">
|
||||
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
|
||||
</ion-refresher>
|
||||
|
||||
<addon-mod-page-index [module]="module" [courseId]="courseId" (dataRetrieved)="updateData($event)">
|
||||
</addon-mod-page-index>
|
||||
</ion-content>
|
|
@ -0,0 +1,46 @@
|
|||
// (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 { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { CoreSharedModule } from '@/core/shared.module';
|
||||
import { AddonModPageComponentsModule } from '../../components/components.module';
|
||||
import { AddonModPageIndexPage } from './index';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: AddonModPageIndexPage,
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TranslateModule.forChild(),
|
||||
CoreSharedModule,
|
||||
AddonModPageComponentsModule,
|
||||
],
|
||||
declarations: [
|
||||
AddonModPageIndexPage,
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class AddonModPageIndexPageModule {}
|
|
@ -0,0 +1,54 @@
|
|||
// (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 { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { CoreCourseWSModule } from '@features/course/services/course';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { AddonModPageIndexComponent } from '../../components/index/index';
|
||||
import { AddonModPagePage } from '../../services/page';
|
||||
|
||||
/**
|
||||
* Page that displays a page.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'page-addon-mod-page-index',
|
||||
templateUrl: 'index.html',
|
||||
})
|
||||
export class AddonModPageIndexPage implements OnInit {
|
||||
|
||||
@ViewChild(AddonModPageIndexComponent) pageComponent?: AddonModPageIndexComponent;
|
||||
|
||||
title?: string;
|
||||
module?: CoreCourseWSModule;
|
||||
courseId?: number;
|
||||
|
||||
/**
|
||||
* Component being initialized.
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.module = CoreNavigator.instance.getRouteParam('module');
|
||||
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId');
|
||||
this.title = this.module?.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update some data based on the page instance.
|
||||
*
|
||||
* @param page Page instance.
|
||||
*/
|
||||
updateData(page: CoreCourseWSModule | AddonModPagePage): void {
|
||||
this.title = 'name' in page ? page.name : this.title;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// (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';
|
||||
import { AddonModPage } from '../page';
|
||||
|
||||
/**
|
||||
* Handler to treat links to page resource.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPageIndexLinkHandlerService extends CoreContentLinksModuleIndexHandler {
|
||||
|
||||
name = 'AddonModPageLinkHandler';
|
||||
|
||||
constructor() {
|
||||
super('AddonModPage', 'page', 'p');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled for a certain site (site + user) and a URL.
|
||||
*
|
||||
* @param siteId The site ID.
|
||||
* @return Whether the handler is enabled for the URL and site.
|
||||
*/
|
||||
isEnabled(siteId: string): Promise<boolean> {
|
||||
return AddonModPage.instance.isPluginEnabled(siteId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AddonModPageIndexLinkHandler extends makeSingleton(AddonModPageIndexLinkHandlerService) {}
|
|
@ -0,0 +1,44 @@
|
|||
// (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';
|
||||
import { AddonModPage } from '../page';
|
||||
|
||||
/**
|
||||
* Handler to treat links to page list page.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPageListLinkHandlerService extends CoreContentLinksModuleListHandler {
|
||||
|
||||
name = 'AddonModPageListLinkHandler';
|
||||
|
||||
constructor() {
|
||||
super('AddonModPage', 'page');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled on a site level.
|
||||
*
|
||||
* @param siteId The site ID.
|
||||
* @return Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(siteId: string): Promise<boolean> {
|
||||
return AddonModPage.instance.isPluginEnabled(siteId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AddonModPageListLinkHandler extends makeSingleton(AddonModPageListLinkHandlerService) {}
|
|
@ -0,0 +1,93 @@
|
|||
// (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, Type } from '@angular/core';
|
||||
import { AddonModPage } from '../page';
|
||||
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
|
||||
import { CoreConstants } from '@/core/constants';
|
||||
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
|
||||
import { CoreCourseModule } from '@features/course/services/course-helper';
|
||||
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
|
||||
import { AddonModPageIndexComponent } from '../../components/index';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
* Handler to support page modules.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPageModuleHandlerService implements CoreCourseModuleHandler {
|
||||
|
||||
static readonly PAGE_NAME = 'mod_page';
|
||||
|
||||
name = 'AddonModPage';
|
||||
modName = 'page';
|
||||
|
||||
supportedFeatures = {
|
||||
[CoreConstants.FEATURE_MOD_ARCHETYPE]: CoreConstants.MOD_ARCHETYPE_RESOURCE,
|
||||
[CoreConstants.FEATURE_GROUPS]: false,
|
||||
[CoreConstants.FEATURE_GROUPINGS]: false,
|
||||
[CoreConstants.FEATURE_MOD_INTRO]: true,
|
||||
[CoreConstants.FEATURE_COMPLETION_TRACKS_VIEWS]: true,
|
||||
[CoreConstants.FEATURE_GRADE_HAS_GRADE]: false,
|
||||
[CoreConstants.FEATURE_GRADE_OUTCOMES]: false,
|
||||
[CoreConstants.FEATURE_BACKUP_MOODLE2]: true,
|
||||
[CoreConstants.FEATURE_SHOW_DESCRIPTION]: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the handler is enabled on a site level.
|
||||
*
|
||||
* @return Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
isEnabled(): Promise<boolean> {
|
||||
return AddonModPage.instance.isPluginEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data required to display the module in the course contents view.
|
||||
*
|
||||
* @param module The module object.
|
||||
* @return Data to render the module.
|
||||
*/
|
||||
getData(module: CoreCourseAnyModuleData): CoreCourseModuleHandlerData {
|
||||
return {
|
||||
icon: CoreCourse.instance.getModuleIconSrc(this.modName, 'modicon' in module ? module.modicon : undefined),
|
||||
title: module.name,
|
||||
class: 'addon-mod_page-handler',
|
||||
showDownloadButton: true,
|
||||
action(event: Event, module: CoreCourseModule, courseId: number, options?: CoreNavigationOptions): void {
|
||||
options = options || {};
|
||||
options.params = options.params || {};
|
||||
Object.assign(options.params, { module });
|
||||
const routeParams = '/' + courseId + '/' + module.id;
|
||||
|
||||
CoreNavigator.instance.navigateToSitePath(AddonModPageModuleHandlerService.PAGE_NAME + routeParams, options);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component to render the module. This is needed to support singleactivity course format.
|
||||
* The component returned must implement CoreCourseModuleMainComponent.
|
||||
*
|
||||
* @param course The course object.
|
||||
* @param module The module object.
|
||||
* @return The component to use, undefined if not found.
|
||||
*/
|
||||
async getMainComponent(): Promise<Type<unknown> | undefined> {
|
||||
return AddonModPageIndexComponent;
|
||||
}
|
||||
|
||||
}
|
||||
export class AddonModPageModuleHandler extends makeSingleton(AddonModPageModuleHandlerService) {}
|
|
@ -0,0 +1,63 @@
|
|||
// (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 { CorePluginFileHandler } from '@services/plugin-file-delegate';
|
||||
import { makeSingleton } from '@singletons';
|
||||
|
||||
/**
|
||||
* Handler to treat links to page.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPagePluginFileHandlerService implements CorePluginFileHandler {
|
||||
|
||||
name = 'AddonModPagePluginFileHandler';
|
||||
component = 'mod_page';
|
||||
|
||||
/**
|
||||
* Return the RegExp to match the revision on pluginfile URLs.
|
||||
*
|
||||
* @param args Arguments of the pluginfile URL defining component and filearea at least.
|
||||
* @return RegExp to match the revision on pluginfile URLs.
|
||||
*/
|
||||
getComponentRevisionRegExp(args: string[]): RegExp | undefined {
|
||||
// Check filearea.
|
||||
if (args[2] == 'content') {
|
||||
// Component + Filearea + Revision
|
||||
return new RegExp('/mod_page/content/([0-9]+)/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should return the string to remove the revision on pluginfile url.
|
||||
*
|
||||
* @return String to remove the revision on pluginfile url.
|
||||
*/
|
||||
getComponentRevisionReplace(): string {
|
||||
// Component + Filearea + Revision
|
||||
return '/mod_page/content/0/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return Whether or not the handler is enabled on a site level.
|
||||
*/
|
||||
async isEnabled(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AddonModPagePluginFileHandler extends makeSingleton(AddonModPagePluginFileHandlerService) {}
|
|
@ -0,0 +1,90 @@
|
|||
// (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 { CoreCourseResourcePrefetchHandlerBase } from '@features/course/classes/resource-prefetch-handler';
|
||||
import { CoreCourse, CoreCourseAnyModuleData, CoreCourseWSModule } from '@features/course/services/course';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { AddonModPage, AddonModPageProvider } from '../page';
|
||||
|
||||
/**
|
||||
* Handler to prefetch pages.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPagePrefetchHandlerService extends CoreCourseResourcePrefetchHandlerBase {
|
||||
|
||||
name = 'AddonModPage';
|
||||
modName = 'page';
|
||||
component = AddonModPageProvider.COMPONENT;
|
||||
updatesNames = /^configuration$|^.*files$/;
|
||||
|
||||
/**
|
||||
* Download or prefetch the content.
|
||||
*
|
||||
* @param module The module object returned by WS.
|
||||
* @param courseId Course ID.
|
||||
* @param prefetch True to prefetch, false to download right away.
|
||||
* @return Promise resolved when all content is downloaded. Data returned is not reliable.
|
||||
*/
|
||||
async downloadOrPrefetch(module: CoreCourseWSModule, courseId: number, prefetch?: boolean): Promise<void> {
|
||||
const promises: Promise<unknown>[] = [];
|
||||
|
||||
promises.push(super.downloadOrPrefetch(module, courseId, prefetch));
|
||||
|
||||
if (AddonModPage.instance.isGetPageWSAvailable()) {
|
||||
promises.push(AddonModPage.instance.getPageData(courseId, module.id));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the prefetched content.
|
||||
*
|
||||
* @param moduleId The module ID.
|
||||
* @param courseId Course ID the module belongs to.
|
||||
* @return Promise resolved when the data is invalidated.
|
||||
*/
|
||||
async invalidateContent(moduleId: number, courseId: number): Promise<void> {
|
||||
await AddonModPage.instance.invalidateContent(moduleId, courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate WS calls needed to determine module status.
|
||||
*
|
||||
* @param module Module.
|
||||
* @param courseId Course ID the module belongs to.
|
||||
* @return Promise resolved when invalidated.
|
||||
*/
|
||||
async invalidateModule(module: CoreCourseAnyModuleData, courseId: number): Promise<void> {
|
||||
const promises: Promise<unknown>[] = [];
|
||||
|
||||
promises.push(AddonModPage.instance.invalidatePageData(courseId));
|
||||
promises.push(CoreCourse.instance.invalidateModule(module.id));
|
||||
|
||||
await CoreUtils.instance.allPromises(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the handler is enabled on a site level.
|
||||
*
|
||||
* @return A boolean, or a promise resolved with a boolean, indicating if the handler is enabled.
|
||||
*/
|
||||
isEnabled(): Promise<boolean> {
|
||||
return AddonModPage.instance.isPluginEnabled();
|
||||
}
|
||||
|
||||
}
|
||||
export class AddonModPagePrefetchHandler extends makeSingleton(AddonModPagePrefetchHandlerService) {}
|
|
@ -0,0 +1,105 @@
|
|||
// (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 { AddonModPageProvider } from './page';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreTextUtils } from '@services/utils/text';
|
||||
import { CoreFile } from '@services/file';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreWS } from '@services/ws';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreCourseModuleContentFile } from '@features/course/services/course';
|
||||
|
||||
/**
|
||||
* Service that provides some features for page.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPageHelperProvider {
|
||||
|
||||
/**
|
||||
* Gets the page HTML.
|
||||
*
|
||||
* @param contents The module contents.
|
||||
* @param moduleId The module ID.
|
||||
* @return The HTML of the page.
|
||||
*/
|
||||
async getPageHtml(contents: CoreCourseModuleContentFile[], moduleId: number): Promise<string> {
|
||||
let indexUrl: string | undefined;
|
||||
const paths: Record<string, string> = {};
|
||||
|
||||
// Extract the information about paths from the module contents.
|
||||
contents.forEach((content) => {
|
||||
const url = content.fileurl;
|
||||
|
||||
if (this.isMainPage(content)) {
|
||||
// This seems to be the most reliable way to spot the index page.
|
||||
indexUrl = url;
|
||||
} else {
|
||||
let key = content.filename;
|
||||
if (content.filepath !== '/') {
|
||||
// Add the folders without the leading slash.
|
||||
key = content.filepath.substr(1) + key;
|
||||
}
|
||||
paths[CoreTextUtils.instance.decodeURIComponent(key)] = url;
|
||||
}
|
||||
});
|
||||
|
||||
// Promise handling when we are in a browser.
|
||||
if (!indexUrl) {
|
||||
// If ever that happens.
|
||||
throw new CoreError('Could not locate the index page');
|
||||
}
|
||||
|
||||
let url: string;
|
||||
if (CoreFile.instance.isAvailable()) {
|
||||
// The file system is available.
|
||||
url = await CoreFilepool.instance.downloadUrl(
|
||||
CoreSites.instance.getCurrentSiteId(),
|
||||
indexUrl,
|
||||
false,
|
||||
AddonModPageProvider.COMPONENT,
|
||||
moduleId,
|
||||
);
|
||||
} else {
|
||||
// We return the live URL.
|
||||
url = await CoreSites.instance.getCurrentSite()?.checkAndFixPluginfileURL(indexUrl) || '';
|
||||
}
|
||||
|
||||
const content = await CoreWS.instance.getText(url);
|
||||
|
||||
// Now that we have the content, we update the SRC to point back to the external resource.
|
||||
// That will be caught by core-format-text.
|
||||
return CoreDomUtils.instance.restoreSourcesInHtml(content, paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the file is the main page of the module.
|
||||
*
|
||||
* @param file An object returned from WS containing file info.
|
||||
* @return Whether the file is the main page or not.
|
||||
*/
|
||||
protected isMainPage(file: CoreCourseModuleContentFile): boolean {
|
||||
const filename = file.filename || '';
|
||||
const fileurl = file.fileurl || '';
|
||||
const url = '/mod_page/content/index.html';
|
||||
const encodedUrl = encodeURIComponent(url);
|
||||
|
||||
return (filename === 'index.html' && (fileurl.indexOf(url) > 0 || fileurl.indexOf(encodedUrl) > 0 ));
|
||||
}
|
||||
|
||||
}
|
||||
export class AddonModPageHelper extends makeSingleton(AddonModPageHelperProvider) {}
|
|
@ -0,0 +1,225 @@
|
|||
// (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 { CoreSitesCommonWSOptions, CoreSites } from '@services/sites';
|
||||
import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
|
||||
import { CoreWSExternalWarning, CoreWSExternalFile } from '@services/ws';
|
||||
import { makeSingleton } from '@singletons';
|
||||
import { CoreFilepool } from '@services/filepool';
|
||||
import { CoreCourse } from '@features/course/services/course';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
|
||||
import { CoreWSError } from '@classes/errors/wserror';
|
||||
|
||||
const ROOT_CACHE_KEY = 'mmaModPage:';
|
||||
|
||||
/**
|
||||
* Service that provides some features for page.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AddonModPageProvider {
|
||||
|
||||
static readonly COMPONENT = 'mmaModPage';
|
||||
|
||||
/**
|
||||
* Get a page by course module ID.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @param cmId Course module ID.
|
||||
* @param options Other options.
|
||||
* @return Promise resolved when the page is retrieved.
|
||||
*/
|
||||
getPageData(courseId: number, cmId: number, options: CoreSitesCommonWSOptions = {}): Promise<AddonModPagePage> {
|
||||
return this.getPageByKey(courseId, 'coursemodule', cmId, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a page.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @param key Name of the property to check.
|
||||
* @param value Value to search.
|
||||
* @param options Other options.
|
||||
* @return Promise resolved when the page is retrieved.
|
||||
*/
|
||||
protected async getPageByKey(
|
||||
courseId: number,
|
||||
key: string,
|
||||
value: number,
|
||||
options: CoreSitesCommonWSOptions = {},
|
||||
): Promise<AddonModPagePage> {
|
||||
const site = await CoreSites.instance.getSite(options.siteId);
|
||||
|
||||
const params: AddonModPageGetPagesByCoursesWSParams = {
|
||||
courseids: [courseId],
|
||||
};
|
||||
const preSets: CoreSiteWSPreSets = {
|
||||
cacheKey: this.getPageCacheKey(courseId),
|
||||
updateFrequency: CoreSite.FREQUENCY_RARELY,
|
||||
component: AddonModPageProvider.COMPONENT,
|
||||
...CoreSites.instance.getReadingStrategyPreSets(options.readingStrategy),
|
||||
};
|
||||
|
||||
const response = await site.read<AddonModPageGetPagesByCoursesWSResponse>('mod_page_get_pages_by_courses', params, preSets);
|
||||
|
||||
const currentPage = response.pages.find((page) => page[key] == value);
|
||||
if (currentPage) {
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
throw new CoreWSError('Page not found');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache key for page data WS calls.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @return Cache key.
|
||||
*/
|
||||
protected getPageCacheKey(courseId: number): string {
|
||||
return ROOT_CACHE_KEY + 'page:' + courseId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the prefetched content.
|
||||
*
|
||||
* @param moduleId The module ID.
|
||||
* @param courseId Course ID of the module.
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
*/
|
||||
invalidateContent(moduleId: number, courseId: number, siteId?: string): Promise<void> {
|
||||
siteId = siteId || CoreSites.instance.getCurrentSiteId();
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
promises.push(this.invalidatePageData(courseId, siteId));
|
||||
promises.push(CoreFilepool.instance.invalidateFilesByComponent(siteId, AddonModPageProvider.COMPONENT, moduleId));
|
||||
promises.push(CoreCourse.instance.invalidateModule(moduleId, siteId));
|
||||
|
||||
return CoreUtils.instance.allPromises(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates page data.
|
||||
*
|
||||
* @param courseId Course ID.
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the data is invalidated.
|
||||
*/
|
||||
async invalidatePageData(courseId: number, siteId?: string): Promise<void> {
|
||||
const site = await CoreSites.instance.getSite(siteId);
|
||||
|
||||
await site.invalidateWsCacheForKey(this.getPageCacheKey(courseId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not getPage WS available or not.
|
||||
*
|
||||
* @return If WS is avalaible.
|
||||
* @since 3.3
|
||||
*/
|
||||
isGetPageWSAvailable(): boolean {
|
||||
return CoreSites.instance.wsAvailableInCurrentSite('mod_page_get_pages_by_courses');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the plugin is enabled.
|
||||
*
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved with true if plugin is enabled, rejected or resolved with false otherwise.
|
||||
*/
|
||||
async isPluginEnabled(siteId?: string): Promise<boolean> {
|
||||
const site = await CoreSites.instance.getSite(siteId);
|
||||
|
||||
return site.canDownloadFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a page as being viewed.
|
||||
*
|
||||
* @param pageid Module ID.
|
||||
* @param name Name of the page.
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved when the WS call is successful.
|
||||
*/
|
||||
logView(pageid: number, name?: string, siteId?: string): Promise<void> {
|
||||
const params: AddonModPageViewPageWSParams = {
|
||||
pageid,
|
||||
};
|
||||
|
||||
return CoreCourseLogHelper.instance.logSingle(
|
||||
'mod_page_view_page',
|
||||
params,
|
||||
AddonModPageProvider.COMPONENT,
|
||||
pageid,
|
||||
name,
|
||||
'page',
|
||||
{},
|
||||
siteId,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class AddonModPage extends makeSingleton(AddonModPageProvider) {}
|
||||
|
||||
|
||||
/**
|
||||
* Page returned by mod_page_get_pages_by_courses.
|
||||
*/
|
||||
export type AddonModPagePage = {
|
||||
id: number; // Module id.
|
||||
coursemodule: number; // Course module id.
|
||||
course: number; // Course id.
|
||||
name: string; // Page name.
|
||||
intro: string; // Summary.
|
||||
introformat: number; // Intro format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
|
||||
introfiles: CoreWSExternalFile[];
|
||||
content: string; // Page content.
|
||||
contentformat: number; // Content format (1 = HTML, 0 = MOODLE, 2 = PLAIN or 4 = MARKDOWN).
|
||||
contentfiles: CoreWSExternalFile[];
|
||||
legacyfiles: number; // Legacy files flag.
|
||||
legacyfileslast: number; // Legacy files last control flag.
|
||||
display: number; // How to display the page.
|
||||
displayoptions: string; // Display options (width, height).
|
||||
revision: number; // Incremented when after each file changes, to avoid cache.
|
||||
timemodified: number; // Last time the page was modified.
|
||||
section: number; // Course section id.
|
||||
visible: number; // Module visibility.
|
||||
groupmode: number; // Group mode.
|
||||
groupingid: number; // Grouping id.
|
||||
};
|
||||
|
||||
/**
|
||||
* Result of WS mod_page_get_pages_by_courses.
|
||||
*/
|
||||
type AddonModPageGetPagesByCoursesWSResponse = {
|
||||
pages: AddonModPagePage[];
|
||||
warnings?: CoreWSExternalWarning[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of mod_page_view_page WS.
|
||||
*/
|
||||
type AddonModPageViewPageWSParams = {
|
||||
pageid: number; // Page instance id.
|
||||
};
|
||||
|
||||
/**
|
||||
* Params of mod_page_get_pages_by_courses WS.
|
||||
*/
|
||||
type AddonModPageGetPagesByCoursesWSParams = {
|
||||
courseids?: number[]; // Array of course ids.
|
||||
};
|
|
@ -310,7 +310,7 @@ export interface CorePluginFileHandler extends CoreDelegateHandler {
|
|||
* @param args Arguments of the pluginfile URL defining component and filearea at least.
|
||||
* @return RegExp to match the revision on pluginfile URLs.
|
||||
*/
|
||||
getComponentRevisionRegExp?(args: string[]): RegExp;
|
||||
getComponentRevisionRegExp?(args: string[]): RegExp | undefined;
|
||||
|
||||
/**
|
||||
* Should return the string to remove the revision on pluginfile url.
|
||||
|
|
Loading…
Reference in New Issue