diff --git a/lib/outputlib.php b/lib/outputlib.php index 61f1b303ae2..3b4a9336704 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -35,8 +35,8 @@ * Which renderer factory to use is chose by the current theme, and an instance * if created automatically when the theme is set up. * - * A renderer factory must also have a constructor that takes a theme object and - * a moodle_page object. (See {@link renderer_factory_base::__construct} for an example.) + * A renderer factory must also have a constructor that takes a theme_config object. + * (See {@link renderer_factory_base::__construct} for an example.) * * @copyright 2009 Tim Hunt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later @@ -57,10 +57,559 @@ interface renderer_factory { * 'Duck typing'. For a tricky example, see {@link template_renderer} below. * renderer ob * - * @param $module the name of part of moodle. E.g. 'core', 'quiz', 'qtype_multichoice'. + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. + * @param moodle_page $page the page the renderer is outputting content for. * @return object an object implementing the requested renderer interface. */ - public function get_renderer($module, $page); + public function get_renderer($component, $page); +} + + +/** + * An icon finder is responsible for working out the correct URL for an icon. + * + * A icon finder must also have a constructor that takes a theme object. + * (See {@link standard_icon_finder::__construct} for an example.) + * + * Note that we are planning to change the Moodle icon naming convention before + * the Moodle 2.0 relase. Therefore, this API will probably change. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +interface icon_finder { + /** + * Return the URL for an icon indentifed as in pre-Moodle 2.0 code. + * + * Suppose you have old code like $url = "$CFG->pixpath/i/course.gif"; + * then old_icon_url('i/course'); will return the equivalent URL that is correct now. + * + * @param $iconname the name of the icon. + * @return string the URL for that icon. + */ + public function old_icon_url($iconname); + + /** + * Return the URL for an icon indentifed as in pre-Moodle 2.0 code. + * + * Suppose you have old code like $url = "$CFG->modpixpath/$mod/icon.gif"; + * then mod_icon_url('icon', $mod); will return the equivalent URL that is correct now. + * + * @param $iconname the name of the icon. + * @param $module the module the icon belongs to. + * @return string the URL for that icon. + */ + public function mod_icon_url($iconname, $module); +} + + +/** + *This class represents the configuration variables of a Moodle theme. + * + * Normally, to create an instance of this class, you should use the + * {@link theme_config::load()} factory method to load a themes config.php file. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class theme_config { + /** + * @var array The names of all the stylesheets from this theme that you would + * like included, in order. + */ + public $sheets = array('styles_layout', 'styles_fonts', 'styles_color'); + + public $standardsheets = true; + +/// This variable can be set to an array containing +/// filenames from the *STANDARD* theme. If the +/// array exists, it will be used to choose the +/// files to include in the standard style sheet. +/// When false, then no files are used. +/// When true or NON-EXISTENT, then ALL standard files are used. +/// This parameter can be used, for example, to prevent +/// having to override too many classes. +/// Note that the trailing .css should not be included +/// eg $THEME->standardsheets = array('styles_layout','styles_fonts','styles_color'); +//////////////////////////////////////////////////////////////////////////////// + + + public $parent = null; + +/// This variable can be set to the name of a parent theme +/// which you want to have included before the current theme. +/// This can make it easy to make modifications to another +/// theme without having to actually change the files +/// If this variable is empty or false then a parent theme +/// is not used. +//////////////////////////////////////////////////////////////////////////////// + + + public $parentsheets = false; + +/// This variable can be set to an array containing +/// filenames from a chosen *PARENT* theme. If the +/// array exists, it will be used to choose the +/// files to include in the standard style sheet. +/// When false, then no files are used. +/// When true or NON-EXISTENT, then ALL standard files are used. +/// This parameter can be used, for example, to prevent +/// having to override too many classes. +/// Note that the trailing .css should not be included +/// eg $THEME->parentsheets = array('styles_layout','styles_fonts','styles_color'); +//////////////////////////////////////////////////////////////////////////////// + + + public $modsheets = true; + +/// When this is enabled, then this theme will search for +/// files named "styles.php" inside all Activity modules and +/// include them. This allows modules to provide some basic +/// layouts so they work out of the box. +/// It is HIGHLY recommended to leave this enabled. + + + public $blocksheets = true; + +/// When this is enabled, then this theme will search for +/// files named "styles.php" inside all Block modules and +/// include them. This allows Blocks to provide some basic +/// layouts so they work out of the box. +/// It is HIGHLY recommended to leave this enabled. + + + public $langsheets = false; + +/// By setting this to true, then this theme will search for +/// a file named "styles.php" inside the current language +/// directory. This allows different languages to provide +/// different styles. + + + public $courseformatsheets = true; + +/// When this is enabled, this theme will search for files +/// named "styles.php" inside all course formats and +/// include them. This allows course formats to provide +/// their own default styles. + + + public $metainclude = false; + +/// When this is enabled (or not set!) then Moodle will try +/// to include a file meta.php from this theme into the +/// part of the page. + + + public $standardmetainclude = true; + + +/// When this is enabled (or not set!) then Moodle will try +/// to include a file meta.php from the standard theme into the +/// part of the page. + + + public $parentmetainclude = false; + +/// When this is enabled (or not set!) then Moodle will try +/// to include a file meta.php from the parent theme into the +/// part of the page. + + + public $navmenuwidth = 50; + +/// You can use this to control the cutoff point for strings +/// in the navmenus (list of activities in popup menu etc) +/// Default is 50 characters wide. + + + public $makenavmenulist = false; + +/// By setting this to true, then you will have access to a +/// new variable in your header.html and footer.html called +/// $navmenulist ... this contains a simple XHTML menu of +/// all activities in the current course, mostly useful for +/// creating popup navigation menus and so on. + + + + public $resource_mp3player_colors = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&font=Arial&fontColour=3333FF&buffer=10&waitForPlay=no&autoPlay=yes'; + +/// With this you can control the colours of the "big" MP3 player +/// that is used for MP3 resources. + + + public $filter_mediaplugin_colors = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&waitForPlay=yes'; + +/// ...And this controls the small embedded player + + + public $custompix = false; + +/// If true, then this theme must have a "pix" +/// subdirectory that contains copies of all +/// files from the moodle/pix directory, plus a +/// "pix/mod" directory containing all the icons +/// for all the activity modules. + + +///$THEME->rarrow = '►' //OR '→'; +///$THEME->larrow = '◄' //OR '←'; +///$CFG->block_search_button = link_arrow_right(get_string('search'), $url='', $accesshide=true); +/// +/// Accessibility: Right and left arrow-like characters are +/// used in the breadcrumb trail, course navigation menu +/// (previous/next activity), calendar, and search forum block. +/// +/// If the theme does not set characters, appropriate defaults +/// are set by (lib/weblib.php:check_theme_arrows). The suggestions +/// above are 'silent' in a screen-reader like JAWS. Please DO NOT +/// use < > » - these are confusing for blind users. +//////////////////////////////////////////////////////////////////////////////// + + + public $blockregions = array('side-pre', 'side-post'); + public $defaultblockregion = 'side-post'; +/// Areas where blocks may appear on any page that uses this theme. For each +/// region you list in $THEME->blockregions you must call blocks_print_group +/// with that region id somewhere in header.html or footer.html. +/// defaultblockregion is the region where new blocks will be added, and +/// where any blocks in unrecognised regions will be shown. (Suppose someone +/// added a block when anther theme was selected). +//////////////////////////////////////////////////////////////////////////////// + + /** @var string the name of this theme. Set automatically. */ + public $name; + /** @var string the folder where this themes fiels are stored. $CFG->themedir . '/' . $this->name */ + public $dir; + + /** @var string Name of the renderer factory class to use. */ + public $rendererfactory = 'standard_renderer_factory'; + /** @var renderer_factory Instance of the renderer_factory class. */ + protected $rf = null; + + /** @var string Name of the icon finder class to use. */ + public $iconfinder = 'pix_icon_finder'; + /** @var renderer_factory Instance of the renderer_factory class. */ + protected $if = null; + + /** + * If you want to do custom processing on the CSS before it is output (for + * example, to replace certain variable names with particular values) you can + * give the name of a function here. + * + * There are two functions avaiable that you may wish to use (defined in lib/outputlib.php): + * output_css_replacing_constants + * output_css_for_css_edit + * If you wish to write your own function, use those two as examples, and it + * should be clear what you have to do. + * + * @var string the name of a function. + */ + public $customcssoutputfunction = null; + + /** + * Load the config.php file for a particular theme, and return an instance + * of this class. (That is, this is a factory method.) + * + * @param string $themename the name of the theme. + * @return theme_config an instance of this class. + */ + public static function load($themename) { + global $CFG; + + // We have to use the variable name $THEME (upper case) becuase that + // is what is used in theme config.php files. + + // Set some other standard properties of the theme. + $THEME = new theme_config; + $THEME->name = $themename; + $THEME->dir = $CFG->themedir . '/' . $themename; + + // Load up the theme config + $configfile = $THEME->dir . '/config.php'; + if (!is_readable($configfile)) { + throw new coding_exception('Cannot use theme ' . $themename . + '. The file ' . $configfile . ' does not exist or is not readable.'); + } + include($configfile); + + $THEME->update_legacy_information(); + + return $THEME; + } + + /** + * Get the renderer for a part of Moodle for this theme. + * @param string $module the name of part of moodle. E.g. 'core', 'quiz', 'qtype_multichoice'. + * @param moodle_page $page the page we are rendering + * @return moodle_renderer_base the requested renderer. + */ + public function get_renderer($module, $page) { + if (is_null($this->rf)) { + if (CLI_SCRIPT) { + $classname = 'cli_renderer_factory'; + } else { + $classname = $this->rendererfactory; + } + $this->rf = new $classname($this); + } + + return $this->rf->get_renderer($module, $page); + } + + /** + * Get the renderer for a part of Moodle for this theme. + * @return moodle_renderer_base the requested renderer. + */ + protected function get_icon_finder() { + if (is_null($this->if)) { + $classname = $this->iconfinder; + $this->if = new $classname($this); + } + return $this->if; + } + + /** + * Return the URL for an icon indentifed as in pre-Moodle 2.0 code. + * + * Suppose you have old code like $url = "$CFG->pixpath/i/course.gif"; + * then old_icon_url('i/course'); will return the equivalent URL that is correct now. + * + * @param $iconname the name of the icon. + * @return string the URL for that icon. + */ + public function old_icon_url($iconname) { + return $this->if->old_icon_url($iconname); + } + + /** + * Return the URL for an icon indentifed as in pre-Moodle 2.0 code. + * + * Suppose you have old code like $url = "$CFG->modpixpath/$mod/icon.gif"; + * then mod_icon_url('icon', $mod); will return the equivalent URL that is correct now. + * + * @param $iconname the name of the icon. + * @param $module the module the icon belongs to. + * @return string the URL for that icon. + */ + public function mod_icon_url($iconname, $module) { + return $this->if->mod_icon_url($iconname, $module); + } + + /** + * Get the list of stylesheet URLs that need to go in the header for this theme. + * @return array of URLs. + */ + public function get_stylesheet_urls() { + global $CFG; + + // Put together the parameters + $params = '?for=' . $this->name; + + // Stylesheets, in order (standard, parent, this - some of which may be the same). + $stylesheets = array(); + if ($this->name != 'standard' && $this->standardsheets) { + $stylesheets[] = $CFG->httpsthemewww . '/standard/styles.php' . $params; + } + if (!empty($this->parent)) { + $stylesheets[] = $CFG->httpsthemewww . '/' . $this->parent . '/styles.php' . $params; + } + + // Pass on the current language, if it will be needed. + if (!empty($this->langsheets)) { + $params .= '&lang=' . current_language(); + } + $stylesheets[] = $CFG->httpsthemewww . '/' . $this->name . '/styles.php' . $params; + + // Additional styles for right-to-left languages. + if (right_to_left()) { + $stylesheets[] = $CFG->httpsthemewww . '/standard/rtl.css'; + + if (!empty($this->parent) && file_exists($CFG->themedir . '/' . $this->parent . '/rtl.css')) { + $stylesheets[] = $CFG->httpsthemewww . '/' . $this->parent . '/rtl.css'; + } + + if (file_exists($this->dir . '/rtl.css')) { + $stylesheets[] = $CFG->httpsthemewww . '/' . $this->name . '/rtl.css'; + } + } + + return $stylesheets; + } + + /** + * This methon looks a the settings that have been loaded, to see whether + * any legacy things are being used, and outputs warning and tries to update + * things to use equivalent newer settings. + */ + protected function update_legacy_information() { + global $CFG; + if (!empty($this->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. Please use $this->rendererfactory = \'custom_corners_renderer_factory\'; ' . + 'in your config.php file instead.', DEBUG_DEVELOPER); + $this->rendererfactory = 'custom_corners_renderer_factory'; + } + + if (!empty($this->cssconstants)) { + debugging('$THEME->cssconstants is deprecated. Please use ' . + '$THEME->customcssoutputfunction = \'output_css_replacing_constants\'; ' . + 'in your config.php file instead.', DEBUG_DEVELOPER); + $this->customcssoutputfunction = 'output_css_replacing_constants'; + } + + if (!empty($this->CSSEdit)) { + debugging('$THEME->CSSEdit is deprecated. Please use ' . + '$THEME->customcssoutputfunction = \'output_css_for_css_edit\'; ' . + 'in your config.php file instead.', DEBUG_DEVELOPER); + $this->customcssoutputfunction = 'output_css_for_css_edit'; + } + + if ($CFG->smartpix) { + $this->iconfinder = 'smartpix_icon_finder'; + } else if ($this->custompix) { + $this->iconfinder = 'theme_icon_finder'; + } + } + + /** + * Set the variable $CFG->pixpath and $CFG->modpixpath to be the right + * ones for this theme. + */ + public function setup_cfg_paths() { + global $CFG; + if (!empty($CFG->smartpix)) { + if ($CFG->slasharguments) { + // Use this method if possible for better caching + $extra = ''; + } else { + $extra = '?file='; + } + $CFG->pixpath = $CFG->httpswwwroot . '/pix/smartpix.php' . $extra . '/' . $this->name; + $CFG->modpixpath = $CFG->httpswwwroot . '/pix/smartpix.php' . $extra . '/' . $this->name . '/mod'; + + } else if (empty($THEME->custompix)) { + $CFG->pixpath = $CFG->httpswwwroot . '/pix'; + $CFG->modpixpath = $CFG->httpswwwroot . '/mod'; + + } else { + $CFG->pixpath = $CFG->httpsthemewww . '/' . $this->name . '/pix'; + $CFG->modpixpath = $CFG->httpsthemewww . '/' . $this->name . '/pix/mod'; + } + } +} + + +/** + * This icon finder implements the old scheme that was used when themes that had + * $THEME->custompix = false. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class pix_icon_finder implements icon_finder { + /** + * Constructor + * @param theme_config $theme the theme we are finding icons for (which is irrelevant). + */ + public function __construct($theme) { + } + + /* Implement interface method. */ + public function old_icon_url($iconname) { + global $CFG; + return $CFG->httpswwwroot . '/pix/' . $iconname . '.gif'; + } + + /* Implement interface method. */ + public function mod_icon_url($iconname, $module) { + global $CFG; + return $CFG->httpswwwroot . '/mod/' . $module . '/' . $iconname . '.gif'; + } +} + + +/** + * This icon finder implements the old scheme that was used for themes that had + * $THEME->custompix = true. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class theme_icon_finder implements icon_finder { + protected $themename; + /** + * Constructor + * @param theme_config $theme the theme we are finding icons for. + */ + public function __construct($theme) { + $this->themename = $theme->name; + } + + /* Implement interface method. */ + public function old_icon_url($iconname) { + global $CFG; + return $CFG->httpsthemewww . '/' . $this->themename . '/pix/' . $iconname . '.gif'; + } + + /* Implement interface method. */ + public function mod_icon_url($iconname, $module) { + global $CFG; + return $CFG->httpsthemewww . '/' . $this->themename . '/pix/mod/' . $module . '/' . $iconname . '.gif'; + } +} + + +/** + * This icon finder implements the algorithm in pix/smartpix.php. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @since Moodle 2.0 + */ +class smartpix_icon_finder extends pix_icon_finder { + protected $places = array(); + + /** + * Constructor + * @param theme_config $theme the theme we are finding icons for. + */ + public function __construct($theme) { + global $CFG; + $this->places[$CFG->themedir . '/' . $theme->name . '/pix/'] = + $CFG->httpsthemewww . '/' . $theme->name . '/pix/'; + if (!empty($theme->parent)) { + $this->places[$CFG->themedir . '/' . $theme->parent . '/pix/'] = + $CFG->httpsthemewww . '/' . $theme->parent . '/pix/'; + } + } + + /* Implement interface method. */ + public function old_icon_url($iconname) { + foreach ($this->places as $dirroot => $urlroot) { + if (file_exists($dirroot . $iconname . '.gif')) { + return $iconname . $iconname . '.gif'; + } + } + return parent::old_icon_url($iconname); + } + + /* Implement interface method. */ + public function mod_icon_url($iconname, $module) { + foreach ($this->places as $dirroot => $urlroot) { + if (file_exists($dirroot . 'mod/' . $iconname . '.gif')) { + return $iconname . 'mod/' . $iconname . '.gif'; + } + } + return parent::old_icon_url($iconname); + } } @@ -95,15 +644,17 @@ abstract class renderer_factory_base implements renderer_factory { * Also, if it exists, include the renderer.php file for that module, so * the class definition of the default renderer has been loaded. * - * @param string $module the name of part of moodle. E.g. 'core', 'quiz', 'qtype_multichoice'. + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @return string the name of the standard renderer class for that module. */ - protected function standard_renderer_class_for_module($module) { - $pluginrenderer = get_plugin_dir($module) . '/renderer.php'; - if (file_exists($pluginrenderer)) { - include_once($pluginrenderer); + protected function standard_renderer_class_for_module($component) { + if ($component != 'core') { + $pluginrenderer = get_component_directory($component) . '/renderer.php'; + if (file_exists($pluginrenderer)) { + include_once($pluginrenderer); + } } - $class = 'moodle_' . $module . '_renderer'; + $class = 'moodle_' . $component . '_renderer'; if (!class_exists($class)) { throw new coding_exception('Request for an unknown renderer class ' . $class); } @@ -357,6 +908,33 @@ class moodle_renderer_base { } return $classes; } + + /** + * Return the URL for an icon indentifed as in pre-Moodle 2.0 code. + * + * Suppose you have old code like $url = "$CFG->pixpath/i/course.gif"; + * then old_icon_url('i/course'); will return the equivalent URL that is correct now. + * + * @param $iconname the name of the icon. + * @return string the URL for that icon. + */ + public function old_icon_url($iconname) { + return $this->page->theme->old_icon_url($iconname); + } + + /** + * Return the URL for an icon indentifed as in pre-Moodle 2.0 code. + * + * Suppose you have old code like $url = "$CFG->modpixpath/$mod/icon.gif"; + * then mod_icon_url('icon', $mod); will return the equivalent URL that is correct now. + * + * @param $iconname the name of the icon. + * @param $module the module the icon belongs to. + * @return string the URL for that icon. + */ + public function mod_icon_url($iconname, $module) { + return $this->page->theme->mod_icon_url($iconname, $module); + } } @@ -1352,356 +1930,6 @@ class moodle_core_renderer extends moodle_renderer_base { } -/** - *This class represents the configuration variables of a Moodle theme. - * - * Normally, to create an instance of this class, you should use the - * {@link theme_config::load()} factory method to load a themes config.php file. - * - * @copyright 2009 Tim Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - * @since Moodle 2.0 - */ -class theme_config { - /** - * @var array The names of all the stylesheets from this theme that you would - * like included, in order. - */ - public $sheets = array('styles_layout', 'styles_fonts', 'styles_color'); - - public $standardsheets = true; - -/// This variable can be set to an array containing -/// filenames from the *STANDARD* theme. If the -/// array exists, it will be used to choose the -/// files to include in the standard style sheet. -/// When false, then no files are used. -/// When true or NON-EXISTENT, then ALL standard files are used. -/// This parameter can be used, for example, to prevent -/// having to override too many classes. -/// Note that the trailing .css should not be included -/// eg $THEME->standardsheets = array('styles_layout','styles_fonts','styles_color'); -//////////////////////////////////////////////////////////////////////////////// - - - public $parent = null; - -/// This variable can be set to the name of a parent theme -/// which you want to have included before the current theme. -/// This can make it easy to make modifications to another -/// theme without having to actually change the files -/// If this variable is empty or false then a parent theme -/// is not used. -//////////////////////////////////////////////////////////////////////////////// - - - public $parentsheets = false; - -/// This variable can be set to an array containing -/// filenames from a chosen *PARENT* theme. If the -/// array exists, it will be used to choose the -/// files to include in the standard style sheet. -/// When false, then no files are used. -/// When true or NON-EXISTENT, then ALL standard files are used. -/// This parameter can be used, for example, to prevent -/// having to override too many classes. -/// Note that the trailing .css should not be included -/// eg $THEME->parentsheets = array('styles_layout','styles_fonts','styles_color'); -//////////////////////////////////////////////////////////////////////////////// - - - public $modsheets = true; - -/// When this is enabled, then this theme will search for -/// files named "styles.php" inside all Activity modules and -/// include them. This allows modules to provide some basic -/// layouts so they work out of the box. -/// It is HIGHLY recommended to leave this enabled. - - - public $blocksheets = true; - -/// When this is enabled, then this theme will search for -/// files named "styles.php" inside all Block modules and -/// include them. This allows Blocks to provide some basic -/// layouts so they work out of the box. -/// It is HIGHLY recommended to leave this enabled. - - - public $langsheets = false; - -/// By setting this to true, then this theme will search for -/// a file named "styles.php" inside the current language -/// directory. This allows different languages to provide -/// different styles. - - - public $courseformatsheets = true; - -/// When this is enabled, this theme will search for files -/// named "styles.php" inside all course formats and -/// include them. This allows course formats to provide -/// their own default styles. - - - public $metainclude = false; - -/// When this is enabled (or not set!) then Moodle will try -/// to include a file meta.php from this theme into the -/// part of the page. - - - public $standardmetainclude = true; - - -/// When this is enabled (or not set!) then Moodle will try -/// to include a file meta.php from the standard theme into the -/// part of the page. - - - public $parentmetainclude = false; - -/// When this is enabled (or not set!) then Moodle will try -/// to include a file meta.php from the parent theme into the -/// part of the page. - - - public $navmenuwidth = 50; - -/// You can use this to control the cutoff point for strings -/// in the navmenus (list of activities in popup menu etc) -/// Default is 50 characters wide. - - - public $makenavmenulist = false; - -/// By setting this to true, then you will have access to a -/// new variable in your header.html and footer.html called -/// $navmenulist ... this contains a simple XHTML menu of -/// all activities in the current course, mostly useful for -/// creating popup navigation menus and so on. - - - - public $resource_mp3player_colors = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&font=Arial&fontColour=3333FF&buffer=10&waitForPlay=no&autoPlay=yes'; - -/// With this you can control the colours of the "big" MP3 player -/// that is used for MP3 resources. - - - public $filter_mediaplugin_colors = 'bgColour=000000&btnColour=ffffff&btnBorderColour=cccccc&iconColour=000000&iconOverColour=00cc00&trackColour=cccccc&handleColour=ffffff&loaderColour=ffffff&waitForPlay=yes'; - -/// ...And this controls the small embedded player - - - public $custompix = false; - -/// If true, then this theme must have a "pix" -/// subdirectory that contains copies of all -/// files from the moodle/pix directory, plus a -/// "pix/mod" directory containing all the icons -/// for all the activity modules. - - -///$THEME->rarrow = '►' //OR '→'; -///$THEME->larrow = '◄' //OR '←'; -///$CFG->block_search_button = link_arrow_right(get_string('search'), $url='', $accesshide=true); -/// -/// Accessibility: Right and left arrow-like characters are -/// used in the breadcrumb trail, course navigation menu -/// (previous/next activity), calendar, and search forum block. -/// -/// If the theme does not set characters, appropriate defaults -/// are set by (lib/weblib.php:check_theme_arrows). The suggestions -/// above are 'silent' in a screen-reader like JAWS. Please DO NOT -/// use < > » - these are confusing for blind users. -//////////////////////////////////////////////////////////////////////////////// - - - public $blockregions = array('side-pre', 'side-post'); - public $defaultblockregion = 'side-post'; -/// Areas where blocks may appear on any page that uses this theme. For each -/// region you list in $THEME->blockregions you must call blocks_print_group -/// with that region id somewhere in header.html or footer.html. -/// defaultblockregion is the region where new blocks will be added, and -/// where any blocks in unrecognised regions will be shown. (Suppose someone -/// added a block when anther theme was selected). -//////////////////////////////////////////////////////////////////////////////// - - /** @var string the name of this theme. Set automatically. */ - public $name; - /** @var string the folder where this themes fiels are stored. $CFG->themedir . '/' . $this->name */ - public $dir; - - /** @var string Name of the renderer factory class to use. */ - public $rendererfactory = 'standard_renderer_factory'; - /** @var renderer_factory Instance of the renderer_factory class. */ - protected $rf = null; - - /** - * If you want to do custom processing on the CSS before it is output (for - * example, to replace certain variable names with particular values) you can - * give the name of a function here. - * - * There are two functions avaiable that you may wish to use (defined in lib/outputlib.php): - * output_css_replacing_constants - * output_css_for_css_edit - * If you wish to write your own function, use those two as examples, and it - * should be clear what you have to do. - * - * @var string the name of a function. - */ - public $customcssoutputfunction = null; - - /** - * Load the config.php file for a particular theme, and return an instance - * of this class. (That is, this is a factory method.) - * - * @param string $themename the name of the theme. - * @return theme_config an instance of this class. - */ - public static function load($themename) { - global $CFG; - - // We have to use the variable name $THEME (upper case) becuase that - // is what is used in theme config.php files. - - // Set some other standard properties of the theme. - $THEME = new theme_config; - $THEME->name = $themename; - $THEME->dir = $CFG->themedir . '/' . $themename; - - // Load up the theme config - $configfile = $THEME->dir . '/config.php'; - if (!is_readable($configfile)) { - throw new coding_exception('Cannot use theme ' . $themename . - '. The file ' . $configfile . ' does not exist or is not readable.'); - } - include($configfile); - - $THEME->update_legacy_information(); - - return $THEME; - } - - /** - * Get the renderer for a part of Moodle for this theme. - * @param string $module the name of part of moodle. E.g. 'core', 'quiz', 'qtype_multichoice'. - * @param moodle_page $page the page we are rendering - * @return moodle_renderer_base the requested renderer. - */ - public function get_renderer($module, $page) { - if (is_null($this->rf)) { - if (CLI_SCRIPT) { - $classname = 'cli_renderer_factory'; - } else { - $classname = $this->rendererfactory; - } - $this->rf = new $classname($this); - } - - return $this->rf->get_renderer($module, $page); - } - - /** - * Set the variable $CFG->pixpath and $CFG->modpixpath to be the right - * ones for this theme. - */ - public function setup_cfg_paths() { - global $CFG; - if (!empty($CFG->smartpix)) { - if ($CFG->slasharguments) { - // Use this method if possible for better caching - $extra = ''; - } else { - $extra = '?file='; - } - $CFG->pixpath = $CFG->httpswwwroot . '/pix/smartpix.php' . $extra . '/' . $this->name; - $CFG->modpixpath = $CFG->httpswwwroot . '/pix/smartpix.php' . $extra . '/' . $this->name . '/mod'; - - } else if (empty($THEME->custompix)) { - $CFG->pixpath = $CFG->httpswwwroot . '/pix'; - $CFG->modpixpath = $CFG->httpswwwroot . '/mod'; - - } else { - $CFG->pixpath = $CFG->httpsthemewww . '/' . $this->name . '/pix'; - $CFG->modpixpath = $CFG->httpsthemewww . '/' . $this->name . '/pix/mod'; - } - } - - /** - * Get the list of stylesheet URLs that need to go in the header for this theme. - * @return array of URLs. - */ - public function get_stylesheet_urls() { - global $CFG; - - // Put together the parameters - $params = '?for=' . $this->name; - - // Stylesheets, in order (standard, parent, this - some of which may be the same). - $stylesheets = array(); - if ($this->name != 'standard' && $this->standardsheets) { - $stylesheets[] = $CFG->httpsthemewww . '/standard/styles.php' . $params; - } - if (!empty($this->parent)) { - $stylesheets[] = $CFG->httpsthemewww . '/' . $this->parent . '/styles.php' . $params; - } - - // Pass on the current language, if it will be needed. - if (!empty($this->langsheets)) { - $params .= '&lang=' . current_language(); - } - $stylesheets[] = $CFG->httpsthemewww . '/' . $this->name . '/styles.php' . $params; - - // Additional styles for right-to-left languages. - if (right_to_left()) { - $stylesheets[] = $CFG->httpsthemewww . '/standard/rtl.css'; - - if (!empty($this->parent) && file_exists($CFG->themedir . '/' . $this->parent . '/rtl.css')) { - $stylesheets[] = $CFG->httpsthemewww . '/' . $this->parent . '/rtl.css'; - } - - if (file_exists($this->dir . '/rtl.css')) { - $stylesheets[] = $CFG->httpsthemewww . '/' . $this->name . '/rtl.css'; - } - } - - return $stylesheets; - } - - /** - * This methon looks a the settings that have been loaded, to see whether - * any legacy things are being used, and outputs warning and tries to update - * things to use equivalent newer settings. - */ - protected function update_legacy_information() { - if (!empty($this->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. Please use $this->rendererfactory = \'custom_corners_renderer_factory\'; ' . - 'in your config.php file instead.', DEBUG_DEVELOPER); - $this->rendererfactory = 'custom_corners_renderer_factory'; - } - - if (!empty($this->cssconstants)) { - debugging('$THEME->cssconstants is deprecated. Please use ' . - '$THEME->customcssoutputfunction = \'output_css_replacing_constants\'; ' . - 'in your config.php file instead.', DEBUG_DEVELOPER); - $this->customcssoutputfunction = 'output_css_replacing_constants'; - } - - if (!empty($this->CSSEdit)) { - debugging('$THEME->CSSEdit is deprecated. Please use ' . - '$THEME->customcssoutputfunction = \'output_css_for_css_edit\'; ' . - 'in your config.php file instead.', DEBUG_DEVELOPER); - $this->customcssoutputfunction = 'output_css_for_css_edit'; - } - } -} - - /** * Base class for classes representing HTML elements, like moodle_select_menu. * diff --git a/lib/setup.php b/lib/setup.php index 98785ab461d..7230c99853a 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -110,7 +110,7 @@ global $OUTPUT; /** * $THEME is a global that defines the current theme. * - * @global object $THEME + * @global theme_config $THEME * @name THEME */ global $THEME; diff --git a/lib/simpletest/testoutputlib.php b/lib/simpletest/testoutputlib.php index 509e2b4e805..dfa5f0ed9cc 100644 --- a/lib/simpletest/testoutputlib.php +++ b/lib/simpletest/testoutputlib.php @@ -30,16 +30,60 @@ if (!defined('MOODLE_INTERNAL')) { require_once($CFG->libdir . '/outputlib.php'); -// TODO this is needed until MDL-16438 is committed. -function get_plugin_dir($module) { - global $CFG; - return $CFG->dirroot; +/** + * Unit tests for the pix_icon_finder class. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class pix_icon_finder_test extends UnitTestCase { + public function test_old_icon_url() { + global $CFG; + $if = new pix_icon_finder(new theme_config()); + $this->assertEqual($CFG->httpswwwroot . '/pix/i/course.gif', $if->old_icon_url('i/course')); + } + + /* Implement interface method. */ + public function test_mod_icon_url() { + global $CFG; + $if = new pix_icon_finder(new theme_config()); + $this->assertEqual($CFG->httpswwwroot . '/mod/quiz/icon.gif', $if->mod_icon_url('icon', 'quiz')); + } +} + + +/** + * Unit tests for the standard_renderer_factory class. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class theme_icon_finder_test extends UnitTestCase { + public function test_old_icon_url_test() { + global $CFG; + $theme = new theme_config(); + $theme->name = 'test'; + $if = new theme_icon_finder($theme); + $this->assertEqual($CFG->httpsthemewww . '/test/pix/i/course.gif', $if->old_icon_url('i/course')); + } + + /* Implement interface method. */ + public function test_mod_icon_url() { + global $CFG; + $theme = new theme_config(); + $theme->name = 'test'; + $if = new theme_icon_finder($theme); + $this->assertEqual($CFG->httpsthemewww . '/test/pix/mod/quiz/icon.gif', $if->mod_icon_url('icon', 'quiz')); + } } /** * Subclass of renderer_factory_base for testing. Implement abstract method and * count calls, so we can test caching behaviour. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class testable_renderer_factory extends renderer_factory_base { public $createcalls = array(); @@ -61,8 +105,11 @@ class testable_renderer_factory extends renderer_factory_base { /** * Renderer class for testing. + * + * @copyright 2009 Tim Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class moodle_test_renderer extends moodle_core_renderer { +class moodle_mod_test_renderer extends moodle_core_renderer { public function __construct($containerstack, $page) { parent::__construct($containerstack, $page, null); } @@ -121,9 +168,9 @@ class renderer_factory_base_test extends UnitTestCase { // Set up. $factory = new testable_renderer_factory(); // Exercise SUT. - $classname = $factory->standard_renderer_class_for_module('test'); + $classname = $factory->standard_renderer_class_for_module('mod_test'); // Verify outcome - $this->assertEqual('moodle_test_renderer', $classname); + $this->assertEqual('moodle_mod_test_renderer', $classname); } public function test_standard_renderer_class_for_module_unknown() { @@ -161,8 +208,8 @@ class standard_renderer_factory_test extends UnitTestCase { } public function test_get_test_renderer() { - $renderer = $this->factory->get_renderer('test', new moodle_page); - $this->assertIsA($renderer, 'moodle_test_renderer'); + $renderer = $this->factory->get_renderer('mod_test', new moodle_page); + $this->assertIsA($renderer, 'moodle_mod_test_renderer'); } } @@ -192,8 +239,8 @@ class custom_corners_renderer_factory_test extends UnitTestCase { } public function test_get_test_renderer() { - $renderer = $this->factory->get_renderer('test', new moodle_page); - $this->assertIsA($renderer, 'moodle_test_renderer'); + $renderer = $this->factory->get_renderer('mod_test', new moodle_page); + $this->assertIsA($renderer, 'moodle_mod_test_renderer'); } } @@ -304,25 +351,25 @@ class theme_overridden_renderer_factory_test extends UnitTestCase { $factory = new testable_theme_overridden_renderer_factory($theme, $this->page); // Exercise SUT. - $renderer = $factory->get_renderer('test', new moodle_page); + $renderer = $factory->get_renderer('mod_test', new moodle_page); // Verify outcome - $this->assertIsA($renderer, 'moodle_test_renderer'); + $this->assertIsA($renderer, 'moodle_mod_test_renderer'); } public function test_get_renderer_overridden() { // Set up - be very careful because the class under test uses require-once. Pick a unique theme name. $theme = $this->make_theme('testrenderertheme'); $this->write_renderers_file($theme, ' - class testrenderertheme_test_renderer extends moodle_test_renderer { + class testrenderertheme_mod_test_renderer extends moodle_mod_test_renderer { }'); $factory = new testable_theme_overridden_renderer_factory($theme, $this->page); // Exercise SUT. - $renderer = $factory->get_renderer('test', new moodle_page); + $renderer = $factory->get_renderer('mod_test', new moodle_page); // Verify outcome - $this->assertIsA($renderer, 'testrenderertheme_test_renderer'); + $this->assertIsA($renderer, 'testrenderertheme_mod_test_renderer'); } public function test_get_renderer_overridden_in_parent() { @@ -519,18 +566,18 @@ class template_renderer_factory_test extends UnitTestCase { $theme = $this->make_theme('mytheme'); $theme->parent = 'parenttheme'; $this->make_theme_template_dir('mytheme', 'core'); - $this->make_theme_template_dir('parenttheme', 'test'); - $this->make_theme_template_dir('standardtemplate', 'test'); + $this->make_theme_template_dir('parenttheme', 'mod_test'); + $this->make_theme_template_dir('standardtemplate', 'mod_test'); $factory = new testable_template_renderer_factory($theme); // Exercise SUT. - $renderer = $factory->get_renderer('test', $this->page); + $renderer = $factory->get_renderer('mod_test', $this->page); // Verify outcome - $this->assertEqual('moodle_test_renderer', $renderer->get_copied_class()); + $this->assertEqual('moodle_mod_test_renderer', $renderer->get_copied_class()); $this->assertEqual(array( - $CFG->themedir . '/parenttheme/templates/test', - $CFG->themedir . '/standardtemplate/templates/test'), + $CFG->themedir . '/parenttheme/templates/mod_test', + $CFG->themedir . '/standardtemplate/templates/mod_test'), $renderer->get_search_paths()); } } @@ -709,7 +756,7 @@ class template_renderer_test extends UnitTestCase { $this->templatefolder = $CFG->dataroot . '/temp/template_renderer_fixtures/test'; make_upload_directory('temp/template_renderer_fixtures/test'); $page = new moodle_page; - $this->renderer = new template_renderer('moodle_test_renderer', + $this->renderer = new template_renderer('moodle_mod_test_renderer', array($this->templatefolder), $page); }