diff --git a/lib/blocklib.php b/lib/blocklib.php index dc391583aef5..83e8ca7f3561 100644 --- a/lib/blocklib.php +++ b/lib/blocklib.php @@ -214,15 +214,17 @@ public function get_addable_blocks() { return $this->addableblocks; } - $unaddableblocks = self::get_undeletable_block_types(); + $undeletableblocks = self::get_undeletable_block_types(); + $unaddablebythemeblocks = $this->get_unaddable_by_theme_block_types(); $requiredbythemeblocks = $this->get_required_by_theme_block_types(); $pageformat = $this->page->pagetype; foreach($allblocks as $block) { if (!$bi = block_instance($block->name)) { continue; } - if ($block->visible && !in_array($block->name, $unaddableblocks) && + if ($block->visible && !in_array($block->name, $undeletableblocks) && !in_array($block->name, $requiredbythemeblocks) && + !in_array($block->name, $unaddablebythemeblocks) && $bi->can_block_be_added($this->page) && ($bi->instance_allow_multiple() || !$this->is_block_present($block->name)) && blocks_name_allowed_in_format($block->name, $pageformat) && @@ -428,6 +430,21 @@ public function get_required_by_theme_block_types() { } } + /** + * It returns the list of blocks that can't be displayed in the "Add a block" list. + * This information is taken from the unaddableblocks theme setting. + * + * @return array A list with the blocks that won't be displayed in the "Add a block" list. + */ + public function get_unaddable_by_theme_block_types(): array { + $unaddablebythemeblocks = []; + if (isset($this->page->theme->settings->unaddableblocks) && !empty($this->page->theme->settings->unaddableblocks)) { + $unaddablebythemeblocks = array_map('trim', explode(',', $this->page->theme->settings->unaddableblocks)); + } + + return $unaddablebythemeblocks; + } + /** * Make this block type undeletable and unaddable. * diff --git a/lib/tests/blocklib_test.php b/lib/tests/blocklib_test.php index f15ce7b32ad7..a8cc9a7f41f9 100644 --- a/lib/tests/blocklib_test.php +++ b/lib/tests/blocklib_test.php @@ -826,6 +826,43 @@ public function test_default_dashboard() { $this->assertEquals('8', $mybr[5]->instance->weight); $PAGE = $storedpage; } + + /** + * Test get_unaddable_by_theme_block_types() method to return expected result depending on the theme. + * + * @covers \block_manager::get_unaddable_by_theme_block_types + */ + public function test_get_unaddable_by_theme_block_types(): void { + global $CFG, $PAGE; + + $this->setAdminUser(); + $this->resetAfterTest(); + $regionname = 'side-pre'; + $context = context_system::instance(); + + $PAGE->reset_theme_and_output(); + $CFG->theme = 'boost'; + + list($page, $blockmanager) = $this->get_a_page_and_block_manager([$regionname], $context, 'page-type'); + $blockmanager->load_blocks(); + $blocks = $blockmanager->get_unaddable_by_theme_block_types(); + // Assert that a few blocks are excluded for boost theme. + $this->assertCount(4, $blocks); + $this->assertContains('navigation', $blocks); + $this->assertContains('settings', $blocks); + $this->assertContains('course_list', $blocks); + $this->assertContains('section_links', $blocks); + + // Change to a theme without unaddable blocks. + $PAGE->reset_theme_and_output(); + $CFG->theme = 'classic'; + + list($page, $blockmanager) = $this->get_a_page_and_block_manager([$regionname], $context, 'page-type'); + $blockmanager->load_blocks(); + $blocks = $blockmanager->get_unaddable_by_theme_block_types(); + // Assert that no blocks are excluded for classic theme. + $this->assertEmpty($blocks); + } } /** diff --git a/lib/upgrade.txt b/lib/upgrade.txt index b5fdd52d3cc6..a5a9d147d95b 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -163,6 +163,8 @@ current value for a pluginname depending on its status (enabled, disabled, other * /renderer.php * /rsslib.php This default applies both when there is no supplied coverage.php file, and is used to supplement any existing coverage configuration file if one is found. +* New method get_unaddable_by_theme_block_types() has been added to block_manager class. It uses the 'unaddableblocks' theme setting +value to get the list of blocks that won't be displayed for a theme. === 3.11.4 === * A new option dontforcesvgdownload has been added to the $options parameter of the send_file() function. diff --git a/theme/boost/lang/en/theme_boost.php b/theme/boost/lang/en/theme_boost.php index 16f509b45d95..2260c455bd4a 100644 --- a/theme/boost/lang/en/theme_boost.php +++ b/theme/boost/lang/en/theme_boost.php @@ -50,6 +50,8 @@ $string['rawscsspre_desc'] = 'In this field you can provide initialising SCSS code, it will be injected before everything else. Most of the time you will use this setting to define variables.'; $string['region-side-pre'] = 'Right'; $string['showfooter'] = 'Show footer'; +$string['unaddableblocks'] = 'Unaddable blocks'; +$string['unaddableblocks_desc'] = 'The blocks defined in this field will not be displayed in the "Add a block" list.'; $string['privacy:metadata:preference:draweropennav'] = 'The user\'s preference for hiding or showing the drawer menu navigation.'; $string['privacy:drawernavclosed'] = 'The current preference for the navigation drawer is closed.'; $string['privacy:drawernavopen'] = 'The current preference for the navigation drawer is open.'; diff --git a/theme/boost/settings.php b/theme/boost/settings.php index 08ddf3d96d7f..46f9d9a4aca3 100644 --- a/theme/boost/settings.php +++ b/theme/boost/settings.php @@ -26,6 +26,15 @@ $settings = new theme_boost_admin_settingspage_tabs('themesettingboost', get_string('configtitle', 'theme_boost')); $page = new admin_settingpage('theme_boost_general', get_string('generalsettings', 'theme_boost')); + // Unaddable blocks. + // Blocks to be excluded when this theme is enabled in the "Add a block" list: Administration, Navigation, Courses and + // Section links. + $default = 'navigation,settings,course_list,section_links'; + $setting = new admin_setting_configtext('theme_boost/unaddableblocks', + get_string('unaddableblocks', 'theme_boost'), get_string('unaddableblocks_desc', 'theme_boost'), $default, PARAM_TEXT); + $setting->set_updatedcallback('theme_reset_all_caches'); + $page->add($setting); + // Preset. $name = 'theme_boost/preset'; $title = get_string('preset', 'theme_boost'); diff --git a/theme/boost/tests/behat/addblock.feature b/theme/boost/tests/behat/addblock.feature new file mode 100644 index 000000000000..d786b887ef13 --- /dev/null +++ b/theme/boost/tests/behat/addblock.feature @@ -0,0 +1,41 @@ +@javascript @theme_boost +Feature: Add a block using boost theme + In order to decide the blocks to display in the Add a block list for a theme + As an administrator + I need to define them using the unaddableblocks setting + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And I log in as "admin" + + Scenario: Default blocks defined in unaddableblocks settings are not displayed in the Add a block list + Given I am on "Course 1" course homepage with editing mode on + When I click on "Add a block" "link" + Then I should not see "Administration" + And I should not see "Navigation" + And I should not see "Courses" + And I should not see "Section links" + And I should see "Online users" + + Scenario: Admins can change unaddable blocks using the unaddableblocks setting + Given the following config values are set as admin: + | unaddableblocks | settings,private_files | theme_boost| + And I am on "Course 1" course homepage with editing mode on + When I click on "Add a block" "link" + Then I should not see "Administration" + And I should not see "Private files" + And I should see "Navigation" + And I should see "Courses" + And I should see "Section links" + + Scenario: If unaddableblocks settting is empty, no block is excluded from the Add a block list + Given the following config values are set as admin: + | unaddableblocks | | theme_boost| + And I am on "Course 1" course homepage with editing mode on + When I click on "Add a block" "link" + Then I should see "Administration" + And I should see "Navigation" + And I should see "Courses" + And I should see "Section links" diff --git a/theme/boost/version.php b/theme/boost/version.php index 60cffec1fd70..32de59ba0f36 100644 --- a/theme/boost/version.php +++ b/theme/boost/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2021052506; +$plugin->version = 2022011000; $plugin->requires = 2021052500; $plugin->component = 'theme_boost'; diff --git a/theme/classic/settings.php b/theme/classic/settings.php index 66049cbb6651..40cad98ae81f 100644 --- a/theme/classic/settings.php +++ b/theme/classic/settings.php @@ -35,6 +35,12 @@ $setting->set_updatedcallback('theme_reset_all_caches'); $page->add($setting); + // Unaddable blocks. + $setting = new admin_setting_configtext('theme_classic/unaddableblocks', + get_string('unaddableblocks', 'theme_boost'), get_string('unaddableblocks_desc', 'theme_boost'), '', PARAM_TEXT); + $setting->set_updatedcallback('theme_reset_all_caches'); + $page->add($setting); + // Preset. $name = 'theme_classic/preset'; $title = get_string('preset', 'theme_classic'); diff --git a/theme/classic/tests/behat/addblock.feature b/theme/classic/tests/behat/addblock.feature new file mode 100644 index 000000000000..01ef799510a9 --- /dev/null +++ b/theme/classic/tests/behat/addblock.feature @@ -0,0 +1,32 @@ +@javascript @theme_classic +Feature: Add a block using classic theme + In order to check the blocks to display in the Add a block list for a them + As an administrator + I need to confirm the unaddableblocks setting is empty for classic. + + Background: + Given the following "courses" exist: + | fullname | shortname | + | Course 1 | C1 | + And I log in as "admin" + + Scenario: All the expected blocks are displayed in the Add a block list for classic + Given I am on "Course 1" course homepage with editing mode on + When I click on "Add a block" "select" + Then I should see "Administration" + And I should see "Navigation" + And I should see "Courses" + And I should see "Section links" + + Scenario: Admins can change unaddable blocks using the unaddableblocks setting for classic + Given the following config values are set as admin: + | unaddableblocks | online_users,private_files,settings | theme_classic| + And I am on "Course 1" course homepage with editing mode on + When I click on "Add a block" "select" + Then I should not see "Online users" + And I should not see "Private files" + # The settings block is defined as required block for classic, so it will be displayed always. + And I should see "Administration" + And I should see "Navigation" + And I should see "Courses" + And I should see "Section links" diff --git a/theme/classic/version.php b/theme/classic/version.php index b06814f07e7e..e27729af4ff2 100644 --- a/theme/classic/version.php +++ b/theme/classic/version.php @@ -25,7 +25,7 @@ // This line protects the file from being accessed by a URL directly. defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2021052500; +$plugin->version = 2022011400; $plugin->requires = 2021052500; $plugin->component = 'theme_classic'; $plugin->dependencies = array('theme_boost' => 2021052500); diff --git a/theme/upgrade.txt b/theme/upgrade.txt index 605cc11a824c..99583776ec8b 100644 --- a/theme/upgrade.txt +++ b/theme/upgrade.txt @@ -3,6 +3,7 @@ information provided here is intended especially for theme designer. === 4.0 === * A new theme config 'usescourseindex' allows a theme to specify whether it implements and uses course index. +* A new theme setting 'unaddableblocks' allows admins to define the blocks that won't be displayed in the "Add a block" list. === 3.11 === * The classname 'viewmode-cobmined' in course/management.php has been changed to 'viewmode-combined'