diff --git a/lib/blocklib.php b/lib/blocklib.php index 127aba33e1d5..a6bb7b244150 100644 --- a/lib/blocklib.php +++ b/lib/blocklib.php @@ -945,6 +945,28 @@ public function add_blocks($blocks, $pagetypepattern = NULL, $subpagepattern = N } } + /** + * Given an array of blocks in the format used by {@see add_blocks}, removes any blocks from + * the list if they are not installed in the system. + * + * @param array $blocks Array keyed by region + * @return array Updated array + */ + public function filter_nonexistent_blocks(array $blocks): array { + $installed = array_fill_keys( + array_map(fn($block) => $block->name, $this->get_installed_blocks()), true); + $result = []; + foreach ($blocks as $region => $regionblocks) { + $result[$region] = []; + foreach ($regionblocks as $blockname) { + if (array_key_exists($blockname, $installed)) { + $result[$region][] = $blockname; + } + } + } + return $result; + } + /** * Move a block to a new position on this page. * @@ -2684,6 +2706,9 @@ function blocks_get_default_site_course_blocks() { /** * Add the default blocks to a course. * + * Because this function is used on install, we skip over any default blocks that do not exist + * so that install can complete successfully even if blocks are removed. + * * @param object $course a course object. */ function blocks_add_default_course_blocks($course) { @@ -2711,11 +2736,15 @@ function blocks_add_default_course_blocks($course) { } $page = new moodle_page(); $page->set_course($course); - $page->blocks->add_blocks($blocknames, $pagetypepattern); + $page->blocks->add_blocks($page->blocks->filter_nonexistent_blocks($blocknames), + $pagetypepattern); } /** * Add the default system-context blocks. E.g. the admin tree. + * + * Because this function is used on install, we skip over any default blocks that do not exist + * so that install can complete successfully even if blocks are removed. */ function blocks_add_default_system_blocks() { global $DB; @@ -2723,7 +2752,10 @@ function blocks_add_default_system_blocks() { $page = new moodle_page(); $page->set_context(context_system::instance()); // We don't add blocks required by the theme, they will be auto-created. - $page->blocks->add_blocks(array(BLOCK_POS_LEFT => array('admin_bookmarks')), 'admin-*', null, null, 2); + $page->blocks->add_blocks($page->blocks->filter_nonexistent_blocks([ + BLOCK_POS_LEFT => [ + 'admin_bookmarks', + ]]), 'admin-*', null, null, 2); if ($defaultmypage = $DB->get_record('my_pages', array('userid' => null, 'name' => '__default', 'private' => 1))) { $subpagepattern = $defaultmypage->id; @@ -2737,22 +2769,22 @@ function blocks_add_default_system_blocks() { $mycoursesubpagepattern = null; } - $page->blocks->add_blocks([ + $page->blocks->add_blocks($page->blocks->filter_nonexistent_blocks([ BLOCK_POS_RIGHT => [ 'recentlyaccesseditems', ], 'content' => [ 'timeline', 'calendar_month', - ]], + ]]), 'my-index', $subpagepattern ); - $page->blocks->add_blocks([ + $page->blocks->add_blocks($page->blocks->filter_nonexistent_blocks([ 'content' => [ 'myoverview' - ]], + ]]), 'my-index', $mycoursesubpagepattern );