diff --git a/src/core/course/providers/course.ts b/src/core/course/providers/course.ts index 35a8a3997..5961b72b8 100644 --- a/src/core/course/providers/course.ts +++ b/src/core/course/providers/course.ts @@ -85,11 +85,22 @@ export class CoreCourseProvider { this.sitesProvider.createTableFromSchema(this.courseStatusTableSchema); } + /** + * Check if the get course blocks WS is available in current site. + * + * @return {boolean} Whether it's available. + * @since 3.3 + */ + canGetCourseBlocks(): boolean { + return this.sitesProvider.wsAvailableInCurrentSite('core_block_get_course_blocks'); + } + /** * Check whether the site supports requesting stealth modules. * * @param {CoreSite} [site] Site. If not defined, current site. * @return {boolean} Whether the site supports requesting stealth modules. + * @since 3.4.6, 3.5.3, 3.6 */ canRequestStealthModules(site?: CoreSite): boolean { site = site || this.sitesProvider.getCurrentSite(); @@ -208,6 +219,39 @@ export class CoreCourseProvider { return this.ROOT_CACHE_KEY + 'activitiescompletion:' + courseId + ':' + userId; } + /** + * Get course blocks. + * + * @param {number} courseId Course ID. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with the list of blocks. + * @since 3.3 + */ + getCourseBlocks(courseId: number, siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + const params = { + courseid: courseId + }, + preSets: CoreSiteWSPreSets = { + cacheKey: this.getCourseBlocksCacheKey(courseId) + }; + + return site.read('core_block_get_course_blocks', params, preSets).then((result) => { + return result.blocks || []; + }); + }); + } + + /** + * Get cache key for course blocks WS calls. + * + * @param {number} courseId Course ID. + * @return {string} Cache key. + */ + protected getCourseBlocksCacheKey(courseId: number): string { + return this.ROOT_CACHE_KEY + 'courseblocks:' + courseId; + } + /** * Get the data stored for a course. * @@ -608,6 +652,19 @@ export class CoreCourseProvider { return modules; } + /** + * Invalidates course blocks WS call. + * + * @param {number} courseId Course ID. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved when the data is invalidated. + */ + invalidateCourseBlocks(courseId: number, siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + return site.invalidateWsCacheForKey(this.getCourseBlocksCacheKey(courseId)); + }); + } + /** * Invalidates module WS call. * diff --git a/src/core/sitehome/components/index/core-sitehome-index.html b/src/core/sitehome/components/index/core-sitehome-index.html index 80850db1f..ba1c2df9a 100644 --- a/src/core/sitehome/components/index/core-sitehome-index.html +++ b/src/core/sitehome/components/index/core-sitehome-index.html @@ -22,14 +22,14 @@ - - + + - - + + - + diff --git a/src/core/sitehome/components/index/index.ts b/src/core/sitehome/components/index/index.ts index ee581ec75..17837f3ab 100644 --- a/src/core/sitehome/components/index/index.ts +++ b/src/core/sitehome/components/index/index.ts @@ -30,7 +30,7 @@ import { CoreSiteHomeProvider } from '../../providers/sitehome'; export class CoreSiteHomeIndexComponent implements OnInit { dataLoaded = false; section: any; - block: any; + mainMenuBlock: any; hasContent: boolean; items: any[] = []; siteHomeId: number; @@ -75,6 +75,10 @@ export class CoreSiteHomeIndexComponent implements OnInit { promises.push(this.prefetchDelegate.invalidateModules(modules, this.siteHomeId)); } + if (this.courseProvider.canGetCourseBlocks()) { + promises.push(this.courseProvider.invalidateCourseBlocks(this.siteHomeId)); + } + Promise.all(promises).finally(() => { this.loadContent().finally(() => { refresher.complete(); @@ -126,40 +130,70 @@ export class CoreSiteHomeIndexComponent implements OnInit { } return this.courseProvider.getSections(this.siteHomeId, false, true).then((sections) => { + const promises = []; + this.sectionsLoaded = Array.from(sections); // Check "Include a topic section" setting from numsections. this.section = config.numsections && sections.length > 0 ? sections.pop() : false; if (this.section) { this.section.hasContent = this.courseHelper.sectionHasContent(this.section); + this.hasContent = this.courseHelper.addHandlerDataForModules([this.section], this.siteHomeId) || this.hasContent; } - this.block = sections.length > 0 ? sections.pop() : false; - if (this.block) { - this.block.hasContent = this.courseHelper.sectionHasContent(this.block); - } + const mainMenuBlock = sections.length > 0 ? sections.pop() : false; + this.mainMenuBlock = false; - this.hasContent = this.courseHelper.addHandlerDataForModules(this.sectionsLoaded, this.siteHomeId) || this.hasContent; + if (mainMenuBlock) { + // Check if the block can be viewed. + let promise; - // Add log in Moodle. - this.courseProvider.logView(this.siteHomeId); + if (this.courseProvider.canGetCourseBlocks()) { + promise = this.courseProvider.getCourseBlocks(this.siteHomeId).then((blocks) => { + // Search if the main menu block is enabled. + return !!blocks.find((block) => { return block.name == 'site_main_menu'; }); + }).catch(() => { + return true; + }); + } else { + // We don't know if it can be viewed, so always display it. + promise = Promise.resolve(true); + } - if (hasNewsItem && this.block && this.block.modules) { - // Remove forum activity (news one only) to prevent duplicates. - return this.siteHomeProvider.getNewsForum(this.siteHomeId).then((forum) => { - // Search the module that belongs to site news. - for (let i = 0; i < this.block.modules.length; i++) { - const module = this.block.modules[i]; + promises.push(promise.then((canView) => { + if (canView) { + // User can view the block, display it and calculate its data. + this.mainMenuBlock = mainMenuBlock; + this.mainMenuBlock.hasContent = this.courseHelper.sectionHasContent(this.mainMenuBlock); + this.hasContent = this.courseHelper.addHandlerDataForModules([mainMenuBlock], this.siteHomeId) || + this.hasContent; - if (module.modname == 'forum' && module.instance == forum.id) { - this.block.modules.splice(i, 1); - break; + if (hasNewsItem && this.mainMenuBlock.modules) { + // Remove forum activity (news one only) from the main menu block to prevent duplicates. + return this.siteHomeProvider.getNewsForum(this.siteHomeId).then((forum) => { + // Search the module that belongs to site news. + for (let i = 0; i < this.mainMenuBlock.modules.length; i++) { + const module = this.mainMenuBlock.modules[i]; + + if (module.modname == 'forum' && module.instance == forum.id) { + this.mainMenuBlock.modules.splice(i, 1); + break; + } + } + }).catch(() => { + // Ignore errors. + }); } } - }).catch(() => { - // Ignore errors. - }); + })); } + + // Add log in Moodle. + this.courseProvider.logView(this.siteHomeId).catch(() => { + // Ignore errors. + }); + + return Promise.all(promises); }).catch((error) => { this.domUtils.showErrorModalDefault(error, 'core.course.couldnotloadsectioncontent', true); });