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:
tjhunt 2009-07-01 05:54:26 +00:00
parent 0456fc1ac4
commit b70094743a
37 changed files with 1646 additions and 1531 deletions

View file

@ -179,22 +179,48 @@ function default_exception_handler($ex, $isupgrade = false, $plugin = null) {
$CFG->debug = DEBUG_DEVELOPER;
}
// If another exception is thrown when we are already handling one, or during $OUTPUT->header,
// and if we did not take special measures, we would just get a very cryptic message
// "Exception thrown without a stack frame in Unknown on line 0", rather than the true error.
// Therefore, we do take special measures.
foreach ($backtrace as $stackframe) {
if (isset($stackframe['function']) && isset($stackframe['type']) &&
$stackframe['type'] == '->' && $stackframe['function'] == 'header') {
echo bootstrap_renderer::early_error($message, $moreinfourl, $link, debug_backtrace());
exit(1); // General error code
}
if (is_stacktrace_during_output_init($backtrace)) {
echo bootstrap_renderer::early_error($message, $moreinfourl, $link, $backtrace);
} else {
echo $OUTPUT->fatal_error($message, $moreinfourl, $link, $backtrace, $debuginfo);
}
echo $OUTPUT->fatal_error($message, $moreinfourl, $link, debug_backtrace());
exit(1); // General error code
}
/**
* This function encapsulates the tests for whether an exception was thrown in the middle
* of initialising the $OUTPUT variable and starting output.
*
* If another exception is thrown then, and if we do not take special measures,
* we would just get a very cryptic message "Exception thrown without a stack
* frame in Unknown on line 0". That makes debugging very hard, so we do take
* special measures in default_exception_handler, with the help of this function.
*
* @param array $backtrace the stack trace to analyse.
* @return boolean whether the stack trace is somewhere in output initialisation.
*/
function is_stacktrace_during_output_init($backtrace) {
$dangerouscode = array(
array('function' => 'header', 'type' => '->'),
array('class' => 'bootstrap_renderer'),
);
foreach ($backtrace as $stackframe) {
foreach ($dangerouscode as $pattern) {
$matches = true;
foreach ($pattern as $property => $value) {
if (!isset($stackframe[$property]) || $stackframe[$property] != $value) {
$matches = false;
}
}
if ($matches) {
return true;
}
}
}
return false;
}
/**
* Abort execution, displaying an error message.
*
@ -751,16 +777,21 @@ class bootstrap_renderer {
*/
protected $initialising = false;
/**
* Have we started output yet?
* @return boolean true if the header has been printed.
*/
public function has_started() {
return false;
}
public function __call($method, $arguments) {
global $OUTPUT;
global $OUTPUT, $PAGE;
// If lib/outputlib.php has been loaded, call it.
if (!$this->initialising && function_exists('initialise_theme_and_output')) {
$this->initialising = true;
initialise_theme_and_output(debug_backtrace());
if (!($OUTPUT instanceof bootstrap_renderer)) {
return call_user_func_array(array($OUTPUT, $method), $arguments);
}
if (!empty($PAGE)) {
$PAGE->initialise_theme_and_output();
return call_user_func_array(array($OUTPUT, $method), $arguments);
}
$this->initialising = true;
@ -782,6 +813,8 @@ class bootstrap_renderer {
*/
public static function early_error($message, $moreinfourl, $link, $backtrace,
$debuginfo = null, $showerrordebugwarning = false) {
global $CFG;
// In the name of protocol correctness, monitoring and performance
// profiling, set the appropriate error headers for machine comsumption
if (isset($_SERVER['SERVER_PROTOCOL'])) {