MOBILE-3814 course: Add helper functions to check stealth and visibility

main
Pau Ferrer Ocaña 2022-03-18 15:00:20 +01:00
parent b4b7743a5a
commit 8a5310ef1e
10 changed files with 70 additions and 23 deletions

View File

@ -21,6 +21,7 @@ import { ContextLevel, CoreConstants } from '@/core/constants';
import { Translate } from '@singletons';
import { CoreUtils } from '@services/utils/utils';
import { CoreNavigator } from '@services/navigator';
import { CoreCourseHelper } from '@features/course/services/course-helper';
/**
* Component to render an "activity modules" block.
@ -67,7 +68,7 @@ export class AddonBlockActivityModulesComponent extends CoreBlockBaseComponent i
}
section.modules.forEach((mod) => {
if (mod.uservisible === false || !CoreCourse.moduleHasView(mod) ||
if (!CoreCourseHelper.canUserViewModule(mod, section) || !CoreCourse.moduleHasView(mod) ||
modFullNames[mod.modname] !== undefined) {
// Ignore this module.
return;

View File

@ -34,6 +34,7 @@ import {
CoreCourseProvider,
} from '@features/course/services/course';
import {
CoreCourseHelper,
CoreCourseSection,
} from '@features/course/services/course-helper';
import { CoreCourseFormatDelegate } from '@features/course/services/format-delegate';
@ -444,7 +445,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
await CoreCourseModuleDelegate.getModuleDataFor(module.modname, module, this.course.id);
}
if (module.uservisible !== false && module.handlerData?.action) {
if (CoreCourseHelper.canUserViewModule(module, section) && module.handlerData?.action) {
module.handlerData.action(data.event, module, module.course);
}
@ -574,7 +575,8 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
continue;
}
modulesLoaded += sections[i].modules.reduce((total, module) => module.visibleoncoursepage !== 0 ? total + 1 : total, 0);
modulesLoaded += sections[i].modules.reduce((total, module) =>
!CoreCourseHelper.isModuleStealth(module, sections[i]) ? total + 1 : total, 0);
if (modulesLoaded >= CoreCourseFormatComponent.LOAD_MORE_ACTIVITIES) {
break;
@ -632,8 +634,7 @@ export class CoreCourseFormatComponent implements OnInit, OnChanges, OnDestroy {
* @return Whether the section can be viewed.
*/
canViewSection(section: CoreCourseSection): boolean {
return section.uservisible !== false && !section.hiddenbynumsections &&
section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
return CoreCourseHelper.canUserViewSection(section) && !CoreCourseHelper.isSectionStealth(section);
}
}

View File

