';
- print_footer();
- } else {
- admin_externalpage_print_footer();
- }
-
-?>
diff --git a/blocks/moodleblock.class.php b/blocks/moodleblock.class.php
index 1ab1eae8bc4..9f1bf0159db 100644
--- a/blocks/moodleblock.class.php
+++ b/blocks/moodleblock.class.php
@@ -331,81 +331,95 @@ class block_base {
}
/**
- * Display the block!
- */
- function _print_block() {
- global $COURSE;
-
- // is_empty() includes a call to get_content()
- if ($this->is_empty() && empty($COURSE->javascriptportal)) {
- if (empty($this->edit_controls)) {
- // No content, no edit controls, so just shut up
- return;
- } else {
- // No content but editing, so show something at least
- $this->_print_shadow();
- }
- } else {
- if ($this->hide_header() && empty($this->edit_controls)) {
- // Header wants to hide, no edit controls to show, so no header it is
- print_side_block(NULL, $this->content->text, NULL, NULL, $this->content->footer, $this->html_attributes());
- } else {
- // The full treatment, please. Include the title text.
- print_side_block($this->_title_html(), $this->content->text, NULL, NULL, $this->content->footer, $this->html_attributes(), $this->title);
- }
- }
- }
-
- /**
- * Block contents are missing. Simply display an empty block so that
- * edit controls are accessbile to the user and they are aware that this
- * block is in place, even if empty.
- */
- function _print_shadow() {
- print_side_block($this->_title_html(), ' ', NULL, NULL, '', array('class' => 'hidden'), $this->title);
- }
-
-
- function _title_html() {
- global $OUTPUT;
-
- //Accessibility: validation, can't have
';
- $this->edit_controls = $movebuttons;
+ return $controls;
}
/**
@@ -556,7 +534,6 @@ class block_base {
* Default behavior: print the config_global.html file
* You don't need to override this if you're satisfied with the above
*
- * @uses $CFG
* @return boolean
*/
function config_print() {
@@ -597,14 +574,6 @@ class block_base {
}
- /**
- * Default case: the block wants to be 180 pixels wide
- * @return int
- */
- function preferred_width() {
- return 180;
- }
-
/**
* Default return is false - header will be shown
* @return boolean
@@ -614,18 +583,17 @@ class block_base {
}
/**
- * Default case: an id with the instance and a class with our name in it
- * @return array
- * @todo finish documenting this function
+ * Return any HTML attributes that you want added to the outer
that
+ * of the block when it is output.
+ * @return array attribute name => value.
*/
function html_attributes() {
return array(
- 'id' => 'inst'.$this->instance->id,
- 'class' => 'block_'. $this->name().
- ($this->edit_controls ? ' block_with_controls' :'')
+ 'id' => 'inst' . $this->instance->id,
+ 'class' => 'block_' . $this->name()
);
}
-
+
/**
* Given an instance set the class var $instance to it and
* load class var $config
@@ -727,7 +695,7 @@ class block_base {
$this->instance_config_save($this->config);
}
- /**
+ /**
* Do any additional initialization you may need at the time a new block instance is created
* @return boolean
* @todo finish documenting this function
@@ -736,7 +704,7 @@ class block_base {
return true;
}
- /**
+ /**
* Delete everything related to this instance if you have been using persistent storage other than the configdata field.
* @return boolean
* @todo finish documenting this function
@@ -745,7 +713,7 @@ class block_base {
return true;
}
- /**
+ /**
* Allows the block class to have a say in the user's ability to edit (i.e., configure) blocks of this type.
* The framework has first say in whether this will be allowed (e.g., no editing allowed unless in edit mode)
* but if the framework does allow it, the block can still decide to refuse.
@@ -756,7 +724,7 @@ class block_base {
return true;
}
- /**
+ /**
* Allows the block class to have a say in the user's ability to create new instances of this block.
* The framework has first say in whether this will be allowed (e.g., no adding allowed unless in edit mode)
* but if the framework does allow it, the block can still decide to refuse.
@@ -771,11 +739,54 @@ class block_base {
function get_extra_capabilities() {
return array('moodle/block:view');
}
+
+ // Methods deprecated in Moodle 2.0 ========================================
+
+ /**
+ * Default case: the block wants to be 180 pixels wide
+ * @deprecated since Moodle 2.0.
+ * @return int
+ */
+ function preferred_width() {
+ return 180;
+ }
+
+ /** @deprecated since Moodle 2.0. */
+ function _print_block() {
+ throw new coding_exception('_print_block is no longer used. It was a private ' .
+ 'method of the block class, only for use by the blocks system. You ' .
+ 'should not have been calling it anyway.');
+ }
+
+ /** @deprecated since Moodle 2.0. */
+ function _print_shadow() {
+ throw new coding_exception('_print_shadow is no longer used. It was a private ' .
+ 'method of the block class, only for use by the blocks system. You ' .
+ 'should not have been calling it anyway.');
+ }
+
+ /** @deprecated since Moodle 2.0. */
+ function _title_html() {
+ throw new coding_exception('_title_html is no longer used. It was a private ' .
+ 'method of the block class, only for use by the blocks system. You ' .
+ 'should not have been calling it anyway.');
+ }
+
+ /** @deprecated since Moodle 2.0. */
+ function _add_edit_controls() {
+ throw new coding_exception('_add_edit_controls is no longer used. It was a private ' .
+ 'method of the block class, only for use by the blocks system. You ' .
+ 'should not have been calling it anyway.');
+ }
+
}
/**
* Specialized class for displaying a block with a list of icons/text labels
*
+ * The get_content method should set $this->content->items and (optionally)
+ * $this->content->icons, instead of $this->content->text.
+ *
* @author Jon Papaioannou
* @package blocks
*/
@@ -801,31 +812,14 @@ class block_list extends block_base {
return (empty($this->content->items) && empty($this->content->footer));
}
- function _print_block() {
- global $COURSE;
-
- // is_empty() includes a call to get_content()
- if ($this->is_empty() && empty($COURSE->javascriptportal)) {
- if (empty($this->edit_controls)) {
- // No content, no edit controls, so just shut up
- return;
- } else {
- // No content but editing, so show something at least
- $this->_print_shadow();
- }
+ protected function formatted_contents($output) {
+ $this->get_content();
+ if (!empty($this->content->items)) {
+ return $output->list_block_contents($this->content->icons, $this->content->items);
} else {
- if ($this->hide_header() && empty($this->edit_controls)) {
- // Header wants to hide, no edit controls to show, so no header it is
- print_side_block(NULL, '', $this->content->items, $this->content->icons,
- $this->content->footer, $this->html_attributes());
- } else {
- // The full treatment, please. Include the title text.
- print_side_block($this->_title_html(), '', $this->content->items, $this->content->icons,
- $this->content->footer, $this->html_attributes(), $this->title);
- }
+ return '';
}
}
-
}
?>
diff --git a/blog/footer.php b/blog/footer.php
index d01553e1a95..9ffb57d2dff 100644
--- a/blog/footer.php
+++ b/blog/footer.php
@@ -1,27 +1,6 @@
-
-
-'."\n";
-
-// The right column
-if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing) {
- echo '
';
- print_container_end();
- }
-
-/// The right column, BEFORE the middle-column.
- if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing) {
- print_container_start();
- echo '
';
- print_container_start();
-
- echo skip_main_destination();
//Print the Your progress icon if the track completion is enabled
$completioninfo = new completion_info($course);
@@ -123,7 +85,7 @@
// Note, 'right side' is BEFORE content.
echo '
';
- print_container_start(true);
- $THEME->open_header_containers++; // this is hacky workaround for the print_error()/notice() autoclosing problems on admin pages
- break;
-
- case 'right':
- if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT)) {
- echo '
';
- }
+// Still 103 referernces in core code. Don't do debugging output yet.
+// debugging('admin_externalpage_print_footer is deprecated. Please use print_footer ' .
+// '(or even $OUTPUT->footer() instead.', DEBUG_DEVELOPER);
print_footer();
}
diff --git a/lib/ajax/ajaxlib.php b/lib/ajax/ajaxlib.php
index 897f12986a8..1e88bcac94c 100644
--- a/lib/ajax/ajaxlib.php
+++ b/lib/ajax/ajaxlib.php
@@ -51,6 +51,8 @@ function setup_core_javascript(page_requirements_manager $requires) {
$requires->yui_lib('logger');
}
+ $requires->skip_link_to('maincontent', get_string('tocontent', 'access'));
+
// Note that, as a short-cut, the code
// $js = "document.body.className += ' jsenabled';\n";
// is hard-coded in {@link page_requirements_manager::get_top_of_body_code)
diff --git a/lib/blocklib.php b/lib/blocklib.php
index 0f505cbb9f9..02cb6af8ca4 100644
--- a/lib/blocklib.php
+++ b/lib/blocklib.php
@@ -18,16 +18,16 @@
/**
* Block Class and Functions
*
- * @todo Document what this file does
- *
+ * This file defines the {@link block_manager} class,
+ *
* @package moodlecore
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
- /**
- * Block Defines
- */
+/**
+ * Block Defines
+ */
define('BLOCK_MOVE_LEFT', 0x01);
define('BLOCK_MOVE_RIGHT', 0x02);
define('BLOCK_MOVE_UP', 0x04);
@@ -41,19 +41,19 @@ define('BLOCKS_PINNED_TRUE',0);
define('BLOCKS_PINNED_FALSE',1);
define('BLOCKS_PINNED_BOTH',2);
-require_once($CFG->libdir.'/pagelib.php');
-
/**
+ * Exception thrown when someone tried to do something with a block that does
+ * not exist on a page.
*
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @package moodlecore
+ * @copyright 2009 Tim Hunt
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since Moodle 2.0
*/
class block_not_on_page_exception extends moodle_exception {
/**
* Contructor
- *
- * @param int $instanceid
- * @param object $page
+ * @param int $instanceid the block instance id of the block that was looked for.
+ * @param object $page the current page.
*/
public function __construct($instanceid, $page) {
$a = new stdClass;
@@ -64,47 +64,36 @@ class block_not_on_page_exception extends moodle_exception {
}
/**
- * Block Manager
- *
* This class keeps track of the block that should appear on a moodle_page.
+ *
* The page to work with as passed to the constructor.
- * The only fields of moodle_page that is uses are ->context, ->pagetype and
- * ->subpage, so instead of passing a full moodle_page object, you may also
- * pass a stdClass object with those three fields. These field values are read
- * only at the point that the load_blocks() method is called. It is the caller's
- * responsibility to ensure that those fields do not subsequently change.
*
- *
- * Note about the weird 'implements ArrayAccess' part of the declaration:
- *
- * ArrayAccess is a magic PHP5 thing. If your class implements the ArrayAccess
- * interface, then other code can use the $object[$index] syntax, and it will
- * call the offsetGet method of the object.
- * See http://php.net/manual/en/class.arrayaccess.php
- *
- * So, why do we do this here? Basically, some of the deprecated blocks methods
- * like blocks_setup used to return an array of blocks on the page, with array
- * keys BLOCK_POS_LEFT, BLOCK_POS_RIGHT. We can keep legacy code that calls those
- * deprecated functions mostly working by changing blocks_setup to return the
- * block_manger object, and then use 'implements ArrayAccess' so that the right
- * thing happens when legacy code does something like $pageblocks[BLOCK_POS_LEFT].
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @package moodlecore
+ * @copyright 2009 Tim Hunt
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ * @since Moodle 2.0
*/
-class block_manager implements ArrayAccess {
+class block_manager {
/// Field declarations =========================================================
- /** @var object */
+
+ /** @var moodle_page the moodle_page we aremanaging blocks for. */
protected $page;
- /** @var array */
+
+ /** @var array region name => 1.*/
protected $regions = array();
- /** @var string */
- protected $defaultregion;
- /** @var array */
- protected $allblocks = null; // Will be get_records('blocks');
- /** @var array */
- protected $addableblocks = null; // Will be a subset of $allblocks.
+
+ /** @var string the region where new blocks are added.*/
+ protected $defaultregion = null;
+
+ /** @var array will be $DB->get_records('blocks') */
+ protected $allblocks = null;
+
+ /**
+ * @var array blocks that this user can add to this page. Will be a subset
+ * of $allblocks. Access this via the {@link get_addable_blocks()} method
+ * to ensure it is lazy-loaded.
+ */
+ protected $addableblocks = null;
/**
* Will be an array region-name => array(db rows loaded in load_blocks);
@@ -120,12 +109,19 @@ class block_manager implements ArrayAccess {
protected $blockinstances = array();
/**
- * array region-name => array(block_content objects) what acutally needs to
+ * array region-name => array(block_contents objects) what acutally needs to
* be displayed in each region.
* @var array
*/
protected $visibleblockcontent = array();
+ /**
+ * array region-name => array(block_contents objects) extra block-like things
+ * to be displayed in each region, before the real blocks.
+ * @var array
+ */
+ protected $extracontent = array();
+
/// Constructor ================================================================
/**
@@ -146,6 +142,7 @@ class block_manager implements ArrayAccess {
* @return array the internal names of the regions on this page where block may appear.
*/
public function get_regions() {
+ $this->page->initialise_theme_and_output();
return array_keys($this->regions);
}
@@ -158,6 +155,7 @@ class block_manager implements ArrayAccess {
* to a theme with different block positions.)
*/
public function get_default_region() {
+ $this->page->initialise_theme_and_output();
return $this->defaultregion;
}
@@ -243,19 +241,37 @@ class block_manager implements ArrayAccess {
/**
* Returns an array of block content objects that exist in a region
*
- * @param $region a block region that exists on this page.
- * @return array of block block_content objects for all the blocks in a region.
+ * @param string $region a block region that exists on this page.
+ * @return array of block block_contents objects for all the blocks in a region.
*/
- public function get_content_for_region($region) {
+ public function get_content_for_region($region, $output) {
$this->check_is_loaded();
- $this->ensure_content_created($region);
+ $this->ensure_content_created($region, $output);
return $this->visibleblockcontent[$region];
}
+ /**
+ * Determine whether a region contains anything. (Either any real blocks, or
+ * the add new block UI.)
+ * @param string $region a block region that exists on this page.
+ * @return boolean Whether there is anything in this region.
+ */
+ public function region_has_content($region) {
+ if (!$this->is_known_region($region)) {
+ return false;
+ }
+ $this->check_is_loaded();
+ if ($this->page->user_is_editing() && $this->page->user_can_edit_blocks()) {
+ // If editing is on, we need all the block regions visible, for the
+ // move blocks UI.
+ return true;
+ }
+ return !empty($this->blockinstances[$region]) || !empty($this->extracontent[$region]);
+ }
+
/**
* Get an array of all of the installed blocks.
*
- * @global object
* @return array contents of the block table.
*/
public function get_installed_blocks() {
@@ -305,16 +321,29 @@ class block_manager implements ArrayAccess {
$this->defaultregion = $defaultregion;
}
+ /**
+ * Add something that looks like a block, but which isn't an actual block_instance,
+ * to this page.
+ *
+ * @param block_contents $bc the content of the block like thing.
+ * @param string $region a block region that exists on this page.
+ */
+ public function add_pretend_block($bc, $region) {
+ $this->page->initialise_theme_and_output();
+ $this->check_region_is_known($region);
+ if (array_key_exists($region, $this->visibleblockcontent)) {
+ throw new coding_exception('block_manager has already prepared the blocks in region ' .
+ $region . 'for output. It is too late to add a pretend block.');
+ }
+ $this->extracontent[$region][] = $bc;
+ }
+
/// Actions ====================================================================
/**
* This method actually loads the blocks for our page from the database.
*
- * @global object
- * @global object
- * @uses SQL_PARAMS_NAMED
* @param bool|null $includeinvisible
- * @return void
*/
public function load_blocks($includeinvisible = NULL) {
global $DB, $CFG;
@@ -329,8 +358,14 @@ class block_manager implements ArrayAccess {
return;
}
+ // Ensure we have been initialised.
if (!isset($this->defaultregion)) {
$this->page->initialise_theme_and_output();
+ // If there are still no block regions, then there are no blocks on this page.
+ if (empty($this->regions)) {
+ $this->birecordsbyregion = array();
+ return;
+ }
}
if (is_null($includeinvisible)) {
@@ -365,6 +400,7 @@ class block_manager implements ArrayAccess {
);
$sql = "SELECT
bi.id,
+ bp.id AS blockpositionid,
bi.blockname,
bi.contextid,
bi.showinsubcontexts,
@@ -404,16 +440,20 @@ class block_manager implements ArrayAccess {
$unknown[] = $bi;
}
}
- $this->birecordsbyregion[$this->defaultregion] = array_merge($this->birecordsbyregion[$this->defaultregion], $unknown);
+
+ // Pages don't necessarily have a defaultregion. The one time this can
+ // happen is when there are no theme block regions, but the script itself
+ // has a block region in the main content area.
+ if (!empty($this->defaultregion)) {
+ $this->birecordsbyregion[$this->defaultregion] =
+ array_merge($this->birecordsbyregion[$this->defaultregion], $unknown);
+ }
}
/**
* Add a block to the current page, or related pages. The block is added to
* context $this->page->contextid. If $pagetypepattern $subpagepattern
*
- * @global object
- * @uses CONTEXT_COURSE
- * @uses CONTEXT_BLOCK
* @param string $blockname The type of block to add.
* @param string $region the block region on this page to add the block to.
* @param integer $weight determines the order where this block appears in the region.
@@ -600,14 +640,10 @@ class block_manager implements ArrayAccess {
* @param array $instances An array of block instances
* @return array An array of content vars
*/
- protected function create_block_content($instances) {
+ protected function create_block_contents($instances, $output) {
$results = array();
foreach ($instances as $instance) {
- if ($instance->is_empty()) {
- continue;
- }
-
- $content = $instance->get_content();
+ $content = $instance->get_content_for_output($output);
if (!empty($content)) {
$results[] = $content;
}
@@ -615,6 +651,46 @@ class block_manager implements ArrayAccess {
return $results;
}
+ /**
+ * Return a {@link block_contents} representing the add a new block UI, if
+ * this user is allowed to see it.
+ *
+ * @return block_contents an appropriate block_contents, or null if the user
+ * cannot add any blocks here.
+ */
+ function add_block_ui($output) {
+ global $CFG;
+ if (!$this->page->user_is_editing() || !$this->page->user_can_edit_blocks()) {
+ return null;
+ }
+
+ $bc = new block_contents();
+ $bc->title = get_string('addblock');
+ $bc->add_class('block_adminblock');
+
+ $missingblocks = array_keys($this->get_addable_blocks());
+ if (empty($missingblocks)) {
+ $bc->title = get_string('noblockstoaddhere');
+ return $bc;
+ }
+
+ $menu = array();
+ foreach ($missingblocks as $blockid) {
+ $block = blocks_get_record($blockid);
+ $blockobject = block_instance($block->name);
+ if ($blockobject !== false && $blockobject->user_can_addto($page)) {
+ $menu[$block->id] = $blockobject->get_title();
+ }
+ }
+ asort($menu, SORT_LOCALE_STRING);
+
+ // TODO convert to $OUTPUT.
+ $returnurlparam = '&returnurl=' . urlencode($this->page->url->out_returnurl());
+ $actionurl = $CFG->wwwroot . '/blocks/add.php?sesskey=' . sesskey() . $returnurlparam . '&blocktype=';
+ $bc->content = popup_form($actionurl, $menu, 'add_block', '', get_string('adddots'), '', '', true);
+ return $bc;
+ }
+
/**
* Ensure block instances exist for a given region
*
@@ -633,66 +709,23 @@ class block_manager implements ArrayAccess {
*
* @param string $region The name of the region to check
*/
- protected function ensure_content_created($region) {
+ protected function ensure_content_created($region, $output) {
$this->ensure_instances_exist($region);
if (!array_key_exists($region, $this->visibleblockcontent)) {
- $this->visibleblockcontent[$region] =
- $this->create_block_content($this->blockinstances[$region]);
+ $contents = array();
+ if (array_key_exists($region, $this->extracontent)) {
+ $contents = $this->extracontent[$region];
+ }
+ $contents = array_merge($contents, $this->create_block_contents($this->blockinstances[$region], $output));
+ if ($region == $this->defaultregion) {
+ $addblockui = $this->add_block_ui($output);
+ if ($addblockui) {
+ $contents[] = $addblockui;
+ }
+ }
+ $this->visibleblockcontent[$region] = $contents;
}
}
-
-/// Deprecated stuff for backwards compatibility ===============================
- /** @deprecated Remains to ensure backwards compatibility */
- public function offsetSet($offset, $value) {
- }
- /** @deprecated Remains to ensure backwards compatibility */
- public function offsetExists($offset) {
- return $this->is_known_region($offset);
- }
- /** @deprecated Remains to ensure backwards compatibility */
- public function offsetUnset($offset) {
- }
- /** @deprecated Remains to ensure backwards compatibility */
- public function offsetGet($offset) {
- return $this->get_blocks_for_region($offset);
- }
-}
-
-/**
- * This class holds all the information required to view a block.
- *
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- * @package moodlecore
- */
-abstract class block_content {
- /** @var int Id used to uniquely identify this block in the HTML. */
- public $id = null;
- /** @var array Class names to add to this block's container in the HTML. */
- public $classes = array();
- /** @var string The content that appears in the title bar at the top of the block (HTML). */
- public $heading = null;
- /** @var string Plain text name of this block instance, used in the skip links. */
- public $title = null;
- /**
- * A (possibly empty) array of editing controls. Array keys should be a
- * short string, e.g. 'edit', 'move' and the values are the HTML of the icons.
- * @var array
- */
- public $editingcontrols = array();
- /** @var string The content that appears within the block, as HTML. */
- public $content = null;
- /** @var string The content that appears at the end of the block. */
- public $footer = null;
- /**
- * Any small print that should appear under the block to explain to the
- * teacher about the block, for example 'This is a sticky block that was
- * added in the system context.'
- * @var string
- */
- public $annotation = null;
- /** @var string The result of the preferred_width method, which the theme may choose to use, or ignore. */
- public $preferredwidth = null;
- public abstract function get_content();
}
/// Helper functions for working with block classes ============================
@@ -739,7 +772,6 @@ function block_instance($blockname, $instance = NULL, $page = NULL) {
/**
* Load the block class for a particular type of block.
*
- * @global object
* @param string $blockname the name of the block.
* @return boolean success or failure.
*/
@@ -839,8 +871,6 @@ function blocks_name_allowed_in_format($name, $pageformat) {
/**
* Delete a block, and associated data.
*
- * @global object
- * @uses CONTEXT_BLOCK
* @param object $instance a row from the block_instances table
* @param bool $nolongerused legacy parameter. Not used, but kept for bacwards compatibility.
* @param bool $skipblockstables for internal use only. Makes @see blocks_delete_all_for_context() more efficient.
@@ -859,28 +889,9 @@ function blocks_delete_instance($instance, $nolongerused = false, $skipblockstab
}
}
-/**
- * @deprecated since 2.0
- * Delete all the blocks from a particular page.
- *
- * @global object
- * @param string $pagetype the page type.
- * @param integer $pageid the page id.
- * @return bool success or failure.
- */
-function blocks_delete_all_on_page($pagetype, $pageid) {
- global $DB;
-
- debugging('Call to deprecated function blocks_delete_all_on_page. ' .
- 'This function cannot work any more. Doing nothing. ' .
- 'Please update your code to use another method.', DEBUG_DEVELOPER);
- return false;
-}
-
/**
* Delete all the blocks that belong to a particular context.
*
- * @global object
* @param int $contextid the context id.
*/
function blocks_delete_all_for_context($contextid) {
@@ -895,98 +906,54 @@ function blocks_delete_all_for_context($contextid) {
}
/**
- * Accepts an array of block instances and checks to see if any of them have content to display
- * (causing them to calculate their content in the process). Returns true or false. Parameter passed
- * by reference for speed; the array is actually not modified.
+ * @deprecated since 2.0
+ * Delete all the blocks from a particular page.
*
- * @todo Deprecate this function
- * @deprecated
- *
- * @param object $blockmanager
- * @param string $region
- * @return bool
+ * @param string $pagetype the page type.
+ * @param integer $pageid the page id.
+ * @return bool success or failure.
*/
-function blocks_have_content(&$blockmanager, $region) {
- // TODO deprecate
- $content = $blockmanager->get_content_for_region($region);
- return !empty($content);
+function blocks_delete_all_on_page($pagetype, $pageid) {
+ global $DB;
+
+ debugging('Call to deprecated function blocks_delete_all_on_page. ' .
+ 'This function cannot work any more. Doing nothing. ' .
+ 'Please update your code to use a block_manager method $PAGE->blocks->....', DEBUG_DEVELOPER);
+ return false;
}
/**
- * This function prints one group of blocks in a page
+ * Dispite what this function is called, it seems to be mostly used to populate
+ * the default blocks when a new course (or whatever) is created.
*
- * @todo Complete this function
+ * @deprecated since 2.0
*
- * @global object
- * @global object
- * @global object
- * @param object $page
- * @param object $blockmanager
- * @param string $region
+ * @param object $page the page to add default blocks to.
+ * @return boolean success or failure.
*/
-function blocks_print_group($page, $blockmanager, $region) {
- global $COURSE, $CFG, $USER;
+function blocks_repopulate_page($page) {
+ global $CFG;
- $isediting = $page->user_is_editing();
- $groupblocks = $blockmanager->get_blocks_for_region($region);
+ debugging('Call to deprecated function blocks_repopulate_page. ' .
+ 'Use a more specific method like blocks_add_default_course_blocks, ' .
+ 'or just call $PAGE->blocks->add_blocks()', DEBUG_DEVELOPER);
- foreach($groupblocks as $instance) {
- if (($isediting && empty($instance->pinned))) {
- $options = 0;
- // The block can be moved up if it's NOT the first one in its position. If it is, we look at the OR clause:
- // the first block might still be able to move up if the page says so (i.e., it will change position)
-// TODO $options |= BLOCK_MOVE_UP * ($instance->weight != 0 || ($page->blocks_move_position($instance, BLOCK_MOVE_UP) != $instance->position));
- // Same thing for downward movement
-// TODO $options |= BLOCK_MOVE_DOWN * ($instance->weight != $maxweight || ($page->blocks_move_position($instance, BLOCK_MOVE_DOWN) != $instance->position));
- // For left and right movements, it's up to the page to tell us whether they are allowed
-// TODO $options |= BLOCK_MOVE_RIGHT * ($page->blocks_move_position($instance, BLOCK_MOVE_RIGHT) != $instance->position);
-// TODO $options |= BLOCK_MOVE_LEFT * ($page->blocks_move_position($instance, BLOCK_MOVE_LEFT ) != $instance->position);
- // Finally, the block can be configured if the block class either allows multiple instances, or if it specifically
- // allows instance configuration (multiple instances override that one). It doesn't have anything to do with what the
- // administrator has allowed for this block in the site admin options.
- $options |= BLOCK_CONFIGURE * ( $instance->instance_allow_multiple() || $instance->instance_allow_config() );
- $instance->_add_edit_controls($options);
- }
-
- if (false /* TODO */&& !$instance->visible && empty($COURSE->javascriptportal)) {
- if ($isediting) {
- $instance->_print_shadow();
- }
- } else {
- global $COURSE;
- if(!empty($COURSE->javascriptportal)) {
- $COURSE->javascriptportal->currentblocksection = $region;
- }
- $instance->_print_block();
- }
- if (!empty($COURSE->javascriptportal)
- && (empty($instance->pinned) || !$instance->pinned)) {
- $COURSE->javascriptportal->block_add('inst'.$instance->id, !$instance->visible);
- }
- } // End foreach
-
- if ($page->blocks->get_default_region() == $region &&
- $page->user_is_editing() && $page->user_can_edit_blocks()) {
- blocks_print_adminblock($page, $blockmanager);
+ /// If the site override has been defined, it is the only valid one.
+ if (!empty($CFG->defaultblocks_override)) {
+ $blocknames = $CFG->defaultblocks_override;
+ } else {
+ $blocknames = $page->blocks_get_default();
}
+
+ $blocks = blocks_parse_default_blocks_list($blocknames);
+ $page->blocks->add_blocks($blocks);
+
+ return true;
}
/**
- * This iterates over an array of blocks and calculates the preferred width
- * Parameter passed by reference for speed; it's not modified.
+ * Get the block record for a particular blockid - that is, a particul type os block.
*
- * @todo Finish this function
- *
- * @param mixed $instances
- */
-function blocks_preferred_width($instances) {
- $width = 210;
-}
-
-/**
- * Get the block record for a particulr blockid.
- *
- * @global object
* @param $int blockid block type id. If null, an array of all block types is returned.
* @param bool $notusedanymore No longer used.
* @return array|object row from block table, or all rows.
@@ -1028,28 +995,8 @@ function blocks_find_block($blockid, $blocksarray) {
}
/**
- * Simple entry point for anyone that wants to use blocks
+ * TODO Document this function, description
*
- * @uses BLOCKS_PINNED_FALSE
- * @param object $page
- * @return array
- */
-function blocks_setup(&$page, $pinned = BLOCKS_PINNED_FALSE) {
- $page->blocks->load_blocks();
- blocks_execute_url_action($page, $page->blocks);
- return $page->blocks;
-}
-
-/**
- * @todo Document this function, description
- *
- * @global object
- * @global object
- * @global object
- * @uses BLOCK_MOVE_UP
- * @uses BLOCK_MOVE_DOWN
- * @uses BLOCK_MOVE_RIGHT
- * @uses BLOCK_MOVE_LEFT
* @param object $page The page object
* @param object $blockmanager The block manager object
* @param string $blockaction One of [config, add, delete]
@@ -1272,10 +1219,10 @@ function blocks_execute_action($page, &$blockmanager, $blockaction, $instanceori
}
/**
+ * TODO deprecate
+ *
* You can use this to get the blocks to respond to URL actions without much hassle
*
- * @uses PARAM_ALPHA
- * @uses PARAM_INT
* @param object $PAGE
* @param object $blockmanager
* @param bool $pinned
@@ -1299,6 +1246,7 @@ function blocks_execute_url_action(&$PAGE, &$blockmanager,$pinned=false) {
}
/**
+ * TODO deprecate
* This shouldn't be used externally at all, it's here for use by blocks_execute_action()
* in order to reduce code repetition.
*
@@ -1348,10 +1296,9 @@ function blocks_execute_repositioning(&$instance, $newpos, $newweight, $pinned=f
/**
+ * TODO deprecate
* Moves a block to the new position (column) and weight (sort order).
*
- * @global object
- * @global object
* @param object $instance The block instance to be moved.
* @param string $destpos BLOCK_POS_LEFT or BLOCK_POS_RIGHT. The destination column.
* @param string $destweight The destination sort order. If NULL, we add to the end
@@ -1368,9 +1315,9 @@ function blocks_move_block($page, &$instance, $destpos, $destweight=NULL, $pinne
throw new moodle_exception('Sorry, blocks editing is currently broken. Will be fixed. See MDL-19010.');
if ($pinned) {
- $blocklist = blocks_get_pinned($page);
+ $blocklist = array(); //blocks_get_pinned($page);
} else {
- $blocklist = blocks_get_by_page($page);
+ $blocklist = array(); //blocks_get_by_page($page);
}
if ($blocklist[$instance->position][$instance->weight]->id != $instance->id) {
@@ -1425,137 +1372,11 @@ function blocks_move_block($page, &$instance, $destpos, $destweight=NULL, $pinne
return $DB->update_record($table, $instance);
}
-
-/**
- * Returns an array consisting of 2 arrays:
- * 1) Array of pinned blocks for position BLOCK_POS_LEFT
- * 2) Array of pinned blocks for position BLOCK_POS_RIGHT
- *
- * @global object
- * @param object $page
- */
-function blocks_get_pinned($page) {
- global $DB;
-
- $visible = true;
- $select = "pagetype = ?";
- $params = array($page->pagetype);
-
- if ($visible) {
- $select .= " AND visible = 1";
- }
-
- $blocks = $DB->get_records_select('block_pinned_old', $select, $params, 'position, weight');
-
- $regions = $page->blocks->get_regions();
- $arr = array();
-
- foreach($regions as $key => $region) {
- $arr[$region] = array();
- }
-
- if(empty($blocks)) {
- return $arr;
- }
-
- foreach($blocks as $block) {
- $block->pinned = true; // so we know we can't move it.
- // make up an instanceid if we can..
- $block->pageid = $page->get_id();
- $arr[$block->position][$block->weight] = $block;
- }
-
- return $arr;
-}
-
-
-/**
- * Similar to blocks_get_by_page(), except that, the array returned includes
- * pinned blocks as well. Pinned blocks are always appended before normal
- * block instances.
- *
- * @param object $page
- * @return array
- */
-function blocks_get_by_page_pinned($page) {
- $pinned = blocks_get_pinned($page);
- $user = blocks_get_by_page($page);
-
- $weights = array();
-
- foreach ($pinned as $pos => $arr) {
- $weights[$pos] = count($arr);
- }
-
- foreach ($user as $pos => $blocks) {
- if (!array_key_exists($pos,$pinned)) {
- $pinned[$pos] = array();
- }
- if (!array_key_exists($pos,$weights)) {
- $weights[$pos] = 0;
- }
- foreach ($blocks as $block) {
- $pinned[$pos][$weights[$pos]] = $block;
- $weights[$pos]++;
- }
- }
- return $pinned;
-}
-
-
-/**
- * Returns an array of blocks for the page. Pinned blocks are excluded.
- *
- * @todo Check backwards compatibility hack
- * @global object
- * @param object $page
- */
-function blocks_get_by_page($page) {
- global $DB;
-
- // TODO check the backwards compatibility hack.
- return $page->blocks;
-}
-
-/**
- * This function prints the block to admin blocks as necessary
- *
- * @global object
- * @uses SORT_LOCALE_STRING
- * @param object $page
- * @param object $blockmanager
- */
-function blocks_print_adminblock($page, $blockmanager) {
- global $USER;
-
- $missingblocks = array_keys($page->blocks->get_addable_blocks());
-
- if (!empty($missingblocks)) {
- $strblocks = '
';
-
- $stradd = get_string('add');
- foreach ($missingblocks as $blockid) {
- $block = blocks_get_record($blockid);
- $blockobject = block_instance($block->name);
- if ($blockobject !== false && $blockobject->user_can_addto($page)) {
- $menu[$block->id] = $blockobject->get_title();
- }
- }
- asort($menu, SORT_LOCALE_STRING);
-
- $target = $page->url->out(false, array('sesskey' => sesskey(), 'blockaction' => 'add'));
- $content = popup_form($target.'&blockid=', $menu, 'add_block', '', $stradd .'...', '', '', true);
- print_side_block($strblocks, $content, NULL, NULL, NULL, array('class' => 'block_adminblock'));
- }
-}
+// Functions for programatically adding default blocks to pages ================
/**
* Parse a list of default blocks. See config-dist for a description of the format.
*
- * @uses BLOCK_POS_LEFT
- * @uses BLOCK_POS_RIGHT
* @param string $blocksstr
* @return array
*/
@@ -1572,9 +1393,6 @@ function blocks_parse_default_blocks_list($blocksstr) {
}
/**
- * @global object
- * @uses BLOCK_POS_LEFT
- * @uses BLOCK_POS_RIGHT
* @return array the blocks that should be added to the site course by default.
*/
function blocks_get_default_site_course_blocks() {
@@ -1593,10 +1411,6 @@ function blocks_get_default_site_course_blocks() {
/**
* Add the default blocks to a course.
*
- * @global object
- * @uses SITEID
- * @uses BLOCK_POS_LEFT
- * @uses BLOCK_POS_RIGHT
* @param object $course a course object.
*/
function blocks_add_default_course_blocks($course) {
@@ -1646,44 +1460,9 @@ function blocks_add_default_course_blocks($course) {
/**
* Add the default system-context blocks. E.g. the admin tree.
- *
- * @uses BLOCK_POS_LEFT
- * @uses CONTEXT_SYSTEM
*/
function blocks_add_default_system_blocks() {
$page = new moodle_page();
$page->set_context(get_context_instance(CONTEXT_SYSTEM));
$page->blocks->add_blocks(array(BLOCK_POS_LEFT => array('admin_tree', 'admin_bookmarks')), 'admin-*');
}
-
-/**
- * Dispite what this function is called, it seems to be mostly used to populate
- * the default blocks when a new course (or whatever) is created.
- *
- * @deprecated since 2.0
- * @global object
- * @uses DEBUG_DEVELOPER
- * @param object $page the page to add default blocks to.
- * @return boolean success or failure.
- */
-function blocks_repopulate_page($page) {
- global $CFG;
-
- debugging('Call to deprecated function blocks_repopulate_page. ' .
- 'Use a more specific method like blocks_add_default_course_blocks, ' .
- 'or just call $PAGE->blocks->add_blocks()', DEBUG_DEVELOPER);
-
- /// If the site override has been defined, it is the only valid one.
- if (!empty($CFG->defaultblocks_override)) {
- $blocknames = $CFG->defaultblocks_override;
- } else {
- $blocknames = $page->blocks_get_default();
- }
-
- $blocks = blocks_parse_default_blocks_list($blocknames);
- $page->blocks->add_blocks($blocks);
-
- return true;
-}
-
-?>
diff --git a/lib/deprecatedlib.php b/lib/deprecatedlib.php
index 77e7c2a3343..57cc4415338 100644
--- a/lib/deprecatedlib.php
+++ b/lib/deprecatedlib.php
@@ -2225,11 +2225,20 @@ function print_footer($course = NULL, $usercourse = NULL, $return = false) {
*/
function print_side_block($heading='', $content='', $list=NULL, $icons=NULL, $footer='', $attributes = array(), $title='') {
global $OUTPUT;
+
+ // We don't use $heading, becuse it often contains HTML that we don't want.
+ // However, sometimes $title is not set, but $heading is.
+ if (empty($title)) {
+ $title = strip_tags($heading);
+ }
+
+ // Render list contents to HTML if required.
+ if (empty($content) && $list) {
+ $content = $OUTPUT->list_block_contents($icons, $list);
+ }
+
$bc = new block_contents();
- $bc->heading = $heading;
$bc->content = $content;
- $bc->list = $list;
- $bc->icons = $icons;
$bc->footer = $footer;
$bc->title = $title;
@@ -2275,3 +2284,66 @@ function print_side_block_start($heading='', $attributes = array()) {
function print_side_block_end($attributes = array(), $title='') {
throw new coding_exception('print_side_block_end has been deprecated. Please cahnge your code to use $OUTPUT->block().');
}
+
+/**
+ * This was used by old code to see whether a block region had anything in it,
+ * and hence wether that region should be printed.
+ *
+ * We don't ever want old code to print blocks, so we now always return false.
+ * The function only exists to avoid fatal errors in old code.
+ *
+ * @deprecated since Moodle 2.0. always returns false.
+ *
+ * @param object $blockmanager
+ * @param string $region
+ * @return bool
+ */
+function blocks_have_content(&$blockmanager, $region) {
+ debugging('The function blocks_have_content should no longer be used. Blocks are now printed by the theme.');
+ return false;
+}
+
+/**
+ * This was used by old code to print the blocks in a region.
+ *
+ * We don't ever want old code to print blocks, so this is now a no-op.
+ * The function only exists to avoid fatal errors in old code.
+ *
+ * @deprecated since Moodle 2.0. does nothing.
+ *
+ * @param object $page
+ * @param object $blockmanager
+ * @param string $region
+ */
+function blocks_print_group($page, $blockmanager, $region) {
+ debugging('The function blocks_print_group should no longer be used. Blocks are now printed by the theme.');
+}
+
+/**
+ * This used to be the old entry point for anyone that wants to use blocks.
+ * Since we don't want people people dealing with blocks this way any more,
+ * just return a suitable empty array.
+ *
+ * @deprecated since Moodle 2.0.
+ *
+ * @param object $page
+ * @return array
+ */
+function blocks_setup(&$page, $pinned = BLOCKS_PINNED_FALSE) {
+ debugging('The function blocks_print_group should no longer be used. Blocks are now printed by the theme.');
+ return array(BLOCK_POS_LEFT => array(), BLOCK_POS_RIGHT => array());
+}
+
+/**
+ * This iterates over an array of blocks and calculates the preferred width
+ * Parameter passed by reference for speed; it's not modified.
+ *
+ * @deprecated since Moodle 2.0. Layout is now controlled by the theme.
+ *
+ * @param mixed $instances
+ */
+function blocks_preferred_width($instances) {
+ debugging('The function blocks_print_group should no longer be used. Blocks are now printed by the theme.');
+ $width = 210;
+}
+
diff --git a/lib/javascript-static.js b/lib/javascript-static.js
index 2c3bc83ab40..fe0da0c29e4 100644
--- a/lib/javascript-static.js
+++ b/lib/javascript-static.js
@@ -617,55 +617,6 @@ date_selector_calendar.prototype.release_calendar = function() {
date_selector_calendar.calendar.selectEvent.unsubscribe(this.set_selects_from_date, this);
}
-/**
- elementToggleHide (element, elementFinder)
-
- If elementFinder is not provided, toggles the "hidden" class for the specified element.
- If elementFinder is provided, then the "hidden" class will be toggled for the object
- returned by the function call elementFinder(element).
-
- If persistent == true, also sets a cookie for this.
-*/
-function elementToggleHide(el, persistent, elementFinder, strShow, strHide) {
- if(!elementFinder) {
- var obj = el; //el:container
- el = document.getElementById('togglehide_'+obj.id);
- }
- else {
- var obj = elementFinder(el); //el:button.
- }
- if(obj.className.indexOf('hidden') == -1) {
- obj.className += ' hidden';
- if (el.src) {
- el.src = el.src.replace('switch_minus', 'switch_plus');
- el.alt = strShow;
- el.title = strShow;
- }
- var shown = 0;
- }
- else {
- obj.className = obj.className.replace(new RegExp(' ?hidden'), '');
- if (el.src) {
- el.src = el.src.replace('switch_plus', 'switch_minus');
- el.alt = strHide;
- el.title = strHide;
- }
- var shown = 1;
- }
-
- if(persistent == true) {
- new cookie('hide:' + obj.id, 1, (shown ? -1 : 356), '/').set();
- }
-}
-
-function elementCookieHide(id, strShow, strHide) {
- var obj = document.getElementById(id);
- var cook = new cookie('hide:' + id).read();
- if(cook != null) {
- elementToggleHide(obj, false, null, strShow, strHide);
- }
-}
-
function filterByParent(elCollection, parentFinder) {
var filteredCollection = [];
for (var i = 0; i < elCollection.length; ++i) {
@@ -921,8 +872,7 @@ function collapsible_region(id, userpref, strtooltip, collapsedicon, expandedico
a.appendChild(this.icon);
// Hook up the event handler.
- var self = this;
- YAHOO.util.Event.addListener(a, 'click', function(e) {self.handle_click(e);});
+ YAHOO.util.Event.addListener(a, 'click', this.handle_click, null, this);
// Handler for the animation finishing.
this.animation.onComplete.subscribe(function() {self.handle_animation_complete();});
@@ -1007,6 +957,67 @@ collapsible_region.prototype.handle_animation_complete = function() {
}
}
+/**
+ * Oject to handle expanding and collapsing blocks when an icon is clicked on.
+ * @constructor
+ * @param String id the HTML id for the div.
+ * @param String userpref the user preference that records the state of this block.
+ * @param String visibletooltip tool tip/alt to show when the block is visible.
+ * @param String hiddentooltip tool tip/alt to show when the block is hidden.
+ * @param String visibleicon URL of the icon to show when the block is visible.
+ * @param String hiddenicon URL of the icon to show when the block is hidden.
+ */
+function block_hider(id, userpref, visibletooltip, hiddentooltip, visibleicon, hiddenicon) {
+ // Find the elemen that is the block.
+ this.block = document.getElementById(id);
+ var title_div = YAHOO.util.Dom.getElementsByClassName('title', 'div', this.block);
+ if (!title_div || !title_div[0]) {
+ return this;
+ }
+ title_div = title_div[0];
+ this.ishidden = YAHOO.util.Dom.hasClass(this.block, 'hidden');
+
+ // Record the pref name
+ this.userpref = userpref;
+ this.visibletooltip = visibletooltip;
+ this.hiddentooltip = hiddentooltip;
+ this.visibleicon = visibleicon;
+ this.hiddenicon = hiddenicon;
+
+ // Add the icon.
+ this.icon = document.createElement('input');
+ this.icon.type = 'image';
+ this.icon.className = 'hide-show-image';
+ this.update_state();
+ title_div.insertBefore(this.icon, title_div.firstChild);
+
+ // Hook up the event handler.
+ YAHOO.util.Event.addListener(this.icon, 'click', this.handle_click, null, this);
+}
+
+/** Handle click on a block show/hide icon. */
+block_hider.prototype.handle_click = function(e) {
+ YAHOO.util.Event.stopEvent(e);
+ this.ishidden = !this.ishidden;
+ this.update_state();
+ set_user_preference(this.userpref, this.ishidden);
+}
+
+/** Set the state of the block show/hide icon to this.ishidden. */
+block_hider.prototype.update_state = function () {
+ if (this.ishidden) {
+ YAHOO.util.Dom.addClass(this.block, 'hidden');
+ this.icon.alt = this.hiddentooltip;
+ this.icon.title = this.hiddentooltip;
+ this.icon.src = this.hiddenicon;
+ } else {
+ YAHOO.util.Dom.removeClass(this.block, 'hidden');
+ this.icon.alt = this.visibletooltip;
+ this.icon.title = this.visibletooltip;
+ this.icon.src = this.visibleicon;
+ }
+}
+
/** Close the current browser window. */
function close_window() {
window.close();
diff --git a/lib/outputlib.php b/lib/outputlib.php
index c084b27f547..7b750cc8603 100644
--- a/lib/outputlib.php
+++ b/lib/outputlib.php
@@ -147,7 +147,7 @@ class theme_config {
/**
* You can base your theme on another theme by linking to the other theme as
* a parent. This lets you use the CSS from the other theme
- * (see {@link $parentsheets}), or layout templates (see {@link $layouttemplates}).
+ * (see {@link $parentsheets}), or layout templates (see {@link $layouts}).
* That makes it easy to create a new theme that is similar to another one
* but with a few changes. In this theme's CSS you only need to override
* those rules you want to change.
@@ -240,50 +240,67 @@ class theme_config {
/**
* Which template to use for each general type of page.
*
- * The array should have keys that are the page types, and values that are
- * the template names, as described below.
+ * This is an array of arrays. The keys of the outer array are the different
+ * types of page. Pages in Moodle are categorised into one of a short list of
+ * types like 'normal', 'home', 'popup', 'form', .... The most reliable way
+ * to get a complete list is to look at
+ * {@link http://cvs.moodle.org/moodle/theme/standard/config.php?view=markup the standard theme config.php file}.
+ * That file also has a good example of how to set this setting.
*
- * There are a few recognised page tyes like 'normal', 'popup', 'home'.
- * If the current page if of a type not listed here, then the first listed
- * template is used. Therefore you should probably list the 'normal' template
- * first.
+ * If Moodle encouters a general type of page that is not listed in your theme,
+ * then it will use the first layout. Therefore, should probably put 'normal'
+ * first in this array.
*
- * To promote conisitency, you are encouraged to call your templates
- * layout.php or layout-something.php.
+ * For each page type, the value in the outer array is an array that describes
+ * how you want that type of page to look. For example
+ *
+ * $THEME->layouts = array(
+ * // Most pages. Put this first, so if we encounter an unknown page type, this is used.
+ * 'normal' => array(
+ * 'layout' => 'parent:layout.php',
+ * 'regions' => array('side-pre', 'side-post'),
+ * 'defaultregion' => 'side-post'
+ * ),
+ * // The site home page.
+ * 'home' => array(
+ * 'layout' => 'layout-home.php',
+ * 'regions' => array('side-pre', 'side-post'),
+ * 'defaultregion' => 'side-post'
+ * ),
+ * // ...
+ * );
+ *
*
- * The name of the template can take one of three forms:
+ * 'layout' is the layout template to use for this type of page. You can
+ * specify this in one of three ways:
*
- *
filename for example 'layout.php'. Use that file from this theme.
- *
parent:filename for example 'parent:layout-popup.php'. Use the
+ *
filename for example 'layout-home.php' as above. Use that file from this theme.
+ *
parent:filename for example 'parent:layout.php' as above. Use the
* specified file from the parent theme. (Obviously, you can only do this
* if this theme has a parent!)
*
standard:filename for example 'standard:layout-popup.php'. Use
* the specified file from the standard theme.
*
+ * To promote conisitency, you are encouraged to call your layout files
+ * layout.php or layout-something.php.
+ *
+ * 'regions' This lists the regions on the page where blocks may appear. For
+ * each region you list here, your layout file must include a call to
+ *
+ * or equivalent so that the blocks are actually visible.
+ *
+ * 'defaultregion' If the list of regions is non-empty, then you must pick
+ * one of the one of them as 'default'. This has two meanings. First, this is
+ * where new blocks are added. Second, if there are any blocks associated with
+ * the page, but in non-existant regions, they appear here. (Imaging, for example,
+ * that someone added blocks using a different theme that used different region
+ * names, and then switched to this theme.)
*
* @var array
*/
- public $layouttemplates = array();
-
- /**
- * Names of the regions where blocks may appear on the page.
- *
- * For each region you list in $THEME->blockregions you must call
- * blocks_print_group with that region id somewhere in your layout template.
- *
- * @var array
- */
- public $blockregions = array('side-pre', 'side-post');
-
- /**
- * The blocks region where new blocks will be added.
- *
- * Also, where any blocks in unrecognised regions will be shown.
- * (Suppose someone added a block when another theme was selected).
- *
- * @var string
- */
- public $defaultblockregion = 'side-post';
+ public $layouts = array();
/**
* With this you can control the colours of the big MP3 player
@@ -572,6 +589,19 @@ class theme_config {
return $metatags;
}
+ /**
+ * Get the information from {@link $layouts} for this type of page.
+ * @param string $generaltype the general type of the page.
+ * @return array the appropriate part of {@link $layouts}.
+ */
+ protected function layout_info_for_page($generaltype) {
+ if (array_key_exists($generaltype, $this->layouts)) {
+ return $this->layouts[$generaltype];
+ } else {
+ return reset($this->layouts);
+ }
+ }
+
/**
* Given the settings of this theme, and the page generaltype, return the
* full path of the page layout template to use.
@@ -580,28 +610,25 @@ class theme_config {
* template cannot be found, returns false to signal that the old-style
* header.html and footer.html files should be used.
*
+ * @param string $generaltype the general type of the page.
* @return string Full path to the template to use, or false if a new-style
* template cannot be found.
*/
- public function find_page_template($generaltype) {
+ public function template_for_page($generaltype) {
global $CFG;
// Legacy fallback.
- if (empty($this->layouttemplates)) {
+ if (empty($this->layouts)) {
return false;
}
- // Look up the page type in the config array.
- if (array_key_exists($generaltype, $this->layouttemplates)) {
- $templatefile = $this->layouttemplates[$generaltype];
- } else {
- $templatefile = reset($this->layouttemplates);
- }
+ $layoutinfo = $this->layout_info_for_page($generaltype);
+ $templatefile = $layoutinfo['layout'];
// Parse the name that was found.
- if (strpos('standard:', $templatefile) === 0) {
+ if (strpos($templatefile, 'standard:') === 0) {
$templatepath = $CFG->themedir . '/standard/' . substr($templatefile, 9);
- } else if (strpos('parent:', $templatefile) === 0) {
+ } else if (strpos($templatefile, 'parent:') === 0) {
if (empty($this->parent)) {
throw new coding_exception('This theme (' . $this->name .
') does not have a parent. You cannot specify a layout template like ' .
@@ -622,6 +649,29 @@ class theme_config {
return $templatepath;
}
+ /**
+ * Inform a block_manager about the block regions this theme wants on this
+ * type of page.
+ * @param string $generaltype the general type of the page.
+ * @param block_manager $blockmanager the block_manger to set up.
+ */
+ public function setup_blocks($generaltype, $blockmanager) {
+ // Legacy fallback.
+ if (empty($this->layouts)) {
+ if (!in_array($generaltype, array('form', 'popup', 'maintenance'))) {
+ $blockmanager->add_regions(array(BLOCK_POS_LEFT, BLOCK_POS_RIGHT));
+ $blockmanager->set_default_region(BLOCK_POS_RIGHT);
+ }
+ return;
+ }
+
+ $layoutinfo = $this->layout_info_for_page($generaltype);
+ if (!empty($layoutinfo['regions'])) {
+ $blockmanager->add_regions($layoutinfo['regions']);
+ $blockmanager->set_default_region($layoutinfo['defaultregion']);
+ }
+ }
+
/**
* Helper method used by {@link update_legacy_information()}. Update one entry
* in the $this->pluginsheets array, based on the legacy $property propery.
@@ -629,7 +679,8 @@ class theme_config {
* @param $property e.g. 'modsheets'.
*/
protected function update_legacy_plugin_sheets($plugintype, $property) {
- if (property_exists($this, $property)) {
+ // In Moodle 1.9, modsheets etc. were ignored if standardsheets was false.
+ if (!empty($this->standardsheets) && property_exists($this, $property)) {
debugging('$THEME->' . $property . ' is deprecated. Please use the new $THEME->pluginsheets instead.', DEBUG_DEVELOPER);
if (!empty($this->$property) && !in_array($plugintype, $this->pluginsheets)) {
$this->pluginsheets[] = $plugintype;
@@ -652,14 +703,6 @@ class theme_config {
$this->update_legacy_plugin_sheets('format', 'formatsheets');
$this->update_legacy_plugin_sheets('gradereport', 'gradereportsheets');
- if (empty($this->standardsheets)) {
- // In Moodle 1.9, these settings were dependant on each other. They
- // are now independant, at least at the time when the CSS is served,
- // to this is necessary to maintain backwards compatibility. Hmm.
- // What if you don't want this?
- $this->pluginsheets = array();
- }
-
if (!empty($this->langsheets)) {
debugging('$THEME->langsheets is no longer supported. No languages were ' .
'using it for anything, and it did not seem to serve any purpose.', DEBUG_DEVELOPER);
@@ -990,7 +1033,7 @@ class theme_overridden_renderer_factory extends standard_renderer_factory {
}
}
- /* Implement the subclass method. */
+ /* Implement the interface method. */
public function get_renderer($module, $page, $subtype=null) {
foreach ($this->prefixes as $prefix) {
if (is_null($subtype)) {
@@ -1073,8 +1116,8 @@ class template_renderer_factory extends renderer_factory_base {
$searchpaths = array();
foreach ($this->searchpaths as $rootpath) {
$path = $rootpath . '/' . $module;
- if (!is_null($subtype)) {
- $path .= '/' . $subtype;
+ if (!is_null($subtype)) {
+ $path .= '/' . $subtype;
}
if (is_dir($path)) {
$searchpaths[] = $path;
@@ -1784,7 +1827,7 @@ class moodle_core_renderer extends moodle_renderer_base {
$this->page->set_state(moodle_page::STATE_PRINTING_HEADER);
// Find the appropriate page template, based on $this->page->generaltype.
- $templatefile = $this->page->theme->find_page_template($this->page->generaltype);
+ $templatefile = $this->page->theme->template_for_page($this->page->generaltype);
if ($templatefile) {
// Render the template.
$template = $this->render_page_template($templatefile, $menu, $navigation);
@@ -1828,10 +1871,11 @@ class moodle_core_renderer extends moodle_renderer_base {
}
protected function handle_legacy_theme($navigation, $menu) {
- global $CFG, $SITE, $THEME, $USER;
+ global $CFG, $SITE, $USER;
// Set a pretend global from the properties of this class.
// See the comment in render_page_template for a fuller explanation.
$COURSE = $this->page->course;
+ $THEME = $this->page->theme;
// Set up local variables that header.html expects.
$direction = $this->htmlattributes();
@@ -1860,10 +1904,53 @@ class moodle_core_renderer extends moodle_renderer_base {
$menu = $loggedinas;
}
+ if (!empty($this->page->theme->layouttable)) {
+ $lt = $this->page->theme->layouttable;
+ } else {
+ $lt = array('left', 'middle', 'right');
+ }
+
+ if (!empty($this->page->theme->block_l_max_width)) {
+ $preferredwidthleft = $this->page->theme->block_l_max_width;
+ } else {
+ $preferredwidthleft = 210;
+ }
+ if (!empty($this->page->theme->block_r_max_width)) {
+ $preferredwidthright = $this->page->theme->block_r_max_width;
+ } else {
+ $preferredwidthright = 210;
+ }
+
ob_start();
- include($THEME->dir . '/header.html');
+ include($this->page->theme->dir . '/header.html');
$this->page->requires->get_top_of_body_code();
- echo self::MAIN_CONTENT_TOKEN;
+
+ echo '
';
+ foreach ($lt as $column) {
+ if ($column == 'left' && $this->page->blocks->region_has_content(BLOCK_POS_LEFT)) {
+ echo '
';
$menu = str_replace('navmenu', 'navmenufooter', $menu);
include($THEME->dir . '/footer.html');
@@ -1901,26 +1988,45 @@ class moodle_core_renderer extends moodle_renderer_base {
return $output . $footer;
}
+ /**
+ * Output the row of editing icons for a block, as defined by the controls array.
+ * @param $controls an array like {@link block_contents::$controls}.
+ * @return HTML fragment.
+ */
+ public function block_controls($controls) {
+ if (empty($controls)) {
+ return '';
+ }
+ $controlshtml = array();
+ foreach ($controls as $control) {
+ $controlshtml[] = $this->output_tag('a', array('class' => 'icon',
+ 'title' => $control['caption'], 'href' => $control['url']),
+ $this->output_empty_tag('img', array('src' => $control['icon'],
+ 'alt' => $control['caption'])));
+ }
+ return $this->output_tag('div', array('class' => 'commands'), implode('', $controlshtml));
+ }
+
/**
* Prints a nice side block with an optional header.
*
* The content is described
* by a {@link block_contents} object.
*
- * @param block $content HTML for the content
+ * @param block_contents $bc HTML for the content
* @return string the HTML to be output.
*/
function block($bc) {
- $bc = clone($bc);
+ $bc = clone($bc); // Avoid messing up the object passed in.
$bc->prepare();
- $title = strip_tags($bc->title);
- if (empty($title)) {
+ $skiptitle = strip_tags($bc->title);
+ if (empty($skiptitle)) {
$output = '';
$skipdest = '';
} else {
$output = $this->output_tag('a', array('href' => '#sb-' . $bc->skipid, 'class' => 'skip-block'),
- get_string('skipa', 'access', $title));
+ get_string('skipa', 'access', $skiptitle));
$skipdest = $this->output_tag('span', array('id' => 'sb-' . $bc->skipid, 'class' => 'skip-block-to'), '');
}
@@ -1928,40 +2034,21 @@ class moodle_core_renderer extends moodle_renderer_base {
$bc->attributes['class'] = $bc->get_classes_string();
$output .= $this->output_start_tag('div', $bc->attributes);
- if ($bc->heading) {
- // Some callers pass in complete html for the heading, which may include
- // complicated things such as the 'hide block' button; some just pass in
- // text. If they only pass in plain text i.e. it doesn't include a
- //
, then we add in standard tags that make it look like a normal
- // page block including the h2 for accessibility
- if (strpos($bc->heading, '
') === false) {
- $bc->heading = $this->output_tag('div', array('class' => 'title'),
- $this->output_tag('h2', null, $bc->heading));
- }
+ $controlshtml = $this->block_controls($bc->controls);
- $output .= $this->output_tag('div', array('class' => 'header'), $bc->heading);
+ $title = '';
+ if ($bc->title) {
+ $title = $this->output_tag('h2', null, $bc->title);
+ }
+
+ if ($title || $controlshtml) {
+ $output .= $this->output_tag('div', array('class' => 'header'),
+ $this->output_tag('div', array('class' => 'title'),
+ $title . $controlshtml));
}
$output .= $this->output_start_tag('div', array('class' => 'content'));
-
- if ($bc->content) {
- $output .= $bc->content;
-
- } else if ($bc->list) {
- $row = 0;
- $items = array();
- foreach ($bc->list as $key => $string) {
- $item = $this->output_start_tag('li', array('class' => 'r' . $row));
- if ($bc->icons) {
- $item .= $this->output_tag('div', array('class' => 'icon column c0'), $bc->icons[$key]);
- }
- $item .= $this->output_tag('div', array('class' => 'column c1'), $string);
- $item .= $this->output_end_tag('li');
- $items[] = $item;
- $row = 1 - $row; // Flip even/odd.
- }
- $output .= $this->output_tag('ul', array('class' => 'list'), implode("\n", $items));
- }
+ $output .= $bc->content;
if ($bc->footer) {
$output .= $this->output_tag('div', array('class' => 'footer'), $bc->footer);
@@ -1969,15 +2056,61 @@ class moodle_core_renderer extends moodle_renderer_base {
$output .= $this->output_end_tag('div');
$output .= $this->output_end_tag('div');
+ if ($bc->annotation) {
+ $output .= $this->output_tag('div', array('class' => 'blockannotation'), $bc->annotation);
+ }
$output .= $skipdest;
- if (!empty($CFG->allowuserblockhiding) && isset($attributes['id'])) {
- $strshow = addslashes_js(get_string('showblocka', 'access', $title));
- $strhide = addslashes_js(get_string('hideblocka', 'access', $title));
- $output .= $this->page->requires->js_function_call('elementCookieHide', array(
- $bc->id, $strshow, $strhide))->asap();
- }
+ $this->init_block_hider_js($bc);
+ return $output;
+ }
+ protected function init_block_hider_js($bc) {
+ if ($bc->collapsible != block_contents::NOT_HIDEABLE) {
+ $userpref = 'block' . $bc->blockinstanceid . 'hidden';
+ user_preference_allow_ajax_update($userpref, PARAM_BOOL);
+ $this->page->requires->yui_lib('dom');
+ $this->page->requires->yui_lib('event');
+ $plaintitle = strip_tags($bc->title);
+ $this->page->requires->js_function_call('new block_hider', array($bc->id, $userpref,
+ get_string('hideblocka', 'access', $plaintitle), get_string('showblocka', 'access', $plaintitle),
+ $this->old_icon_url('t/switch_minus'), $this->old_icon_url('t/switch_plus')));
+ }
+ }
+
+ /**
+ * Render the contents of a block_list.
+ * @param array $icons the icon for each item.
+ * @param array $items the content of each item.
+ * @return string HTML
+ */
+ public function list_block_contents($icons, $items) {
+ $row = 0;
+ $lis = array();
+ foreach ($items as $key => $string) {
+ $item = $this->output_start_tag('li', array('class' => 'r' . $row));
+ if ($icons) {
+ $item .= $this->output_tag('div', array('class' => 'icon column c0'), $icons[$key]);
+ }
+ $item .= $this->output_tag('div', array('class' => 'column c1'), $string);
+ $item .= $this->output_end_tag('li');
+ $lis[] = $item;
+ $row = 1 - $row; // Flip even/odd.
+ }
+ return $this->output_tag('ul', array('class' => 'list'), implode("\n", $lis));
+ }
+
+ /**
+ * Output all the blocks in a particular region.
+ * @param $region the name of a region on this page.
+ * @return string the HTML to be output.
+ */
+ public function blocks_for_region($region) {
+ $blockcontents = $this->page->blocks->get_content_for_region($region, $this);
+ $output = '';
+ foreach ($blockcontents as $bc) {
+ $output .= $this->block($bc);
+ }
return $output;
}
@@ -2172,7 +2305,7 @@ class moodle_core_renderer extends moodle_renderer_base {
* @param $id The target name from the corresponding $PAGE->requires->skip_link_to($target) call.
* @return string the HTML to output.
*/
- public function skip_link_target($id = 'maincontent') {
+ public function skip_link_target($id = '') {
return $this->output_tag('span', array('id' => $id), '');
}
@@ -2240,7 +2373,7 @@ class moodle_html_component {
* string containing class names.
* @return array the class names as an array.
*/
- public static function clean_clases($classes) {
+ public static function clean_classes($classes) {
if (is_array($classes)) {
return $classes;
} else {
@@ -2254,7 +2387,7 @@ class moodle_html_component {
* string containing class names.
*/
public function set_classes($classes) {
- $this->classes = self::clean_clases($classes);
+ $this->classes = self::clean_classes($classes);
}
/**
@@ -2271,7 +2404,7 @@ class moodle_html_component {
* string containing class names.
*/
public function add_classes($classes) {
- $this->classes += self::clean_clases($classes);
+ $this->classes += self::clean_classes($classes);
}
/**
@@ -2287,7 +2420,7 @@ class moodle_html_component {
* instance of this class is output.
*/
public function prepare() {
- $this->classes = array_unique(self::clean_clases($this->classes));
+ $this->classes = array_unique(self::clean_classes($this->classes));
}
}
@@ -2401,57 +2534,107 @@ class moodle_select_menu extends moodle_html_component {
/**
- * This class hold all the information required to describe a Moodle block.
+ * This class represents how a block appears on a page.
*
- * That is, it holds all the different bits of HTML content that need to be put into the block.
+ * During output, each block instance is asked to return a block_contents object,
+ * those are then passed to the $OUTPUT->block function for display.
+ *
+ * {@link $contents} should probably be generated using a moodle_block_..._renderer.
+ *
+ * Other block-like things that need to appear on the page, for example the
+ * add new block UI, are also represented as block_contents objects.
*
* @copyright 2009 Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 2.0
*/
class block_contents extends moodle_html_component {
+ /** @var int used to set $skipid. */
protected static $idcounter = 1;
+
+ const NOT_HIDEABLE = 0;
+ const VISIBLE = 1;
+ const HIDDEN = 2;
+
/**
- * @param string $heading HTML for the heading. Can include full HTML or just
- * plain text - plain text will automatically be enclosed in the appropriate
- * heading tags.
+ * @param integer $skipid All the blocks (or things that look like blocks)
+ * printed on a page are given a unique number that can be used to construct
+ * id="" attributes. This is set automatically be the {@link prepare()} method.
+ * Do not try to set it manually.
*/
- public $heading = '';
+ public $skipid;
+
/**
- * @param string $title Plain text title, as embedded in the $heading.
+ * @var integer If this is the contents of a real block, this should be set to
+ * the block_instance.id. Otherwise this should be set to 0.
*/
- public $title = '';
+ public $blockinstanceid = 0;
+
/**
- * @param string $content HTML for the content
+ * @var integer if this is a real block instance, and there is a corresponding
+ * block_position.id for the block on this page, this should be set to that id.
+ * Otherwise it should be 0.
*/
- public $content = '';
- /**
- * @param array $list an alternative to $content, it you want a list of things with optional icons.
- */
- public $list = array();
- /**
- * @param array $icons optional icons for the things in $list.
- */
- public $icons = array();
- /**
- * @param string $footer Extra HTML content that gets output at the end, inside a <div class="footer">
- */
- public $footer = '';
+ public $blockpositionid = 0;
+
/**
* @param array $attributes an array of attribute => value pairs that are put on the
* outer div of this block. {@link $id} and {@link $classes} attributes should be set separately.
*/
public $attributes = array();
+
/**
- * @param integer $skipid do not set this manually. It is set automatically be the {@link prepare()} method.
+ * @param string $title The title of this block. If this came from user input,
+ * it should already have had format_string() processing done on it. This will
+ * be output inside
tags. Please do not cause invalid XHTML.
*/
- public $skipid;
+ public $title = '';
+
+ /**
+ * @param string $content HTML for the content
+ */
+ public $content = '';
+
+ /**
+ * @param array $list an alternative to $content, it you want a list of things with optional icons.
+ */
+ public $footer = '';
+
+ /**
+ * Any small print that should appear under the block to explain to the
+ * teacher about the block, for example 'This is a sticky block that was
+ * added in the system context.'
+ * @var string
+ */
+ public $annotation = '';
+
+ /**
+ * @var integer one of the constants NOT_HIDEABLE, VISIBLE, HIDDEN. Whether
+ * the user can toggle whether this block is visible.
+ */
+ public $collapsible = self::NOT_HIDEABLE;
+
+ /**
+ * A (possibly empty) array of editing controls. Each element of this array
+ * should be an array('url' => $url, 'icon' => $icon, 'caption' => $caption)
+ * @var array
+ */
+ public $controls = array();
/* @see lib/moodle_html_component#prepare() */
public function prepare() {
$this->skipid = self::$idcounter;
self::$idcounter += 1;
$this->add_class('sideblock');
+ if (empty($this->blockinstanceid) || !strip_tags($this->title)) {
+ $this->collapsible = self::NOT_HIDEABLE;
+ }
+ if ($this->collapsible == self::HIDDEN) {
+ $this->add_class('hidden');
+ }
+ if (!empty($this->controls)) {
+ $this->add_class('block_with_controls');
+ }
parent::prepare();
}
}
diff --git a/lib/pagelib.php b/lib/pagelib.php
index 7f0c049f15a..7c1a822ab39 100644
--- a/lib/pagelib.php
+++ b/lib/pagelib.php
@@ -336,8 +336,8 @@ class moodle_page {
public function get_url() {
if (is_null($this->_url)) {
debugging('This page did no call $PAGE->set_url(...). Realying on a guess.', DEBUG_DEVELOPER);
- global $ME;
- return new moodle_url($ME);
+ global $FULLME;
+ return new moodle_url($FULLME);
}
return new moodle_url($this->_url); // Return a clone for safety.
}
@@ -888,6 +888,10 @@ class moodle_page {
public function initialise_theme_and_output() {
global $OUTPUT, $PAGE, $SITE, $THEME;
+ if (!empty($this->_wherethemewasinitialised)) {
+ return;
+ }
+
if (!$this->_course && !during_initial_install()) {
$this->set_course($SITE);
}
@@ -897,8 +901,7 @@ class moodle_page {
$this->_theme = theme_config::load($themename);
}
- $this->blocks->add_regions($this->_theme->blockregions);
- $this->blocks->set_default_region($this->_theme->defaultblockregion);
+ $this->_theme->setup_blocks($this->generaltype, $this->blocks);
if ($this === $PAGE) {
$THEME = $this->_theme;
diff --git a/lib/questionlib.php b/lib/questionlib.php
index 5833a7c2b87..45842430977 100644
--- a/lib/questionlib.php
+++ b/lib/questionlib.php
@@ -1458,7 +1458,7 @@ function question_extract_responses($questions, $formdata, $defaultevent=QUESTIO
* @return string
*/
function question_get_feedback_image($fraction, $selected=true) {
- global $CFG;
+ global $CFG, $OUTPUT;
static $icons = array('correct' => 'tick_green', 'partiallycorrect' => 'tick_amber',
'incorrect' => 'cross_red');
diff --git a/lib/setup.php b/lib/setup.php
index 74905e26d77..f2ed938a50d 100644
--- a/lib/setup.php
+++ b/lib/setup.php
@@ -246,6 +246,7 @@ global $SCRIPT;
require_once($CFG->libdir .'/accesslib.php'); // Access control functions
require_once($CFG->libdir .'/deprecatedlib.php'); // Deprecated functions included for backward compatibility
require_once($CFG->libdir .'/moodlelib.php'); // Other general-purpose functions
+ require_once($CFG->libdir .'/pagelib.php'); // Library that defines the moodle_page class, used for $PAGE
require_once($CFG->libdir .'/blocklib.php'); // Library for controlling blocks
require_once($CFG->libdir .'/eventslib.php'); // Events functions
require_once($CFG->libdir .'/grouplib.php'); // Groups functions
diff --git a/lib/setuplib.php b/lib/setuplib.php
index 2e8f4abf92c..d73a8c74fe6 100644
--- a/lib/setuplib.php
+++ b/lib/setuplib.php
@@ -297,7 +297,7 @@ function prepare_error_message($errorcode, $module, $link, $a) {
}
$moreinfourl = $errordocroot . '/en/error/' . $modulelink . '/' . $errorcode;
- if (empty($link) && !defined('ADMIN_EXT_HEADER_PRINTED')) {
+ if (empty($link)) {
if (!empty($SESSION->fromurl)) {
$link = $SESSION->fromurl;
unset($SESSION->fromurl);
diff --git a/lib/upgradelib.php b/lib/upgradelib.php
index 420977ad723..778d9aa3481 100644
--- a/lib/upgradelib.php
+++ b/lib/upgradelib.php
@@ -725,7 +725,7 @@ function upgrade_started($preinstall=false) {
} else {
if (!CLI_SCRIPT and !$PAGE->headerprinted) {
$strupgrade = get_string('upgradingversion', 'admin');
-
+ $PAGE->set_generaltype('maintenance');
upgrade_get_javascript();
print_header($strupgrade.' - Moodle '.$CFG->target_release, $strupgrade,
build_navigation(array(array('name' => $strupgrade, 'link' => null, 'type' => 'misc'))), '',
@@ -764,7 +764,7 @@ function upgrade_finished($continueurl=null) {
ignore_user_abort(false);
if ($continueurl) {
print_continue($continueurl);
- print_footer('upgrade');
+ print_footer();
die;
}
}
diff --git a/lib/weblib.php b/lib/weblib.php
index 8a72f14024e..9b84b376e89 100644
--- a/lib/weblib.php
+++ b/lib/weblib.php
@@ -444,6 +444,30 @@ class moodle_url {
return $uri;
}
+ /**
+ * Return a URL relative to $CFG->wwwroot.
+ *
+ * Throws an exception if this URL does not start with $CFG->wwwroot.
+ *
+ * The main use for this is when you want to pass a returnurl from one script to another.
+ * In this case the returnurl should be relative to $CFG->wwwroot for two reasons.
+ * First, it is shorter. More imporatantly, some web servers (e.g. IIS by default)
+ * give a 'security' error if you try to pass a full URL as a GET parameter in another URL.
+ *
+ * @return string the URL relative to $CFG->wwwroot. Note, you will need to urlencode
+ * this result if you are outputting a URL manually (but not if you are adding
+ * it to another moodle_url).
+ */
+ public function out_returnurl() {
+ global $CFG;
+ $fulluri = $this->out(false, array(), false);
+ $uri = str_replace($CFG->wwwroot . '/', '', $fulluri);
+ if ($uri == $fulluri) {
+ throw new coding_exception('This URL (' . $fulluri . ') is not relative to $CFG->wwwroot.');
+ }
+ return $uri;
+ }
+
/**
* Output action url with sesskey
*
@@ -5112,6 +5136,7 @@ function print_maintenance_message() {
global $CFG, $SITE, $PAGE;
$PAGE->set_pagetype('maintenance-message');
+ $PAGE->set_generaltype('maintenance');
print_header(strip_tags($SITE->fullname), $SITE->fullname, 'home');
print_heading(get_string('sitemaintenance', 'admin'));
if (isset($CFG->maintenance_message) and !html_is_blank($CFG->maintenance_message)) {
diff --git a/mod/chat/view.php b/mod/chat/view.php
index 0262da25251..e0d05bb390e 100644
--- a/mod/chat/view.php
+++ b/mod/chat/view.php
@@ -62,11 +62,6 @@
// Initialize $PAGE, compute blocks
$PAGE->set_url('mod/chat/view.php', array('id' => $cm->id));
- // Note: MDL-19010 there will be further changes to printing header and blocks.
- // The code will be much nicer than this eventually.
- $pageblocks = blocks_setup($PAGE);
- $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210);
-
/// Print the page header
$strenterchat = get_string('enterchat', 'chat');
$stridle = get_string('idle', 'chat');
@@ -91,133 +86,103 @@
$navigation = build_navigation(array(), $cm);
print_header($title, $course->fullname, $navigation, '', '', true, $buttons, navmenu($course, $cm));
- echo '
';
+ /// Check to see if groups are being used here
+ $groupmode = groups_get_activity_groupmode($cm);
+ $currentgroup = groups_get_activity_group($cm, true);
+ groups_print_activity_menu($cm, "view.php?id=$cm->id");
- $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable;
- foreach ($lt as $column) {
- switch ($column) {
- case 'left':
+ if ($currentgroup) {
+ $groupselect = " AND groupid = '$currentgroup'";
+ $groupparam = "&groupid=$currentgroup";
+ } else {
+ $groupselect = "";
+ $groupparam = "";
+ }
- if(!empty($CFG->showblocksonmodpages) && (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) {
- echo '
';
- }
- }
-
-
- print_heading(format_string($chat->name));
-
- if (has_capability('mod/chat:chat',$context)) {
- /// Print the main part of the page
- print_box_start('generalbox', 'enterlink');
- // users with screenreader set, will only see 1 link, to the manual refresh page
- // for better accessibility
- if (!empty($USER->screenreader)) {
- $chattarget = "/mod/chat/gui_basic/index.php?id=$chat->id$groupparam";
- } else {
- $chattarget = "/mod/chat/gui_$CFG->chat_method/index.php?id=$chat->id$groupparam";
- }
-
- echo '
';
- }
-
- // if user is using screen reader, then there is no need to display this link again
- if ($CFG->chat_method == 'header_js' && empty($USER->screenreader)) {
- // show frame/js-less alternative
- echo '
';
+
+ print_heading(format_string($chat->name));
+
+ if (has_capability('mod/chat:chat',$context)) {
+ /// Print the main part of the page
+ print_box_start('generalbox', 'enterlink');
+ // users with screenreader set, will only see 1 link, to the manual refresh page
+ // for better accessibility
+ if (!empty($USER->screenreader)) {
+ $chattarget = "/mod/chat/gui_basic/index.php?id=$chat->id$groupparam";
+ } else {
+ $chattarget = "/mod/chat/gui_$CFG->chat_method/index.php?id=$chat->id$groupparam";
+ }
+
+ echo '
';
+ }
+
+ // if user is using screen reader, then there is no need to display this link again
+ if ($CFG->chat_method == 'header_js' && empty($USER->screenreader)) {
+ // show frame/js-less alternative
+ echo '
';
- print_container_start();
- }
-
/// Check to see if groups are being used here
$returnurl = 'view.php?d='.$data->id.'&search='.s($search).'&sort='.s($sort).'&order='.s($order).'&';
groups_print_activity_menu($cm, $returnurl);
@@ -680,23 +664,9 @@
data_print_preference_form($data, $perpage, $search, $sort, $order, $search_array, $advanced, $mode);
}
-/// If we have blocks, then print the left side here
- if (!empty($CFG->showblocksonmodpages)) {
- print_container_end();
- echo '
\n";
- }
-
-/// Start the main part of the page
- echo '
';
- print_container_start();
-
/// Print heading and tabs (if there is more than one).
$currenttab = 'info';
include('tabs.php');
@@ -133,7 +117,8 @@
if (isguestuser()) {
notice_yesno('
' . get_string('guestsno', 'quiz') . "
\n\n
" .
get_string('liketologin') . "
\n", get_login_url(), get_referer(false));
- finish_page($course);
+ print_footer($course);
+ exit;
}
/// If they are not enrolled in this course in a good enough role, tell them to enrol.
@@ -141,7 +126,8 @@
print_box('
\n", 'generalbox', 'notice');
- finish_page($course);
+ print_footer($course);
+ exit;
}
/// Get this user's attempts.
@@ -398,23 +384,10 @@
}
print_box_end();
- // Should we not be seeing if we need to print right-hand-side blocks?
-
- finish_page($course);
-
// Mark module as viewed (note, we do this here and not in finish_page,
// otherwise the 'not enrolled' error conditions would result in marking
// 'viewed', I think it's better if they don't.)
$completion=new completion_info($course);
- $completion->set_module_viewed(cm);
+ $completion->set_module_viewed($cm);
-// Utility functions =================================================================
-
-function finish_page($course) {
- global $THEME;
- print_container_end();
- echo '
';
print_footer($course);
- exit;
-}
-?>
diff --git a/mod/resource/lib.php b/mod/resource/lib.php
index 704f592b628..62a84e91610 100644
--- a/mod/resource/lib.php
+++ b/mod/resource/lib.php
@@ -108,27 +108,11 @@ class resource_base {
/**
* Display the resource with the course blocks.
- *
- * @global stdClass
- * @uses PAGE_COURSE_VIEW
- * @uses PARAM_BOOL
- * @uses BLOCK_POS_LEFT
- * @uses BLOCK_POS_RIGHT
*/
function display_course_blocks_start() {
- global $CFG, $USER, $THEME;
-
- require_once($CFG->dirroot.'/course/lib.php'); //required by some blocks
-
- $PAGE = page_create_object(PAGE_COURSE_VIEW, $this->course->id);
- $PAGE->set_url('mod/resource/view.php', array('id' => $this->cm->id));
- $this->PAGE = $PAGE;
- $pageblocks = blocks_setup($PAGE);
-
- $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210);
+ global $CFG, $USER, $PAGE;
/// Print the page header
-
$edit = optional_param('edit', -1, PARAM_BOOL);
if (($edit != -1) and $PAGE->user_allowed_editing()) {
@@ -140,53 +124,11 @@ class resource_base {
$PAGE->print_header($this->course->shortname.': %fullname%', $morenavlinks, "", "",
update_module_button($this->cm->id, $this->course->id, $this->strresource));
-
- echo '
';
- print_container_start(TRUE);
-
/// The main overview in the middle of the page
-
+
// limits the number of courses showing up
$courses_limit = 21;
if (!empty($CFG->mycoursesperpage)) {
@@ -95,39 +67,17 @@
$courses[$c->id]->lastaccess = 0;
}
}
-
+
if (empty($courses)) {
- print_simple_box(get_string('nocourses','my'),'center');
+ print_box(get_string('nocourses','my'));
} else {
print_overview($courses);
}
-
+
// if more than 20 courses
if (count($courses) > 20) {
echo ' ...';
}
-
- print_container_end();
- echo '
';
-
print_footer();
?>
diff --git a/tag/search.php b/tag/search.php
index 313ca050481..4bfd1b8e2c1 100644
--- a/tag/search.php
+++ b/tag/search.php
@@ -14,6 +14,18 @@ $query = optional_param('query', '', PARAM_RAW);
$page = optional_param('page', 0, PARAM_INT); // which page to show
$perpage = optional_param('perpage', 18, PARAM_INT);
+$params = array();
+if ($query) {
+ $params['query'] = $query;
+}
+if ($page) {
+ $params['page'] = $page;
+}
+if ($perpage) {
+ $params['perpage'] = $perpage;
+}
+$PAGE->set_url('tag/search.php', $params);
+
$navlinks = array();
$navlinks[] = array('name' => get_string('tags', 'tag'), 'link' => "{$CFG->wwwroot}/tag/search.php", 'type' => '');
$navigation = build_navigation($navlinks);
diff --git a/test.php b/test.php
new file mode 100644
index 00000000000..76a873f13cf
--- /dev/null
+++ b/test.php
@@ -0,0 +1,8 @@
+';
+var_dump($things);
+echo '';
+
+?>
\ No newline at end of file
diff --git a/theme/anomaly/config.php b/theme/anomaly/config.php
index ff07fda9a35..aa3fcf901e1 100644
--- a/theme/anomaly/config.php
+++ b/theme/anomaly/config.php
@@ -81,6 +81,11 @@ $THEME->parentmetainclude = false;
/// part of the page.
+$THEME->block_l_max_width = 200;
+$THEME->block_r_max_width = 200;
+/// Deprecated, but needed until this themes is updated to use layout.php
+
+
$THEME->navmenuwidth = 50;
/// You can use this to control the cutoff point for strings
diff --git a/theme/custom_corners/config.php b/theme/custom_corners/config.php
index e6cb506c1ef..eed045b1577 100644
--- a/theme/custom_corners/config.php
+++ b/theme/custom_corners/config.php
@@ -79,6 +79,9 @@ $THEME->parentmetainclude = false;
/// to include a file meta.php from the parent theme into the
/// part of the page.
+$THEME->block_l_max_width = 200;
+$THEME->block_r_max_width = 200;
+/// Deprecated, but needed until this themes is updated to use layout.php
$THEME->navmenuwidth = 50;
diff --git a/theme/custom_corners/renderers.php b/theme/custom_corners/renderers.php
index 9f666af3aeb..e87e8610f02 100644
--- a/theme/custom_corners/renderers.php
+++ b/theme/custom_corners/renderers.php
@@ -133,46 +133,24 @@ class custom_corners_core_renderer extends moodle_core_renderer {
$output .= $this->output_start_tag('div', $bc->attributes);
$output .= $this->output_start_tag('div', array('class' => 'wrap'));
- if ($bc->heading) {
- // Some callers pass in complete html for the heading, which may include
- // complicated things such as the 'hide block' button; some just pass in
- // text. If they only pass in plain text i.e. it doesn't include a
- //
, then we add in standard tags that make it look like a normal
- // page block including the h2 for accessibility
- if (strpos($bc->heading, '