mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +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
826
lib/weblib.php
826
lib/weblib.php
|
@ -2357,256 +2357,6 @@ function send_headers($contenttype, $cacheable = true) {
|
|||
@header('Accept-Ranges: none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a standard header
|
||||
*
|
||||
* @param string $title Appears at the top of the window
|
||||
* @param string $heading Appears at the top of the page
|
||||
* @param string $navigation Array of $navlinks arrays (keys: name, link, type) for use as breadcrumbs links
|
||||
* @param string $focus Indicates form element to get cursor focus on load eg inputform.password
|
||||
* @param string $meta Meta tags to be added to the header
|
||||
* @param boolean $cache Should this page be cacheable?
|
||||
* @param string $button HTML code for a button (usually for module editing)
|
||||
* @param string $menu HTML code for a popup menu
|
||||
* @param boolean $usexml use XML for this page
|
||||
* @param string $bodytags This text will be included verbatim in the <body> tag (useful for onload() etc)
|
||||
* @param bool $return If true, return the visible elements of the header instead of echoing them.
|
||||
* @return string|void If return=true then string else void
|
||||
*/
|
||||
function print_header_old($title='', $heading='', $navigation='', $focus='',
|
||||
$meta='', $cache=true, $button=' ', $menu='',
|
||||
$usexml=false, $bodytags='', $return=false) {
|
||||
|
||||
global $USER, $CFG, $THEME, $SESSION, $ME, $SITE, $COURSE, $PAGE;
|
||||
|
||||
if (gettype($navigation) == 'string' && strlen($navigation) != 0 && $navigation != 'home') {
|
||||
debugging("print_header() was sent a string as 3rd ($navigation) parameter. "
|
||||
. "This is deprecated in favour of an array built by build_navigation(). Please upgrade your code.", DEBUG_DEVELOPER);
|
||||
}
|
||||
|
||||
$PAGE->set_state(moodle_page::STATE_PRINTING_HEADER);
|
||||
|
||||
$heading = format_string($heading); // Fix for MDL-8582
|
||||
|
||||
if (CLI_SCRIPT) {
|
||||
$output = $heading."\n";
|
||||
if ($return) {
|
||||
return $output;
|
||||
} else {
|
||||
echo $output;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// Add the required stylesheets
|
||||
$stylesheetshtml = '';
|
||||
foreach ($CFG->stylesheets as $stylesheet) {
|
||||
$stylesheetshtml .= '<link rel="stylesheet" type="text/css" href="'.$stylesheet.'" />'."\n";
|
||||
}
|
||||
$meta = $stylesheetshtml.$meta;
|
||||
|
||||
|
||||
/// Add the meta page from the themes if any were requested
|
||||
|
||||
$metapage = '';
|
||||
|
||||
if (!isset($THEME->standardmetainclude) || $THEME->standardmetainclude) {
|
||||
ob_start();
|
||||
include_once($CFG->dirroot.'/theme/standard/meta.php');
|
||||
$metapage .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if ($THEME->parent && (!isset($THEME->parentmetainclude) || $THEME->parentmetainclude)) {
|
||||
if (file_exists($CFG->dirroot.'/theme/'.$THEME->parent.'/meta.php')) {
|
||||
ob_start();
|
||||
include_once($CFG->dirroot.'/theme/'.$THEME->parent.'/meta.php');
|
||||
$metapage .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($THEME->metainclude) || $THEME->metainclude) {
|
||||
if (file_exists($CFG->dirroot.'/theme/'.current_theme().'/meta.php')) {
|
||||
ob_start();
|
||||
include_once($CFG->dirroot.'/theme/'.current_theme().'/meta.php');
|
||||
$metapage .= ob_get_contents();
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
$meta = $meta."\n".$metapage;
|
||||
$meta .= $PAGE->requires->get_head_code();
|
||||
|
||||
/// Set up some navigation variables
|
||||
|
||||
if (is_newnav($navigation)){
|
||||
$home = false;
|
||||
} else {
|
||||
if ($navigation == 'home') {
|
||||
$home = true;
|
||||
$navigation = '';
|
||||
} else {
|
||||
$home = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// This is another ugly hack to make navigation elements available to print_footer later
|
||||
$THEME->title = $title;
|
||||
$THEME->heading = $heading;
|
||||
$THEME->navigation = $navigation;
|
||||
$THEME->button = $button;
|
||||
$THEME->menu = $menu;
|
||||
$navmenulist = isset($THEME->navmenulist) ? $THEME->navmenulist : '';
|
||||
|
||||
if ($button == '') {
|
||||
$button = ' ';
|
||||
}
|
||||
|
||||
if (!empty($CFG->maintenance_enabled)) {
|
||||
$button = '<a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/settings.php?section=maintenancemode">'.get_string('maintenancemode', 'admin').'</a> '.$button;
|
||||
if(!empty($title)) {
|
||||
$title .= ' - ';
|
||||
}
|
||||
$title .= get_string('maintenancemode', 'admin');
|
||||
}
|
||||
|
||||
if (!$menu and $navigation) {
|
||||
if (empty($CFG->loginhttps)) {
|
||||
$wwwroot = $CFG->wwwroot;
|
||||
} else {
|
||||
$wwwroot = str_replace('http:','https:',$CFG->wwwroot);
|
||||
}
|
||||
$menu = user_login_string($COURSE);
|
||||
}
|
||||
|
||||
if (isset($SESSION->justloggedin)) {
|
||||
unset($SESSION->justloggedin);
|
||||
if (!empty($CFG->displayloginfailures)) {
|
||||
if (!empty($USER->username) and $USER->username != 'guest') {
|
||||
if ($count = count_login_failures($CFG->displayloginfailures, $USER->username, $USER->lastlogin)) {
|
||||
$menu .= ' <font size="1">';
|
||||
if (empty($count->accounts)) {
|
||||
$menu .= get_string('failedloginattempts', '', $count);
|
||||
} else {
|
||||
$menu .= get_string('failedloginattemptsall', '', $count);
|
||||
}
|
||||
if (has_capability('coursereport/log:view', get_context_instance(CONTEXT_SYSTEM))) {
|
||||
$menu .= ' (<a href="'.$CFG->wwwroot.'/course/report/log/index.php'.
|
||||
'?chooselog=1&id=1&modid=site_errors">'.get_string('logs').'</a>)';
|
||||
}
|
||||
$menu .= '</font>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$meta = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' .
|
||||
"\n" . $meta . "\n";
|
||||
if (!$usexml) {
|
||||
@header('Content-Type: text/html; charset=utf-8');
|
||||
}
|
||||
@header('Content-Script-Type: text/javascript');
|
||||
@header('Content-Style-Type: text/css');
|
||||
|
||||
//Accessibility: added the 'lang' attribute to $direction, used in theme <html> tag.
|
||||
$direction = get_html_lang($dir=true);
|
||||
|
||||
if ($cache) { // Allow caching on "back" (but not on normal clicks)
|
||||
@header('Cache-Control: private, pre-check=0, post-check=0, max-age=0');
|
||||
@header('Pragma: no-cache');
|
||||
@header('Expires: ');
|
||||
} else { // Do everything we can to always prevent clients and proxies caching
|
||||
@header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||
@header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
@header('Pragma: no-cache');
|
||||
@header('Expires: Mon, 20 Aug 1969 09:23:00 GMT');
|
||||
@header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
|
||||
$meta .= "\n<meta http-equiv=\"pragma\" content=\"no-cache\" />";
|
||||
$meta .= "\n<meta http-equiv=\"expires\" content=\"0\" />";
|
||||
}
|
||||
@header('Accept-Ranges: none');
|
||||
|
||||
$currentlanguage = current_language();
|
||||
|
||||
if (empty($usexml)) {
|
||||
$direction = ' xmlns="http://www.w3.org/1999/xhtml"'. $direction; // See debug_header
|
||||
} else {
|
||||
$mathplayer = preg_match("/MathPlayer/i", $_SERVER['HTTP_USER_AGENT']);
|
||||
if(!$mathplayer) {
|
||||
header('Content-Type: application/xhtml+xml');
|
||||
}
|
||||
echo '<?xml version="1.0" ?>'."\n";
|
||||
if (!empty($CFG->xml_stylesheets)) {
|
||||
$stylesheets = explode(';', $CFG->xml_stylesheets);
|
||||
foreach ($stylesheets as $stylesheet) {
|
||||
echo '<?xml-stylesheet type="text/xsl" href="'. $CFG->wwwroot .'/'. $stylesheet .'" ?>' . "\n";
|
||||
}
|
||||
}
|
||||
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1';
|
||||
if (!empty($CFG->xml_doctype_extra)) {
|
||||
echo ' plus '. $CFG->xml_doctype_extra;
|
||||
}
|
||||
echo '//' . strtoupper($currentlanguage) . '" "'. $CFG->xml_dtd .'">'."\n";
|
||||
$direction = " xmlns=\"http://www.w3.org/1999/xhtml\"
|
||||
xmlns:math=\"http://www.w3.org/1998/Math/MathML\"
|
||||
xmlns:xlink=\"http://www.w3.org/1999/xlink\"
|
||||
$direction";
|
||||
if($mathplayer) {
|
||||
$meta .= '<object id="mathplayer" classid="clsid:32F66A20-7614-11D4-BD11-00104BD3F987">' . "\n";
|
||||
$meta .= '<!--comment required to prevent this becoming an empty tag-->'."\n";
|
||||
$meta .= '</object>'."\n";
|
||||
$meta .= '<?import namespace="math" implementation="#mathplayer" ?>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up the title
|
||||
|
||||
$title = format_string($title); // fix for MDL-8582
|
||||
$title = str_replace('"', '"', $title);
|
||||
|
||||
// Create class and id for this page
|
||||
$pageid = $PAGE->pagetype;
|
||||
$pageclass = $PAGE->bodyclasses;
|
||||
$bodytags .= ' class="'.$pageclass.'" id="'.$pageid.'"';
|
||||
|
||||
ob_start();
|
||||
include($CFG->header);
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// container debugging info
|
||||
$THEME->open_header_containers = open_containers();
|
||||
|
||||
// Skip to main content, see skip_main_destination().
|
||||
if ($pageid=='course-view' or $pageid=='site-index' or $pageid=='course-index') {
|
||||
$skiplink = '<a class="skip" href="#maincontent">'.get_string('tocontent', 'access').'</a>';
|
||||
if (! preg_match('/(.*<div[^>]+id="page"[^>]*>)(.*)/s', $output, $matches)) {
|
||||
preg_match('/(.*<body.*?>)(.*)/s', $output, $matches);
|
||||
}
|
||||
$output = $matches[1]."\n". $skiplink .$matches[2];
|
||||
}
|
||||
|
||||
$output = force_strict_header($output);
|
||||
|
||||
if (!empty($CFG->messaging)) {
|
||||
$output .= message_popup_window();
|
||||
}
|
||||
|
||||
// Add in any extra JavaScript libraries that occurred during the header
|
||||
$output .= $PAGE->requires->get_top_of_body_code();
|
||||
|
||||
$PAGE->set_state(moodle_page::STATE_IN_BODY);
|
||||
|
||||
if ($return) {
|
||||
return $output;
|
||||
} else {
|
||||
echo $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This version of print_header is simpler because the course name does not have to be
|
||||
* provided explicitly in the strings. It can be used on the site page as in courses
|
||||
|
@ -2656,569 +2406,6 @@ function print_header_simple($title='', $heading='', $navigation='', $focus='',
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Can provide a course object to make the footer contain a link to
|
||||
* to the course home page, otherwise the link will go to the site home
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @global object
|
||||
* @global object Apparently not used in this function
|
||||
* @global string
|
||||
* @global object
|
||||
* @param mixed $course course object, used for course link button or
|
||||
* 'none' means no user link, only docs link
|
||||
* 'empty' means nothing printed in footer
|
||||
* 'home' special frontpage footer
|
||||
* @param object $usercourse course used in user link
|
||||
* @param boolean $return output as string
|
||||
* @return mixed string or void
|
||||
*/
|
||||
function print_footer_old($course=NULL, $usercourse=NULL, $return=false) {
|
||||
global $USER, $CFG, $THEME, $COURSE, $SITE, $PAGE;
|
||||
|
||||
if (defined('ADMIN_EXT_HEADER_PRINTED') and !defined('ADMIN_EXT_FOOTER_PRINTED')) {
|
||||
admin_externalpage_print_footer();
|
||||
return;
|
||||
}
|
||||
|
||||
$PAGE->set_state(moodle_page::STATE_PRINTING_FOOTER);
|
||||
|
||||
/// Course links or special footer
|
||||
if ($course) {
|
||||
if ($course === 'empty') {
|
||||
// special hack - sometimes we do not want even the docs link in footer
|
||||
$output = '';
|
||||
if (!empty($THEME->open_header_containers)) {
|
||||
for ($i=0; $i<$THEME->open_header_containers; $i++) {
|
||||
$output .= print_container_end_all(); // containers opened from header
|
||||
}
|
||||
} else {
|
||||
//1.8 theme compatibility
|
||||
$output .= "\n</div>"; // content div
|
||||
}
|
||||
$output .= "\n</div>\n" . $PAGE->requires->get_end_code() . "</body>\n</html>"; // close page div started in header
|
||||
if ($return) {
|
||||
return $output;
|
||||
} else {
|
||||
echo $output;
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ($course === 'none') { // Don't print any links etc
|
||||
$homelink = '';
|
||||
$loggedinas = '';
|
||||
$home = false;
|
||||
|
||||
} else if ($course === 'home') { // special case for site home page - please do not remove
|
||||
$course = $SITE;
|
||||
$homelink = '<div class="sitelink">'.
|
||||
'<a title="Moodle '. $CFG->release .'" href="http://moodle.org/">'.
|
||||
'<img style="width:100px;height:30px" src="'.$CFG->wwwroot.'/pix/moodlelogo.gif" alt="moodlelogo" /></a></div>';
|
||||
$home = true;
|
||||
|
||||
} else if ($course === 'upgrade') {
|
||||
$home = false;
|
||||
$loggedinas = '';
|
||||
$homelink = '<div class="sitelink">'.
|
||||
'<a title="Moodle '. $CFG->target_release .'" href="http://docs.moodle.org/en/Administrator_documentation" onclick="this.target=\'_blank\'">'.
|
||||
'<img style="width:100px;height:30px" src="'.$CFG->wwwroot.'/pix/moodlelogo.gif" alt="moodlelogo" /></a></div>';
|
||||
|
||||
} else {
|
||||
$homelink = '<div class="homelink"><a '.$CFG->frametarget.' href="'.$CFG->wwwroot.
|
||||
'/course/view.php?id='.$course->id.'">'.format_string($course->shortname).'</a></div>';
|
||||
$home = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
$course = $SITE; // Set course as site course by default
|
||||
$homelink = '<div class="homelink"><a '.$CFG->frametarget.' href="'.$CFG->wwwroot.'/">'.get_string('home').'</a></div>';
|
||||
$home = false;
|
||||
}
|
||||
|
||||
/// Set up some other navigation links (passed from print_header by ugly hack)
|
||||
$menu = isset($THEME->menu) ? str_replace('navmenu', 'navmenufooter', $THEME->menu) : '';
|
||||
$title = isset($THEME->title) ? $THEME->title : '';
|
||||
$button = isset($THEME->button) ? $THEME->button : '';
|
||||
$heading = isset($THEME->heading) ? $THEME->heading : '';
|
||||
$navigation = isset($THEME->navigation) ? $THEME->navigation : '';
|
||||
$navmenulist = isset($THEME->navmenulist) ? $THEME->navmenulist : '';
|
||||
|
||||
|
||||
/// Set the user link if necessary
|
||||
if (!$usercourse and is_object($course)) {
|
||||
$usercourse = $course;
|
||||
}
|
||||
|
||||
if (!isset($loggedinas)) {
|
||||
$loggedinas = user_login_string($usercourse, $USER);
|
||||
}
|
||||
|
||||
if ($loggedinas == $menu) {
|
||||
$menu = '';
|
||||
}
|
||||
|
||||
/// there should be exactly the same number of open containers as after the header
|
||||
if ($THEME->open_header_containers != open_containers()) {
|
||||
debugging('Unexpected number of open containers: '.open_containers().', expecting '.$THEME->open_header_containers, DEBUG_DEVELOPER);
|
||||
}
|
||||
|
||||
/// Provide some performance info if required
|
||||
$performanceinfo = '';
|
||||
if (defined('MDL_PERF') || (!empty($CFG->perfdebug) and $CFG->perfdebug > 7)) {
|
||||
$perf = get_performance_info();
|
||||
if (defined('MDL_PERFTOLOG') && !function_exists('register_shutdown_function')) {
|
||||
error_log("PERF: " . $perf['txt']);
|
||||
}
|
||||
if (defined('MDL_PERFTOFOOT') || debugging() || $CFG->perfdebug > 7) {
|
||||
$performanceinfo = $perf['html'];
|
||||
}
|
||||
}
|
||||
|
||||
/// Include the actual footer file
|
||||
|
||||
ob_start();
|
||||
include($CFG->footer);
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
// Put the end of page <script> tags just inside </body> to maintain validity.
|
||||
$output = str_replace('</body>', $PAGE->requires->get_end_code() . '</body>', $output);
|
||||
|
||||
$PAGE->set_state(moodle_page::STATE_DONE);
|
||||
|
||||
if ($return) {
|
||||
return $output;
|
||||
} else {
|
||||
echo $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the current theme
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @global object
|
||||
* @global object
|
||||
* @global string
|
||||
* @return string
|
||||
*/
|
||||
function current_theme() {
|
||||
global $CFG, $USER, $SESSION, $COURSE, $SCRIPT;
|
||||
|
||||
if (empty($CFG->themeorder)) {
|
||||
$themeorder = array('page', 'course', 'category', 'session', 'user', 'site');
|
||||
} else {
|
||||
$themeorder = $CFG->themeorder;
|
||||
}
|
||||
|
||||
if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id) {
|
||||
require_once($CFG->dirroot.'/mnet/peer.php');
|
||||
$mnet_peer = new mnet_peer();
|
||||
$mnet_peer->set_id($USER->mnethostid);
|
||||
}
|
||||
|
||||
$theme = '';
|
||||
foreach ($themeorder as $themetype) {
|
||||
|
||||
if (!empty($theme)) continue;
|
||||
|
||||
switch ($themetype) {
|
||||
case 'page': // Page theme is for special page-only themes set by code
|
||||
if (!empty($CFG->pagetheme)) {
|
||||
$theme = $CFG->pagetheme;
|
||||
}
|
||||
break;
|
||||
case 'course':
|
||||
if (!empty($CFG->allowcoursethemes) and !empty($COURSE->theme)) {
|
||||
$theme = $COURSE->theme;
|
||||
}
|
||||
break;
|
||||
case 'category':
|
||||
if (!empty($CFG->allowcategorythemes)) {
|
||||
/// Nasty hack to check if we're in a category page
|
||||
if ($SCRIPT == '/course/category.php') {
|
||||
global $id;
|
||||
if (!empty($id)) {
|
||||
$theme = current_category_theme($id);
|
||||
}
|
||||
/// Otherwise check if we're in a course that has a category theme set
|
||||
} else if (!empty($COURSE->category)) {
|
||||
$theme = current_category_theme($COURSE->category);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'session':
|
||||
if (!empty($SESSION->theme)) {
|
||||
$theme = $SESSION->theme;
|
||||
}
|
||||
break;
|
||||
case 'user':
|
||||
if (!empty($CFG->allowuserthemes) and !empty($USER->theme)) {
|
||||
if (isloggedin() and $USER->mnethostid != $CFG->mnet_localhost_id && $mnet_peer->force_theme == 1 && $mnet_peer->theme != '') {
|
||||
$theme = $mnet_peer->theme;
|
||||
} else {
|
||||
$theme = $USER->theme;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'site':
|
||||
if (isloggedin() and isset($CFG->mnet_localhost_id) and $USER->mnethostid != $CFG->mnet_localhost_id && $mnet_peer->force_theme == 1 && $mnet_peer->theme != '') {
|
||||
$theme = $mnet_peer->theme;
|
||||
} else {
|
||||
$theme = $CFG->theme;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
/// A final check in case 'site' was not included in $CFG->themeorder
|
||||
if (empty($theme)) {
|
||||
$theme = $CFG->theme;
|
||||
}
|
||||
|
||||
return $theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the category theme if one exists, otherwise checks the parent categories.
|
||||
* Recursive function.
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @param integer $categoryid id of the category to check
|
||||
* @return string theme name
|
||||
*/
|
||||
function current_category_theme($categoryid=0) {
|
||||
global $COURSE, $DB;
|
||||
|
||||
/// Use the COURSE global if the categoryid not set
|
||||
if (empty($categoryid)) {
|
||||
if (!empty($COURSE->category)) {
|
||||
$categoryid = $COURSE->category;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve the current category
|
||||
if ($category = $DB->get_record('course_categories', array('id'=>$categoryid))) {
|
||||
|
||||
/// Return the category theme if it exists
|
||||
if (!empty($category->theme)) {
|
||||
return $category->theme;
|
||||
|
||||
/// Otherwise try the parent category if one exists
|
||||
} else if (!empty($category->parent)) {
|
||||
return current_category_theme($category->parent);
|
||||
}
|
||||
|
||||
/// Return false if we can't find the category record
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by stylesheets to set up the header
|
||||
* approriately as well as the current path
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @uses PARAM_SAFEDIR
|
||||
* @param int $lastmodified Always gets set to now
|
||||
* @param int $lifetime The max-age header setting (seconds) defaults to 300
|
||||
* @param string $themename The name of the theme to use (optional) defaults to current theme
|
||||
* @param string $forceconfig Force a particular theme config (optional)
|
||||
* @param string $lang Load styles for the specified language (optional)
|
||||
*/
|
||||
function style_sheet_setup($lastmodified=0, $lifetime=300, $themename='', $forceconfig='', $lang='') {
|
||||
|
||||
global $CFG, $THEME;
|
||||
|
||||
// Fix for IE6 caching - we don't want the filemtime('styles.php'), instead use now.
|
||||
$lastmodified = time();
|
||||
|
||||
header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastmodified) . ' GMT');
|
||||
header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $lifetime) . ' GMT');
|
||||
header('Cache-Control: max-age='. $lifetime);
|
||||
header('Pragma: ');
|
||||
header('Content-type: text/css'); // Correct MIME type
|
||||
|
||||
$DEFAULT_SHEET_LIST = array('styles_layout', 'styles_fonts', 'styles_color');
|
||||
|
||||
if (empty($themename)) {
|
||||
$themename = current_theme(); // So we have something. Normally not needed.
|
||||
} else {
|
||||
$themename = clean_param($themename, PARAM_SAFEDIR);
|
||||
}
|
||||
|
||||
theme_setup($themename);
|
||||
|
||||
if (!empty($forceconfig)) { // Page wants to use the config from this theme instead
|
||||
unset($THEME);
|
||||
include($CFG->themedir.'/'.$forceconfig.'/'.'config.php');
|
||||
}
|
||||
|
||||
/// If this is the standard theme calling us, then find out what sheets we need
|
||||
if ($themename == 'standard') {
|
||||
if (!isset($THEME->standardsheets) or $THEME->standardsheets === true) { // Use all the sheets we have
|
||||
$THEME->sheets = $DEFAULT_SHEET_LIST;
|
||||
} else if (empty($THEME->standardsheets)) { // We can stop right now!
|
||||
echo "/***** Nothing required from this stylesheet by main theme *****/\n\n";
|
||||
exit;
|
||||
} else { // Use the provided subset only
|
||||
$THEME->sheets = $THEME->standardsheets;
|
||||
}
|
||||
|
||||
/// If we are a parent theme, then check for parent definitions
|
||||
} else if (!empty($THEME->parent) && $themename == $THEME->parent) {
|
||||
if (!isset($THEME->parentsheets) or $THEME->parentsheets === true) { // Use all the sheets we have
|
||||
$THEME->sheets = $DEFAULT_SHEET_LIST;
|
||||
} else if (empty($THEME->parentsheets)) { // We can stop right now!
|
||||
echo "/***** Nothing required from this stylesheet by main theme *****/\n\n";
|
||||
exit;
|
||||
} else { // Use the provided subset only
|
||||
$THEME->sheets = $THEME->parentsheets;
|
||||
}
|
||||
}
|
||||
|
||||
/// Work out the last modified date for this theme
|
||||
foreach ($THEME->sheets as $sheet) {
|
||||
if (file_exists($CFG->themedir.'/'.$themename.'/'.$sheet.'.css')) {
|
||||
$sheetmodified = filemtime($CFG->themedir.'/'.$themename.'/'.$sheet.'.css');
|
||||
if ($sheetmodified > $lastmodified) {
|
||||
$lastmodified = $sheetmodified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a list of all the files we want to include
|
||||
$files = array();
|
||||
|
||||
foreach ($THEME->sheets as $sheet) {
|
||||
$files[] = array($CFG->themedir, $themename.'/'.$sheet.'.css');
|
||||
}
|
||||
|
||||
if ($themename == 'standard') { // Add any standard styles included in any modules
|
||||
if (!empty($THEME->modsheets)) { // Search for styles.php within activity modules
|
||||
$mods = get_plugin_list('mod');
|
||||
foreach ($mods as $mod => $moddir) {
|
||||
if (file_exists($moddir.'/styles.php')) {
|
||||
$files[] = array($moddir, 'styles.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($THEME->blocksheets)) { // Search for styles.php within block modules
|
||||
$mods = get_plugin_list('blocks');
|
||||
foreach ($mods as $mod => $moddir) {
|
||||
if (file_exists($moddir.'/styles.php')) {
|
||||
$files[] = array($moddir, 'styles.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($THEME->courseformatsheets) || $THEME->courseformatsheets) { // Search for styles.php in course formats
|
||||
$mods = get_plugin_list('format');
|
||||
foreach ($mods as $mod => $moddir) {
|
||||
if (file_exists($moddir.'/styles.php')) {
|
||||
$files[] = array($moddir, 'styles.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($THEME->gradereportsheets) || $THEME->gradereportsheets) { // Search for styles.php in grade reports
|
||||
$reports = get_plugin_list('gradereport');
|
||||
foreach ($reports as $report => $reportdir) {
|
||||
if (file_exists($reportdir.'/styles.php')) {
|
||||
$files[] = array($reportdir, 'styles.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($THEME->langsheets)) { // Search for styles.php within the current language
|
||||
if (file_exists($CFG->dirroot.'/lang/'.$lang.'/styles.php')) {
|
||||
$files[] = array($CFG->dirroot, 'lang/'.$lang.'/styles.php');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($files) {
|
||||
/// Produce a list of all the files first
|
||||
echo '/**************************************'."\n";
|
||||
echo ' * THEME NAME: '.$themename."\n *\n";
|
||||
echo ' * Files included in this sheet:'."\n *\n";
|
||||
foreach ($files as $file) {
|
||||
echo ' * '.$file[1]."\n";
|
||||
}
|
||||
echo ' **************************************/'."\n\n";
|
||||
|
||||
|
||||
/// check if csscobstants is set
|
||||
if (!empty($THEME->cssconstants)) {
|
||||
require_once("$CFG->libdir/cssconstants.php");
|
||||
/// Actually collect all the files in order.
|
||||
$css = '';
|
||||
foreach ($files as $file) {
|
||||
$css .= '/***** '.$file[1].' start *****/'."\n\n";
|
||||
$css .= file_get_contents($file[0].'/'.$file[1]);
|
||||
$ccs .= '/***** '.$file[1].' end *****/'."\n\n";
|
||||
}
|
||||
/// replace css_constants with their values
|
||||
echo replace_cssconstants($css);
|
||||
} else {
|
||||
/// Actually output all the files in order.
|
||||
if (empty($CFG->CSSEdit) && empty($THEME->CSSEdit)) {
|
||||
foreach ($files as $file) {
|
||||
echo '/***** '.$file[1].' start *****/'."\n\n";
|
||||
@include_once($file[0].'/'.$file[1]);
|
||||
echo '/***** '.$file[1].' end *****/'."\n\n";
|
||||
}
|
||||
} else {
|
||||
foreach ($files as $file) {
|
||||
echo '/* @group '.$file[1].' */'."\n\n";
|
||||
if (strstr($file[1], '.css') !== FALSE) {
|
||||
echo '@import url("'.$CFG->themewww.'/'.$file[1].'");'."\n\n";
|
||||
} else {
|
||||
@include_once($file[0].'/'.$file[1]);
|
||||
}
|
||||
echo '/* @end */'."\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $CFG->themewww.'/'.$themename; // Only to help old themes (1.4 and earlier)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the global variables related to theme
|
||||
*
|
||||
* @global object
|
||||
* @global object
|
||||
* @global object Apparently not used here
|
||||
* @global object Apparently not used here
|
||||
* @global object
|
||||
* @global object
|
||||
* @param string $theme The theme to use defaults to current theme
|
||||
* @param array $params An array of parameters to use
|
||||
*/
|
||||
function theme_setup($theme = '', $params=NULL) {
|
||||
/// Sets up global variables related to themes
|
||||
|
||||
global $CFG, $THEME, $SESSION, $USER, $HTTPSPAGEREQUIRED, $PAGE;
|
||||
|
||||
/// Do not mess with THEME if header already printed - this would break all the extra stuff in global $THEME from print_header()!!
|
||||
if ($PAGE->headerprinted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($theme)) {
|
||||
$theme = current_theme();
|
||||
}
|
||||
|
||||
/// If the theme doesn't exist for some reason then revert to standardwhite
|
||||
if (!file_exists($CFG->themedir .'/'. $theme .'/config.php')) {
|
||||
$CFG->theme = $theme = 'standardwhite';
|
||||
}
|
||||
|
||||
/// Load up the theme config
|
||||
$THEME = NULL; // Just to be sure
|
||||
include($CFG->themedir .'/'. $theme .'/config.php'); // Main config for current theme
|
||||
$THEME->name = $theme;
|
||||
$THEME->dir = $CFG->themedir .'/'. $theme;
|
||||
|
||||
/// Put together the parameters
|
||||
if (!$params) {
|
||||
$params = array();
|
||||
}
|
||||
|
||||
if ($theme != $CFG->theme) {
|
||||
$params[] = 'forceconfig='.$theme;
|
||||
}
|
||||
|
||||
/// Force language too if required
|
||||
if (!empty($THEME->langsheets)) {
|
||||
$params[] = 'lang='.current_language();
|
||||
}
|
||||
|
||||
/// Convert params to string
|
||||
if ($params) {
|
||||
$paramstring = '?'.implode('&', $params);
|
||||
} else {
|
||||
$paramstring = '';
|
||||
}
|
||||
|
||||
/// Set up image paths
|
||||
if(isset($CFG->smartpix) && $CFG->smartpix==1) {
|
||||
if($CFG->slasharguments) { // Use this method if possible for better caching
|
||||
$extra='';
|
||||
} else {
|
||||
$extra='?file=';
|
||||
}
|
||||
|
||||
$CFG->pixpath = $CFG->wwwroot. '/pix/smartpix.php'.$extra.'/'.$theme;
|
||||
$CFG->modpixpath = $CFG->wwwroot .'/pix/smartpix.php'.$extra.'/'.$theme.'/mod';
|
||||
} else if (empty($THEME->custompix)) { // Could be set in the above file
|
||||
$CFG->pixpath = $CFG->wwwroot .'/pix';
|
||||
$CFG->modpixpath = $CFG->wwwroot .'/mod';
|
||||
} else {
|
||||
$CFG->pixpath = $CFG->themewww .'/'. $theme .'/pix';
|
||||
$CFG->modpixpath = $CFG->themewww .'/'. $theme .'/pix/mod';
|
||||
}
|
||||
|
||||
/// Define stylesheet loading order
|
||||
$CFG->stylesheets = array();
|
||||
if ($theme != 'standard') { /// The standard sheet is always loaded first
|
||||
$CFG->stylesheets[] = $CFG->themewww.'/standard/styles.php'.$paramstring;
|
||||
}
|
||||
if (!empty($THEME->parent)) { /// Parent stylesheets are loaded next
|
||||
$CFG->stylesheets[] = $CFG->themewww.'/'.$THEME->parent.'/styles.php'.$paramstring;
|
||||
}
|
||||
$CFG->stylesheets[] = $CFG->themewww.'/'.$theme.'/styles.php'.$paramstring;
|
||||
|
||||
/// We have to change some URLs in styles if we are in a $HTTPSPAGEREQUIRED page
|
||||
if (!empty($HTTPSPAGEREQUIRED)) {
|
||||
$CFG->themewww = str_replace('http:', 'https:', $CFG->themewww);
|
||||
$CFG->pixpath = str_replace('http:', 'https:', $CFG->pixpath);
|
||||
$CFG->modpixpath = str_replace('http:', 'https:', $CFG->modpixpath);
|
||||
foreach ($CFG->stylesheets as $key => $stylesheet) {
|
||||
$CFG->stylesheets[$key] = str_replace('http:', 'https:', $stylesheet);
|
||||
}
|
||||
}
|
||||
|
||||
// RTL support - only for RTL languages, add RTL CSS
|
||||
if (get_string('thisdirection') == 'rtl') {
|
||||
$CFG->stylesheets[] = $CFG->themewww.'/standard/rtl.css'.$paramstring;
|
||||
$CFG->stylesheets[] = $CFG->themewww.'/'.$theme.'/rtl.css'.$paramstring;
|
||||
}
|
||||
|
||||
// Support legacy themes, by setting sensible defaults for some of the new
|
||||
// properties that were introduced in Moodle 2.0.
|
||||
if (empty($THEME->rendererfactory)) {
|
||||
if (!empty($THEME->customcorners)) {
|
||||
// $THEME->customcorners is deprecated but we provide support for it via the
|
||||
// custom_corners_renderer_factory class in lib/deprecatedlib.php
|
||||
debugging('$THEME->customcorners is deprecated. Please use the new $THEME->rendererfactory to control HTML generation.', DEBUG_DEVELOPER);
|
||||
$THEME->rendererfactory = 'custom_corners_renderer_factory';
|
||||
} else {
|
||||
$THEME->rendererfactory = 'standard_renderer_factory';
|
||||
}
|
||||
}
|
||||
if (empty($THEME->blockregions)) {
|
||||
$THEME->blockregions = array('side-pre', 'side-post');
|
||||
}
|
||||
if (empty($THEME->defaultblockregion)) {
|
||||
$THEME->defaultblockregion = 'side-post';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns text to be displayed to the user which reflects their login status
|
||||
*
|
||||
|
@ -5729,7 +4916,7 @@ function redirect($url, $message='', $delay=-1) {
|
|||
$encodedurl = preg_replace('/^.*href="([^"]*)".*$/', "\\1", clean_text('<a href="'.$encodedurl.'" />'));
|
||||
|
||||
$message .= '<a href="'. $encodedurl .'">'. get_string('continue') .'</a>';
|
||||
|
||||
|
||||
$CFG->docroot = false; // to prevent the link to moodle docs from being displayed on redirect page.
|
||||
echo $OUTPUT->redirect($encodedurl, $message, $delay);
|
||||
die();
|
||||
|
@ -6349,18 +5536,15 @@ function print_arrow($direction='up', $strsort=null, $return=false) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns boolean true if the current language is right-to-left (Hebrew, Arabic etc)
|
||||
*
|
||||
* @staticvar bool $result
|
||||
* @return bool
|
||||
* @return boolean true if the current language is right-to-left (Hebrew, Arabic etc)
|
||||
*/
|
||||
function right_to_left() {
|
||||
static $result;
|
||||
|
||||
if (isset($result)) {
|
||||
return $result;
|
||||
if (!isset($result)) {
|
||||
$result = get_string('thisdirection') == 'rtl';
|
||||
}
|
||||
return $result = (get_string('thisdirection') == 'rtl');
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue