mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
Merge branch 'MDL-57232-master' of git://github.com/damyon/moodle
This commit is contained in:
commit
76e337ab96
@ -4,6 +4,7 @@
|
||||
|
||||
require_once('../config.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/blocklib.php');
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
|
||||
admin_externalpage_setup('manageblocks');
|
||||
@ -49,36 +50,18 @@
|
||||
admin_get_root(true, false); // settings not required - only pages
|
||||
}
|
||||
|
||||
if (!isset($CFG->undeletableblocktypes) || (!is_array($CFG->undeletableblocktypes) && !is_string($CFG->undeletableblocktypes))) {
|
||||
$undeletableblocktypes = array('navigation', 'settings');
|
||||
} else if (is_string($CFG->undeletableblocktypes)) {
|
||||
$undeletableblocktypes = explode(',', $CFG->undeletableblocktypes);
|
||||
} else {
|
||||
$undeletableblocktypes = $CFG->undeletableblocktypes;
|
||||
}
|
||||
|
||||
if (!empty($protect) && confirm_sesskey()) {
|
||||
if (!$block = $DB->get_record('block', array('id'=>$protect))) {
|
||||
print_error('blockdoesnotexist', 'error');
|
||||
}
|
||||
if (!in_array($block->name, $undeletableblocktypes)) {
|
||||
$undeletableblocktypes[] = $block->name;
|
||||
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
|
||||
}
|
||||
block_manager::protect_block((int)$protect);
|
||||
admin_get_root(true, false); // settings not required - only pages
|
||||
}
|
||||
|
||||
if (!empty($unprotect) && confirm_sesskey()) {
|
||||
if (!$block = $DB->get_record('block', array('id'=>$unprotect))) {
|
||||
print_error('blockdoesnotexist', 'error');
|
||||
}
|
||||
if (in_array($block->name, $undeletableblocktypes)) {
|
||||
$undeletableblocktypes = array_diff($undeletableblocktypes, array($block->name));
|
||||
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
|
||||
}
|
||||
block_manager::unprotect_block((int)$unprotect);
|
||||
admin_get_root(true, false); // settings not required - only pages
|
||||
}
|
||||
|
||||
$undeletableblocktypes = block_manager::get_undeletable_block_types();
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading($strmanageblocks);
|
||||
|
||||
|
116
lib/blocklib.php
116
lib/blocklib.php
@ -215,12 +215,14 @@ class block_manager {
|
||||
}
|
||||
|
||||
$unaddableblocks = self::get_undeletable_block_types();
|
||||
$requiredbythemeblocks = self::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) &&
|
||||
!in_array($block->name, $requiredbythemeblocks) &&
|
||||
($bi->instance_allow_multiple() || !$this->is_block_present($block->name)) &&
|
||||
blocks_name_allowed_in_format($block->name, $pageformat) &&
|
||||
$bi->user_can_addto($this->page)) {
|
||||
@ -376,6 +378,80 @@ class block_manager {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array names of block types that must exist on every page with this theme.
|
||||
*/
|
||||
public static function get_required_by_theme_block_types() {
|
||||
global $CFG, $PAGE;
|
||||
$requiredbythemeblocks = false;
|
||||
if (isset($PAGE->theme->requiredblocks)) {
|
||||
$requiredbythemeblocks = $PAGE->theme->requiredblocks;
|
||||
}
|
||||
|
||||
if ($requiredbythemeblocks === false) {
|
||||
return array('navigation', 'settings');
|
||||
} else if ($requiredbythemeblocks === '') {
|
||||
return array();
|
||||
} else if (is_string($requiredbythemeblocks)) {
|
||||
return explode(',', $requiredbythemeblocks);
|
||||
} else {
|
||||
return $requiredbythemeblocks;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this block type undeletable and unaddable.
|
||||
*
|
||||
* @param mixed $blockidorname string or int
|
||||
*/
|
||||
public static function protect_block($blockidorname) {
|
||||
global $DB;
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
|
||||
require_capability('moodle/site:config', $syscontext);
|
||||
|
||||
$block = false;
|
||||
if (is_int($blockidorname)) {
|
||||
$block = $DB->get_record('block', array('id' => $blockidorname), 'id, name', MUST_EXIST);
|
||||
} else {
|
||||
$block = $DB->get_record('block', array('name' => $blockidorname), 'id, name', MUST_EXIST);
|
||||
}
|
||||
$undeletableblocktypes = self::get_undeletable_block_types();
|
||||
if (!in_array($block->name, $undeletableblocktypes)) {
|
||||
$undeletableblocktypes[] = $block->name;
|
||||
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this block type deletable and addable.
|
||||
*
|
||||
* @param mixed $blockidorname string or int
|
||||
*/
|
||||
public static function unprotect_block($blockidorname) {
|
||||
global $DB;
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
|
||||
require_capability('moodle/site:config', $syscontext);
|
||||
|
||||
$block = false;
|
||||
if (is_int($blockidorname)) {
|
||||
$block = $DB->get_record('block', array('id' => $blockidorname), 'id, name', MUST_EXIST);
|
||||
} else {
|
||||
$block = $DB->get_record('block', array('name' => $blockidorname), 'id, name', MUST_EXIST);
|
||||
}
|
||||
$undeletableblocktypes = self::get_undeletable_block_types();
|
||||
if (in_array($block->name, $undeletableblocktypes)) {
|
||||
$undeletableblocktypes = array_diff($undeletableblocktypes, array($block->name));
|
||||
set_config('undeletableblocktypes', implode(',', $undeletableblocktypes));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of "protected" blocks via admin block manager ui.
|
||||
*
|
||||
* @return array names of block types that cannot be added or deleted. E.g. array('navigation','settings').
|
||||
*/
|
||||
public static function get_undeletable_block_types() {
|
||||
@ -383,13 +459,9 @@ class block_manager {
|
||||
$undeletableblocks = false;
|
||||
if (isset($CFG->undeletableblocktypes)) {
|
||||
$undeletableblocks = $CFG->undeletableblocktypes;
|
||||
} else if (isset($PAGE->theme->undeletableblocktypes)) {
|
||||
$undeletableblocks = $PAGE->theme->undeletableblocktypes;
|
||||
}
|
||||
|
||||
if ($undeletableblocks === false) {
|
||||
return array('navigation','settings');
|
||||
} else if ($undeletableblocks === '') {
|
||||
if (empty($undeletableblocks)) {
|
||||
return array();
|
||||
} else if (is_string($undeletableblocks)) {
|
||||
return explode(',', $undeletableblocks);
|
||||
@ -596,17 +668,18 @@ class block_manager {
|
||||
}
|
||||
|
||||
// Exclude auto created blocks if they are not undeletable in this theme.
|
||||
$undeletable = $this->get_undeletable_block_types();
|
||||
$undeletablecheck = '';
|
||||
$undeletableparams = array();
|
||||
$undeletablenotparams = array();
|
||||
if (!empty($undeletable)) {
|
||||
list($testsql, $undeletableparams) = $DB->get_in_or_equal($undeletable, SQL_PARAMS_NAMED, 'undeletable');
|
||||
list($testnotsql, $undeletablenotparams) = $DB->get_in_or_equal($undeletable, SQL_PARAMS_NAMED, 'deletable', false);
|
||||
$undeletablecheck = 'AND ((bi.blockname ' . $testsql . ' AND bi.requiredbytheme = 1) OR ' .
|
||||
$requiredbytheme = $this->get_required_by_theme_block_types();
|
||||
$requiredbythemecheck = '';
|
||||
$requiredbythemeparams = array();
|
||||
$requiredbythemenotparams = array();
|
||||
if (!empty($requiredbytheme)) {
|
||||
list($testsql, $requiredbythemeparams) = $DB->get_in_or_equal($requiredbytheme, SQL_PARAMS_NAMED, 'requiredbytheme');
|
||||
list($testnotsql, $requiredbythemenotparams) = $DB->get_in_or_equal($requiredbytheme, SQL_PARAMS_NAMED,
|
||||
'notrequiredbytheme', false);
|
||||
$requiredbythemecheck = 'AND ((bi.blockname ' . $testsql . ' AND bi.requiredbytheme = 1) OR ' .
|
||||
' (bi.blockname ' . $testnotsql . ' AND bi.requiredbytheme = 0))';
|
||||
} else {
|
||||
$undeletablecheck = 'AND (bi.requiredbytheme = 0)';
|
||||
$requiredbythemecheck = 'AND (bi.requiredbytheme = 0)';
|
||||
}
|
||||
|
||||
if (is_null($includeinvisible)) {
|
||||
@ -680,14 +753,14 @@ class block_manager {
|
||||
AND (bi.subpagepattern IS NULL OR bi.subpagepattern = :subpage2)
|
||||
$visiblecheck
|
||||
AND b.visible = 1
|
||||
$undeletablecheck
|
||||
$requiredbythemecheck
|
||||
|
||||
ORDER BY
|
||||
COALESCE(bp.region, bi.defaultregion),
|
||||
COALESCE(bp.weight, bi.defaultweight),
|
||||
bi.id";
|
||||
|
||||
$allparams = $params + $parentcontextparams + $pagetypepatternparams + $undeletableparams + $undeletablenotparams;
|
||||
$allparams = $params + $parentcontextparams + $pagetypepatternparams + $requiredbythemeparams + $requiredbythemenotparams;
|
||||
$blockinstances = $DB->get_recordset_sql($sql, $allparams);
|
||||
|
||||
$this->birecordsbyregion = $this->prepare_per_region_arrays();
|
||||
@ -992,7 +1065,7 @@ class block_manager {
|
||||
* chance to initialise themselves via the {@link block_base::specialize()}
|
||||
* method, before any output is done.
|
||||
*
|
||||
* It is also used to create any blocks that are "undeletable" by the current theme.
|
||||
* It is also used to create any blocks that are "requiredbytheme" by the current theme.
|
||||
* These blocks that are auto-created have requiredbytheme set on the block instance
|
||||
* so they are only visible on themes that require them.
|
||||
*/
|
||||
@ -1001,9 +1074,9 @@ class block_manager {
|
||||
$missing = false;
|
||||
|
||||
// If there are any un-removable blocks that were not created - force them.
|
||||
$undeletable = $this->get_undeletable_block_types();
|
||||
$requiredbytheme = $this->get_required_by_theme_block_types();
|
||||
if (!$this->fakeblocksonly) {
|
||||
foreach ($undeletable as $forced) {
|
||||
foreach ($requiredbytheme as $forced) {
|
||||
if (empty($forced)) {
|
||||
continue;
|
||||
}
|
||||
@ -1283,7 +1356,8 @@ class block_manager {
|
||||
protected function user_can_delete_block($block) {
|
||||
return $this->page->user_can_edit_blocks() && $block->user_can_edit() &&
|
||||
$block->user_can_addto($this->page) &&
|
||||
!in_array($block->instance->blockname, self::get_undeletable_block_types());
|
||||
!in_array($block->instance->blockname, self::get_undeletable_block_types()) &&
|
||||
!in_array($block->instance->blockname, self::get_required_by_theme_block_types());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2453,7 +2527,7 @@ function blocks_add_default_system_blocks() {
|
||||
|
||||
$page = new moodle_page();
|
||||
$page->set_context(context_system::instance());
|
||||
$page->blocks->add_blocks(array(BLOCK_POS_LEFT => block_manager::get_undeletable_block_types()), '*', null, true);
|
||||
// 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);
|
||||
|
||||
if ($defaultmypage = $DB->get_record('my_pages', array('userid' => null, 'name' => '__default', 'private' => 1))) {
|
||||
|
@ -349,10 +349,10 @@ class theme_config {
|
||||
public $doctype = 'html5';
|
||||
|
||||
/**
|
||||
* @var string undeletableblocktypes If set to a string, will list the block types that cannot be deleted. Defaults to
|
||||
* @var string requiredblocks If set to a string, will list the block types that cannot be deleted. Defaults to
|
||||
* navigation and settings.
|
||||
*/
|
||||
public $undeletableblocktypes = false;
|
||||
public $requiredblocks = false;
|
||||
|
||||
//==Following properties are not configurable from theme config.php==
|
||||
|
||||
@ -542,7 +542,7 @@ class theme_config {
|
||||
$configurable = array(
|
||||
'parents', 'sheets', 'parents_exclude_sheets', 'plugins_exclude_sheets',
|
||||
'javascripts', 'javascripts_footer', 'parents_exclude_javascripts',
|
||||
'layouts', 'enable_dock', 'enablecourseajax', 'undeletableblocktypes',
|
||||
'layouts', 'enable_dock', 'enablecourseajax', 'requiredblocks',
|
||||
'rendererfactory', 'csspostprocess', 'editor_sheets', 'rarrow', 'larrow', 'uarrow', 'darrow',
|
||||
'hidefromselector', 'doctype', 'yuicssmodules', 'blockrtlmanipulations',
|
||||
'lessfile', 'extralesscallback', 'lessvariablescallback', 'blockrendermethod',
|
||||
|
@ -545,6 +545,7 @@ class core_blocklib_testcase extends advanced_testcase {
|
||||
public function test_create_all_block_instances() {
|
||||
global $CFG, $PAGE, $DB;
|
||||
|
||||
$this->setAdminUser();
|
||||
$this->resetAfterTest();
|
||||
$regionname = 'side-pre';
|
||||
$context = context_system::instance();
|
||||
@ -557,6 +558,7 @@ class core_blocklib_testcase extends advanced_testcase {
|
||||
$blockmanager->load_blocks();
|
||||
$blockmanager->create_all_block_instances();
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
// Assert that we no auto created blocks in boost by default.
|
||||
$this->assertEmpty($blocks);
|
||||
// There should be no blocks in the DB.
|
||||
|
||||
@ -571,6 +573,7 @@ class core_blocklib_testcase extends advanced_testcase {
|
||||
$blockmanager->load_blocks();
|
||||
$blockmanager->create_all_block_instances();
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
// Assert that we no auto created blocks when viewing a fake blocks only page.
|
||||
$this->assertEmpty($blocks);
|
||||
|
||||
$PAGE->reset_theme_and_output();
|
||||
@ -581,10 +584,22 @@ class core_blocklib_testcase extends advanced_testcase {
|
||||
$blockmanager->load_blocks();
|
||||
$blockmanager->create_all_block_instances();
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
// Assert that we get the required block for this theme auto-created.
|
||||
$this->assertCount(2, $blocks);
|
||||
|
||||
$undeletable = block_manager::get_undeletable_block_types();
|
||||
foreach ($undeletable as $blockname) {
|
||||
$PAGE->reset_theme_and_output();
|
||||
list($page, $blockmanager) = $this->get_a_page_and_block_manager(array($regionname),
|
||||
$context, 'page-type');
|
||||
|
||||
$blockmanager->protect_block('html');
|
||||
$blockmanager->load_blocks();
|
||||
$blockmanager->create_all_block_instances();
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
// Assert that protecting a block does not make it auto-created.
|
||||
$this->assertCount(2, $blocks);
|
||||
|
||||
$requiredbytheme = block_manager::get_required_by_theme_block_types();
|
||||
foreach ($requiredbytheme as $blockname) {
|
||||
$instance = $DB->get_record('block_instances', array('blockname' => $blockname));
|
||||
$this->assertEquals(1, $instance->requiredbytheme);
|
||||
}
|
||||
@ -598,9 +613,10 @@ class core_blocklib_testcase extends advanced_testcase {
|
||||
$blockmanager->load_blocks();
|
||||
$blockmanager->create_all_block_instances();
|
||||
$blocks = $blockmanager->get_blocks_for_region($regionname);
|
||||
// Assert that we do not return requiredbytheme blocks when they are not required.
|
||||
$this->assertEmpty($blocks);
|
||||
// But they should exist in the DB.
|
||||
foreach ($undeletable as $blockname) {
|
||||
foreach ($requiredbytheme as $blockname) {
|
||||
$count = $DB->count_records('block_instances', array('blockname' => $blockname));
|
||||
$this->assertEquals(1, $count);
|
||||
}
|
||||
|
@ -151,5 +151,5 @@ $THEME->extrascsscallback = 'theme_boost_get_extra_scss';
|
||||
$THEME->prescsscallback = 'theme_boost_get_pre_scss';
|
||||
$THEME->yuicssmodules = array();
|
||||
$THEME->rendererfactory = 'theme_overridden_renderer_factory';
|
||||
$THEME->undeletableblocktypes = '';
|
||||
$THEME->requiredblocks = '';
|
||||
$THEME->addblockposition = BLOCK_ADDBLOCK_POSITION_FLATNAV;
|
||||
|
@ -35,7 +35,7 @@ information provided here is intended especially for theme designer.
|
||||
* A new class .text-ltr may be used to force the direction to LTR. This is especially useful
|
||||
for forms fields (numbers, emails, URLs must not be RTL'd), and for displaying code
|
||||
snippets or configuration samples.
|
||||
* A new theme config 'undeletableblocktypes' allows a theme to define which blocks are deletable.
|
||||
* A new theme config 'requiredblocks' allows a theme to define which blocks are deletable.
|
||||
* You may no longer override the following core_course_renderer methods.
|
||||
See course/upgrade.txt for more information:
|
||||
- course_modchooser_module_types
|
||||
|
Loading…
x
Reference in New Issue
Block a user