Skip to content

Commit

Permalink
MDL-35964 blocks: prevent undeletable blocks being deleted!
Browse files Browse the repository at this point in the history
This commit simplifies the logic, so that $CFG->undeletableblocks
applies to all blocks, not just ones on certain page types in the
system context.

It also makes the setting apply to adding blocks, so you cannot
accidentally add a block that you cannot delete.
  • Loading branch information
timhunt committed Oct 12, 2012
1 parent ccd90e7 commit 1c76fc9
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 21 deletions.
6 changes: 4 additions & 2 deletions lang/en/admin.php
Expand Up @@ -76,8 +76,10 @@
$string['blockediplist'] = 'Blocked IP List';
$string['blockinstances'] = 'Instances';
$string['blockmultiple'] = 'Multiple';
$string['blockprotect'] = 'Protect from delete';
$string['blockprotect_help'] = 'Selected block instances will be protected from deletion from the site-wide context. This is primarily used to protect the navigation and settings blocks which can be very hard to get back if accidentally deleted.';
$string['blockprotect'] = 'Protect instances';
$string['blockprotect_help'] = 'If you lock a particular type of block, then no-one will be able to add or delete instances. (You can, of course, unlock again if you need to edit instances.)
This is intended to protect blocks like the navigation and settings which are very hard to get back if accidentally deleted.';
$string['blockunprotect'] = 'Unprotect';
$string['blocksettings'] = 'Manage blocks';
$string['bloglevel'] = 'Blog visibility';
Expand Down
50 changes: 31 additions & 19 deletions lib/blocklib.php
Expand Up @@ -224,12 +224,13 @@ public function get_addable_blocks() {
return $this->addableblocks;
}

$unaddableblocks = self::get_undeletable_block_types();
$pageformat = $this->page->pagetype;
foreach($allblocks as $block) {
if (!$bi = block_instance($block->name)) {
continue;
}
if ($block->visible &&
if ($block->visible && !in_array($block->name, $unaddableblocks) &&
($bi->instance_allow_multiple() || !$this->is_block_present($block->name)) &&
blocks_name_allowed_in_format($block->name, $pageformat) &&
$bi->user_can_addto($this->page)) {
Expand Down Expand Up @@ -373,6 +374,19 @@ public function get_installed_blocks() {
return $this->allblocks;
}

/**
* @return array names of block types that cannot be added or deleted. E.g. array('navigation','settings').
*/
public static function get_undeletable_block_types() {
if (!isset($CFG->undeletableblocktypes) || (!is_array($CFG->undeletableblocktypes) && !is_string($CFG->undeletableblocktypes))) {
return array('navigation','settings');
} else if (is_string($CFG->undeletableblocktypes)) {
return explode(',', $CFG->undeletableblocktypes);
} else {
return $CFG->undeletableblocktypes;
}
}

/// Setter methods =============================================================

/**
Expand Down Expand Up @@ -798,7 +812,7 @@ public function reposition_block($blockinstanceid, $newregion, $newweight) {
* Find a given block by its instance id
*
* @param integer $instanceid
* @return object
* @return block_base
*/
public function find_instance($instanceid) {
foreach ($this->regions as $region => $notused) {
Expand Down Expand Up @@ -1007,14 +1021,6 @@ protected function ensure_content_created($region, $output) {
public function edit_controls($block) {
global $CFG;

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;
}

$controls = array();
$actionurl = $this->page->url->out(false, array('sesskey'=> sesskey()));

Expand All @@ -1030,14 +1036,10 @@ public function edit_controls($block) {
'icon' => 't/edit', 'caption' => get_string('configuration'), 'class' => 'editing_edit');
}

if ($this->page->user_can_edit_blocks() && $block->user_can_edit() && $block->user_can_addto($this->page)) {
if (!in_array($block->instance->blockname, $undeletableblocktypes)
|| !in_array($block->instance->pagetypepattern, array('*', 'site-index'))
|| $block->instance->parentcontextid != SITEID) {
// Delete icon.
$controls[] = array('url' => $actionurl . '&bui_deleteid=' . $block->instance->id,
'icon' => 't/delete', 'caption' => get_string('delete'), 'class' => 'editing_delete');
}
if ($this->user_can_delete_block($block)) {
// Delete icon.
$controls[] = array('url' => $actionurl . '&bui_deleteid=' . $block->instance->id,
'icon' => 't/delete', 'caption' => get_string('delete'), 'class' => 'editing_delete');
}

if ($this->page->user_can_edit_blocks() && $block->instance_can_be_hidden()) {
Expand Down Expand Up @@ -1067,6 +1069,16 @@ public function edit_controls($block) {
return $controls;
}

/**
* @param block_base $block a block that appears on this page.
* @return boolean boolean whether the currently logged in user is allowed to delete this block.
*/
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());
}

/**
* Process any block actions that were specified in the URL.
*
Expand Down Expand Up @@ -1125,7 +1137,7 @@ public function process_url_delete() {

require_sesskey();
$block = $this->page->blocks->find_instance($blockid);
if (!$block->user_can_edit() || !$this->page->user_can_edit_blocks() || !$block->user_can_addto($this->page)) {
if (!$this->user_can_delete_block($block)) {
throw new moodle_exception('nopermissions', '', $this->page->url->out(), get_string('deleteablock'));
}

Expand Down

0 comments on commit 1c76fc9

Please sign in to comment.