mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
themes: MDL-19077 change how the theme is initialised and CSS is served.
This is part of http://docs.moodle.org/en/Development:Theme_engines_for_Moodle%3F $THEME is now initialised at the same time as $OUTPUT. Old functions like theme_setup are deprecated in favour of methods on $PAGE. There is a new theme_config class in outputlib.php that deals with loading the theme config.php file. CSS used to be served by themes styles.php files calling a function in weblib.php. Now it works by each theme's styles.php file doing $themename = basename(dirname(__FILE__)); require_once(dirname(__FILE__) . '/../../theme/styles.php'); which is less code to be copied into each theme. (Old-style styles.php files still work thanks to some code in deprecatedlib.php.) Admin UI for choosing a theme cleaned up. A couple of theme-specific hard-coded hacks like $THEME->cssconstants and $THEME->CSSEdit have been replaced by a more generic $THEME->customcssoutputfunction hook. See examples at the end of outputlib.php Also: * Fix setting the theme in the URL, which seems to have been broken since 1.9. * Fix up errors on a few pages caused by the new initialisation order. * MDL-19097 moodle_page::set_course should not set $COURSE unless it is $PAGE. * httpsrequired() from moodlelib.php moved to $PAGE->https_required(). * Move has_started() method to the renderer base class. * Further fixes to display of early errors. * Remove print_header/footer_old from weblib. I did not mean to commit them before.
This commit is contained in:
parent
0456fc1ac4
commit
b70094743a
37 changed files with 1646 additions and 1531 deletions
211
lib/pagelib.php
211
lib/pagelib.php
|
@ -125,6 +125,14 @@ class moodle_page {
|
|||
|
||||
protected $_button = '';
|
||||
|
||||
protected $_theme = null;
|
||||
|
||||
/**
|
||||
* Then the theme is initialsed, we save the stack trace, for use in error messages.
|
||||
* @var array stack trace.
|
||||
*/
|
||||
protected $_wherethemewasinitialised = null;
|
||||
|
||||
/**
|
||||
* Sets the page to refresh after a given delay (in seconds) using meta refresh
|
||||
* in {@link standard_head_html()} in outputlib.php
|
||||
|
@ -346,15 +354,12 @@ class moodle_page {
|
|||
public function get_blocks() {
|
||||
global $CFG, $THEME;
|
||||
if (is_null($this->_blocks)) {
|
||||
initialise_theme_and_output();
|
||||
if (!empty($CFG->blockmanagerclass)) {
|
||||
$classname = $CFG->blockmanagerclass;
|
||||
} else {
|
||||
$classname = 'block_manager';
|
||||
}
|
||||
$this->_blocks = new $classname($this);
|
||||
$this->_blocks->add_regions($THEME->blockregions);
|
||||
$this->_blocks->set_default_region($THEME->defaultblockregion);
|
||||
}
|
||||
return $this->_blocks;
|
||||
}
|
||||
|
@ -395,6 +400,17 @@ class moodle_page {
|
|||
return $this->_button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Please do not call this method directly, use the ->theme syntax. {@link __get()}.
|
||||
* @return string the initialised theme for this page.
|
||||
*/
|
||||
public function get_theme() {
|
||||
if (is_null($this->_theme)) {
|
||||
$this->initialise_theme_and_output();
|
||||
}
|
||||
return $this->_theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Please do not call this method directly use the ->periodicrefreshdelay syntax
|
||||
* {@link __get()}
|
||||
|
@ -482,28 +498,28 @@ class moodle_page {
|
|||
* @param object the course to set as the global course.
|
||||
*/
|
||||
public function set_course($course) {
|
||||
global $COURSE;
|
||||
global $COURSE, $PAGE;
|
||||
|
||||
if (empty($course->id)) {
|
||||
throw new coding_exception('$course passed to moodle_page::set_course does not look like a proper course object.');
|
||||
}
|
||||
|
||||
if ($this->_state > self::STATE_BEFORE_HEADER) {
|
||||
throw new coding_exception('Cannot call moodle_page::set_course after output has been started.');
|
||||
}
|
||||
$this->ensure_theme_not_set();
|
||||
|
||||
if (!empty($this->_course->id) && $this->_course->id != $course->id) {
|
||||
$this->_categories = null;
|
||||
}
|
||||
|
||||
$this->_course = clone($course);
|
||||
$COURSE = $this->_course;
|
||||
|
||||
if ($this === $PAGE) {
|
||||
$COURSE = $this->_course;
|
||||
moodle_setlocale();
|
||||
}
|
||||
|
||||
if (!$this->_context) {
|
||||
$this->set_context(get_context_instance(CONTEXT_COURSE, $this->_course->id));
|
||||
}
|
||||
|
||||
moodle_setlocale();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -646,6 +662,7 @@ class moodle_page {
|
|||
if (is_array($this->_categories)) {
|
||||
throw new coding_exception('Course category has already been set. You are not allowed to change it.');
|
||||
}
|
||||
$this->ensure_theme_not_set();
|
||||
$this->set_course($SITE);
|
||||
$this->load_category($categoryid);
|
||||
$this->set_context(get_context_instance(CONTEXT_COURSECAT, $categoryid));
|
||||
|
@ -771,6 +788,46 @@ class moodle_page {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force this page to use a particular theme.
|
||||
*
|
||||
* Please use this cautiously. It is only intended to be used by the themes selector
|
||||
* admin page, and theme/styles.php.
|
||||
*
|
||||
* @param $themename the name of the theme to use.
|
||||
*/
|
||||
public function force_theme($themename) {
|
||||
global $PAGE, $THEME;
|
||||
$this->ensure_theme_not_set();
|
||||
$this->_theme = theme_config::load($themename);
|
||||
if ($this === $PAGE) {
|
||||
$THEME = $this->_theme;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function sets the $HTTPSPAGEREQUIRED global
|
||||
* (used in some parts of moodle to change some links)
|
||||
* and calculate the proper wwwroot to be used
|
||||
*
|
||||
* By using this function properly, we can ensure 100% https-ized pages
|
||||
* at our entire discretion (login, forgot_password, change_password)
|
||||
*/
|
||||
public function https_required() {
|
||||
global $CFG, $HTTPSPAGEREQUIRED;
|
||||
|
||||
$this->ensure_theme_not_set();
|
||||
|
||||
if (!empty($CFG->loginhttps)) {
|
||||
$HTTPSPAGEREQUIRED = true;
|
||||
$CFG->httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot);
|
||||
$CFG->httpsthemewww = str_replace('http:', 'https:', $CFG->themewww);
|
||||
} else {
|
||||
$CFG->httpswwwroot = $CFG->wwwroot;
|
||||
$CFG->httpsthemewww = $CFG->themewww;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialisation methods =====================================================
|
||||
/// These set various things up in a default way.
|
||||
|
||||
|
@ -794,6 +851,129 @@ class moodle_page {
|
|||
|
||||
$this->initialise_standard_body_classes();
|
||||
$this->blocks->load_blocks();
|
||||
|
||||
// Add any stylesheets required using the horrible legacy mechanism.
|
||||
if (!empty($CFG->stylesheets)) {
|
||||
debugging('Some code on this page is using the horrible legacy mechanism $CFG->stylesheets to include links to ' .
|
||||
'extra stylesheets. This is deprecated. Please use $PAGE->requires->css(...) instead.', DEBUG_DEVELOPER);
|
||||
foreach ($CFG->stylesheets as $stylesheet) {
|
||||
$this->page->requires->css($stylesheet, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Require theme stylesheets.
|
||||
$stylesheets = $this->theme->get_stylesheet_urls();
|
||||
foreach ($stylesheets as $stylesheet) {
|
||||
$this->requires->css($stylesheet, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for use by Moodle core to set up the theme. Do not
|
||||
* use this in your own code.
|
||||
*
|
||||
* Make sure the right theme for this page is loaded. Tell our
|
||||
* blocks_manager about the theme block regions, and then, if
|
||||
* we are $PAGE, set up the globals $THEME and $OUTPUT.
|
||||
*/
|
||||
public function initialise_theme_and_output() {
|
||||
global $OUTPUT, $PAGE, $SITE, $THEME;
|
||||
|
||||
if (!$this->_course) {
|
||||
$this->set_course($SITE);
|
||||
}
|
||||
|
||||
if (is_null($this->_theme)) {
|
||||
$themename = $this->resolve_theme();
|
||||
$this->_theme = theme_config::load($themename);
|
||||
}
|
||||
|
||||
$this->blocks->add_regions($this->_theme->blockregions);
|
||||
$this->blocks->set_default_region($this->_theme->defaultblockregion);
|
||||
|
||||
if ($this === $PAGE) {
|
||||
$THEME = $this->_theme;
|
||||
$this->_theme->setup_cfg_paths();
|
||||
if (CLI_SCRIPT) {
|
||||
$classname = 'cli_renderer_factory';
|
||||
} else {
|
||||
$classname = $this->_theme->rendererfactory;
|
||||
}
|
||||
$rendererfactory = new $classname($this->_theme, $this);
|
||||
$OUTPUT = $rendererfactory->get_renderer('core');
|
||||
}
|
||||
|
||||
$this->_wherethemewasinitialised = debug_backtrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Work out the theme this page should use.
|
||||
*
|
||||
* This depends on numerous $CFG settings, and the properties of this page.
|
||||
*
|
||||
* @return string the name of the theme that should be used on this page.
|
||||
*/
|
||||
protected function resolve_theme() {
|
||||
global $CFG, $USER, $SESSION;
|
||||
|
||||
if (empty($CFG->themeorder)) {
|
||||
$themeorder = array('course', 'category', 'session', 'user', 'site');
|
||||
} else {
|
||||
$themeorder = $CFG->themeorder;
|
||||
// Just in case, make sure we always use the site theme if nothing else matched.
|
||||
$themeorder[] = 'site';
|
||||
}
|
||||
|
||||
$mnetpeertheme = '';
|
||||
if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id) {
|
||||
require_once($CFG->dirroot.'/mnet/peer.php');
|
||||
$mnetpeer = new mnet_peer();
|
||||
$mnetpeer->set_id($USER->mnethostid);
|
||||
if ($mnetpeer->force_theme == 1 && $mnetpeer->theme != '') {
|
||||
$mnetpeertheme = $mnetpeer->theme;
|
||||
}
|
||||
}
|
||||
|
||||
$theme = '';
|
||||
foreach ($themeorder as $themetype) {
|
||||
switch ($themetype) {
|
||||
case 'course':
|
||||
if (!empty($CFG->allowcoursethemes) and !empty($this->course->theme)) {
|
||||
return $this->course->theme;
|
||||
}
|
||||
|
||||
case 'category':
|
||||
if (!empty($CFG->allowcategorythemes)) {
|
||||
$categories = $this->categories;
|
||||
foreach ($categories as $category) {
|
||||
if (!empty($category->theme)) {
|
||||
return $category->theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case 'session':
|
||||
if (!empty($SESSION->theme)) {
|
||||
return $SESSION->theme;
|
||||
}
|
||||
|
||||
case 'user':
|
||||
if (!empty($CFG->allowuserthemes) and !empty($USER->theme)) {
|
||||
if ($mnetpeertheme) {
|
||||
return $mnetpeertheme;
|
||||
} else {
|
||||
return $USER->theme;
|
||||
}
|
||||
}
|
||||
|
||||
case 'site':
|
||||
if ($mnetpeertheme) {
|
||||
return $mnetpeertheme;
|
||||
} else {
|
||||
return $CFG->theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -835,7 +1015,7 @@ class moodle_page {
|
|||
}
|
||||
|
||||
protected function initialise_standard_body_classes() {
|
||||
global $CFG;
|
||||
global $CFG, $USER;
|
||||
|
||||
$pagetype = $this->pagetype;
|
||||
if ($pagetype == 'site-index') {
|
||||
|
@ -948,6 +1128,15 @@ class moodle_page {
|
|||
}
|
||||
}
|
||||
|
||||
protected function ensure_theme_not_set() {
|
||||
if (!is_null($this->_theme)) {
|
||||
throw new coding_exception('The theme has already been set up for this page ready for output. ' .
|
||||
'Therefore, you can no longer change the theme, or anything that might affect what ' .
|
||||
'the current theme is, for example, the course.',
|
||||
'Stack trace when the theme was set up: ' . format_backtrace($this->_wherethemewasinitialised));
|
||||
}
|
||||
}
|
||||
|
||||
protected function url_to_class_name($url) {
|
||||
$bits = parse_url($url);
|
||||
$class = str_replace('.', '-', $bits['host']);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue