Skip to content

Commit

Permalink
blocks: MDL-19893 move blocks on page UI - part 2
Browse files Browse the repository at this point in the history
This updates the DB.

I beleive this is correct, but it is very hairy and badly needs unit tests.
  • Loading branch information
tjhunt committed Jul 30, 2009
1 parent 1d7e341 commit 2cdb8d8
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 6 deletions.
7 changes: 3 additions & 4 deletions blocks/edit_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_edit_form extends moodleform {
const MAX_WEIGHT = 10;
/**
* The block instance we are editing.
* @var block_base
Expand Down Expand Up @@ -66,13 +65,13 @@ function definition() {
// If the current weight of the block is out-of-range, add that option in.
$blockweight = $this->block->instance->weight;
$weightoptions = array();
if ($blockweight < -self::MAX_WEIGHT) {
if ($blockweight < -block_manager::MAX_WEIGHT) {
$weightoptions[$blockweight] = $blockweight;
}
for ($i = -self::MAX_WEIGHT; $i <= self::MAX_WEIGHT; $i++) {
for ($i = -block_manager::MAX_WEIGHT; $i <= block_manager::MAX_WEIGHT; $i++) {
$weightoptions[$i] = $i;
}
if ($blockweight > self::MAX_WEIGHT) {
if ($blockweight > block_manager::MAX_WEIGHT) {
$weightoptions[$blockweight] = $blockweight;
}
$first = reset($weightoptions);
Expand Down
1 change: 1 addition & 0 deletions lang/en_utf8/error.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@
$string['unknowcategory'] = 'Category not known!';
$string['unknowcontext'] = 'This is an unknown context ($a) in get_child_contexts!';
$string['unknowformat'] = 'Format not known ($a)';
$string['unknownblockregion'] = 'The block region \'$a\' is not recognised on this page.';
$string['unknowncourse'] = 'Unknown course named \"$a\"';
$string['unknowncourseidnumber'] = 'Unknown Course ID \"$a\"';
$string['unknowncourserequest'] = 'Unknown course request';
Expand Down
125 changes: 123 additions & 2 deletions lib/blocklib.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public function __construct($instanceid, $page) {
* @since Moodle 2.0
*/
class block_manager {
/**
* The UI normally only shows block weights between -MAX_WEIGHT and MAX_WEIGHT,
* although other weights are valid.
*/
const MAX_WEIGHT = 10;

/// Field declarations =========================================================

Expand Down Expand Up @@ -591,6 +596,67 @@ public function add_blocks($blocks, $pagetypepattern = NULL, $subpagepattern = N
}
}

/**
* Move a block to a new position on this page.
*
* If this block cannot appear on any other pages, then we change defaultposition/weight
* in the block_instances table. Otherwise we just set the postition on this page.
*
* @param $blockinstanceid the block instance id.
* @param $newregion the new region name.
* @param $newweight the new weight.
*/
public function reposition_block($blockinstanceid, $newregion, $newweight) {
global $DB;

$this->check_region_is_known($newregion);
$inst = $this->find_instance($blockinstanceid);

$bi = $inst->instance;
if ($bi->weight == $bi->defaultweight && $bi->region == $bi->defaultregion &&
!$bi->showinsubcontexts && strpos($bi->pagetypepattern, '*') === false &&
(!$this->page->subpage || $bi->subpagepattern)) {

// Set default position
$newbi = new stdClass;
$newbi->id = $bi->id;
$newbi->defaultregion = $newregion;
$newbi->defaultweight = $newweight;
$DB->update_record('block_instances', $newbi);

if ($bi->blockpositionid) {
$bp = new stdClass;
$bp->id = $bi->blockpositionid;
$bp->region = $newregion;
$bp->weight = $newweight;
$DB->update_record('block_positions', $bp);
}

} else {
// Just set position on this page.
$bp = new stdClass;
$bp->region = $newregion;
$bp->weight = $newweight;

if ($bi->blockpositionid) {
$bp->id = $bi->blockpositionid;
$DB->update_record('block_positions', $bp);

} else {
$bp->blockinstanceid = $bi->id;
$bp->contextid = $this->page->context->id;
$bp->pagetype = $this->page->pagetype;
if ($this->page->subpage) {
$bp->subpage = $this->page->subpage;
} else {
$bp->subpage = '';
}
$bp->visible = $bi->visible;
$DB->insert_record('block_positions', $bp);
}
}
}

/**
* Find a given block by its instance id
*
Expand Down Expand Up @@ -1105,8 +1171,63 @@ public function process_url_move() {
return false;
}

// Work out if we should be setting defaultposition or just position on this page.
// TODO$block = $this->
if (!$this->is_known_region($newregion)) {
throw new moodle_exception('unknownblockregion', '', $this->page->url, $newregion);
}

// Move this block. This may involve moving other nearby blocks.
$blocks = $this->birecordsbyregion[$newregion];

// First we find the nearest gap in the list of weights.
$spareweights = array();
$usedweights = array();
for ($i = -self::MAX_WEIGHT; $i <= self::MAX_WEIGHT; $i++) {
$spareweights[$i] = $i;
$usedweights[$i] = array();
}
foreach ($blocks as $bi) {
if ($bi->id == $block->instance->id) {
continue;
}
unset($spareweights[$bi->weight]);
$usedweights[$bi->weight][] = $bi->id;
}

$bestdistance = max(abs($newweight - self::MAX_WEIGHT), abs($newweight + self::MAX_WEIGHT)) + 1;
$bestgap = null;
foreach ($spareweights as $spareweight) {
if (abs($newweight - $spareweight) < $bestdistance) {
$bestdistance = abs($newweight - $spareweight);
$bestgap = $spareweight;
}
}

// If there is no gap, we have to go outside -self::MAX_WEIGHT .. self::MAX_WEIGHT.
if (is_null($bestgap)) {
$bestgap = self::MAX_WEIGHT + 1;
while (!empty($usedweights[$bestgap])) {
$bestgap++;
}
}

// Now we know the gap we are aiming for, so move all the blocks along.
if ($bestgap < $newweight) {
$newweight = floor($newweight);
for ($weight = $bestgap + 1; $weight <= $newweight; $weight++) {
foreach ($usedweights[$weight] as $biid) {
$this->reposition_block($biid, $newregion, $weight - 1);
}
}
$this->reposition_block($block->instance->id, $newregion, $newweight);
} else {
$newweight = ceil($newweight);
for ($weight = $bestgap - 1; $weight >= $newweight; $weight--) {
foreach ($usedweights[$weight] as $biid) {
$this->reposition_block($biid, $newregion, $weight + 1);
}
}
$this->reposition_block($block->instance->id, $newregion, $newweight);
}

$this->page->ensure_param_not_in_url('bui_moveid');
$this->page->ensure_param_not_in_url('bui_newregion');
Expand Down

0 comments on commit 2cdb8d8

Please sign in to comment.