@ -18,7 +18,7 @@ import {
CoreCourseModuleCompletionTracking,
CoreCourseProvider,
} from '@features/course/services/course';
import { CoreCourseSection } from '@features/course/services/course-helper';
import { CoreCourseHelper, CoreCourseSection } from '@features/course/services/course-helper';
import { CoreCourseFormatDelegate } from '@features/course/services/format-delegate';
import { CoreCourseAnyCourseData } from '@features/courses/services/courses';
import { IonContent } from '@ionic/angular';
@ -77,11 +77,10 @@ export class CoreCourseCourseIndexComponent implements OnInit {
// Clone sections to add information.
this.sectionsToRender = this.sections
.filter((section) => !section.hiddenbynumsections &&
section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID)
.filter((section) => !CoreCourseHelper.isSectionStealth(section))
.map((section) => {
const modules = section.modules
.filter((module) => module.visibleoncoursepage !== 0 && !module.noviewlink)
.filter((module) => !CoreCourseHelper.isModuleStealth(module, section) && !module.noviewlink)
.map((module) => {
const completionStatus = !completionEnabled || module.completiondata === undefined ||
module.completiondata.tracking == CoreCourseModuleCompletionTracking.COMPLETION_TRACKING_NONE
@ -93,7 +92,7 @@ export class CoreCourseCourseIndexComponent implements OnInit {
name: module.name,
course: module.course,
visible: !!module.visible,
uservisible: !!module.uservisible,
uservisible: CoreCourseHelper.canUserViewModule(module, section),
completionStatus,
};
});
@ -103,7 +102,7 @@ export class CoreCourseCourseIndexComponent implements OnInit {
name: section.name,
availabilityinfo: !!section.availabilityinfo,
visible: !!section.visible,
uservisible: section.uservisible !== false,
uservisible: CoreCourseHelper.canUserViewSection(section),
expanded: section.id === this.selectedId,
highlighted: currentSectionData.section.id === section.id,
hasVisibleModules: modules.length > 0,

View File

@ -13,8 +13,8 @@
// limitations under the License.
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { CoreCourse, CoreCourseProvider, CoreCourseWSSection } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreCourse, CoreCourseWSSection } from '@features/course/services/course';
import { CoreCourseHelper, CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreCourseModuleDelegate } from '@features/course/services/module-delegate';
import { IonContent } from '@ionic/angular';
import { CoreNavigationOptions, CoreNavigator } from '@services/navigator';
@ -187,7 +187,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
* @return Wether the module is available to the user or not.
*/
protected isSectionAvailable(section: CoreCourseWSSection): boolean {
return section.uservisible !== false && section.id != CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
return CoreCourseHelper.canUserViewSection(section) && !CoreCourseHelper.isSectionStealth(section);
}
/**
@ -223,7 +223,7 @@ export class CoreCourseModuleNavigationComponent implements OnInit, OnDestroy {
animationDirection: next ? 'forward' : 'back',
};
if (module.uservisible === false) {
if (!CoreCourseHelper.canUserViewModule(module)) {
const section = next ? this.nextModuleSection : this.previousModuleSection;
options.params = {
module,

View File

@ -19,6 +19,7 @@ import {
CoreCourseModuleData,
CoreCourseModuleCompletionData,
CoreCourseSection,
CoreCourseHelper,
} from '@features/course/services/course-helper';
import { CoreCourse, CoreCourseModuleCompletionStatus, CoreCourseModuleCompletionTracking } from '@features/course/services/course';
import { CoreCourseModuleDelegate, CoreCourseModuleHandlerButton } from '@features/course/services/module-delegate';
@ -166,7 +167,7 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
* @param event Click event.
*/
moduleClicked(event: Event): void {
if (this.module.uservisible !== false && this.module.handlerData?.action) {
if (CoreCourseHelper.canUserViewModule(this.module, this.section) && this.module.handlerData?.action) {
this.module.handlerData.action(event, this.module, this.module.course);
}
}

View File

@ -75,7 +75,7 @@ export class CoreCourseListModTypePage implements OnInit {
}
section.modules = section.modules.filter((mod) => {
if (mod.uservisible === false || !CoreCourse.moduleHasView(mod)) {
if (!CoreCourseHelper.canUserViewModule(mod, section) || !CoreCourse.moduleHasView(mod)) {
// Ignore this module.
return false;
}

View File

@ -198,7 +198,7 @@ export class CoreCourseHelperProvider {
}
// Check if the module is stealth.
module.isStealth = module.visibleoncoursepage === 0 || (!!module.visible && !section.visible);
module.isStealth = CoreCourseHelper.isModuleStealth(module, section);
}));
return section;
@ -208,6 +208,50 @@ export class CoreCourseHelperProvider {
return { hasContent, sections: formattedSections };
}
/**
* Module is stealth.
*
* @param module Module to check.
* @param section Section to check.
* @return Wether the module is stealth.
*/
isModuleStealth(module: CoreCourseModuleData, section?: CoreCourseWSSection): boolean {
// visibleoncoursepage can be 1 for teachers when the section is hidden.
return !!module.visible && (!module.visibleoncoursepage || (!!section && !section.visible));
}
/**
* Module is visible by the user.
*
* @param module Module to check.
* @param section Section to check. Omitted if not defined.
* @return Wether the section is visible by the user.
*/
canUserViewModule(module: CoreCourseModuleData, section?: CoreCourseWSSection): boolean {
return module.uservisible !== false && (!section || CoreCourseHelper.canUserViewSection(section));
}
/**
* Section is stealth.
* This should not be true on Moodle 4.0 onwards.
*
* @param section Section to check.
* @return Wether section is stealth (accessible but not visible to students).
*/
isSectionStealth(section: CoreCourseWSSection): boolean {
return section.hiddenbynumsections === 1 || section.id === CoreCourseProvider.STEALTH_MODULES_SECTION_ID;
}
/**
* Section is visible by the user.
*
* @param section Section to check.
* @return Wether the section is visible by the user.
*/
canUserViewSection(section: CoreCourseWSSection): boolean {
return section.uservisible !== false;
}
/**
* Calculate completion data of a module.
*

View File

@ -33,7 +33,7 @@ import { CoreError } from '@classes/errors/error';
import { CoreWSFile, CoreWSExternalWarning } from '@services/ws';
import { CHECK_UPDATES_TIMES_TABLE, CoreCourseCheckUpdatesDBRecord } from './database/module-prefetch';
import { CoreFileSizeSum } from '@services/plugin-file-delegate';
import { CoreCourseModuleData } from './course-helper';
import { CoreCourseHelper, CoreCourseModuleData } from './course-helper';
const ROOT_CACHE_KEY = 'mmCourse:';
@ -956,7 +956,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
* @return Promise resolved with true if downloadable, false otherwise.
*/
async isModuleDownloadable(module: CoreCourseAnyModuleData, courseId: number): Promise<boolean> {
if ('uservisible' in module && module.uservisible === false) {
if ('uservisible' in module && !CoreCourseHelper.canUserViewModule(module)) {
// Module isn't visible by the user, cannot be downloaded.
return false;
}

View File

@ -30,6 +30,7 @@ import { makeSingleton } from '@singletons';
import { CoreEvents, CoreEventSiteData } from '@singletons/events';
import { CoreLogger } from '@singletons/logger';
import { CoreSite } from '@classes/site';
import { CoreCourseHelper } from '@features/course/services/course-helper';
/**
* Helper service to provide filter functionalities.
@ -159,7 +160,7 @@ export class CoreFilterHelperProvider {
sections.forEach((section) => {
if (section.modules) {
section.modules.forEach((module) => {
if (module.uservisible) {
if (CoreCourseHelper.canUserViewModule(module, section)) {
contexts.push({
contextlevel: 'module',
instanceid: module.id,

View File

@ -16,7 +16,7 @@ import { Type } from '@angular/core';
import { CoreConstants } from '@/core/constants';
import { CoreCourse } from '@features/course/services/course';
import { CoreCourseModuleData } from '@features/course/services/course-helper';
import { CoreCourseHelper, 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';
import {
@ -105,7 +105,7 @@ export class CoreSitePluginsModuleHandler extends CoreSitePluginsBaseHandler imp
};
}
if (forCoursePage && this.handlerSchema.coursepagemethod && module.visibleoncoursepage !== 0) {
if (forCoursePage && this.handlerSchema.coursepagemethod && !CoreCourseHelper.isModuleStealth(module)) {
// Call the method to get the course page template.
const method = this.handlerSchema.coursepagemethod;
this.loadCoursePageTemplate(module, courseId, handlerData, method);