From d4a03c00ea3885ac2b264b7d7a8c6c635d5714d2 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Thu, 9 Jul 2009 07:35:03 +0000 Subject: [PATCH] themes & blocks - MDL-19077 & MDL-19010 blocks are now printed by the theme The code to print blocks in now in theme layout.php files. (Or in moodle_core_renderer::handle_legacy_theme) Code for printing blocks everywhere else has been stripped out. (Total diffstat 1225 insertions, 2019 deletions) The way the HTML for a block instance is generated has been cleaned up a lot. Now, the block_instance generates a block_contents object which gives a structured representation of the block, and then $OUTPUT->block builds all the HTML from that. How theme config.php files specify the layout template and block regions by page general type has been changed to be even more flexible. Further refinement for how the theme and block code gets initialised. Ability for scrits to add 'pretend blocks' to the page. That is, things that look like blocks, but are not normal block_instances. (Like the add a new block UI.) Things that are still broken: * some pages in lesson, quiz and resource. I'm working on it. * lots of developer debug notices pointing out things that need to be updated. --- admin/index.php | 12 +- admin/settings.php | 39 -- admin/settings/plugins.php | 1 - admin/stickyblocks.php | 90 --- blocks/moodleblock.class.php | 340 +++++----- blog/footer.php | 21 - blog/header.php | 37 -- course/edit.php | 1 + course/format/scorm/format.php | 40 -- course/format/social/format.php | 47 -- course/format/topics/format.php | 47 -- course/format/weeks/format.php | 48 +- course/modedit.php | 2 + course/rest.php | 15 - course/view.php | 4 - index.php | 74 +-- install.php | 1 + lib/adminlib.php | 156 +---- lib/ajax/ajaxlib.php | 2 + lib/blocklib.php | 609 ++++++------------ lib/deprecatedlib.php | 78 ++- lib/javascript-static.js | 113 ++-- lib/outputlib.php | 425 ++++++++---- lib/pagelib.php | 11 +- lib/questionlib.php | 2 +- lib/setup.php | 1 + lib/setuplib.php | 2 +- lib/upgradelib.php | 4 +- lib/weblib.php | 25 + mod/chat/view.php | 223 +++---- mod/data/view.php | 34 +- mod/lesson/view.php | 4 - mod/quiz/accessrules.php | 1 + mod/quiz/attempt.php | 23 +- mod/quiz/attemptlib.php | 23 +- mod/quiz/locallib.php | 33 - mod/quiz/review.php | 21 +- mod/quiz/view.php | 37 +- mod/resource/lib.php | 60 +- my/index.php | 58 +- tag/index.php | 33 - tag/search.php | 12 + test.php | 8 + theme/anomaly/config.php | 5 + theme/custom_corners/config.php | 3 + theme/custom_corners/renderers.php | 48 +- theme/standard/config.php | 33 +- theme/standard/layout-home.php | 23 +- .../layout-popup.php | 9 +- theme/standard/layout.php | 24 +- theme/standard/styles_color.css | 4 +- theme/standard/styles_ie6.css | 3 - theme/standard/styles_ie7.css | 3 - theme/standard/styles_layout.css | 63 +- theme/standardwhite/config.php | 33 +- theme/standardwhite/layout-home.php | 46 -- theme/standardwhite/layout.php | 49 -- user/editadvanced.php | 7 +- 58 files changed, 1188 insertions(+), 1982 deletions(-) delete mode 100644 admin/stickyblocks.php create mode 100644 test.php rename theme/{standardwhite => standard}/layout-popup.php (79%) delete mode 100644 theme/standardwhite/layout-home.php delete mode 100644 theme/standardwhite/layout.php diff --git a/admin/index.php b/admin/index.php index 22e60a51d2..f86aa09375 100644 --- a/admin/index.php +++ b/admin/index.php @@ -105,7 +105,7 @@ $origxmlstrictheaders = !empty($CFG->xmlstrictheaders); $CFG->xmlstrictheaders = false; if (!core_tables_exist()) { - // hide errors from headers in case debug enabled in config.php + $PAGE->set_generaltype('maintenance'); // fake some settings $CFG->docroot = 'http://docs.moodle.org'; @@ -127,7 +127,7 @@ if (!core_tables_exist()) { echo '
'; notice_yesno(get_string('doyouagree'), "index.php?agreelicense=1&lang=$CFG->lang", "http://docs.moodle.org/en/License"); - print_footer('upgrade'); + print_footer(); die; } if (empty($confirmrelease)) { @@ -147,7 +147,7 @@ if (!core_tables_exist()) { print_continue("index.php?agreelicense=1&confirmrelease=1&lang=$CFG->lang"); } - print_footer('upgrade'); + print_footer(); die; } @@ -178,6 +178,8 @@ if (empty($CFG->version)) { } if ($version > $CFG->version) { // upgrade + $PAGE->set_generaltype('maintenance'); + $a->oldversion = "$CFG->release ($CFG->version)"; $a->newversion = "$release ($version)"; $strdatabasechecking = get_string('databasechecking', '', $a); @@ -187,7 +189,7 @@ if ($version > $CFG->version) { // upgrade print_header($strdatabasechecking, $stradministration, $navigation, '', '', false, ' ', ' '); notice_yesno(get_string('upgradesure', 'admin', $a->newversion), 'index.php?confirmupgrade=1', 'index.php'); - print_footer('upgrade'); + print_footer(); exit; } else if (empty($confirmrelease)){ @@ -212,7 +214,7 @@ if ($version > $CFG->version) { // upgrade print_continue('index.php?confirmupgrade=1&confirmrelease=1'); } - print_footer('upgrade'); + print_footer(); die; } elseif (empty($confirmplugins)) { diff --git a/admin/settings.php b/admin/settings.php index 667ee3ab98..58bd013e70 100644 --- a/admin/settings.php +++ b/admin/settings.php @@ -83,13 +83,6 @@ if (empty($SITE->fullname)) { echo ''; } else { - // 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); - - $preferred_width_left = blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]); - $preferred_width_right = blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]); - if ($PAGE->user_allowed_editing()) { $options = $PAGE->url->params(); if ($PAGE->user_is_editing()) { @@ -111,22 +104,6 @@ if (empty($SITE->fullname)) { print_header("$SITE->shortname: " . implode(": ",$visiblepathtosection), $SITE->fullname, $navigation, $focus, '', true, $buttons, ''); - echo ''; - $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - switch ($column) { - case 'left': - echo ''; - break; - case 'middle': - echo ''; - break; - case 'right': - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT)) { - echo ''; - } - break; - } - } - echo '
'; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''; - print_container_start(); - echo ''; - if ($errormsg !== '') { notify ($errormsg); @@ -149,22 +126,6 @@ if (empty($SITE->fullname)) { echo ''; echo ''; - - print_container_end(); - echo ''; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
'; } print_footer(); diff --git a/admin/settings/plugins.php b/admin/settings/plugins.php index e5105cdc00..e329660ef1 100644 --- a/admin/settings/plugins.php +++ b/admin/settings/plugins.php @@ -44,7 +44,6 @@ if ($hassiteconfig || has_capability('moodle/question:config', $systemcontext)) $ADMIN->add('modules', new admin_category('blocksettings', get_string('blocks'))); $ADMIN->add('blocksettings', new admin_page_manageblocks()); - $ADMIN->add('blocksettings', new admin_externalpage('stickyblocks', get_string('stickyblocks', 'admin'), "$CFG->wwwroot/$CFG->admin/stickyblocks.php")); if ($blocks = $DB->get_records('block')) { $blockbyname = array(); diff --git a/admin/stickyblocks.php b/admin/stickyblocks.php deleted file mode 100644 index 15b7e4637b..0000000000 --- a/admin/stickyblocks.php +++ /dev/null @@ -1,90 +0,0 @@ -dirroot.'/lib/pagelib.php'); - - $pt = optional_param('pt', null, PARAM_SAFEDIR); //alhanumeric and - - - $pagetypes = array('my-index' => array('id' => 'my-index', - 'lib' => '/lib/pagelib.php', - 'name' => get_string('mymoodle','admin')), - PAGE_COURSE_VIEW => array('id' => PAGE_COURSE_VIEW, - 'lib' => '/lib/pagelib.php', - 'name' => get_string('stickyblockscourseview','admin')) - // ... more? - ); - - // for choose_from_menu - $options = array(); - foreach ($pagetypes as $p) { - $options[$p['id']] = $p['name']; - } - - require_login(); - - require_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM)); - - // first thing to do is print the dropdown menu - - $strtitle = get_string('stickyblocks','admin'); - $strheading = get_string('adminhelpstickyblocks'); - - - - if (!empty($pt)) { - - require_once($CFG->dirroot.$pagetypes[$pt]['lib']); - - define('ADMIN_STICKYBLOCKS',$pt); - - $PAGE = page_create_object($pt, SITEID); - $blocks = blocks_setup($PAGE, BLOCKS_PINNED_TRUE); - $blocks_preferred_width = bounded_number(180, blocks_preferred_width($blocks[BLOCK_POS_LEFT]), 210); - - $navlinks = array(array('name' => get_string('administration'), - 'link' => "$CFG->wwwroot/$CFG->admin/index.php", - 'type' => 'misc')); - $navlinks[] = array('name' => $strtitle, 'link' => null, 'type' => 'misc'); - $navigation = build_navigation($navlinks); - print_header($strtitle,$strtitle,$navigation); - - echo ''; - echo ''; - - echo ''; - echo ''; - echo ''; - echo '
'; - print_container_start(); - blocks_print_group($PAGE, $blocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''; - print_container_start(); - - } else { - require_once($CFG->libdir.'/adminlib.php'); - admin_externalpage_setup('stickyblocks'); - admin_externalpage_print_header(); - } - - - print_box_start(); - print_heading($strheading); - popup_form("$CFG->wwwroot/$CFG->admin/stickyblocks.php?pt=", $options, 'selecttype', $pt, 'choose', '', '', false, 'self', get_string('stickyblockspagetype','admin').': '); - echo '

