MOBILE-3833 course: Reduce usage of CoreCourseAnyModuleData

main
Pau Ferrer Ocaña 2021-12-17 00:27:04 +01:00
parent 27c7a7a952
commit ed05adffbf
59 changed files with 355 additions and 296 deletions

View File

@ -242,7 +242,7 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref
promises.push(this.prefetchSubmissions(assign, courseId, module.id, userId, siteId));
promises.push(CoreCourse.getModuleBasicInfoByInstance(assign.id, 'assign', siteId));
promises.push(CoreCourse.getModuleBasicInfoByInstance(assign.id, 'assign', { siteId }));
// Get course data, needed to determine upload max size if it's configured to be course limit.
promises.push(CoreUtils.ignoreErrors(CoreCourses.getCourseByField('id', courseId, siteId)));
@ -253,7 +253,6 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref
promises.push(CoreFilepool.addFilesToQueue(siteId, files, this.component, module.id));
await Promise.all(promises);
}
/**

View File

@ -17,6 +17,7 @@ import { CoreCourse } from '@features/course/services/course';
import { CoreTagFeedComponent } from '@features/tag/components/feed/feed';
import { CoreTagAreaHandler } from '@features/tag/services/tag-area-delegate';
import { CoreTagFeedElement, CoreTagHelper } from '@features/tag/services/tag-helper';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreUrlUtils } from '@services/utils/url';
import { makeSingleton } from '@singletons';
import { AddonModBook } from '../book';
@ -49,16 +50,17 @@ export class AddonModBookTagAreaHandlerService implements CoreTagAreaHandler {
const items = CoreTagHelper.parseFeedContent(content);
// Find module ids of the returned books, they are needed by the link delegate.
await Promise.all(items.map((item) => {
await Promise.all(items.map(async (item) => {
const params = item.url ? CoreUrlUtils.extractUrlParams(item.url) : {};
if (params.b && !params.id) {
const bookId = parseInt(params.b, 10);
return CoreCourse.getModuleBasicInfoByInstance(bookId, 'book').then((module) => {
item.url += '&id=' + module.id;
return;
});
const module = await CoreCourse.getModuleBasicInfoByInstance(
bookId,
'book',
{ readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
item.url += '&id=' + module.id;
}
}));

View File

@ -197,7 +197,7 @@ export class AddonModChoiceSyncProvider extends CoreCourseActivitySyncBaseProvid
// Data has been sent to server, prefetch choice if needed.
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(choiceId, 'choice', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(choiceId, 'choice', { siteId });
await this.prefetchAfterUpdate(AddonModChoicePrefetchHandler.instance, module, courseId, undefined, siteId);
} catch {

View File

@ -14,7 +14,6 @@
import { Component, OnInit, Input } from '@angular/core';
import { Params } from '@angular/router';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreTag } from '@features/tag/services/tag';
import { CoreUser } from '@features/user/services/user';
import { CoreNavigator } from '@services/navigator';
@ -44,8 +43,8 @@ export class AddonModDataActionComponent implements OnInit {
@Input() action!: AddonModDataAction; // The field to render.
@Input() entry!: AddonModDataEntry; // The value of the field.
@Input() database!: AddonModDataData; // Database object.
@Input() module!: CoreCourseModuleData; // Module object.
@Input() group = 0; // Module object.
@Input() title = ''; // Name of the module.
@Input() group = 0; // Module group.
@Input() offset?: number; // Offset of the entry.
siteId: string;
@ -92,13 +91,13 @@ export class AddonModDataActionComponent implements OnInit {
* Go to the edit page of the entry.
*/
editEntry(): void {
const params = {
courseId: this.database.course,
module: this.module,
const params: Params = {
title: this.title,
};
const basePath = AddonModDataModuleHandlerService.PAGE_NAME;
CoreNavigator.navigateToSitePath(
`${AddonModDataModuleHandlerService.PAGE_NAME}/${this.module.course}/${this.module.id}/edit/${this.entry.id}`,
`${basePath}/${this.database.course}/${this.database.coursemodule}/edit/${this.entry.id}`,
{ params },
);
}
@ -108,15 +107,14 @@ export class AddonModDataActionComponent implements OnInit {
*/
viewEntry(): void {
const params: Params = {
courseId: this.database.course,
module: this.module,
entryId: this.entry.id,
title: this.title,
group: this.group,
offset: this.offset,
};
const basePath = AddonModDataModuleHandlerService.PAGE_NAME;
CoreNavigator.navigateToSitePath(
`${AddonModDataModuleHandlerService.PAGE_NAME}/${this.module.course}/${this.module.id}/${this.entry.id}`,
`${basePath}/${this.database.course}/${this.database.coursemodule}/${this.entry.id}`,
{ params },
);
}

View File

@ -19,7 +19,6 @@ import { CoreCommentsProvider } from '@features/comments/services/comments';
import { CoreCourseModuleMainActivityComponent } from '@features/course/classes/main-activity-component';
import { CoreCourseContentsPage } from '@features/course/pages/contents/contents';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreRatingProvider } from '@features/rating/services/rating';
import { CoreRatingSyncProvider } from '@features/rating/services/rating-sync';
import { IonContent } from '@ionic/angular';
@ -95,7 +94,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
fields: Record<number, AddonModDataField>;
entries: Record<number, AddonModDataEntry>;
database: AddonModDataData;
module: CoreCourseModuleData;
title: string;
group: number;
gotoEntry: (a: number) => void;
};
@ -371,7 +370,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
fields: this.fields,
entries: entriesById,
database: this.database!,
module: this.module,
title: this.module.name,
group: this.selectedGroup,
gotoEntry: this.gotoEntry.bind(this),
};
@ -474,8 +473,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
*/
gotoAddEntries(): void {
const params: Params = {
module: this.module,
courseId: this.courseId,
title: this.module.name,
group: this.selectedGroup,
};
@ -492,8 +490,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
*/
gotoEntry(entryId: number): void {
const params: Params = {
module: this.module,
courseId: this.courseId,
title: this.module.name,
group: this.selectedGroup,
};

View File

@ -5,7 +5,7 @@
</ion-buttons>
<ion-title>
<h1>
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
</core-format-text>
</h1>
</ion-title>

View File

@ -15,7 +15,6 @@
import { Component, OnInit, ViewChild, ElementRef, Type } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { CoreError } from '@classes/errors/error';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
import { CoreTag } from '@features/tag/services/tag';
import { IonContent } from '@ionic/angular';
@ -66,7 +65,7 @@ export class AddonModDataEditPage implements OnInit {
entry?: AddonModDataEntry;
fields: Record<number, AddonModDataField> = {};
courseId!: number;
module!: CoreCourseModuleData;
moduleId = 0;
database?: AddonModDataData;
title = '';
component = AddonModDataProvider.COMPONENT;
@ -97,9 +96,10 @@ export class AddonModDataEditPage implements OnInit {
*/
ngOnInit(): void {
try {
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseModuleData>('module');
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
this.moduleId = CoreNavigator.getRequiredRouteNumberParam('cmId');
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
this.title = CoreNavigator.getRouteParam<string>('title') || '';
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
} catch (error) {
CoreDomUtils.showErrorModal(error);
@ -112,8 +112,6 @@ export class AddonModDataEditPage implements OnInit {
// If entryId is lower than 0 or null, it is a new entry or an offline entry.
this.isEditing = this.entryId !== undefined && this.entryId > 0;
this.title = this.module.name;
this.fetchEntryData(true);
}
@ -134,7 +132,7 @@ export class AddonModDataEditPage implements OnInit {
if (changed) {
// Show confirmation if some data has been modified.
await CoreDomUtils.showConfirm(Translate.instant('coentryre.confirmcanceledit'));
await CoreDomUtils.showConfirm(Translate.instant('core.confirmcanceledit'));
}
// Delete the local files from the tmp folder.
@ -154,11 +152,11 @@ export class AddonModDataEditPage implements OnInit {
*/
protected async fetchEntryData(refresh = false): Promise<void> {
try {
this.database = await AddonModData.getDatabase(this.courseId, this.module.id);
this.database = await AddonModData.getDatabase(this.courseId, this.moduleId);
this.title = this.database.name || this.title;
this.cssClass = 'addon-data-entries-' + this.database.id;
this.fieldsArray = await AddonModData.getFields(this.database.id, { cmId: this.module.id });
this.fieldsArray = await AddonModData.getFields(this.database.id, { cmId: this.moduleId });
this.fields = CoreUtils.arrayToObject(this.fieldsArray, 'id');
const entry = await AddonModDataHelper.fetchEntry(this.database, this.fieldsArray, this.entryId || 0);
@ -183,7 +181,7 @@ export class AddonModDataEditPage implements OnInit {
await Promise.all(this.groupInfo.groups.map(async (group) => {
const accessData = await AddonModData.getDatabaseAccessInformation(this.database!.id, {
cmId: this.module.id, groupId: group.id });
cmId: this.moduleId, groupId: group.id });
canAddGroup[group.id] = accessData.canaddentry;
}));
@ -196,7 +194,7 @@ export class AddonModDataEditPage implements OnInit {
haveAccess = true;
}
} else {
const accessData = await AddonModData.getDatabaseAccessInformation(this.database.id, { cmId: this.module.id });
const accessData = await AddonModData.getDatabaseAccessInformation(this.database.id, { cmId: this.moduleId });
haveAccess = accessData.canaddentry;
}

View File

@ -5,7 +5,7 @@
</ion-buttons>
<ion-title>
<h1>
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
<core-format-text [text]="title" contextLevel="module" [contextInstanceId]="moduleId" [courseId]="courseId">
</core-format-text>
</h1>
</ion-title>

View File

@ -16,7 +16,6 @@ import { Component, OnDestroy, ViewChild, ChangeDetectorRef, OnInit, Type } from
import { CoreCommentsCommentsComponent } from '@features/comments/components/comments/comments';
import { CoreComments } from '@features/comments/services/comments';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreRatingInfo } from '@features/rating/services/rating';
import { IonContent, IonRefresher } from '@ionic/angular';
import { CoreGroups, CoreGroupInfo } from '@services/groups';
@ -57,7 +56,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
protected fields: Record<number, AddonModDataField> = {};
protected fieldsArray: AddonModDataField[] = [];
module!: CoreCourseModuleData;
moduleId = 0;
courseId!: number;
offset?: number;
title = '';
@ -82,7 +81,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
fields: Record<number, AddonModDataField>;
entries: Record<number, AddonModDataEntry>;
database: AddonModDataData;
module: CoreCourseModuleData;
title: string;
group: number;
};
@ -133,9 +132,10 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
*/
async ngOnInit(): Promise<void> {
try {
this.module = CoreNavigator.getRequiredRouteParam<CoreCourseModuleData>('module');
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
this.moduleId = CoreNavigator.getRequiredRouteNumberParam('cmId');
this.courseId = CoreNavigator.getRequiredRouteNumberParam('courseId');
this.entryId = CoreNavigator.getRouteNumberParam('entryId') || undefined;
this.title = CoreNavigator.getRouteParam<string>('title') || '';
this.selectedGroup = CoreNavigator.getRouteNumberParam('group') || 0;
this.offset = CoreNavigator.getRouteNumberParam('offset');
} catch (error) {
@ -146,8 +146,6 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
return;
}
this.title = this.module.name;
this.commentsEnabled = !CoreComments.areCommentsDisabledInSite();
await this.fetchEntryData();
@ -165,15 +163,15 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
this.isPullingToRefresh = isPtr;
try {
this.database = await AddonModData.getDatabase(this.courseId, this.module.id);
this.database = await AddonModData.getDatabase(this.courseId, this.moduleId);
this.title = this.database.name || this.title;
this.fieldsArray = await AddonModData.getFields(this.database.id, { cmId: this.module.id });
this.fieldsArray = await AddonModData.getFields(this.database.id, { cmId: this.moduleId });
this.fields = CoreUtils.arrayToObject(this.fieldsArray, 'id');
await this.setEntryFromOffset();
this.access = await AddonModData.getDatabaseAccessInformation(this.database.id, { cmId: this.module.id });
this.access = await AddonModData.getDatabaseAccessInformation(this.database.id, { cmId: this.moduleId });
this.groupInfo = await CoreGroups.getActivityGroupInfo(this.database.coursemodule);
this.selectedGroup = CoreGroups.validateGroupId(this.selectedGroup, this.groupInfo);
@ -200,7 +198,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
fields: this.fields,
entries: entries,
database: this.database,
module: this.module,
title: this.title,
group: this.selectedGroup,
};
} catch (error) {
@ -363,7 +361,7 @@ export class AddonModDataEntryPage implements OnInit, OnDestroy {
if (this.entryId > 0) {
// Online entry, we need to fetch the the rating info.
const entry = await AddonModData.getEntry(this.database!.id, this.entryId, { cmId: this.module.id });
const entry = await AddonModData.getEntry(this.database!.id, this.entryId, { cmId: this.moduleId });
this.ratingInfo = entry.ratinginfo;
}
}

View File

@ -18,7 +18,7 @@ import { CoreCourse } from '@features/course/services/course';
import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
import { CoreRatingOffline } from '@features/rating/services/rating-offline';
import { FileEntry } from '@ionic-native/file/ngx';
import { CoreSites } from '@services/sites';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreFormFields } from '@singletons/form';
import { CoreTextUtils } from '@services/utils/text';
@ -230,7 +230,7 @@ export class AddonModDataHelperProvider {
render = Translate.instant('addon.mod_data.' + (entry.approved ? 'approved' : 'notapproved'));
} else {
render = '<addon-mod-data-action action="' + action + '" [entry]="entries[' + entry.id + ']" mode="' + mode +
'" [database]="database" [module]="module" [offset]="' + offset + '" [group]="group" ></addon-mod-data-action>';
'" [database]="database" [title]="title" [offset]="' + offset + '" [group]="group" ></addon-mod-data-action>';
}
template = template.replace(replaceRegex, render);
} else {
@ -437,7 +437,11 @@ export class AddonModDataHelperProvider {
return courseId;
}
const module = await CoreCourse.getModuleBasicInfoByInstance(dataId, 'data', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
dataId,
'data',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
return module.course;
}

View File

@ -18,6 +18,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModDataModuleHandlerService } from './module';
@ -44,10 +45,13 @@ export class AddonModDataEditLinkHandlerService extends CoreContentLinksHandlerB
const rId = params.rid || '';
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(dataId, 'data', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
dataId,
'data',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
const pageParams: Params = {
module,
courseId: module.course,
title: module.name,
};
CoreNavigator.navigateToSitePath(

View File

@ -261,7 +261,7 @@ export class AddonModDataPrefetchHandlerService extends CoreCourseActivityPrefet
});
// Add Basic Info to manage links.
promises.push(CoreCourse.getModuleBasicInfoByInstance(database.id, 'data', siteId));
promises.push(CoreCourse.getModuleBasicInfoByInstance(database.id, 'data', { siteId }));
// Get course data, needed to determine upload max size if it's configured to be course limit.
promises.push(CoreUtils.ignoreErrors(CoreCourses.getCourseByField('id', courseId, siteId)));

View File

@ -18,6 +18,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModDataModuleHandlerService } from './module';
@ -47,10 +48,13 @@ export class AddonModDataShowLinkHandlerService extends CoreContentLinksHandlerB
const page = parseInt(params.page, 10) || false;
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(dataId, 'data', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
dataId,
'data',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
const pageParams: Params = {
module: module,
courseId: module.course,
title: module.name,
};
if (group) {

View File

@ -176,7 +176,10 @@ export class AddonModFeedbackHelperProvider {
const modal = await CoreDomUtils.showModalLoading();
try {
const module = await CoreCourse.getModuleBasicInfo(Number(params.id), siteId);
const module = await CoreCourse.getModuleBasicInfo(
Number(params.id),
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
if (params.showcompleted === undefined) {
// Param showcompleted not defined. Show entry list.

View File

@ -223,7 +223,7 @@ export class AddonModFeedbackSyncProvider extends CoreCourseActivitySyncBaseProv
if (result.updated) {
// Data has been sent to server, update data.
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(feedbackId, 'feedback', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(feedbackId, 'feedback', { siteId });
await this.prefetchAfterUpdate(AddonModFeedbackPrefetchHandler.instance, module, courseId, undefined, siteId);
} catch {

View File

@ -43,13 +43,11 @@ export class AddonModFeedbackAnalysisLinkHandlerService extends CoreContentLinks
const moduleId = Number(params.id);
try {
const moduleBasicInfo = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
// Get the module.
const module = await CoreCourse.getModule(
moduleId,
moduleBasicInfo.course,
moduleBasicInfo.section,
undefined,
undefined,
false,
false,
siteId,

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModFeedbackModuleHandlerService } from './module';
@ -43,7 +44,10 @@ export class AddonModFeedbackCompleteLinkHandlerService extends CoreContentLinks
const moduleId = Number(params.id);
try {
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
CoreNavigator.navigateToSitePath(
AddonModFeedbackModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/form`,

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModFeedbackModuleHandlerService } from './module';
@ -43,7 +44,10 @@ export class AddonModFeedbackPrintLinkHandlerService extends CoreContentLinksHan
const moduleId = Number(params.id);
try {
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
CoreNavigator.navigateToSitePath(
AddonModFeedbackModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/form`,

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModFeedbackModuleHandlerService } from './module';
@ -42,7 +43,10 @@ export class AddonModFeedbackShowNonRespondentsLinkHandlerService extends CoreCo
const moduleId = Number(params.id);
try {
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
await CoreNavigator.navigateToSitePath(
AddonModFeedbackModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/nonrespondents`,

View File

@ -96,7 +96,7 @@ export class AddonModFolderIndexComponent extends CoreCourseModuleMainResourceCo
try {
this.folderInstance = await AddonModFolder.getFolder(this.courseId, this.module.id);
const contents = await CoreCourse.getModuleContents(this.module, this.courseId, undefined, false, refresh);
const contents = await CoreCourse.getModuleContents(this.module, undefined, undefined, false, refresh);
this.dataRetrieved.emit(this.folderInstance || this.module);

View File

@ -18,6 +18,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModForumModuleHandlerService } from './module';
@ -53,7 +54,11 @@ export class AddonModForumPostLinkHandlerService extends CoreContentLinksHandler
const forumId = parseInt(params.forum, 10);
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(forumId, 'forum', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
forumId,
'forum',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
await CoreNavigator.navigateToSitePath(
`${AddonModForumModuleHandlerService.PAGE_NAME}/${module.course}/${module.id}/new/0`,

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModGlossaryModuleHandlerService } from './module';
@ -44,7 +45,10 @@ export class AddonModGlossaryEditLinkHandlerService extends CoreContentLinksHand
const cmId = Number(params.cmid);
try {
const module = await CoreCourse.getModuleBasicInfo(cmId, siteId);
const module = await CoreCourse.getModuleBasicInfo(
cmId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
await CoreNavigator.navigateToSitePath(
AddonModGlossaryModuleHandlerService.PAGE_NAME + '/edit/0',

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModGlossary } from '../glossary';
@ -43,12 +44,15 @@ export class AddonModGlossaryEntryLinkHandlerService extends CoreContentLinksHan
try {
const entryId = params.mode == 'entry' ? Number(params.hook) : Number(params.eid);
const response = await AddonModGlossary.getEntry(entryId, { siteId });
const response = await AddonModGlossary.getEntry(
entryId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
const module = await CoreCourse.getModuleBasicInfoByInstance(
response.entry.glossaryid,
'glossary',
siteId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
await CoreNavigator.navigateToSitePath(

View File

@ -205,8 +205,8 @@ export class AddonModGlossaryPrefetchHandlerService extends CoreCourseActivityPr
promises.push(AddonModGlossary.getAllCategories(glossary.id, options));
// Prefetch data for link handlers.
promises.push(CoreCourse.getModuleBasicInfo(module.id, siteId));
promises.push(CoreCourse.getModuleBasicInfoByInstance(glossary.id, 'glossary', siteId));
promises.push(CoreCourse.getModuleBasicInfo(module.id, { siteId }));
promises.push(CoreCourse.getModuleBasicInfoByInstance(glossary.id, 'glossary', { siteId }));
// Get course data, needed to determine upload max size if it's configured to be course limit.
promises.push(CoreUtils.ignoreErrors(CoreCourses.getCourseByField('id', courseId, siteId)));

View File

@ -18,7 +18,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModH5PActivity } from '../h5pactivity';
@ -41,54 +41,36 @@ export class AddonModH5PActivityReportLinkHandlerService extends CoreContentLink
siteIds: string[],
url: string,
params: Record<string, string>,
courseId?: number,
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
courseId = courseId || Number(params.courseid) || Number(params.cid);
return [{
action: async (siteId) => {
const modal = await CoreDomUtils.showModalLoading();
try {
const instanceId = Number(params.a);
if (!courseId) {
courseId = await this.getCourseId(instanceId, siteId);
}
const module = await CoreCourse.getModuleBasicInfoByInstance(instanceId, 'h5pactivity', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
instanceId,
'h5pactivity',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
if (params.attemptid !== undefined) {
this.openAttemptResults(module.id, Number(params.attemptid), courseId, siteId);
this.openAttemptResults(module.id, Number(params.attemptid), module.course, siteId);
} else {
const userId = params.userid ? Number(params.userid) : undefined;
this.openUserAttempts(module.id, courseId, siteId, userId);
this.openUserAttempts(module.id, module.course, siteId, userId);
}
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'Error processing link.');
} finally {
modal.dismiss();
}
},
}];
}
/**
* Get course Id for an activity.
*
* @param id Activity ID.
* @param siteId Site ID.
* @return Promise resolved with course ID.
*/
protected async getCourseId(id: number, siteId: string): Promise<number> {
const modal = await CoreDomUtils.showModalLoading();
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(id, 'h5pactivity', siteId);
return module.course;
} finally {
modal.dismiss();
}
}
/**
* @inheritdoc
*/

View File

@ -84,7 +84,7 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
this.dataRetrieved.emit(imscp);
// Get contents. No need to refresh, it has been done in downloadResourceIfNeeded.
const contents = await CoreCourse.getModuleContents(this.module, this.courseId);
const contents = await CoreCourse.getModuleContents(this.module);
this.items = AddonModImscp.createItemList(contents);

View File

@ -18,6 +18,7 @@ import { CoreContentLinksModuleGradeHandler } from '@features/contentlinks/class
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModLesson } from '../lesson';
@ -57,8 +58,10 @@ export class AddonModLessonGradeLinkHandlerService extends CoreContentLinksModul
const modal = await CoreDomUtils.showModalLoading();
try {
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
courseId = Number(module.course || courseId || params.courseid || params.cid);
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
// Check if the user can see the user reports in the lesson.
const accessInfo = await AddonModLesson.getAccessInformation(module.instance, { cmId: module.id, siteId });
@ -66,14 +69,14 @@ export class AddonModLessonGradeLinkHandlerService extends CoreContentLinksModul
if (accessInfo.canviewreports) {
// User can view reports, go to view the report.
CoreNavigator.navigateToSitePath(
AddonModLessonModuleHandlerService.PAGE_NAME + `/${courseId}/${module.id}/user-retake/${userId}`,
AddonModLessonModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/user-retake/${userId}`,
{
siteId,
},
);
} else {
// User cannot view the report, go to lesson index.
CoreCourseHelper.navigateToModule(moduleId, siteId, courseId, module.section);
CoreCourseHelper.navigateToModule(moduleId, siteId, module.course, module.section);
}
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true);

View File

@ -18,6 +18,7 @@ import { CoreContentLinksModuleIndexHandler } from '@features/contentlinks/class
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseHelper } from '@features/course/services/course-helper';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
@ -85,14 +86,15 @@ export class AddonModLessonIndexLinkHandlerService extends CoreContentLinksModul
try {
// Get the module.
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
courseId = courseId || module.course;
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
// Store the password so it's automatically used.
await CoreUtils.ignoreErrors(AddonModLesson.storePassword(module.instance, password, siteId));
await CoreCourseHelper.navigateToModule(moduleId, siteId, courseId, module.section);
await CoreCourseHelper.navigateToModule(moduleId, siteId, module.course, module.section);
} catch {
// Error, go to index page.
await CoreCourseHelper.navigateToModule(moduleId, siteId, courseId);

View File

@ -18,6 +18,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModLessonModuleHandlerService } from './module';
@ -38,26 +39,20 @@ export class AddonModLessonReportLinkHandlerService extends CoreContentLinksHand
* @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<string, string>,
courseId?: number,
data?: unknown, // eslint-disable-line @typescript-eslint/no-unused-vars
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
courseId = Number(courseId || params.courseid || params.cid);
return [{
action: (siteId) => {
if (!params.action || params.action == 'reportoverview') {
// Go to overview.
this.openReportOverview(Number(params.id), courseId, Number(params.group), siteId);
this.openReportOverview(Number(params.id), Number(params.group), siteId);
} else if (params.action == 'reportdetail') {
this.openUserRetake(Number(params.id), Number(params.userid), Number(params.try), siteId, courseId);
this.openUserRetake(Number(params.id), Number(params.userid), Number(params.try), siteId);
}
},
}];
@ -70,11 +65,9 @@ export class AddonModLessonReportLinkHandlerService extends CoreContentLinksHand
* @param siteId The site ID.
* @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.
* @return Whether the handler is enabled for the URL and site.
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async isEnabled(siteId: string, url: string, params: Record<string, string>, courseId?: number): Promise<boolean> {
async isEnabled(siteId: string, url: string, params: Record<string, string>): Promise<boolean> {
if (params.action == 'reportdetail' && !params.userid) {
// Individual details are only available if the teacher is seeing a certain user.
return false;
@ -87,29 +80,33 @@ export class AddonModLessonReportLinkHandlerService extends CoreContentLinksHand
* Open report overview.
*
* @param moduleId Module ID.
* @param courseId Course ID.
* @param groupId Group ID.
* @param siteId Site ID.
* @param navCtrl The NavController to use to navigate.
* @return Promise resolved when done.
*/
protected async openReportOverview(moduleId: number, courseId?: number, groupId?: number, siteId?: string): Promise<void> {
protected async openReportOverview(moduleId: number, groupId?: number, siteId?: string): Promise<void> {
const modal = await CoreDomUtils.showModalLoading();
try {
// Get the module object.
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
const module = await CoreCourse.getModule(
moduleId,
undefined,
undefined,
false,
false,
siteId,
);
courseId = courseId || module.course;
const params = {
module: module,
module,
action: 'report',
group: groupId === undefined || isNaN(groupId) ? null : groupId,
};
CoreNavigator.navigateToSitePath(
`${AddonModLessonModuleHandlerService.PAGE_NAME}/${courseId}/${module.id}`,
`${AddonModLessonModuleHandlerService.PAGE_NAME}/${module.course}/${module.id}`,
{ params, siteId },
);
} catch (error) {
@ -126,7 +123,6 @@ export class AddonModLessonReportLinkHandlerService extends CoreContentLinksHand
* @param userId User ID.
* @param retake Retake to open.
* @param siteId Site ID.
* @param courseId Course ID.
* @return Promise resolved when done.
*/
protected async openUserRetake(
@ -134,22 +130,22 @@ export class AddonModLessonReportLinkHandlerService extends CoreContentLinksHand
userId: number,
retake: number,
siteId: string,
courseId?: number,
): Promise<void> {
const modal = await CoreDomUtils.showModalLoading();
try {
// Get the module object.
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
courseId = courseId || module.course;
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
const params = {
retake: retake || 0,
};
CoreNavigator.navigateToSitePath(
AddonModLessonModuleHandlerService.PAGE_NAME + `/${courseId}/${module.id}/user-retake/${userId}`,
AddonModLessonModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/user-retake/${userId}`,
{ params, siteId },
);
} catch (error) {

View File

@ -243,7 +243,7 @@ export class AddonModLessonSyncProvider extends CoreCourseActivitySyncBaseProvid
if (result.updated && result.courseId) {
try {
// Data has been sent to server, update data.
const module = await CoreCourse.getModuleBasicInfoByInstance(lessonId, 'lesson', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(lessonId, 'lesson', { siteId });
await this.prefetchAfterUpdate(AddonModLessonPrefetchHandler.instance, module, result.courseId, undefined, siteId);
} catch {
// Ignore errors.

View File

@ -82,7 +82,7 @@ export class AddonModPageIndexComponent extends CoreCourseModuleMainResourceComp
const downloadResult = await this.downloadResourceIfNeeded(refresh);
// Get contents. No need to refresh, it has been done in downloadResourceIfNeeded.
const contents = await CoreCourse.getModuleContents(this.module, this.courseId);
const contents = await CoreCourse.getModuleContents(this.module);
const results = await Promise.all([
this.loadPageData(),

View File

@ -62,7 +62,6 @@ export class AddonModQuizPushClickHandlerService implements CorePushNotification
return AddonModQuizHelper.handleReviewLink(
Number(contextUrlParams.attempt),
Number(contextUrlParams.page),
courseId,
Number(data.instance),
notification.site,
);

View File

@ -46,17 +46,13 @@ export class AddonModQuizReviewLinkHandlerService extends CoreContentLinksHandle
courseId?: number,
data?: Record<string, unknown>,
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
courseId = Number(courseId || params.courseid || params.cid);
data = data || {};
const quizId = data?.instance ? Number(data.instance) : undefined;
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.handleReviewLink(attemptId, page, courseId, quizId, siteId);
AddonModQuizHelper.handleReviewLink(attemptId, page, quizId, siteId);
},
}];
}

View File

@ -215,12 +215,11 @@ export class AddonModQuizHelperProvider {
*
* @param attemptId Attempt ID.
* @param page Page to load, -1 to all questions in same page.
* @param courseId Course ID.
* @param quizId Quiz ID.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when done.
*/
async handleReviewLink(attemptId: number, page?: number, courseId?: number, quizId?: number, siteId?: string): Promise<void> {
async handleReviewLink(attemptId: number, page?: number, quizId?: number, siteId?: string): Promise<void> {
siteId = siteId || CoreSites.getCurrentSiteId();
const modal = await CoreDomUtils.showModalLoading();
@ -230,13 +229,15 @@ export class AddonModQuizHelperProvider {
quizId = await this.getQuizIdByAttemptId(attemptId, { siteId });
}
const module = await CoreCourse.getModuleBasicInfoByInstance(quizId, 'quiz', siteId);
courseId = courseId || module.course;
const module = await CoreCourse.getModuleBasicInfoByInstance(
quizId,
'quiz',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
// Go to the review page.
await CoreNavigator.navigateToSitePath(
`${AddonModQuizModuleHandlerService.PAGE_NAME}/${courseId}/${module.id}/review/${attemptId}`,
`${AddonModQuizModuleHandlerService.PAGE_NAME}/${module.course}/${module.id}/review/${attemptId}`,
{
params: {
page: page == undefined || isNaN(page) ? -1 : page,

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { CoreError } from '@classes/errors/error';
import { CoreCourseActivitySyncBaseProvider } from '@features/course/classes/activity-sync';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourse, CoreCourseModuleBasicInfo } from '@features/course/services/course';
import { CoreCourseLogHelper } from '@features/course/services/log-helper';
import { CoreCourseModulePrefetchDelegate } from '@features/course/services/module-prefetch-delegate';
import { CoreQuestion, CoreQuestionQuestionParsed } from '@features/question/services/question';
@ -92,9 +92,9 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
if (options.updated) {
try {
// Data has been sent. Update prefetched data.
const module = await CoreCourse.getModuleBasicInfoByInstance(quiz.id, 'quiz', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(quiz.id, 'quiz', { siteId });
await this.prefetchAfterUpdateQuiz(module, quiz, courseId, undefined, siteId);
await this.prefetchAfterUpdateQuiz(module, quiz, courseId, siteId);
} catch {
// Ignore errors.
}
@ -139,27 +139,25 @@ export class AddonModQuizSyncProvider extends CoreCourseActivitySyncBaseProvider
* @param module Module.
* @param quiz Quiz.
* @param courseId Course ID.
* @param regex If regex matches, don't download the data. Defaults to check files.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when done.
*/
async prefetchAfterUpdateQuiz(
module: CoreCourseAnyModuleData,
protected async prefetchAfterUpdateQuiz(
module: CoreCourseModuleBasicInfo,
quiz: AddonModQuizQuizWSData,
courseId: number,
regex?: RegExp,
siteId?: string,
): Promise<void> {
regex = regex || /^.*files$/;
let shouldDownload = false;
// Get the module updates to check if the data was updated or not.
const result = await CoreCourseModulePrefetchDelegate.getModuleUpdates(module, courseId, true, siteId);
if (result?.updates?.length) {
const regex = /^.*files$/;
// Only prefetch if files haven't changed.
shouldDownload = !result.updates.find((entry) => entry.name.match(regex!));
shouldDownload = !result.updates.find((entry) => entry.name.match(regex));
if (shouldDownload) {
await AddonModQuizPrefetchHandler.download(module, courseId, undefined, false, false);

View File

@ -101,7 +101,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
*/
protected async fetchContent(refresh?: boolean): Promise<void> {
// Load module contents if needed. Passing refresh is needed to force reloading contents.
const contents = await CoreCourse.getModuleContents(this.module, this.courseId, undefined, false, refresh);
const contents = await CoreCourse.getModuleContents(this.module, undefined, undefined, false, refresh);
if (!contents.length) {
throw new CoreError(Translate.instant('core.filenotfound'));
@ -148,7 +148,7 @@ export class AddonModResourceIndexComponent extends CoreCourseModuleMainResource
this.mode = 'embedded';
this.warning = '';
this.contentText = await AddonModResourceHelper.getEmbeddedHtml(this.module, this.courseId);
this.contentText = await AddonModResourceHelper.getEmbeddedHtml(this.module);
this.mode = this.contentText.length > 0 ? 'embedded' : 'external';
} else {
this.mode = 'external';

View File

@ -85,7 +85,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
icon: openWithPicker ? 'fas-share-square' : 'fas-file',
label: module.name + ': ' + Translate.instant(openWithPicker ? 'core.openwith' : 'addon.mod_resource.openthefile'),
action: async (event: Event, module: CoreCourseModuleData, courseId: number): Promise<void> => {
const hide = await this.hideOpenButton(module, courseId);
const hide = await this.hideOpenButton(module);
if (!hide) {
AddonModResourceHelper.openModuleFile(module, courseId);
}
@ -109,15 +109,14 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
* Returns if contents are loaded to show open button.
*
* @param module The module object.
* @param courseId The course ID.
* @return Resolved when done.
*/
protected async hideOpenButton(module: CoreCourseModuleData, courseId: number): Promise<boolean> {
if (!('contentsinfo' in module) || !module.contentsinfo) {
await CoreCourse.loadModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
protected async hideOpenButton(module: CoreCourseModuleData): Promise<boolean> {
if (!module.contentsinfo) { // Not informed before 3.7.6.
await CoreCourse.loadModuleContents(module, undefined, undefined, false, false, undefined, this.modName);
}
const status = await CoreCourseModulePrefetchDelegate.getModuleStatus(module, courseId);
const status = await CoreCourseModulePrefetchDelegate.getModuleStatus(module, module.course);
return status !== CoreConstants.DOWNLOADED || AddonModResourceHelper.isDisplayedInIframe(module);
}
@ -138,7 +137,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
let options: AddonModResourceCustomData = {};
// Check if the button needs to be shown or not.
promises.push(this.hideOpenButton(module, courseId).then((hideOpenButton) => {
promises.push(this.hideOpenButton(module).then((hideOpenButton) => {
if (!handlerData.buttons) {
return;
}
@ -148,7 +147,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
return;
}));
if ('customdata' in module && module.customdata !== undefined) {
if (module.customdata !== undefined) {
options = CoreTextUtils.unserialize(CoreTextUtils.parseJSON(module.customdata));
} else {
// Get the resource data.
@ -164,7 +163,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
let mimetypeIcon = '';
const extra: string[] = [];
if ('contentsinfo' in module && module.contentsinfo) {
if (module.contentsinfo) {
// No need to use the list of files.
const mimetype = module.contentsinfo.mimetypes[0];
if (mimetype) {
@ -235,7 +234,7 @@ export class AddonModResourceModuleHandlerService extends CoreModuleHandlerBase
}
let mimetypeIcon = '';
if ('contentsinfo' in module && module.contentsinfo) {
if (module.contentsinfo) {
// No need to use the list of files.
const mimetype = module.contentsinfo.mimetypes[0];
if (mimetype) {

View File

@ -39,15 +39,14 @@ export class AddonModResourceHelperProvider {
* Get the HTML to display an embedded resource.
*
* @param module The module object.
* @param courseId The course ID.
* @return Promise resolved with the HTML.
*/
async getEmbeddedHtml(module: CoreCourseModuleData, courseId: number): Promise<string> {
const contents = await CoreCourse.getModuleContents(module, courseId);
async getEmbeddedHtml(module: CoreCourseModuleData): Promise<string> {
const contents = await CoreCourse.getModuleContents(module);
const result = await CoreCourseHelper.downloadModuleWithMainFileIfNeeded(
module,
courseId,
module.course,
AddonModResourceProvider.COMPONENT,
module.id,
contents,
@ -124,14 +123,14 @@ export class AddonModResourceHelperProvider {
* @param module The module object.
* @return Whether the resource should be displayed in an iframe.
*/
isDisplayedInIframe(module: CoreCourseAnyModuleData): boolean {
isDisplayedInIframe(module: CoreCourseModuleData): boolean {
if (!CoreFile.isAvailable()) {
return false;
}
let mimetype: string | undefined;
if ('contentsinfo' in module && module.contentsinfo) {
if (module.contentsinfo) {
mimetype = module.contentsinfo.mimetypes[0];
} else if (module.contents) {
const ext = CoreMimetypeUtils.getFileExtension(module.contents[0].filename);

View File

@ -198,7 +198,7 @@ export class AddonModScormSyncProvider extends CoreCourseActivitySyncBaseProvide
if (updated) {
try {
// Update downloaded data.
const module = await CoreCourse.getModule(scorm.coursemodule, scorm.course, undefined, false, false, siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(scorm.id, 'scorm', { siteId });
await this.prefetchAfterUpdate(AddonModScormPrefetchHandler.instance, module, scorm.course, undefined, siteId);
} catch {

View File

@ -202,7 +202,7 @@ export class AddonModSurveySyncProvider extends CoreCourseActivitySyncBaseProvid
await AddonModSurvey.invalidateSurveyData(result.courseId, siteId);
// Data has been sent to server, update survey data.
const module = await CoreCourse.getModuleBasicInfoByInstance(surveyId, 'survey', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(surveyId, 'survey', { siteId });
CoreUtils.ignoreErrors(
this.prefetchAfterUpdate(AddonModSurveyPrefetchHandler.instance, module, result.courseId, undefined, siteId),

View File

@ -98,7 +98,7 @@ export class AddonModUrlIndexComponent extends CoreCourseModuleMainResourceCompo
// Try to get module contents, it's needed to get the URL with parameters.
const contents = await CoreCourse.getModuleContents(
this.module,
this.courseId,
undefined,
undefined,
false,
refresh,

View File

@ -54,7 +54,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
/**
* @inheritdoc
*/
async getData(module: CoreCourseModuleData, courseId: number): Promise<CoreCourseModuleHandlerData> {
async getData(module: CoreCourseModuleData): Promise<CoreCourseModuleHandlerData> {
/**
* Open the URL.
@ -62,17 +62,17 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
* @param module The module object.
* @param courseId The course ID.
*/
const openUrl = async (module: CoreCourseModuleData, courseId: number): Promise<void> => {
const openUrl = async (module: CoreCourseModuleData): Promise<void> => {
try {
if (module.instance) {
await AddonModUrl.logView(module.instance, module.name);
CoreCourse.checkModuleCompletion(courseId, module.completiondata);
CoreCourse.checkModuleCompletion(module.course, module.completiondata);
}
} catch {
// Ignore errors.
}
const contents = await CoreCourse.getModuleContents(module, courseId);
const contents = await CoreCourse.getModuleContents(module);
AddonModUrlHelper.open(contents[0].fileurl);
};
@ -85,12 +85,12 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
const modal = await CoreDomUtils.showModalLoading();
try {
const shouldOpen = await this.shouldOpenLink(module, courseId);
const shouldOpen = await this.shouldOpenLink(module);
if (shouldOpen) {
openUrl(module, courseId);
openUrl(module);
} else {
this.openActivityPage(module, courseId, options);
this.openActivityPage(module, module.course, options);
}
} finally {
modal.dismiss();
@ -100,13 +100,13 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
hidden: true, // Hide it until we calculate if it should be displayed or not.
icon: 'fas-link',
label: 'core.openmodinbrowser',
action: (event: Event, module: CoreCourseModuleData, courseId: number): void => {
openUrl(module, courseId);
action: (event: Event, module: CoreCourseModuleData): void => {
openUrl(module);
},
}],
};
this.hideLinkButton(module, courseId).then(async (hideButton) => {
this.hideLinkButton(module).then(async (hideButton) => {
if (!handlerData.buttons) {
return;
}
@ -135,9 +135,10 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
* @param courseId The course ID.
* @return Resolved when done.
*/
protected async hideLinkButton(module: CoreCourseModuleData, courseId: number): Promise<boolean> {
protected async hideLinkButton(module: CoreCourseModuleData): Promise<boolean> {
try {
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
const contents =
await CoreCourse.getModuleContents(module, undefined, undefined, false, false, undefined, this.modName);
return !(contents[0] && contents[0].fileurl);
} catch {
@ -157,22 +158,22 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
* Check whether the link should be opened directly.
*
* @param module Module.
* @param courseId Course ID.
* @return Promise resolved with boolean.
*/
protected async shouldOpenLink(module: CoreCourseModuleData, courseId?: number): Promise<boolean> {
protected async shouldOpenLink(module: CoreCourseModuleData): Promise<boolean> {
try {
const contents = await CoreCourse.getModuleContents(module, courseId, undefined, false, false, undefined, this.modName);
const contents =
await CoreCourse.getModuleContents(module, undefined, undefined, false, false, undefined, this.modName);
// Check if the URL can be handled by the app. If so, always open it directly.
const canHandle = await CoreContentLinksHelper.canHandleLink(contents[0].fileurl, courseId, undefined, true);
const canHandle = await CoreContentLinksHelper.canHandleLink(contents[0].fileurl, module.course, undefined, true);
if (canHandle) {
// URL handled by the app, open it directly.
return true;
} else {
// Not handled by the app, check the display type.
const url = courseId ? await CoreUtils.ignoreErrors(AddonModUrl.getUrl(courseId, module.id)) : undefined;
const url = await CoreUtils.ignoreErrors(AddonModUrl.getUrl(module.course, module.id));
const displayType = AddonModUrl.getFinalDisplayType(url);
return displayType == CoreConstants.RESOURCELIB_DISPLAY_OPEN ||
@ -187,7 +188,7 @@ export class AddonModUrlModuleHandlerService extends CoreModuleHandlerBase imple
* @inheritdoc
*/
manualCompletionAlwaysShown(module: CoreCourseModuleData): Promise<boolean> {
return this.shouldOpenLink(module, module.course);
return this.shouldOpenLink(module);
}
}

View File

@ -18,7 +18,7 @@ import { CoreError } from '@classes/errors/error';
import { CoreCourse } from '@features/course/services/course';
import { CanLeave } from '@guards/can-leave';
import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreSync } from '@services/sync';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text';
@ -262,7 +262,11 @@ export class AddonModWikiEditPage implements OnInit, OnDestroy, CanLeave {
return;
}
const module = await CoreCourse.getModuleBasicInfoByInstance(this.wikiId, 'wiki');
const module = await CoreCourse.getModuleBasicInfoByInstance(
this.wikiId,
'wiki',
{ readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
this.cmId = module.id;
this.courseId = module.course;

View File

@ -115,7 +115,11 @@ export class AddonModWikiCreateLinkHandlerService extends CoreContentLinksHandle
path = path + `/${route!.snapshot.params.courseId}/${route!.snapshot.params.cmId}/edit`;
} else if (wikiId) {
// The URL specifies which wiki it belongs to. Get the module.
const module = await CoreCourse.getModuleBasicInfoByInstance(wikiId, 'wiki', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
wikiId,
'wiki',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
path = path + `/${module.course}/${module.id}/edit`;
} else {

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { AddonModWiki } from '../wiki';
@ -39,7 +40,6 @@ export class AddonModWikiEditLinkHandlerService extends CoreContentLinksHandlerB
siteIds: string[],
url: string,
params: Record<string, string>,
courseId?: number,
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
return [{
@ -51,17 +51,19 @@ export class AddonModWikiEditLinkHandlerService extends CoreContentLinksHandlerB
const pageContents = await AddonModWiki.getPageContents(pageId, { siteId });
const module = await CoreCourse.getModuleBasicInfoByInstance(pageContents.wikiid, 'wiki', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
pageContents.wikiid,
'wiki',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
let section = '';
if (params.section !== undefined) {
section = params.section.replace(/\+/g, ' ');
}
courseId = module.course || courseId || Number(params.courseid || params.cid);
CoreNavigator.navigateToSitePath(
AddonModWikiModuleHandlerService.PAGE_NAME + `/${courseId}/${module.id}/edit`,
AddonModWikiModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/edit`,
{
params: {
section: section,

View File

@ -17,6 +17,7 @@ import { CoreContentLinksHandlerBase } from '@features/contentlinks/classes/base
import { CoreContentLinksAction } from '@features/contentlinks/services/contentlinks-delegate';
import { CoreCourse } from '@features/course/services/course';
import { CoreNavigator } from '@services/navigator';
import { CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { makeSingleton } from '@singletons';
import { Md5 } from 'ts-md5';
@ -40,11 +41,8 @@ export class AddonModWikiPageOrMapLinkHandlerService extends CoreContentLinksHan
siteIds: string[],
url: string,
params: Record<string, string>,
courseId?: number,
): CoreContentLinksAction[] | Promise<CoreContentLinksAction[]> {
courseId = Number(courseId || params.courseid || params.cid);
return [{
action: async (siteId: string) => {
const modal = await CoreDomUtils.showModalLoading();
@ -55,7 +53,11 @@ export class AddonModWikiPageOrMapLinkHandlerService extends CoreContentLinksHan
// Get the page data to obtain wikiId, subwikiId, etc.
const page = await AddonModWiki.getPageContents(pageId, { siteId });
const module = await CoreCourse.getModuleBasicInfoByInstance(page.wikiid, 'wiki', siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(
page.wikiid,
'wiki',
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
const hash = <string> Md5.hashAsciiStr(JSON.stringify({
pageId: page.id,
@ -64,10 +66,9 @@ export class AddonModWikiPageOrMapLinkHandlerService extends CoreContentLinksHan
action: action,
timestamp: Date.now(),
}));
courseId = courseId || module.course;
CoreNavigator.navigateToSitePath(
AddonModWikiModuleHandlerService.PAGE_NAME + `/${courseId}/${module.id}/page/${hash}`,
AddonModWikiModuleHandlerService.PAGE_NAME + `/${module.course}/${module.id}/page/${hash}`,
{
params: {
module,

View File

@ -189,7 +189,7 @@ export class AddonModWikiPrefetchHandlerService extends CoreCourseActivityPrefet
// Fetch info to provide wiki links.
promises.push(AddonModWiki.getWiki(courseId, module.id, { siteId }).then((wiki) =>
CoreCourse.getModuleBasicInfoByInstance(wiki.id, 'wiki', siteId)));
CoreCourse.getModuleBasicInfoByInstance(wiki.id, 'wiki', { siteId })));
// Get related page files and fetch them.
promises.push(this.getFiles(module, courseId, single, siteId).then((files) =>

View File

@ -363,7 +363,7 @@ export class AddonModWorkshopPrefetchHandlerService extends CoreCourseActivityPr
}));
// Add Basic Info to manage links.
promises.push(CoreCourse.getModuleBasicInfoByInstance(workshop.id, 'workshop', siteId));
promises.push(CoreCourse.getModuleBasicInfoByInstance(workshop.id, 'workshop', { siteId }));
promises.push(CoreCourse.getModuleBasicGradeInfo(module.id, siteId));
// Get course data, needed to determine upload max size if it's configured to be course limit.

View File

@ -119,7 +119,7 @@ export class CoreCourseActivityPrefetchHandlerBase extends CoreCourseModulePrefe
// Package marked as downloading, get module info to be able to handle links. Get module filters too.
await Promise.all([
CoreCourse.getModuleBasicInfo(module.id, siteId),
CoreCourse.getModuleBasicInfo(module.id, { siteId }),
CoreCourse.getModule(module.id, courseId, undefined, false, true, siteId),
CoreFilterHelper.getFilters('module', module.id, { courseId }),
]);

View File

@ -47,7 +47,7 @@ export class CoreCourseModuleMainActivityPage<ActivityType extends CoreCourseMod
return;
}
this.title = this.module?.name;
this.title = this.module.name;
}
/**

View File

@ -394,11 +394,11 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
const ignoreCache = refresh && CoreApp.isOnline();
try {
await CoreCourse.loadModuleContents(this.module, this.courseId, undefined, false, ignoreCache);
await CoreCourse.loadModuleContents(this.module, undefined, undefined, false, ignoreCache);
} catch (error) {
// Error loading contents. If we ignored cache, try to get the cached value.
if (ignoreCache && !this.module.contents) {
await CoreCourse.loadModuleContents(this.module, this.courseId);
await CoreCourse.loadModuleContents(this.module);
} else if (!this.module.contents) {
// Not able to load contents, throw the error.
throw error;

View File

@ -92,7 +92,7 @@ export class CoreCourseResourcePrefetchHandlerBase extends CoreCourseModulePrefe
dirPath?: string,
): Promise<void> {
// Get module info to be able to handle links.
await CoreCourse.getModuleBasicInfo(module.id, siteId);
await CoreCourse.getModuleBasicInfo(module.id, { siteId });
// Load module contents (ignore cache so we always have the latest data).
await this.loadContents(module, courseId, true);

View File

@ -106,7 +106,7 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
if (this.module.handlerData.showDownloadButton) {
// Listen for changes on this module status, even if download isn't enabled.
this.prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module);
this.prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.name);
this.statusObserver = CoreEvents.on(CoreEvents.PACKAGE_STATUS_CHANGED, (data) => {
if (!this.module || data.componentId != this.module.id || !this.prefetchHandler ||
@ -180,14 +180,14 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
try {
// Get download size to ask for confirm if it's high.
const size = await this.prefetchHandler.getDownloadSize(this.module, this.courseId!, true);
const size = await this.prefetchHandler.getDownloadSize(this.module, this.module.course, true);
await CoreCourseHelper.prefetchModule(this.prefetchHandler, this.module, size, this.courseId!, refresh);
await CoreCourseHelper.prefetchModule(this.prefetchHandler, this.module, size, this.module.course, refresh);
const eventData = {
sectionId: this.section?.id,
moduleId: this.module.id,
courseId: this.courseId!,
courseId: this.module.course,
};
this.statusChanged.emit(eventData);
} catch (error) {

View File

@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
import { Params } from '@angular/router';
import moment from 'moment';
import { CoreSites } from '@services/sites';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import {
CoreCourse,
CoreCourseCompletionActivityStatus,
@ -725,7 +725,7 @@ export class CoreCourseHelperProvider {
if (!files || !files.length) {
// Try to use module contents.
files = await CoreCourse.getModuleContents(module, courseId);
files = await CoreCourse.getModuleContents(module);
}
if (!files.length) {
@ -1013,7 +1013,7 @@ export class CoreCourseHelperProvider {
): Promise<void> {
siteId = siteId || CoreSites.getCurrentSiteId();
const prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module);
const prefetchHandler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module.name);
if (prefetchHandler) {
// Use the prefetch handler to download the module.
@ -1429,6 +1429,31 @@ export class CoreCourseHelperProvider {
return CoreConstants.ICON_DOWNLOADING;
}
/**
* Get the course ID from a module instance ID, showing an error message if it can't be retrieved.
*
* @deprecated since 4.0.
* @param instanceId Instance ID.
* @param moduleName Name of the module. E.g. 'glossary'.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the module's course ID.
*/
async getModuleCourseIdByInstance(instanceId: number, moduleName: string, siteId?: string): Promise<number> {
try {
const cm = await CoreCourse.getModuleBasicInfoByInstance(
instanceId,
moduleName,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
return cm.course;
} catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'core.course.errorgetmodule', true);
throw error;
}
}
/**
* Get prefetch info for a module.
*
@ -1551,7 +1576,7 @@ export class CoreCourseHelperProvider {
const modal = await CoreDomUtils.showModalLoading();
try {
const module = await CoreCourse.getModuleBasicInfoByInstance(instanceId, modName, siteId);
const module = await CoreCourse.getModuleBasicInfoByInstance(instanceId, modName, { siteId });
this.navigateToModule(
module.id,
@ -1594,15 +1619,14 @@ export class CoreCourseHelperProvider {
const modal = await CoreDomUtils.showModalLoading();
try {
if (!courseId) {
// We don't have courseId.
const module = await CoreCourse.getModuleBasicInfo(moduleId, siteId);
if (!courseId || !sectionId) {
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
courseId = module.course;
sectionId = module.section;
} else if (!sectionId) {
// We don't have sectionId but we have courseId.
sectionId = await CoreCourse.getModuleSectionId(moduleId, siteId);
}
// Get the site.
@ -2024,7 +2048,7 @@ export class CoreCourseHelperProvider {
promises.push(CoreCourseModulePrefetchDelegate.removeModuleFiles(module, courseId));
const handler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module);
const handler = CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(module.name);
const site = CoreSites.getCurrentSite();
if (handler && site) {
promises.push(site.deleteComponentFromCache(handler.component, module.id));

View File

@ -18,7 +18,7 @@ import { Params } from '@angular/router';
import { CoreApp } from '@services/app';
import { CoreEvents } from '@singletons/events';
import { CoreLogger } from '@singletons/logger';
import { CoreSitesCommonWSOptions, CoreSites } from '@services/sites';
import { CoreSitesCommonWSOptions, CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils';
import { CoreSiteWSPreSets, CoreSite } from '@classes/site';
@ -502,8 +502,12 @@ export class CoreCourseProvider {
if (!courseId) {
// No courseId passed, try to retrieve it.
const module = await this.getModuleBasicInfo(moduleId, siteId);
const module = await this.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
courseId = module.course;
sectionId = module.section;
}
let sections: CoreCourseGetContentsWSSection[];
@ -530,9 +534,8 @@ export class CoreCourseProvider {
let foundModule: CoreCourseGetContentsWSModule | undefined;
const foundSection = sections.some((section) => {
if (sectionId != null &&
!isNaN(sectionId) &&
section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID &&
if (section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID &&
sectionId !== undefined &&
sectionId != section.id
) {
return false;
@ -585,17 +588,18 @@ export class CoreCourseProvider {
* Gets a module basic info by module ID.
*
* @param moduleId Module ID.
* @param siteId Site ID. If not defined, current site.
* @param options Comon site WS options.
* @return Promise resolved with the module's info.
*/
async getModuleBasicInfo(moduleId: number, siteId?: string): Promise<CoreCourseModuleBasicInfo> {
const site = await CoreSites.getSite(siteId);
async getModuleBasicInfo(moduleId: number, options: CoreSitesCommonWSOptions = {}): Promise<CoreCourseModuleBasicInfo> {
const site = await CoreSites.getSite(options.siteId);
const params: CoreCourseGetCourseModuleWSParams = {
cmid: moduleId,
};
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getModuleCacheKey(moduleId),
updateFrequency: CoreSite.FREQUENCY_RARELY,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
};
const response = await site.read<CoreCourseGetCourseModuleWSResponse>('core_course_get_course_module', params, preSets);
@ -614,7 +618,7 @@ export class CoreCourseProvider {
* @return Promise resolved with the module's grade info.
*/
async getModuleBasicGradeInfo(moduleId: number, siteId?: string): Promise<CoreCourseModuleGradeInfo | undefined> {
const info = await this.getModuleBasicInfo(moduleId, siteId);
const info = await this.getModuleBasicInfo(moduleId, { siteId });
if (
info.grade !== undefined ||
@ -636,21 +640,29 @@ export class CoreCourseProvider {
/**
* Gets a module basic info by instance.
*
* @param id Instance ID.
* @param module Name of the module. E.g. 'glossary'.
* @param siteId Site ID. If not defined, current site.
* @param instanceId Instance ID.
* @param moduleName Name of the module. E.g. 'glossary'.
* @param options Comon site WS options.
* @return Promise resolved with the module's info.
*/
async getModuleBasicInfoByInstance(id: number, module: string, siteId?: string): Promise<CoreCourseModuleBasicInfo> {
const site = await CoreSites.getSite(siteId);
async getModuleBasicInfoByInstance(
instanceId: number,
moduleName: string,
options: CoreSitesCommonWSOptions = {},
): Promise<CoreCourseModuleBasicInfo> {
const site = await CoreSites.getSite(options.siteId);
const params: CoreCourseGetCourseModuleByInstanceWSParams = {
instance: id,
module: module,
instance: instanceId,
module: moduleName,
};
const preSets = {
cacheKey: this.getModuleBasicInfoByInstanceCacheKey(id, module),
const preSets: CoreSiteWSPreSets = {
cacheKey: this.getModuleBasicInfoByInstanceCacheKey(instanceId, moduleName),
updateFrequency: CoreSite.FREQUENCY_RARELY,
...CoreSites.getReadingStrategyPreSets(options.readingStrategy), // Include reading strategy preSets.
};
const response: CoreCourseGetCourseModuleWSResponse =
await site.read('core_course_get_course_module_by_instance', params, preSets);
@ -666,12 +678,12 @@ export class CoreCourseProvider {
/**
* Get cache key for get module by instance WS calls.
*
* @param id Instance ID.
* @param module Name of the module. E.g. 'glossary'.
* @param instanceId Instance ID.
* @param moduleName Name of the module. E.g. 'glossary'.
* @return Cache key.
*/
protected getModuleBasicInfoByInstanceCacheKey(id: number, module: string): string {
return ROOT_CACHE_KEY + 'moduleByInstance:' + module + ':' + id;
protected getModuleBasicInfoByInstanceCacheKey(instanceId: number, moduleName: string): string {
return ROOT_CACHE_KEY + 'moduleByInstance:' + moduleName + ':' + instanceId;
}
/**
@ -721,13 +733,17 @@ export class CoreCourseProvider {
/**
* Get the section ID a module belongs to.
*
* @deprecated since 4.0.
* @param moduleId The module ID.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the section ID.
*/
async getModuleSectionId(moduleId: number, siteId?: string): Promise<number> {
// Try to get the section using getModuleBasicInfo.
const module = await this.getModuleBasicInfo(moduleId, siteId);
const module = await CoreCourse.getModuleBasicInfo(
moduleId,
{ siteId, readingStrategy: CoreSitesReadingStrategy.PREFER_CACHE },
);
return module.section;
}
@ -974,7 +990,7 @@ export class CoreCourseProvider {
* It will throw an error if contents cannot be loaded.
*
* @param module Module to get its contents.
* @param courseId The course ID. Recommended to speed up the process and minimize data usage.
* @param courseId Not used since 4.0.
* @param sectionId The section ID.
* @param preferCache True if shouldn't call WS if data is cached, false otherwise.
* @param ignoreCache True if it should ignore cached data (it will always fail in offline or server down).
@ -984,7 +1000,7 @@ export class CoreCourseProvider {
* @return Promise resolved when loaded.
*/
async getModuleContents(
module: CoreCourseAnyModuleData,
module: CoreCourseModuleData,
courseId?: number,
sectionId?: number,
preferCache?: boolean,
@ -993,7 +1009,7 @@ export class CoreCourseProvider {
modName?: string,
): Promise<CoreCourseModuleContentFile[]> {
// Make sure contents are loaded.
await this.loadModuleContents(module, courseId, sectionId, preferCache, ignoreCache, siteId, modName);
await this.loadModuleContents(module, undefined, sectionId, preferCache, ignoreCache, siteId, modName);
if (!module.contents) {
throw new CoreError(Translate.instant('core.course.modulenotfound'));

View File

@ -95,7 +95,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved with boolean: whether the module can use check updates WS.
*/
async canModuleUseCheckUpdates(module: CoreCourseAnyModuleData, courseId: number): Promise<boolean> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
// Module not supported, cannot use check updates.
@ -171,7 +171,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Module status.
*/
determineModuleStatus(module: CoreCourseAnyModuleData, status: string): string {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
const siteId = CoreSites.getCurrentSiteId();
if (!handler) {
@ -203,7 +203,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
*/
async downloadModule(module: CoreCourseAnyModuleData, courseId: number, dirPath?: string): Promise<void> {
// Check if the module has a prefetch handler.
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return;
@ -227,7 +227,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
const id = <string> Md5.hashAsciiStr(courseId + '#' + JSON.stringify(modules));
const siteId = CoreSites.getCurrentSiteId();
if (this.courseUpdatesPromises[siteId] && this.courseUpdatesPromises[siteId][id]) {
if (this.courseUpdatesPromises[siteId] && this.courseUpdatesPromises[siteId][id] !== undefined) {
// There's already a get updates ongoing, return the promise.
return this.courseUpdatesPromises[siteId][id];
} else if (!this.courseUpdatesPromises[siteId]) {
@ -381,7 +381,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved with the size.
*/
async getModuleDownloadSize(module: CoreCourseAnyModuleData, courseId: number, single?: boolean): Promise<CoreFileSizeSum> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return { size: 0, total: false };
@ -419,7 +419,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved with the size.
*/
async getModuleDownloadedSize(module: CoreCourseAnyModuleData, courseId: number): Promise<number> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return 0;
}
@ -492,7 +492,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
}
const site = CoreSites.getCurrentSite();
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler || !site) {
// If there is no handler then we can't find out the component name.
// We can't work out the cached size, so just return downloaded size.
@ -515,7 +515,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
module: CoreCourseAnyModuleData,
courseId: number,
): Promise<(CoreWSFile | CoreCourseModuleContentFile)[]> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (handler?.getFiles) {
// The handler defines a function to get files, use it.
@ -548,7 +548,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
refresh?: boolean,
sectionId?: number,
): Promise<string> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
// No handler found, module not downloadable.
@ -712,7 +712,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
}
await Promise.all(modules.map(async (module) => {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler || (onlyToDisplay && handler.skipListStatus)) {
return;
}
@ -758,7 +758,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
module: CoreCourseAnyModuleData,
courseId: number,
): Promise<{ status: string; downloadTime?: number }> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
const siteId = CoreSites.getCurrentSiteId();
if (!handler) {
@ -863,11 +863,11 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
/**
* Get a prefetch handler.
*
* @param module The module to work on.
* @param moduleName The module name to work on.
* @return Prefetch handler.
*/
getPrefetchHandlerFor(module: CoreCourseAnyModuleData): CoreCourseModulePrefetchHandler | undefined {
return this.getHandler(module.modname, true);
getPrefetchHandlerFor(moduleName: string): CoreCourseModulePrefetchHandler | undefined {
return this.getHandler(moduleName, true);
}
/**
@ -895,7 +895,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
async invalidateModules(modules: CoreCourseModuleData[], courseId: number): Promise<void> {
const promises = modules.map(async (module) => {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return;
}
@ -919,7 +919,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @param module Module to be invalidated.
*/
invalidateModuleStatusCache(module: CoreCourseAnyModuleData): void {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (handler) {
this.statusCache.invalidate(CoreFilepool.getPackageId(handler.component, module.id));
}
@ -964,7 +964,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
return false;
}
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return false;
}
@ -1000,7 +1000,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved with boolean: whether the module has updates.
*/
async moduleHasUpdates(module: CoreCourseAnyModuleData, courseId: number, updates: CourseUpdates): Promise<boolean> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
const moduleUpdates = updates[module.id];
if (handler?.hasUpdates) {
@ -1033,7 +1033,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved when finished.
*/
async prefetchModule(module: CoreCourseAnyModuleData, courseId: number, single?: boolean): Promise<void> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return;
}
@ -1067,7 +1067,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved when finished.
*/
async syncModule<T = unknown>(module: CoreCourseAnyModuleData, courseId: number): Promise<T | undefined> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler?.sync) {
return;
}
@ -1124,7 +1124,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
const promises = modules.map(async (module) => {
// Check if the module has a prefetch handler.
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
if (!handler) {
return;
}
@ -1170,7 +1170,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved when done.
*/
async removeModuleFiles(module: CoreCourseAnyModuleData, courseId: number): Promise<void> {
const handler = this.getPrefetchHandlerFor(module);
const handler = this.getPrefetchHandlerFor(module.name);
const siteId = CoreSites.getCurrentSiteId();
if (handler?.removeFiles) {

View File

@ -15,7 +15,7 @@
import { Type } from '@angular/core';
import { CoreConstants } from '@/core/constants';
import { CoreCourse, CoreCourseAnyModuleData } from '@features/course/services/course';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreCourseModuleHandler, CoreCourseModuleHandlerData } from '@features/course/services/module-delegate';
import { CoreSitePluginsModuleIndexComponent } from '@features/siteplugins/components/module-index/module-index';
@ -64,12 +64,12 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
* @inheritdoc
*/
getData(
module: CoreCourseAnyModuleData,
module: CoreCourseModuleData,
courseId: number,
sectionId?: number,
forCoursePage?: boolean,
): CoreCourseModuleHandlerData {
if ('description' in module && this.shouldOnlyDisplayDescription(module, forCoursePage)) {
if (this.shouldOnlyDisplayDescription(module, forCoursePage)) {
const title = module.description;
module.description = '';
@ -128,7 +128,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
* @param forCoursePage Whether the data will be used to render the course page.
* @return Bool.
*/
protected shouldOnlyDisplayDescription(module: CoreCourseAnyModuleData, forCoursePage?: boolean): boolean {
protected shouldOnlyDisplayDescription(module: CoreCourseModuleData, forCoursePage?: boolean): boolean {
if (forCoursePage && this.handlerSchema.coursepagemethod) {
// The plugin defines a method for course page, don't display just the description.
return false;
@ -167,7 +167,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
* @return Promise resolved when done.
*/
protected async loadCoursePageTemplate(
module: CoreCourseAnyModuleData,
module: CoreCourseModuleData,
courseId: number,
handlerData: CoreCourseModuleHandlerData,
method: string,

View File

@ -145,7 +145,7 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C
this.refreshIcon = CoreConstants.ICON_REFRESH;
// Check if there is a prefetch handler for this type of module.
if (CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module)) {
if (CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor(this.module.name)) {
CoreCourseHelper.fillContextMenu(this, this.module, this.courseId, refresh, this.component);
}
}

View File

@ -1,11 +1,13 @@
This files describes API changes in the Moodle Mobile app,
information provided here is intended especially for developers.
=== 3.9.6 ===
=== 4.0.0 ===
- The parameters of the functions confirmAndPrefetchCourse and confirmAndPrefetchCourses have changed, they now accept an object with options.
- Component core-navigation-bar changed to add an slider inside. previous, previousTitle, next, nextTitle, info and title have been removed.
Now you have to pass all items and 3 optional params have been added.
- CoreCourseModulePrefetchDelegate.getPrefetchHandlerFor now admits module name instead of full module object.
- CoreCourse.getModuleBasicInfoByInstance and CoreCourse.getModuleBasicInfo have been modified to accept an "options" parameter instead of only siteId.
=== 3.9.5 ===