Merge branch '41551-27' of git://github.com/samhemelryk/moodle

This commit is contained in:
Dan Poltawski 2014-04-07 10:28:27 +08:00
commit 1c9e738b54
16 changed files with 232 additions and 33 deletions

View file

@ -56,17 +56,14 @@ $PAGE->set_context(context::instance_by_id($contextid));
// Setting layout to replicate blocks configuration for the page we edit.
$PAGE->set_pagelayout($pagelayout);
$PAGE->set_subpage($subpage);
$PAGE->blocks->add_custom_regions_for_pagetype($pagetype);
$pagetype = explode('-', $pagetype);
switch ($pagetype[0]) {
case 'my':
// My Home page needs to have 'content' block region set up.
$PAGE->set_blocks_editing_capability('moodle/my:manageblocks');
$PAGE->blocks->add_region('content');
break;
case 'user':
if ($pagelayout == 'mydashboard') {
// User profile pages also need the 'content' block region set up.
$PAGE->blocks->add_region('content');
// If it's not the current user's profile, we need a different capability.
if ($PAGE->context->contextlevel == CONTEXT_USER && $PAGE->context->instanceid != $USER->id) {
$PAGE->set_blocks_editing_capability('moodle/user:manageblocks');

View file

@ -394,12 +394,30 @@ class block_manager {
/**
* Add a region to a page
*
* @param string $region add a named region where blocks may appear on the
* current page. This is an internal name, like 'side-pre', not a string to
* display in the UI.
* @param string $region add a named region where blocks may appear on the current page.
* This is an internal name, like 'side-pre', not a string to display in the UI.
* @param bool $custom True if this is a custom block region, being added by the page rather than the theme layout.
*/
public function add_region($region) {
public function add_region($region, $custom = true) {
global $SESSION;
$this->check_not_yet_loaded();
if ($custom) {
if (array_key_exists($region, $this->regions)) {
// This here is EXACTLY why we should not be adding block regions into a page. It should
// ALWAYS be done in a theme layout.
debugging('A custom region conflicts with a block region in the theme.', DEBUG_DEVELOPER);
}
// We need to register this custom region against the page type being used.
// This allows us to check, when performing block actions, that unrecognised regions can be worked with.
$type = $this->page->pagetype;
if (!isset($SESSION->custom_block_regions)) {
$SESSION->custom_block_regions = array($type => array($region));
} else if (!isset($SESSION->custom_block_regions[$type])) {
$SESSION->custom_block_regions[$type] = array($region);
} else if (!in_array($region, $SESSION->custom_block_regions[$type])) {
$SESSION->custom_block_regions[$type][] = $region;
}
}
$this->regions[$region] = 1;
}
@ -409,9 +427,23 @@ class block_manager {
*
* @param array $regions this utility method calls add_region for each array element.
*/
public function add_regions($regions) {
public function add_regions($regions, $custom = true) {
foreach ($regions as $region) {
$this->add_region($region);
$this->add_region($region, $custom);
}
}
/**
* Finds custom block regions associated with a page type and registers them with this block manager.
*
* @param string $pagetype
*/
public function add_custom_regions_for_pagetype($pagetype) {
global $SESSION;
if (isset($SESSION->custom_block_regions[$pagetype])) {
foreach ($SESSION->custom_block_regions[$pagetype] as $customregion) {
$this->add_region($customregion, false);
}
}
}
@ -746,7 +778,7 @@ class block_manager {
* @param string $subpagepattern optional. Passed to @see add_block()
*/
public function add_blocks($blocks, $pagetypepattern = NULL, $subpagepattern = NULL, $showinsubcontexts=false, $weight=0) {
$this->add_regions(array_keys($blocks));
$this->add_regions(array_keys($blocks), false);
foreach ($blocks as $region => $regionblocks) {
$weight = 0;
foreach ($regionblocks as $blockname) {

View file

@ -380,6 +380,13 @@ class theme_config {
*/
public $lessvariablescallback = null;
/**
* Sets the render method that should be used for rendering custom block regions by scripts such as my/index.php
* Defaults to {@link core_renderer::blocks_for_region()}
* @var string
*/
public $blockrendermethod = null;
/**
* Load the config.php file for a particular theme, and return an instance
* of this class. (That is, this is a factory method.)
@ -448,7 +455,8 @@ class theme_config {
$configurable = array('parents', 'sheets', 'parents_exclude_sheets', 'plugins_exclude_sheets', 'javascripts', 'javascripts_footer',
'parents_exclude_javascripts', 'layouts', 'enable_dock', 'enablecourseajax', 'supportscssoptimisation',
'rendererfactory', 'csspostprocess', 'editor_sheets', 'rarrow', 'larrow', 'hidefromselector', 'doctype',
'yuicssmodules', 'blockrtlmanipulations', 'lessfile', 'extralesscallback', 'lessvariablescallback');
'yuicssmodules', 'blockrtlmanipulations', 'lessfile', 'extralesscallback', 'lessvariablescallback',
'blockrendermethod');
foreach ($config as $key=>$value) {
if (in_array($key, $configurable)) {
@ -1844,7 +1852,7 @@ class theme_config {
public function setup_blocks($pagelayout, $blockmanager) {
$layoutinfo = $this->layout_info_for_page($pagelayout);
if (!empty($layoutinfo['regions'])) {
$blockmanager->add_regions($layoutinfo['regions']);
$blockmanager->add_regions($layoutinfo['regions'], false);
$blockmanager->set_default_region($layoutinfo['defaultregion']);
}
}
@ -1899,6 +1907,32 @@ class theme_config {
public function get_theme_name() {
return get_string('pluginname', 'theme_'.$this->name);
}
/**
* Returns the block render method.
*
* It is set by the theme via:
* $THEME->blockrendermethod = '...';
*
* It can be one of two values, blocks or blocks_for_region.
* It should be set to the method being used by the theme layouts.
*
* @return string
*/
public function get_block_render_method() {
if ($this->blockrendermethod) {
// Return the specified block render method.
return $this->blockrendermethod;
}
// Its not explicitly set, check the parent theme configs.
foreach ($this->parent_configs as $config) {
if (isset($config->blockrendermethod)) {
return $config->blockrendermethod;
}
}
// Default it to blocks.
return 'blocks';
}
}
/**

View file

@ -3246,6 +3246,28 @@ EOD;
return html_writer::tag($tag, $content, $attributes);
}
/**
* Renders a custom block region.
*
* Use this method if you want to add an additional block region to the content of the page.
* Please note this should only be used in special situations.
* We want to leave the theme is control where ever possible!
*
* This method must use the same method that the theme uses within its layout file.
* As such it asks the theme what method it is using.
* It can be one of two values, blocks or blocks_for_region (deprecated).
*
* @param string $regionname The name of the custom region to add.
* @return string HTML for the block region.
*/
public function custom_block_region($regionname) {
if ($this->page->theme->get_block_render_method() === 'blocks') {
return $this->blocks($regionname);
} else {
return $this->blocks_for_region($regionname);
}
}
/**
* Returns the CSS classes to apply to the body tag.
*

View file

@ -43,6 +43,7 @@ class core_blocklib_testcase extends advanced_testcase {
parent::setUp();
$this->testpage = new moodle_page();
$this->testpage->set_context(context_system::instance());
$this->testpage->set_pagetype('phpunit-block-test');
$this->blockmanager = new testable_block_manager($this->testpage);
}
@ -69,7 +70,7 @@ class core_blocklib_testcase extends advanced_testcase {
public function test_add_region() {
// Exercise SUT.
$this->blockmanager->add_region('a-region-name');
$this->blockmanager->add_region('a-region-name', false);
// Validate.
$this->assertEquals(array('a-region-name'), $this->blockmanager->get_regions());
}
@ -78,15 +79,15 @@ class core_blocklib_testcase extends advanced_testcase {
// Set up fixture.
$regions = array('a-region', 'another-region');
// Exercise SUT.
$this->blockmanager->add_regions($regions);
$this->blockmanager->add_regions($regions, false);
// Validate.
$this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
}
public function test_add_region_twice() {
// Exercise SUT.
$this->blockmanager->add_region('a-region-name');
$this->blockmanager->add_region('another-region');
$this->blockmanager->add_region('a-region-name', false);
$this->blockmanager->add_region('another-region', false);
// Validate.
$this->assertEquals(array('a-region-name', 'another-region'), $this->blockmanager->get_regions(), '', 0, 10, true);
}
@ -95,6 +96,63 @@ class core_blocklib_testcase extends advanced_testcase {
* @expectedException coding_exception
*/
public function test_cannot_add_region_after_loaded() {
// Set up fixture.
$this->blockmanager->mark_loaded();
// Exercise SUT.
$this->blockmanager->add_region('too-late', false);
}
/**
* Testing adding a custom region.
*/
public function test_add_custom_region() {
global $SESSION;
// Exercise SUT.
$this->blockmanager->add_region('a-custom-region-name');
// Validate.
$this->assertEquals(array('a-custom-region-name'), $this->blockmanager->get_regions());
$this->assertTrue(isset($SESSION->custom_block_regions));
$this->assertArrayHasKey('phpunit-block-test', $SESSION->custom_block_regions);
$this->assertTrue(in_array('a-custom-region-name', $SESSION->custom_block_regions['phpunit-block-test']));
}
/**
* Test adding two custom regions using add_regions method.
*/
public function test_add_custom_regions() {
global $SESSION;
// Set up fixture.
$regions = array('a-region', 'another-custom-region');
// Exercise SUT.
$this->blockmanager->add_regions($regions);
// Validate.
$this->assertEquals($regions, $this->blockmanager->get_regions(), '', 0, 10, true);
$this->assertTrue(isset($SESSION->custom_block_regions));
$this->assertArrayHasKey('phpunit-block-test', $SESSION->custom_block_regions);
$this->assertTrue(in_array('another-custom-region', $SESSION->custom_block_regions['phpunit-block-test']));
}
/**
* Test adding two custom block regions.
*/
public function test_add_custom_region_twice() {
// Exercise SUT.
$this->blockmanager->add_region('a-custom-region-name');
$this->blockmanager->add_region('another-custom-region');
// Validate.
$this->assertEquals(
array('a-custom-region-name', 'another-custom-region'),
$this->blockmanager->get_regions(),
'', 0, 10, true
);
}
/**
* Test to ensure that we cannot add a region after the blocks have been loaded.
* @expectedException coding_exception
*/
public function test_cannot_add_custom_region_after_loaded() {
// Set up fixture.
$this->blockmanager->mark_loaded();
// Exercise SUT.
@ -103,7 +161,7 @@ class core_blocklib_testcase extends advanced_testcase {
public function test_set_default_region() {
// Set up fixture.
$this->blockmanager->add_region('a-region-name');
$this->blockmanager->add_region('a-region-name', false);
// Exercise SUT.
$this->blockmanager->set_default_region('a-region-name');
// Validate.
@ -149,7 +207,7 @@ class core_blocklib_testcase extends advanced_testcase {
$page->set_subpage($subpage);
$blockmanager = new testable_block_manager($page);
$blockmanager->add_regions($regions);
$blockmanager->add_regions($regions, false);
$blockmanager->set_default_region($regions[0]);
return array($page, $blockmanager);

View file

@ -18,7 +18,8 @@ CSS = {
SKIPBLOCK : 'skip-block',
SKIPBLOCKTO : 'skip-block-to',
MYINDEX : 'page-my-index',
REGIONMAIN : 'region-main'
REGIONMAIN : 'region-main',
BLOCKSMOVING : 'blocks-moving'
};
var SELECTOR = {
@ -166,6 +167,9 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
this.skipnodebottom = drag.get('node').next();
}
// Add the blocks-moving class so that the theme can respond if need be.
Y.one('body').addClass(CSS.BLOCKSMOVING);
},
drop_over : function(e) {
@ -210,11 +214,13 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
}
},
drop_end : function() {
drag_end : function() {
// clear variables
this.skipnodetop = null;
this.skipnodebottom = null;
this.dragsourceregion = null;
// Remove the blocks moving class once the drag-drop is over.
Y.one('body').removeClass(CSS.BLOCKSMOVING);
},
drag_dropmiss : function(e) {
@ -345,6 +351,9 @@ M.core.blockdraganddrop.is_using_blocks_render_method = function() {
var goodregions = Y.all('.block-region[data-blockregion]').size();
var allregions = Y.all('.block-region').size();
this._isusingnewblocksmethod = (allregions === goodregions);
if (goodregions > 0 && allregions > 0) {
Y.log('Both core_renderer::blocks and core_renderer::blocks_for_region have been used.', 'warn', 'moodle-core_blocks');
}
}
return this._isusingnewblocksmethod;
};
@ -359,8 +368,10 @@ M.core.blockdraganddrop.is_using_blocks_render_method = function() {
*/
M.core.blockdraganddrop.init = function(params) {
if (this.is_using_blocks_render_method()) {
Y.log('Block drag and drop initialised for the blocks method.', 'info', 'moodle-core_blocks');
new MANAGER(params);
} else {
Y.log('Block drag and drop initialised with the legacy manager (blocks_for_region used).', 'info', 'moodle-core_blocks');
new DRAGBLOCK(params);
}
};

File diff suppressed because one or more lines are too long

View file

@ -18,7 +18,8 @@ CSS = {
SKIPBLOCK : 'skip-block',
SKIPBLOCKTO : 'skip-block-to',
MYINDEX : 'page-my-index',
REGIONMAIN : 'region-main'
REGIONMAIN : 'region-main',
BLOCKSMOVING : 'blocks-moving'
};
var SELECTOR = {
@ -166,6 +167,9 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
this.skipnodebottom = drag.get('node').next();
}
// Add the blocks-moving class so that the theme can respond if need be.
Y.one('body').addClass(CSS.BLOCKSMOVING);
},
drop_over : function(e) {
@ -210,11 +214,13 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
}
},
drop_end : function() {
drag_end : function() {
// clear variables
this.skipnodetop = null;
this.skipnodebottom = null;
this.dragsourceregion = null;
// Remove the blocks moving class once the drag-drop is over.
Y.one('body').removeClass(CSS.BLOCKSMOVING);
},
drag_dropmiss : function(e) {
@ -345,6 +351,8 @@ M.core.blockdraganddrop.is_using_blocks_render_method = function() {
var goodregions = Y.all('.block-region[data-blockregion]').size();
var allregions = Y.all('.block-region').size();
this._isusingnewblocksmethod = (allregions === goodregions);
if (goodregions > 0 && allregions > 0) {
}
}
return this._isusingnewblocksmethod;
};

View file

@ -16,7 +16,8 @@ CSS = {
SKIPBLOCK : 'skip-block',
SKIPBLOCKTO : 'skip-block-to',
MYINDEX : 'page-my-index',
REGIONMAIN : 'region-main'
REGIONMAIN : 'region-main',
BLOCKSMOVING : 'blocks-moving'
};
var SELECTOR = {
@ -164,6 +165,9 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
if (drag.get('node').next() && drag.get('node').next().hasClass(CSS.SKIPBLOCKTO)) {
this.skipnodebottom = drag.get('node').next();
}
// Add the blocks-moving class so that the theme can respond if need be.
Y.one('body').addClass(CSS.BLOCKSMOVING);
},
drop_over : function(e) {
@ -208,11 +212,13 @@ Y.extend(DRAGBLOCK, M.core.dragdrop, {
}
},
drop_end : function() {
drag_end : function() {
// clear variables
this.skipnodetop = null;
this.skipnodebottom = null;
this.dragsourceregion = null;
// Remove the blocks moving class once the drag-drop is over.
Y.one('body').removeClass(CSS.BLOCKSMOVING);
},
drag_dropmiss : function(e) {
@ -343,6 +349,9 @@ M.core.blockdraganddrop.is_using_blocks_render_method = function() {
var goodregions = Y.all('.block-region[data-blockregion]').size();
var allregions = Y.all('.block-region').size();
this._isusingnewblocksmethod = (allregions === goodregions);
if (goodregions > 0 && allregions > 0) {
Y.log('Both core_renderer::blocks and core_renderer::blocks_for_region have been used.', 'warn', 'moodle-core_blocks');
}
}
return this._isusingnewblocksmethod;
};
@ -357,8 +366,10 @@ M.core.blockdraganddrop.is_using_blocks_render_method = function() {
*/
M.core.blockdraganddrop.init = function(params) {
if (this.is_using_blocks_render_method()) {
Y.log('Block drag and drop initialised for the blocks method.', 'info', 'moodle-core_blocks');
new MANAGER(params);
} else {
Y.log('Block drag and drop initialised with the legacy manager (blocks_for_region used).', 'info', 'moodle-core_blocks');
new DRAGBLOCK(params);
}
};

View file

@ -166,6 +166,6 @@ if ($currentpage->userid == 0) {
echo $OUTPUT->header();
echo $OUTPUT->blocks_for_region('content');
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();

View file

@ -63,6 +63,6 @@ $PAGE->set_subpage($currentpage->id);
echo $OUTPUT->header();
echo $OUTPUT->blocks_for_region('content');
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();

View file

@ -174,3 +174,7 @@ $THEME->hidefromselector = true;
/** List of javascript files that need to included on each page */
$THEME->javascripts = array();
$THEME->javascripts_footer = array();
// Set this to the method you will use in your layout files for rendering blocks.
// It should be either blocks (default) or blocks_for_region.
$THEME->blockrendermethod = 'blocks_for_region';

View file

@ -53,6 +53,12 @@ body {margin:auto 0px;width:auto;}
.side-post-only #page-content #region-pre {width:0px;}
.has_dock.side-post-only .page-middle #region-main {margin-left:200px;}
/** Moving block when side pre only **/
.blocks-moving.side-pre-only #page-content #region-post-box {margin-left:-400px;}
.blocks-moving.side-pre-only #page-content #region-main {margin-left:400px;}
.blocks-moving.side-pre-only #page-content #region-pre {left:200px;}
.blocks-moving.side-pre-only #page-content #region-post {width:200px;}
/** Moving block when side-post-only **/
.blocks-moving.side-post-only #page-content #region-main-box {left:200px;width:200%;}
.blocks-moving.side-post-only #page-content #region-post-box {margin-left:-400px;}

View file

@ -70,4 +70,21 @@ left: 210px;
.blocks-moving.side-post-only #page-content #region-post {
width: 210px;
}
/** Moving block when side pre only **/
.blocks-moving.side-pre-only #page-content #region-post-box {
margin-left:-420px;
}
.blocks-moving.side-pre-only #page-content #region-main {
margin-left:420px;
}
.blocks-moving.side-pre-only #page-content #region-pre {
left:210px;
}
.blocks-moving.side-pre-only #page-content #region-post {
width:210px;
}

View file

@ -437,9 +437,8 @@ if (!empty($CFG->enablebadges)) {
echo html_writer::end_tag('dl');
echo "</div></div>"; // Closing desriptionbox and userprofilebox.
echo '<div id="region-content" class="block-region"><div class="region-content">';
echo $OUTPUT->blocks_for_region('content');
echo '</div></div>';
echo $OUTPUT->custom_block_region('content');
// Print messaging link if allowed.
if (isloggedin() && has_capability('moodle/site:sendmessage', $context)

View file

@ -56,6 +56,6 @@ $PAGE->set_subpage($currentpage->id);
echo $OUTPUT->header();
echo $OUTPUT->blocks_for_region('content');
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();