'.get_string('stickyblocksduplicatenotice','admin').'

'; - print_box_end(); - - - if (!empty($pt)) { - print_container_end(); - echo '
'; - print_container_start(); - blocks_print_group($PAGE, $blocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
'; - print_footer(); - } else { - admin_externalpage_print_footer(); - } - -?> diff --git a/blocks/moodleblock.class.php b/blocks/moodleblock.class.php index 1ab1eae8bc..9f1bf0159d 100644 --- a/blocks/moodleblock.class.php +++ b/blocks/moodleblock.class.php @@ -331,81 +331,95 @@ class block_base { } /** - * Display the block! + * Return a block_contents oject representing the full contents of this block. + * + * This internally calls ->get_content(), and then adds the editing controls etc. + * + * You probably should not override this method, but instead override + * {@link html_attributes()}, {@link formatted_contents()} or {@link get_content()}, + * {@link hide_header()}, {@link (get_edit_controls)}, etc. + * + * @return block_contents a represntation of the block, for rendering. + * @since Moodle 2.0. */ - function _print_block() { - global $COURSE; + public function get_content_for_output($output) { + global $CFG; - // 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); - } - } - } + $bc = new block_contents(); + $bc->blockinstanceid = $this->instance->id; + $bc->blockpositionid = $this->instance->blockpositionid; - /** - * 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); - } + $attributes = $this->html_attributes(); + if (isset($attributes['id'])) { + $bc->id = $attributes['id']; + unset($attributes['id']); + } + if (isset($attributes['class'])) { + $bc->set_classes($attributes['class']); + unset($attributes['class']); + } + $bc->attributes = $attributes; + if (!$this->hide_header()) { + $bc->title = $this->title; + } + $bc->content = $this->formatted_contents($output); + if (!empty($this->content->footer)) { + $bc->footer = $this->content->footer; + } - function _title_html() { - global $OUTPUT; - - //Accessibility: validation, can't have
inside

, use . - $title = '
'; - - if (!empty($CFG->allowuserblockhiding)) { - //Accessibility: added 'alt' text for the +- icon. - //Theme the buttons using, Admin - Miscellaneous - smartpix. - $strshow = addslashes_js(get_string('showblocka', 'access', strip_tags($this->title))); - $strhide = addslashes_js(get_string('hideblocka', 'access', strip_tags($this->title))); - $title .= ''; + if ($this->is_empty() && !$bc->controls) { + return null; } - //Accesssibility: added H2 (was in, weblib.php: print_side_block) - $title .= '

'.format_string($this->title).'

'; + if ($this->page->user_is_editing()) { + $bc->controls = $this->get_edit_controls($output); + } - if ($this->edit_controls !== NULL) { - $title .= $this->edit_controls; + if (empty($CFG->allowuserblockhiding)) { + $bc->collapsible = block_contents::NOT_HIDEABLE; + } else if (get_user_preferences('block' . $bc->blockinstanceid . 'hidden', false)) { + $bc->collapsible = block_contents::HIDDEN; + } else { + $bc->collapsible = block_contents::VISIBLE; } - $title .= '
'; - return $title; + $bc->annotation = ''; // TODO + + return $bc; } /** - * Sets class $edit_controls var with correct block manipulation links. + * Convert the contents of the block to HTML. * - * @uses $CFG - * @uses $USER - * @param stdObject $options ? - * @todo complete documenting this function. Define $options. + * This is used by block base classes like block_list to convert the structured + * $this->content->list and $this->content->icons arrays to HTML. So, in most + * blocks, you probaby want to override the {@link get_contents()} method, + * which generates that structured representation of the contents. + * + * @param $output The core_renderer to use when generating the output. + * @return string the HTML that should appearn in the body of the block. + * @since Moodle 2.0. */ - function _add_edit_controls($options) { - global $CFG, $USER, $OUTPUT; + protected function formatted_contents($output) { + $this->get_content(); + if (!empty($this->content->text)) { + return $this->content->text; + } else { + return ''; + } + } + + /** + * Get the appropriate list of editing icons for this block. This is used + * to set {@link block_contents::$controls} in {@link get_contents_for_output()}. + * + * @param $output The core_renderer to use when generating the output. (Need to get icon paths.) + * @return an array in the format for {@link block_contents::$controls} + * @since Moodle 2.0. + */ + protected function get_edit_controls($output) { + global $CFG, $DB; // TODO - temporary hack to get the block context only if it already exists. global $DB; @@ -415,86 +429,50 @@ class block_base { $context = get_context_instance(CONTEXT_SYSTEM); // pinned blocks do not have own context } - // context for site or course, i.e. participant list etc - // check to see if user can edit site or course blocks. - // blocks can appear on other pages such as mod and blog pages... - - if (!$this->page->user_can_edit_blocks()) { - return null; - } - - if (!isset($this->str)) { - $this->str->delete = get_string('delete'); - $this->str->moveup = get_string('moveup'); - $this->str->movedown = get_string('movedown'); - $this->str->moveright = get_string('moveright'); - $this->str->moveleft = get_string('moveleft'); - $this->str->hide = get_string('hide'); - $this->str->show = get_string('show'); - $this->str->configure = get_string('configuration'); - $this->str->assignroles = get_string('assignroles', 'role'); - } + $returnurlparam = '&returnurl=' . urlencode($this->page->url->out_returnurl()); + $actionurl = $CFG->wwwroot.'/blocks/action.php?block=' . $this->instance->id . + '&sesskey=' . sesskey() . $returnurlparam; - // RTL support - exchange right and left arrows - if (right_to_left()) { - $rightarrow = 't/left'; - $leftarrow = 't/right'; - } else { - $rightarrow = 't/right'; - $leftarrow = 't/left'; - } + $controls = array(); - $movebuttons = '
'; - - if ($this->instance->visible) { - $icon = 't/hide'; - $title = $this->str->hide; - } else { - $icon = 't/show'; - $title = $this->str->show; + // Assign roles icon. + if ($context->contextlevel == CONTEXT_BLOCK && has_capability('moodle/role:assign', $context)) { + $controls[] = array('url' => $CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id, + 'icon' => $output->old_icon_url('i/roles'), 'caption' => get_string('assignroles', 'role')); } - $page = $this->page; - $script = $page->url->out(false, array('instanceid' => $this->instance->id, 'sesskey' => sesskey())); - - $movebuttons .= '' . - ''.$this->str->assignroles.''; - - // TODO MDL-19010 fix and re-enable. - if (false && $this->user_can_edit()) { - $movebuttons .= '' . - ''.$title.''; - } + if ($this->user_can_edit() && $this->page->user_can_edit_blocks()) { + // Show/hide icon. + if ($this->instance->visible) { + $controls[] = array('url' => $actionurl . '&action=hide', + 'icon' => $output->old_icon_url('t/hide'), 'caption' => get_string('hide')); + } else { + $controls[] = array('url' => $actionurl . '&action=show', + 'icon' => $output->old_icon_url('t/show'), 'caption' => get_string('show')); + } - if ($options & BLOCK_CONFIGURE && $this->user_can_edit()) { - $movebuttons .= '' . - ''. $this->str->configure .''; - } + // Edit config icon. + if ($this->instance_allow_multiple() || $this->instance_allow_config()) { + $editurl = $CFG->wwwroot . '/blocks/edit.php?block=' . $this->instance->id; + if (!empty($this->instance->blockpositionid)) { + $editurl .= '&positionid=' . $this->instance->blockpositionid; + } + $controls[] = array('url' => $editurl . $returnurlparam, + 'icon' => $output->old_icon_url('t/edit'), 'caption' => get_string('configuration')); + } - if ($this->user_can_addto($page)) { - $movebuttons .= '' . - ''. $this->str->delete .''; - } + // Delete icon. + if ($this->user_can_addto($this->page)) { + $controls[] = array('url' => $actionurl . 'action=delete', + 'icon' => $output->old_icon_url('t/delete'), 'caption' => get_string('deletet')); + } - if ($options & BLOCK_MOVE_LEFT) { - $movebuttons .= '' . - ''. $this->str->moveleft .''; - } - if ($options & BLOCK_MOVE_UP) { - $movebuttons .= '' . - ''. $this->str->moveup .''; - } - if ($options & BLOCK_MOVE_DOWN) { - $movebuttons .= '' . - ''. $this->str->movedown .''; - } - if ($options & BLOCK_MOVE_RIGHT) { - $movebuttons .= '' . - ''. $this->str->moveright .''; + // Move icon. + $controls[] = array('url' => $this->page->url->out(false, array('moveblockid' => $this->instance->id)), + 'icon' => $output->old_icon_url('t/move'), 'caption' => get_string('move')); } - $movebuttons .= '
'; - $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 d01553e1a9..9ffb57d2df 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 ''; - echo ''."\n"; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_spacer(1, 120, true); - print_container_end(); - echo ''."\n"; - echo ''; -} -?> - - - - get_record('course', array('id'=>$courseid))) { print_error('invalidcourseid', '', '', $courseid); } -// Bounds for block widths -// more flexible for theme designers taken from theme config.php -$lmin = (empty($THEME->block_l_min_width)) ? 160 : $THEME->block_l_min_width; -$lmax = (empty($THEME->block_l_max_width)) ? 210 : $THEME->block_l_max_width; -$rmin = (empty($THEME->block_r_min_width)) ? 160 : $THEME->block_r_min_width; -$rmax = (empty($THEME->block_r_max_width)) ? 210 : $THEME->block_r_max_width; - -define('BLOCK_L_MIN_WIDTH', $lmin); -define('BLOCK_L_MAX_WIDTH', $lmax); -define('BLOCK_R_MIN_WIDTH', $rmin); -define('BLOCK_R_MAX_WIDTH', $rmax); - //_____________ new page class code ________ $pagetype = PAGE_BLOG_VIEW; $pageclass = 'page_blog'; @@ -70,12 +58,6 @@ if ($PAGE->user_allowed_editing()) { $editing = $PAGE->user_is_editing(); } -// Calculate the preferred width for left, right and center (both center positions will use the same) -$preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), - BLOCK_L_MAX_WIDTH); -$preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), - BLOCK_R_MAX_WIDTH); - if (!empty($tagid)) { $taginstance = $DB->get_record('tag', array('id'=>$tagid)); } elseif (!empty($tag)) { @@ -241,25 +223,6 @@ $currenttab = 'blogs'; require_once($CFG->dirroot .'/user/tabs.php'); -/// Layout the whole page as three big columns. -print '' . "\n"; -print '' . "\n"; - -/// The left column ... -if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $editing) { - print '' . "\n"; -} - -/// Start main column -print '' . "\n"; -print '
' . "\n"; - print '' . "\n"; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - print '' . "\n"; - print ''; -print_container_start(); ?> diff --git a/course/edit.php b/course/edit.php index d680a13e1b..5ba15b74fb 100644 --- a/course/edit.php +++ b/course/edit.php @@ -9,6 +9,7 @@ $id = optional_param('id', 0, PARAM_INT); // course id $categoryid = optional_param('category', 0, PARAM_INT); // course category - can be changed in edit form + $PAGE->set_generaltype('form'); /// basic access control checks if ($id) { // editing course diff --git a/course/format/scorm/format.php b/course/format/scorm/format.php index 299b6aedd1..37032b5eef 100644 --- a/course/format/scorm/format.php +++ b/course/format/scorm/format.php @@ -5,53 +5,13 @@ $module = $course->format; require_once($CFG->dirroot.'/mod/'.$module.'/locallib.php'); - // Bounds for block widths - // more flexible for theme designers taken from theme config.php - $lmin = (empty($THEME->block_l_min_width)) ? 100 : $THEME->block_l_min_width; - $lmax = (empty($THEME->block_l_max_width)) ? 210 : $THEME->block_l_max_width; - $rmin = (empty($THEME->block_r_min_width)) ? 100 : $THEME->block_r_min_width; - $rmax = (empty($THEME->block_r_max_width)) ? 210 : $THEME->block_r_max_width; - - define('BLOCK_L_MIN_WIDTH', $lmin); - define('BLOCK_L_MAX_WIDTH', $lmax); - define('BLOCK_R_MIN_WIDTH', $rmin); - define('BLOCK_R_MAX_WIDTH', $rmax); - - $preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), - BLOCK_L_MAX_WIDTH); - $preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), - BLOCK_R_MAX_WIDTH); - $strgroups = get_string('groups'); $strgroupmy = get_string('groupmy'); $editing = $PAGE->user_is_editing(); - echo '
'; - echo ''; - - if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $editing) { - echo ''; - } - - echo ''; - - // The right column - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing) { - echo ''; - } - - echo ''; - echo '
'; - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - echo ''. skip_main_destination(); $moduleformat = $module.'_course_format_display'; if (function_exists($moduleformat)) { $moduleformat($USER,$course); } else { notify('The module '. $module. ' does not support single activity course format'); } - echo ''; - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - echo '
'; - -?> diff --git a/course/format/social/format.php b/course/format/social/format.php index 7dd42a5302..8492a05383 100644 --- a/course/format/social/format.php +++ b/course/format/social/format.php @@ -1,42 +1,11 @@ block_l_min_width)) ? 100 : $THEME->block_l_min_width; - $lmax = (empty($THEME->block_l_max_width)) ? 210 : $THEME->block_l_max_width; - $rmin = (empty($THEME->block_r_min_width)) ? 100 : $THEME->block_r_min_width; - $rmax = (empty($THEME->block_r_max_width)) ? 210 : $THEME->block_r_max_width; - - define('BLOCK_L_MIN_WIDTH', $lmin); - define('BLOCK_L_MAX_WIDTH', $lmax); - define('BLOCK_R_MIN_WIDTH', $rmin); - define('BLOCK_R_MAX_WIDTH', $rmax); - - $preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), - BLOCK_L_MAX_WIDTH); - $preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), - BLOCK_R_MAX_WIDTH); $strgroups = get_string('groups'); $strgroupmy = get_string('groupmy'); $editing = $PAGE->user_is_editing(); - echo ''; - echo ''; - - if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $editing) { - echo ''; - } - - echo ''; - - // The right column - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing) { - echo ''; - } - - echo ''; - echo '
'; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''; - print_container_start(); - echo skip_main_destination(); if ($forum = forum_get_course_forum($course->id, 'social')) { /// Print forum intro above posts MDL-18483 @@ -54,19 +23,3 @@ } else { notify('Could not find or create a social forum here'); } - print_container_end(); - echo ''; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
'; - -?> diff --git a/course/format/topics/format.php b/course/format/topics/format.php index 6e3acffec4..c2f9236125 100644 --- a/course/format/topics/format.php +++ b/course/format/topics/format.php @@ -67,45 +67,6 @@ $strmovedown = get_string('movedown'); } -/* Internet Explorer min-width fix. (See theme/standard/styles_layout.css: min-width for Firefox.) - Window width: 800px, Firefox 763px, IE 752px. (Window width: 640px, Firefox 602px, IE 588px.) -*/ -?> - - -'; - -/// The left column ... - - if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $editing) { - echo '
'; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo '
'; - } - -/// The right column, BEFORE the middle-column. - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing) { - echo '
'; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
'; - } - -/// Start main column - echo '
'; - print_container_start(); - - echo skip_main_destination(); - // Print the Your progress icon if the track completion is enabled $completioninfo = new completion_info($course); $completioninfo->print_help_icon(); @@ -295,11 +256,3 @@ 'sectionmenu', '', get_string('jumpto'), '', '', true); echo '
'; } - - print_container_end(); - echo ''; - - echo ''; - echo '
'; - -?> diff --git a/course/format/weeks/format.php b/course/format/weeks/format.php index 5c570023a6..8601ccf46b 100644 --- a/course/format/weeks/format.php +++ b/course/format/weeks/format.php @@ -57,44 +57,6 @@ } $context = get_context_instance(CONTEXT_COURSE, $course->id); -/* Internet Explorer min-width fix. (See theme/standard/styles_layout.css: min-width for Firefox.) - Window width: 800px, Firefox 763px, IE 752px. (Window width: 640px, Firefox 602px, IE 588px.) -*/ -?> - - -'; - -/// The left column ... - - if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $editing) { - print_container_start(); - echo '
'; - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - echo '
'; - print_container_end(); - } - -/// The right column, BEFORE the middle-column. - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing) { - print_container_start(); - echo '
'; - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - echo '
'; - print_container_end(); - } - -/// Start main column - 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 '
  • '; - echo '
     
    '; + echo '
     
    '; echo '
     
    '; echo '
    '; @@ -286,11 +248,3 @@ 'sectionmenu', '', get_string('jumpto'), '', '', true); echo '
    '; } - - print_container_end(); - echo '
  • '; - - echo ''; - echo '
    '; - -?> diff --git a/course/modedit.php b/course/modedit.php index e8c4f4cce4..924b7f9c39 100644 --- a/course/modedit.php +++ b/course/modedit.php @@ -14,6 +14,8 @@ $return = optional_param('return', 0, PARAM_BOOL); //return to course/view.php if false or mod/modname/view.php if true $type = optional_param('type', '', PARAM_ALPHANUM); + $PAGE->set_generaltype('form'); + require_login(); if (!empty($add)) { diff --git a/course/rest.php b/course/rest.php index 7f445849cf..562af297bd 100644 --- a/course/rest.php +++ b/course/rest.php @@ -25,25 +25,10 @@ if (!$course = $DB->get_record('course', array('id'=>$courseid))) { die; } -$PAGE = page_create_object(PAGE_COURSE_VIEW, $course->id); -$pageblocks = blocks_setup($PAGE, BLOCKS_PINNED_BOTH); - -if (!empty($instanceid)) { - throw new moodle_exception('ajax blocks editing currently broken. MDL-19010'); -// $blockinstance = blocks_find_instance($instanceid, $pageblocks); -// if (!$blockinstance || $blockinstance->pageid != $course->id -// || $blockinstance->pagetype != 'course-view') { -// error_log('AJAX commands.php: Bad block ID '.$instanceid); -// die; -// } -} - $context = get_context_instance(CONTEXT_COURSE, $course->id); require_login($course); require_capability('moodle/course:update', $context); - - // OK, now let's process the parameters and do stuff switch($_SERVER['REQUEST_METHOD']) { case 'POST': diff --git a/course/view.php b/course/view.php index a3e58eea48..4c7288d517 100644 --- a/course/view.php +++ b/course/view.php @@ -93,10 +93,6 @@ $PAGE->set_pagetype('course-view-' . $course->format); $PAGE->set_other_editing_capability('moodle/course:manageactivities'); - // 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_PINNED_BOTH); - if ($reset_user_allowed_editing) { // ugly hack unset($PAGE->_user_allowed_editing); diff --git a/index.php b/index.php index aee1d81e2e..d6b680c2f9 100644 --- a/index.php +++ b/index.php @@ -34,18 +34,6 @@ require_once($CFG->dirroot .'/course/lib.php'); require_once($CFG->libdir .'/filelib.php'); - // Bounds for block widths - // more flexible for theme designers taken from theme config.php - $lmin = (empty($THEME->block_l_min_width)) ? 100 : $THEME->block_l_min_width; - $lmax = (empty($THEME->block_l_max_width)) ? 210 : $THEME->block_l_max_width; - $rmin = (empty($THEME->block_r_min_width)) ? 100 : $THEME->block_r_min_width; - $rmax = (empty($THEME->block_r_max_width)) ? 210 : $THEME->block_r_max_width; - - define('BLOCK_L_MIN_WIDTH', $lmin); - define('BLOCK_L_MAX_WIDTH', $lmax); - define('BLOCK_R_MIN_WIDTH', $rmin); - define('BLOCK_R_MAX_WIDTH', $rmax); - // check if major upgrade needed - also present in login/index.php if (empty($CFG->version) or (int)$CFG->version < 2009011900 or !empty($CFG->adminsetuppending)) { //1.9 or older @require_logout(); @@ -97,36 +85,10 @@ $PAGE->set_url(''); $PAGE->set_docs_path(''); $PAGE->set_generaltype('home'); - $pageblocks = blocks_setup($PAGE); $editing = $PAGE->user_is_editing(); - $preferred_width_left = bounded_number(BLOCK_L_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), - BLOCK_L_MAX_WIDTH); - $preferred_width_right = bounded_number(BLOCK_R_MIN_WIDTH, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), - BLOCK_R_MAX_WIDTH); - print_header($SITE->fullname, $SITE->fullname, 'home', '', '', true, '', user_login_string($SITE).$langmenu); - -?> - - - - - layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - switch ($column) { - case 'left': - if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $editing) { - echo ''; - } - break; - case 'middle': - echo ''; - break; - case 'right': - // The right column - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $editing || $PAGE->user_allowed_editing()) { - echo ''; - } - break; - } - } -?> - - -
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''. skip_main_destination(); - - print_container_start(); + $PAGE->set_title($SITE->fullname); + $PAGE->set_heading($SITE->fullname); + echo $OUTPUT->header('', user_login_string($SITE) . $langmenu); /// Print Section if ($SITE->numsections > 0) { @@ -249,32 +211,4 @@ echo '
    '; } - print_container_end(); - - echo '
    '; - print_container_start(); - if ($PAGE->user_allowed_editing()) { - echo '
    '.update_course_icon($SITE->id).'
    '; - echo '
    '; - } - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
    - - - + echo $OUTPUT->footer(); diff --git a/install.php b/install.php index 0cc136f75e..283140b00f 100644 --- a/install.php +++ b/install.php @@ -146,6 +146,7 @@ require_once($CFG->libdir.'/weblib.php'); require_once($CFG->libdir.'/outputlib.php'); require_once($CFG->libdir.'/dmllib.php'); require_once($CFG->libdir.'/moodlelib.php'); +require_once($CFG->libdir .'/pagelib.php'); require_once($CFG->libdir.'/deprecatedlib.php'); require_once($CFG->libdir.'/adminlib.php'); require_once($CFG->libdir.'/environmentlib.php'); diff --git a/lib/adminlib.php b/lib/adminlib.php index 62e7408c57..3cccbf9758 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -5046,143 +5046,57 @@ function admin_externalpage_setup($section, $extrabutton = '', * @param string $focus focus element */ function admin_externalpage_print_header($focus='') { + global $CFG, $PAGE, $SITE, $THEME; if (!is_string($focus)) { $focus = ''; // BC compatibility, there used to be adminroot parameter } - global $CFG, $PAGE, $SITE, $THEME; - - define('ADMIN_EXT_HEADER_PRINTED', 'true'); - - if (!empty($SITE->fullname) and !empty($SITE->shortname)) { - // 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); - - $preferred_width_left = blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]); - $preferred_width_right = blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]); - - $adminroot = admin_get_root(false, false); //settings not required - only pages - - // fetch the path parameter - $section = $PAGE->url->param('section'); - $current = $adminroot->locate($section, true); - $visiblepathtosection = array_reverse($current->visiblepath); - - if ($PAGE->user_allowed_editing()) { - $options = $PAGE->url->params(); - if ($PAGE->user_is_editing()) { - $caption = get_string('blockseditoff'); - $options['adminedit'] = 'off'; - } else { - $caption = get_string('blocksediton'); - $options['adminedit'] = 'on'; - } - $buttons = print_single_button($PAGE->url->out(false), $options, $caption, 'get', '', true); - } - - $navlinks = array(); - foreach ($visiblepathtosection as $element) { - $navlinks[] = array('name' => $element, 'link' => null, 'type' => 'misc'); - } - $navigation = build_navigation($navlinks); - - print_header("$SITE->shortname: " . implode(": ",$visiblepathtosection), $SITE->fullname, $navigation, $focus, '', true, $buttons, ''); - - echo ''; - - $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - $lt1[] = $column; - if ($column == 'middle') break; - } - foreach ($lt1 as $column) { - switch ($column) { - case 'left': - echo ''; - break; - - case 'middle': - echo ''; - } - break; - } - } - } else { + if (empty($SITE->fullname) || empty($SITE->shortname)) { + // During initial install. $strinstallation = get_string('installation', 'install'); $strsettings = get_string('settings'); $navigation = build_navigation(array(array('name'=>$strsettings, 'link'=>null, 'type'=>'misc'))); print_header($strinstallation, $strinstallation, $navigation, "", "", false, " ", " "); + return; } -} -/** - * Print footer on admin page - please use normal print_footer() instead - */ -function admin_externalpage_print_footer() { - - global $CFG, $PAGE, $SITE, $THEME; + // Normal case. + $adminroot = admin_get_root(false, false); //settings not required - only pages - define('ADMIN_EXT_FOOTER_PRINTED', 'true'); + // fetch the path parameter + $section = $PAGE->url->param('section'); + $current = $adminroot->locate($section, true); + $visiblepathtosection = array_reverse($current->visiblepath); - if (!empty($SITE->fullname)) { - $pageblocks = blocks_setup($PAGE); - $preferred_width_left = blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]); - $preferred_width_right = blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]); - - $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - if ($column != 'middle') { - array_shift($lt); - } else if ($column == 'middle') { - break; - } + if ($PAGE->user_allowed_editing()) { + $options = $PAGE->url->params(); + if ($PAGE->user_is_editing()) { + $caption = get_string('blockseditoff'); + $options['adminedit'] = 'off'; + } else { + $caption = get_string('blocksediton'); + $options['adminedit'] = 'on'; } - foreach ($lt as $column) { - switch ($column) { - case 'left': - echo ''; - break; - - case 'middle': - print_container_end(); - $THEME->open_header_containers--; // this is hacky workaround for the print_error()/notice() autoclosing problems on admin pages - echo ''; - break; + $buttons = print_single_button($PAGE->url->out(false), $options, $caption, 'get', '', true); + } - case 'right': - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT)) { - echo ''; - } - break; - } - } - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - 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 ''; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo ''; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
    '; + $navlinks = array(); + foreach ($visiblepathtosection as $element) { + $navlinks[] = array('name' => $element, 'link' => null, 'type' => 'misc'); } + $navigation = build_navigation($navlinks); + + print_header("$SITE->shortname: " . implode(": ",$visiblepathtosection), $SITE->fullname, $navigation, $focus, '', true, $buttons, ''); +} + +/** + * @deprecated since Moodle 1.9. Please use normal print_footer() instead + */ +function admin_externalpage_print_footer() { +// 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 897f12986a..1e88bcac94 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 0f505cbb9f..02cb6af8ca 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. * + * The page to work with as passed to the constructor. * - * 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. - * - * @todo Deprecate this function - * @deprecated + * @deprecated since 2.0 + * Delete all the blocks from a particular page. * - * @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; - - $isediting = $page->user_is_editing(); - $groupblocks = $blockmanager->get_blocks_for_region($region); - - 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); - } +function blocks_repopulate_page($page) { + global $CFG; - 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 + 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 ($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(); } -} -/** - * This iterates over an array of blocks and calculates the preferred width - * Parameter passed by reference for speed; it's not modified. - * - * @todo Finish this function - * - * @param mixed $instances - */ -function blocks_preferred_width($instances) { - $width = 210; + $blocks = blocks_parse_default_blocks_list($blocknames); + $page->blocks->add_blocks($blocks); + + return true; } /** - * Get the block record for a particulr blockid. + * Get the block record for a particular blockid - that is, a particul type os block. * - * @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 = '

    '; - $strblocks .= get_string('blocks'); - $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 77e7c2a334..57cc441533 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 2c3bc83ab4..fe0da0c29e 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 c084b27f54..7b750cc860 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: *
      - *
    1. filename for example 'layout.php'. Use that file from this theme.
    2. - *
    3. parent:filename for example 'parent:layout-popup.php'. Use the + *
    4. filename for example 'layout-home.php' as above. Use that file from this theme.
    5. + *
    6. 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!)
    7. *
    8. standard:filename for example 'standard:layout-popup.php'. Use * the specified file from the standard theme.
    9. *
    + * To promote conisitency, you are encouraged to call your layout files + * layout.php or layout-something.php. * - * @var array - */ - public $layouttemplates = array(); - - /** - * Names of the regions where blocks may appear on the page. + * '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 + *
    +     *   echo $OUTPUT->blocks_for_region($regionname);
    +     * 
    + * or equivalent so that the blocks are actually visible. * - * For each region you list in $THEME->blockregions you must call - * blocks_print_group with that region id somewhere in your layout template. + * '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 $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 ''; + + } else if ($column == 'middle') { + echo ''; + + } else if ($column == 'right' && $this->page->blocks->region_has_content(BLOCK_POS_RIGHT)) { + echo ''; + } + } + echo '
    '; + echo $this->container_start(); + echo $this->blocks_for_region(BLOCK_POS_LEFT); + echo $this->container_end(); + echo ''; + echo $this->container_start(); + echo $this->skip_link_target(); + echo self::MAIN_CONTENT_TOKEN; + echo $this->container_end(); + echo ''; + echo $this->container_start(); + echo $this->blocks_for_region(BLOCK_POS_RIGHT); + echo $this->container_end(); + 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,56 +2034,83 @@ 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); } - $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)); + 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')); + $output .= $bc->content; + if ($bc->footer) { $output .= $this->output_tag('div', array('class' => 'footer'), $bc->footer); } $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. + * + * 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. * - * That is, it holds all the different bits of HTML content that need to be put into the block. + * 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; + + /** + * @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 $blockinstanceid = 0; + /** - * @param string $title Plain text title, as embedded in the $heading. + * @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 $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 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 $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 $list = array(); - /** - * @param array $icons optional icons for the things in $list. - */ - public $icons = array(); + public $footer = ''; + /** - * @param string $footer Extra HTML content that gets output at the end, inside a <div class="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 $footer = ''; + public $annotation = ''; + /** - * @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. + * @var integer one of the constants NOT_HIDEABLE, VISIBLE, HIDDEN. Whether + * the user can toggle whether this block is visible. */ - public $attributes = array(); + public $collapsible = self::NOT_HIDEABLE; + /** - * @param integer $skipid do not set this manually. It is set automatically be the {@link prepare()} method. + * 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 $skipid; + 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 7f0c049f15..7c1a822ab3 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 5833a7c2b8..4584243097 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 74905e26d7..f2ed938a50 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 2e8f4abf92..d73a8c74fe 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 420977ad72..778d9aa348 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 8a72f14024..9b84b376e8 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 0262da2525..e0d05bb390 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 ''; - - $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - switch ($column) { - case 'left': - - if(!empty($CFG->showblocksonmodpages) && (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) { - echo ''; - } - break; - - case 'middle': - - echo ''; - - break; + /// 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"); + + if ($currentgroup) { + $groupselect = " AND groupid = '$currentgroup'"; + $groupparam = "&groupid=$currentgroup"; + } else { + $groupselect = ""; + $groupparam = ""; + } + + if ($chat->studentlogs or has_capability('mod/chat:readlog',$context)) { + if ($msg = $DB->get_records_select('chat_messages', "chatid = ? $groupselect", array($chat->id))) { + echo ''; } } - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''; - print_container_start(); - - /// 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"); - - if ($currentgroup) { - $groupselect = " AND groupid = '$currentgroup'"; - $groupparam = "&groupid=$currentgroup"; - } else { - $groupselect = ""; - $groupparam = ""; - } - - if ($chat->studentlogs or has_capability('mod/chat:readlog',$context)) { - if ($msg = $DB->get_records_select('chat_messages', "chatid = ? $groupselect", array($chat->id))) { - 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 '

    '; - link_to_popup_window ($chattarget, - "chat$course->id$chat->id$groupparam", "$strenterchat", 500, 700, get_string('modulename', 'chat')); - echo '

    '; - - if ($CFG->enableajax) { - echo '

    '; - link_to_popup_window ("/mod/chat/gui_ajax/index.php?id=$chat->id$groupparam", - "chat$course->id$chat->id$groupparam", get_string('ajax_gui', 'message'), 500, 700, get_string('modulename', 'chat')); - 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 '

    ('; - link_to_popup_window ("/mod/chat/gui_basic/index.php?id=$chat->id$groupparam", - "chat$course->id$chat->id$groupparam", get_string('noframesjs', 'message'), 500, 700, get_string('modulename', 'chat')); - echo ')

    '; - } - - print_box_end(); - - } else { - print_box_start('generalbox', 'notallowenter'); - echo '

    '.get_string('notallowenter', 'chat').'

    '; - print_box_end(); - } - - if ($chat->chattime and $chat->schedule) { // A chat is scheduled - echo "

    $strnextsession: ".userdate($chat->chattime).' ('.usertimezone($USER->timezone).')

    '; - } else { - echo '
    '; - } - - if ($chat->intro) { - print_box(format_module_intro('chat', $chat, $cm->id), 'generalbox', 'intro'); - } - - chat_delete_old_users(); - - if ($chatusers = chat_get_users($chat->id, $currentgroup, $cm->groupingid)) { - $timenow = time(); - print_simple_box_start('center'); - print_heading($strcurrentusers); - echo ''; - foreach ($chatusers as $chatuser) { - $lastping = $timenow - $chatuser->lastmessageping; - echo ''; - } - echo '
    '; - echo "wwwroot/user/view.php?id=$chatuser->id&course=$chat->course\">"; - print_user_picture($chatuser, 0, $chatuser->picture, false, false, false); - echo ''; - echo '

    '; - echo fullname($chatuser).'
    '; - echo "$stridle: ".format_time($lastping).""; - echo '

    '; - echo '
    '; - print_simple_box_end(); - } - - print_container_end(); - 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 '

    '; + link_to_popup_window ($chattarget, + "chat$course->id$chat->id$groupparam", "$strenterchat", 500, 700, get_string('modulename', 'chat')); + echo '

    '; + + if ($CFG->enableajax) { + echo '

    '; + link_to_popup_window ("/mod/chat/gui_ajax/index.php?id=$chat->id$groupparam", + "chat$course->id$chat->id$groupparam", get_string('ajax_gui', 'message'), 500, 700, get_string('modulename', 'chat')); + 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 '

    ('; + link_to_popup_window ("/mod/chat/gui_basic/index.php?id=$chat->id$groupparam", + "chat$course->id$chat->id$groupparam", get_string('noframesjs', 'message'), 500, 700, get_string('modulename', 'chat')); + echo ')

    '; + } + + print_box_end(); + + } else { + print_box_start('generalbox', 'notallowenter'); + echo '

    '.get_string('notallowenter', 'chat').'

    '; + print_box_end(); + } + + if ($chat->chattime and $chat->schedule) { // A chat is scheduled + echo "

    $strnextsession: ".userdate($chat->chattime).' ('.usertimezone($USER->timezone).')

    '; + } else { + echo '
    '; + } + + if ($chat->intro) { + print_box(format_module_intro('chat', $chat, $cm->id), 'generalbox', 'intro'); + } + + chat_delete_old_users(); + + if ($chatusers = chat_get_users($chat->id, $currentgroup, $cm->groupingid)) { + $timenow = time(); + print_simple_box_start('center'); + print_heading($strcurrentusers); + echo ''; + foreach ($chatusers as $chatuser) { + $lastping = $timenow - $chatuser->lastmessageping; + echo ''; + } + echo '
    '; + echo "wwwroot/user/view.php?id=$chatuser->id&course=$chat->course\">"; + print_user_picture($chatuser, 0, $chatuser->picture, false, false, false); + echo ''; + echo '

    '; + echo fullname($chatuser).'
    '; + echo "$stridle: ".format_time($lastping).""; + echo '

    '; + echo '
    '; + print_simple_box_end(); + } print_footer($course); diff --git a/mod/data/view.php b/mod/data/view.php index 840ff67cf8..8501027627 100755 --- a/mod/data/view.php +++ b/mod/data/view.php @@ -255,8 +255,6 @@ // Initialize $PAGE, compute blocks $PAGE->set_url('mod/data/view.php', array('id' => $cm->id)); - $pageblocks = blocks_setup($PAGE); - $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210); if (($edit != -1) and $PAGE->user_allowed_editing()) { $USER->editing = $edit; @@ -293,20 +291,6 @@ $navigation = build_navigation(array(), $cm); print_header($title, $course->fullname, $navigation, '', '', true, $buttons, navmenu($course, $cm)); -/// If we have blocks, then print the left side here - if (!empty($CFG->showblocksonmodpages)) { - echo ''; - if ((blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) { - echo ''; - } - echo ''; // Middle column - if ((blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing())) { - echo ''; - } - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - 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 ''; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
    '; - } - - print_footer($course); - /// Mark as viewed $completion=new completion_info($course); $completion->set_module_viewed($cm); + + print_footer($course); ?> diff --git a/mod/lesson/view.php b/mod/lesson/view.php index 9a9c49d79b..b882bf7a94 100644 --- a/mod/lesson/view.php +++ b/mod/lesson/view.php @@ -501,10 +501,6 @@ $PAGE->set_url('mod/lesson/view.php', array('id' => $cm->id, 'pageid' => $page->id)); $PAGE->set_subpage($page->id); - $pageblocks = blocks_setup($PAGE); - - $leftcolumnwidth = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210); - $rightcolumnwidth = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210); if (($edit != -1) and $PAGE->user_allowed_editing()) { $USER->editing = $edit; diff --git a/mod/quiz/accessrules.php b/mod/quiz/accessrules.php index 9f31e62d80..baf66601bd 100644 --- a/mod/quiz/accessrules.php +++ b/mod/quiz/accessrules.php @@ -158,6 +158,7 @@ class quiz_access_manager { } public function show_attempt_timer_if_needed($attempt, $timenow) { + global $PAGE; $timeleft = false; foreach ($this->_rules as $rule) { $ruletimeleft = $rule->time_left($attempt, $timenow); diff --git a/mod/quiz/attempt.php b/mod/quiz/attempt.php index f429e77aef..0bc05abc16 100644 --- a/mod/quiz/attempt.php +++ b/mod/quiz/attempt.php @@ -76,6 +76,11 @@ /// Print the quiz page //////////////////////////////////////////////////////// + // Arrange for the navigation to be displayed. + $navbc = $attemptobj->get_navigation_panel('quiz_attempt_nav_panel', $page); + $firstregion = reset($PAGE->blocks->get_regions()); + $PAGE->blocks->add_pretend_block($navbc, $firstregion); + // Print the page header $PAGE->requires->yui_lib('event'); $title = get_string('attempt', 'quiz', $attemptobj->get_attempt_number()); @@ -126,18 +131,6 @@ echo $PAGE->requires->js_function_call('init_quiz_form')->asap(); echo '
    '; -/// Print the navigation panel in a left column. - print_container_start(); - echo '
    '; - $attemptobj->print_navigation_panel('quiz_attempt_nav_panel', $page); - echo '
    '; - print_container_end(); - -/// Start the main column. - echo '
    '; - print_container_start(); - echo skip_main_destination(); - /// Print all the questions foreach ($attemptobj->get_question_ids($page) as $id) { $attemptobj->print_question($id, false, $attemptobj->attempt_url($id, $page)); @@ -167,16 +160,10 @@ echo '\n"; - // End middle column. - print_container_end(); - // Finish the form echo '
    '; - echo '
    '; echo "\n"; - echo '
    '; - // Finish the page $accessmanager->show_attempt_timer_if_needed($attemptobj->get_attempt(), time()); if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) { diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index d8f8644a91..6fca3878b7 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -707,9 +707,9 @@ class quiz_attempt extends quiz { $this->context, $this->cm); } - public function print_navigation_panel($panelclass, $page) { + public function get_navigation_panel($panelclass, $page) { $panel = new $panelclass($this, $this->get_review_options(), $page); - $panel->display(); + return $panel->get_contents(); } /// List of all this user's attempts for people who can see reports. @@ -807,8 +807,13 @@ class quiz_attempt extends quiz { $page = 0; } $fragment = ''; - if ($questionid && $questionid != reset($this->pagequestionids[$page])) { - $fragment = '#q' . $questionid; + if ($questionid) { + if ($questionid == reset($this->pagequestionids[$page])) { + // First question on page, go to top. + $fragment = '#'; + } else { + $fragment = '#q' . $questionid; + } } $param = ''; if ($showall) { @@ -936,15 +941,19 @@ abstract class quiz_nav_panel_base { return $classes; } - public function display() { - $strquiznavigation = get_string('quiznavigation', 'quiz'); + public function get_contents() { $content = ''; if ($this->attemptobj->get_quiz()->showuserpicture) { $content .= $this->get_user_picture() . "\n"; } $content .= $this->get_question_buttons() . "\n"; $content .= '
    ' . "\n" . $this->get_end_bits() . "\n
    \n"; - print_side_block($strquiznavigation, $content, NULL, NULL, '', array('id' => 'quiznavigation'), $strquiznavigation); + + $bc = new block_contents(); + $bc->id = 'quiznavigation'; + $bc->title = get_string('quiznavigation', 'quiz'); + $bc->content = $content; + return $bc; } } diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index d5f7c5b49d..00cd7d7061 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -362,39 +362,6 @@ function quiz_repaginate($layout, $perpage, $shuffle = false) { return $layout.'0'; } -/** - * Print navigation panel for quiz attempt and review pages - * - * @param integer $page The number of the current page (counting from 0). - * @param integer $pages The total number of pages. - */ -function quiz_print_navigation_panel($page, $pages) { - //$page++; - echo '
    '; - echo '' . get_string('page') . ':'; - if ($page > 0) { - // Print previous link - $strprev = get_string('previous'); - echo ''; - } - for ($i = 0; $i < $pages; $i++) { - if ($i == $page) { - echo ''.($i+1).''; - } else { - echo ''.($i+1).''; - } - } - - if ($page < $pages - 1) { - // Print next link - $strnext = get_string('next'); - echo ''; - } - echo '
    '; -} - /// Functions to do with quiz grades ////////////////////////////////////////// /** diff --git a/mod/quiz/review.php b/mod/quiz/review.php index 22e9a397da..619f0a0b20 100644 --- a/mod/quiz/review.php +++ b/mod/quiz/review.php @@ -71,6 +71,11 @@ $strreviewtitle = get_string('reviewofattempt', 'quiz', $attemptobj->get_attempt_number()); } +/// Arrange for the navigation to be displayed. + $navbc = $attemptobj->get_navigation_panel('quiz_review_nav_panel', $page); + $firstregion = reset($PAGE->blocks->get_regions()); + $PAGE->blocks->add_pretend_block($navbc, $firstregion); + /// Print the page header $PAGE->requires->js('mod/quiz/quiz.js'); $headtags = $attemptobj->get_html_head_contributions($page); @@ -100,17 +105,6 @@ } print_heading($strreviewtitle); -/// Print the navigation panel in a left column. - print_container_start(); - echo '
    '; - $attemptobj->print_navigation_panel('quiz_review_nav_panel', $page); - echo '
    '; - print_container_end(); - -/// Start the main column. - echo '
    '; - echo skip_main_destination(); - /// Summary table start ============================================================================ /// Work out some time-related things. @@ -247,11 +241,6 @@ } echo "
    "; - // End middle column. - echo ''; - - echo '
    '; - // Finish the page if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) { print_footer('empty'); diff --git a/mod/quiz/view.php b/mod/quiz/view.php index d621b3c909..40dd99a6af 100644 --- a/mod/quiz/view.php +++ b/mod/quiz/view.php @@ -57,8 +57,6 @@ /// Initialize $PAGE, compute blocks $PAGE->set_url('mod/quiz/view.php', array('id' => $cm->id)); - $pageblocks = blocks_setup($PAGE); - $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210); $edit = optional_param('edit', -1, PARAM_BOOL); if ($edit != -1 && $PAGE->user_allowed_editing()) { @@ -88,20 +86,6 @@ $navigation = build_navigation(array(), $cm); print_header($title, $course->fullname, $navigation, '', '', true, $buttons, navmenu($course, $cm), false, $bodytags); -/// Print any blocks on the left of the page. - echo ''; - if(!empty($CFG->showblocksonmodpages) && (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) { - echo '\n"; - } - -/// Start the main part of the page - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - 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('

    ' . get_string('youneedtoenrol', 'quiz') . "

    \n\n

    " . print_continue($CFG->wwwroot . '/course/view.php?id=' . $course->id, true) . "

    \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); - -// Utility functions ================================================================= + $completion->set_module_viewed($cm); -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 704f592b62..62a84e9161 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 ''; - - $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - $lt1[] = $column; - if ($column == 'middle') break; - } - foreach ($lt1 as $column) { - switch ($column) { - case 'left': - if((blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing())) { - echo ''; - } - break; - - case 'middle': - echo ''; - } - break; - } - } } /** * Finish displaying the resource with the course blocks - * - * @global stdClass - * @global object - * @uses BLOCK_POS_LEFT - * @uses BLOCK_POS_RIGHT */ function display_course_blocks_end() { global $CFG, $THEME; diff --git a/my/index.php b/my/index.php index 5a5eb8c433..57f1a022af 100644 --- a/my/index.php +++ b/my/index.php @@ -24,10 +24,6 @@ $PAGE->set_url('my/index.php'); $PAGE->set_blocks_editing_capability('moodle/my:manageblocks'); - // 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_PINNED_BOTH); - if (($edit != -1) and $PAGE->user_allowed_editing()) { $USER->editing = $edit; } @@ -49,32 +45,8 @@ print_header($strmymoodle, $header, $navigation, '', '', true, $button, $loggedinas . $langmenu); - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - echo ''; - print_container_start(false, 'middle-column-wrap'); - echo '
    '; - break; - - case 'right': - if((blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing())) { - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
    '; - echo ''; - - $lt = (empty($THEME->layouttable)) ? array('left', 'middle', 'right') : $THEME->layouttable; - foreach ($lt as $column) { - switch ($column) { - case 'left': - - $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210); - - if(blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing()) { - echo ''; - } - - break; - case 'middle': - - echo ''; - - break; - case 'right': - - $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210); - - if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing()) { - echo ''; - } - break; - } - } - - /// Finish the page - echo '
    '; - print_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - print_container_end(); - 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_container_start(); - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - print_container_end(); - echo '
    '; print_footer(); diff --git a/tag/index.php b/tag/index.php index a29ca6719b..a254f1d64b 100644 --- a/tag/index.php +++ b/tag/index.php @@ -33,7 +33,6 @@ if (empty($tag)) { $PAGE->set_url('tag/index.php', array('id' => $tag->id)); $PAGE->set_subpage($tag->id); $PAGE->set_blocks_editing_capability('moodle/tag:editblocks'); -$pageblocks = blocks_setup($PAGE,BLOCKS_PINNED_BOTH); if (($edit != -1) and $PAGE->user_allowed_editing()) { $USER->editing = $edit; @@ -61,23 +60,6 @@ if (has_capability('moodle/tag:manage', $systemcontext)) { echo '' ; } -echo ''; -echo ''; - -//----------------- left column ----------------- - -$blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_LEFT]), 210); - -if (blocks_have_content($pageblocks, BLOCK_POS_LEFT) || $PAGE->user_is_editing()) { - echo ''; -} - -//----------------- middle column ----------------- - -echo ''; - -//----------------- right column ----------------- - -$blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210); - -if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing()) { - echo ''; -} - -/// Finish the page -echo '
    '; - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_LEFT); - echo ''; - $tagname = tag_display_name($tag); if ($tag->flag > 0 && has_capability('moodle/tag:manage', $systemcontext)) { @@ -168,20 +150,5 @@ if ($usercount > 0) { print_box_end(); } -echo ''; - blocks_print_group($PAGE, $pageblocks, BLOCK_POS_RIGHT); - echo '
    '; - print_footer(); ?> diff --git a/tag/search.php b/tag/search.php index 313ca05048..4bfd1b8e2c 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 0000000000..76a873f13c --- /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 ff07fda9a3..aa3fcf901e 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 e6cb506c1e..eed045b157 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 9f666af3ae..e87e8610f0 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, '
    ') === false) { - $bc->heading = $this->output_tag('div', array('class' => 'title'), - $this->output_tag('h2', null, $bc->heading)); - } + $controlshtml = $this->block_controls($bc->controls); + $title = ''; + if ($bc->title) { + $title = $this->output_tag('h2', null, $bc->title); + } + + if ($title || $controlshtml) { $output .= '
     
    '; $output .= '
    '; - $output .= $bc->heading; + $output .= '
    ' . $title . $controlshtml . '
    '; $output .= '
    '; } else { $output .= '
     
    '; } $output .= '
    '; - - if ($bc->content) { - $output .= $bc->content; - - } else if ($bc->list) { - $row = 0; - $output .= $this->output_start_tag('ul', array('class' => 'list')); - $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); @@ -181,13 +159,7 @@ class custom_corners_core_renderer extends moodle_core_renderer { $output .= '
     
    '; $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; } diff --git a/theme/standard/config.php b/theme/standard/config.php index 97aea11199..dd28ffb765 100644 --- a/theme/standard/config.php +++ b/theme/standard/config.php @@ -44,12 +44,35 @@ $THEME->standardmetainclude = true; $THEME->custompix = false; -$THEME->layouttemplates = array( - 'normal' => 'layout.php', - 'home' => 'layout-home.php', +$THEME->layouts = array( + // Most pages. Put this first, so if we encounter an unknown page type, this is used. + 'normal' => array( + 'layout' => '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' + ), + // Settings form pages, like course of module settings. + 'form' => array( + 'layout' => 'layout.php', + 'regions' => array(), + ), + // Pages that appear in pop-up windows. + 'popup' => array( + 'layout' => 'layout-popup.php', + 'regions' => array(), + ), + // Used during upgrade and install, and for the 'This site is undergoing maintenance' message. + 'maintenance' => array( + 'layout' => 'layout-popup.php', + 'regions' => array(), + ), ); -$THEME->blockregions = array('side-pre', 'side-post'); -$THEME->defaultblockregion = 'side-post'; $THEME->resource_mp3player_colors = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&'. diff --git a/theme/standard/layout-home.php b/theme/standard/layout-home.php index 28edf447cd..e5c45d511f 100644 --- a/theme/standard/layout-home.php +++ b/theme/standard/layout-home.php @@ -24,9 +24,26 @@
    -
    - [MAIN CONTENT GOES HERE] -
    + + + + blocks->region_has_content('side-pre')) { ?> + + + + blocks->region_has_content('side-post')) { ?> + + + +
    + blocks_for_region('side-pre') ?> + + [MAIN CONTENT GOES HERE] + + blocks_for_region('side-post') ?> +