From 56cbc53b76a4a8f0bf170737bb52232f2852e417 Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Thu, 17 Dec 2009 13:45:54 +0000 Subject: [PATCH] MDL-21143 theme renderers related refactoring, it should detect more problems now, there is also a list of core renderer subtypes, hopefully the api changes are improvements --- lib/blocklib.php | 2 +- lib/outputfactories.php | 101 ++++++++++-------- lib/outputlib.php | 6 +- lib/outputrenderers.php | 4 +- lib/pagelib.php | 12 ++- mod/forum/renderer.php | 7 +- mod/forum/subscribers.php | 2 +- mod/lesson/continue.php | 2 +- mod/lesson/edit.php | 2 +- mod/lesson/editpage.php | 2 +- mod/lesson/essay.php | 2 +- mod/lesson/highscores.php | 2 +- mod/lesson/lesson.php | 2 +- mod/lesson/mediafile.php | 2 +- mod/lesson/renderer.php | 5 +- mod/lesson/report.php | 2 +- mod/lesson/view.php | 2 +- theme/custom_corners/lib.php | 5 +- .../{wsdocrenderer.php => renderer.php} | 15 +++ webservice/wsdoc.php | 5 +- 20 files changed, 107 insertions(+), 75 deletions(-) rename webservice/{wsdocrenderer.php => renderer.php} (97%) diff --git a/lib/blocklib.php b/lib/blocklib.php index 7bb4d615ea..7620e5df6d 100644 --- a/lib/blocklib.php +++ b/lib/blocklib.php @@ -1147,7 +1147,7 @@ class block_manager { $editpage->set_title($strheading); $editpage->set_heading($strheading); - $output = $editpage->theme->get_renderer('core', $editpage); + $output = $editpage->find_renderer('core'); echo $output->header(); echo $output->heading($strheading, 2); $mform->display(); diff --git a/lib/outputfactories.php b/lib/outputfactories.php index 3fa552887e..9418c6dca9 100644 --- a/lib/outputfactories.php +++ b/lib/outputfactories.php @@ -61,12 +61,12 @@ interface renderer_factory { * $subtype parameter. For example workshop_renderer, * workshop_allocation_manual_renderer etc. * - * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param moodle_page $page the page the renderer is outputting content for. + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return object an object implementing the requested renderer interface. */ - public function get_renderer($component, $page, $subtype=null); + public function get_renderer(moodle_page $page, $component, $subtype=null); } @@ -86,6 +86,8 @@ interface renderer_factory { abstract class renderer_factory_base implements renderer_factory { /** @var theme_config the theme we belong to. */ protected $theme; + /** @var hardcoded list of core subtypes and their locations */ + protected $core_subtypes = array('webservice'=>'webservice'); /** * Constructor. @@ -106,28 +108,38 @@ abstract class renderer_factory_base implements renderer_factory { * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return string the name of the standard renderer class for that module. */ - protected function standard_renderer_class_for_plugin($component, $subtype=null) { + protected function standard_renderer_classname($component, $subtype=null) { global $CFG; // needed in incldued files if ($component !== 'core') { - // renderers are stored in lib.php files like the rest of standard functions and classes - $libfile = get_component_directory($component) . '/renderer.php'; - if (file_exists($libfile)) { - include_once($libfile); + // standardize component names + if (strpos($component, '_') === false) { + $component = $component.'_mod'; + } + // renderers are stored in renderer.php files + if (!$compdirectory = get_component_directory($component)) { + throw new coding_exception('Invalid component specified in renderer request'); + } + $rendererfile = $compdirectory . '/renderer.php'; + if (file_exists($rendererfile)) { + include_once($rendererfile); } - } - if (strpos($component, 'mod_') === 0) { - $component = substr($component, 4); + } else if (!empty($subtype)) { + if (!isset($this->core_subtypes[$subtype])) { + throw new coding_exception('Invalid core subtype "'.$subtype.'" in renderer request'); + } + $rendererfile = $CFG->dirroot . '/' . $this->core_subtypes[$subtype] . '/renderer.php'; + if (file_exists($rendererfile)) { + include_once($rendererfile); + } } - if (is_null($subtype)) { + + if (empty($subtype)) { $class = $component . '_renderer'; } else { $class = $component . '_' . $subtype . '_renderer'; } - if (!class_exists($class)) { - throw new coding_exception('Request for an unknown renderer class ' . $class); - } return $class; } } @@ -144,43 +156,45 @@ abstract class renderer_factory_base implements renderer_factory { class standard_renderer_factory extends renderer_factory_base { /** * Implement the subclass method - * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param moodle_page $page the page the renderer is outputting content for. + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return object an object implementing the requested renderer interface. */ - public function get_renderer($component, $page, $subtype=null) { - if ($component === 'core') { - return new core_renderer($page); - } else { - $class = $this->standard_renderer_class_for_plugin($component, $subtype); - return new $class($page, $this->get_renderer('core', $page)); + public function get_renderer(moodle_page $page, $component, $subtype=null) { + $classname = $this->standard_renderer_classname($component, $subtype); + if (!class_exists($classname)) { + throw new coding_exception('Request for an unknown renderer class ' . $classname); } + return new $classname($page); } } /** * This is a slight variation on the standard_renderer_factory used by CLI scripts. + * CLI renderers use suffic '_cli' added to the standard renderer names * * @copyright 2009 Tim Hunt * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 2.0 */ -class cli_renderer_factory extends standard_renderer_factory { +class cli_renderer_factory extends renderer_factory_base { /** * Implement the subclass method - * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param moodle_page $page the page the renderer is outputting content for. + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return object an object implementing the requested renderer interface. */ - public function get_renderer($component, $page, $subtype=null) { - if ($component === 'core') { - return new cli_core_renderer($page); - } else { - parent::get_renderer($component, $page, $subtype); + public function get_renderer(moodle_page $page, $component, $subtype=null) { + $classname = $this->standard_renderer_classname($component, $subtype); + if (class_exists($classname . '_cli')) { + $classname = $classname . '_cli'; + } else if (!class_exists($classname)) { + throw new coding_exception('Request for an unknown renderer class ' . $classname); } + return new $classname($page); } } @@ -199,7 +213,8 @@ class cli_renderer_factory extends standard_renderer_factory { * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 2.0 */ -class theme_overridden_renderer_factory extends standard_renderer_factory { +class theme_overridden_renderer_factory extends renderer_factory_base { + protected $prefixes = array(); /** @@ -214,32 +229,26 @@ class theme_overridden_renderer_factory extends standard_renderer_factory { /** * Implement the subclass method - * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param moodle_page $page the page the renderer is outputting content for. + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return object an object implementing the requested renderer interface. */ - public function get_renderer($component, $page, $subtype=null) { - if (strpos($component, 'mod_') === 0) { - $component = substr($component, 4); + public function get_renderer(moodle_page $page, $component, $subtype=null) { + $classname = $this->standard_renderer_classname($component, $subtype); + if (!class_exists($classname)) { + // standard renderer must always exist + throw new coding_exception('Request for an unknown renderer class ' . $classname); } foreach ($this->prefixes as $prefix) { - // theme lib.php files are loaded automatically - if (is_null($subtype)) { - $classname = $prefix . '_' . $component . '_renderer'; - } else { - $classname = $prefix . '_' . $component . '_' . $subtype . '_renderer'; - } - if (class_exists($classname)) { - if ($component === 'core') { - return new $classname($page); - } else { - return new $classname($page, $this->get_renderer('core', $page)); - } + // theme lib.php and renderers.php files are loaded automatically + if (class_exists($prefix . '_' . $classname)) { + $classname = $prefix . '_' . $classname; + return new $classname($page); } } // use standard renderes if themes do not contain overridden renderer - return parent::get_renderer($component, $page, $subtype); + return new $classname($page); } } diff --git a/lib/outputlib.php b/lib/outputlib.php index ce627ea2c5..8f7948c3b3 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -906,12 +906,12 @@ class theme_config { /** * 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 + * @param string $module the name of part of moodle. E.g. 'core', 'quiz', 'qtype_multichoice'. * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' * @return renderer_base the requested renderer. */ - public function get_renderer($module, $page, $subtype=null) { + public function get_renderer(moodle_page $page, $component, $subtype=null) { if (is_null($this->rf)) { if (CLI_SCRIPT) { $classname = 'cli_renderer_factory'; @@ -921,7 +921,7 @@ class theme_config { $this->rf = new $classname($this); } - return $this->rf->get_renderer($module, $page, $subtype); + return $this->rf->get_renderer($page, $component, $subtype); } /** diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index d2271647a4..18c91b34ed 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -47,7 +47,7 @@ class renderer_base { * Constructor * @param moodle_page $page the page we are doing output for. */ - public function __construct($page) { + public function __construct(moodle_page $page) { $this->opencontainers = $page->opencontainers; $this->page = $page; } @@ -2072,7 +2072,7 @@ class core_renderer extends renderer_base { * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 2.0 */ -class cli_core_renderer extends core_renderer { +class core_renderer_cli extends core_renderer { /** * Returns the page header. * @return string HTML fragment diff --git a/lib/pagelib.php b/lib/pagelib.php index 1f3879f5cb..415f647845 100644 --- a/lib/pagelib.php +++ b/lib/pagelib.php @@ -167,6 +167,16 @@ class moodle_page { */ protected $_legacypageobject = null; + /** + * Returns instance of page renderer + * @param string $component name such as 'core', 'mod_forum' or 'qtype_multichoice'. + * @param string $subtype optional subtype such as 'news' resulting to 'mod_forum_news' + * @return renderer_base + */ + public function find_renderer($component, $subtype = null) { + return $this->get_theme()->get_renderer($this, $component, $subtype); + } + /// Getter methods ============================================================= /// Due to the __get magic below, you normally do not call these as $PAGE->get_x /// methods, but instead use the $PAGE->x syntax. @@ -1039,7 +1049,7 @@ class moodle_page { if ($this === $PAGE) { $THEME = $this->_theme; - $OUTPUT = $this->_theme->get_renderer('core', $this); + $OUTPUT = $this->find_renderer('core'); } $this->_wherethemewasinitialised = debug_backtrace(); diff --git a/mod/forum/renderer.php b/mod/forum/renderer.php index 6ee4e2cf11..db0a5bb66f 100644 --- a/mod/forum/renderer.php +++ b/mod/forum/renderer.php @@ -34,7 +34,7 @@ class mod_forum_renderer extends renderer_base { /** - * A reference to the current general renderer probably {@see moodle_core_renderer} + * A reference to the current general renderer probably {@see core_renderer} * @var renderer_base */ protected $output; @@ -42,11 +42,10 @@ class mod_forum_renderer extends renderer_base { /** * Contructor method, calls the parent constructor * @param moodle_page $page - * @param renderer_base $output Probably moodle_core_renderer */ - public function __construct($page, $output) { + public function __construct(moodle_page $page) { + $this->output = $page->find_renderer('core'); parent::__construct($page); - $this->output = $output; } /** diff --git a/mod/forum/subscribers.php b/mod/forum/subscribers.php index b55dd21dd2..5d3b01d63b 100644 --- a/mod/forum/subscribers.php +++ b/mod/forum/subscribers.php @@ -56,7 +56,7 @@ unset($SESSION->fromdiscussion); add_to_log($course->id, "forum", "view subscribers", "subscribers.php?id=$forum->id", $forum->id, $cm->id); -$forumoutput = $PAGE->theme->get_renderer('mod_forum', $PAGE); +$forumoutput = $PAGE->find_renderer('mod_forum'); $currentgroup = groups_get_activity_group($cm); $options = array('forumid'=>$forum->id, 'currentgroup'=>$currentgroup, 'context'=>$context); $existingselector = new forum_existing_subscriber_selector('existingsubscribers', $options); diff --git a/mod/lesson/continue.php b/mod/lesson/continue.php index a943f0d247..42f4f72b73 100644 --- a/mod/lesson/continue.php +++ b/mod/lesson/continue.php @@ -40,7 +40,7 @@ require_sesskey(); $context = get_context_instance(CONTEXT_MODULE, $cm->id); $canmanage = has_capability('mod/lesson:manage', $context); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); $url = new moodle_url($CFG->wwwroot.'/mod/lesson/continue.php', array('id'=>$cm->id)); $PAGE->set_url($url); diff --git a/mod/lesson/edit.php b/mod/lesson/edit.php index 25de1d3ac4..4c46a3db3f 100644 --- a/mod/lesson/edit.php +++ b/mod/lesson/edit.php @@ -45,7 +45,7 @@ if ($mode != get_user_preferences('lesson_view', 'collapsed') && $mode !== 'sing set_user_preference('lesson_view', $mode); } -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); $PAGE->navbar->add(get_string('edit')); echo $lessonoutput->header($lesson, $mode); if (!$lesson->has_pages()) { diff --git a/mod/lesson/editpage.php b/mod/lesson/editpage.php index ec40524a1a..5e9a60ba6b 100644 --- a/mod/lesson/editpage.php +++ b/mod/lesson/editpage.php @@ -98,7 +98,7 @@ if ($data = $mform->get_data()) { redirect(new moodle_url($CFG->wwwroot.'/mod/lesson/edit.php', array('id'=>$cm->id))); } -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); echo $lessonoutput->header($lesson); $mform->display(); echo $lessonoutput->footer(); \ No newline at end of file diff --git a/mod/lesson/essay.php b/mod/lesson/essay.php index 6ab45d680b..87bd7e45df 100644 --- a/mod/lesson/essay.php +++ b/mod/lesson/essay.php @@ -277,7 +277,7 @@ switch ($mode) { // Log it add_to_log($course->id, 'lesson', 'view grade', "essay.php?id=$cm->id", get_string('manualgrading', 'lesson'), $cm->id); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); echo $lessonoutput->header($lesson, 'essay'); switch ($mode) { diff --git a/mod/lesson/highscores.php b/mod/lesson/highscores.php index 31d2976f87..2cb842a280 100644 --- a/mod/lesson/highscores.php +++ b/mod/lesson/highscores.php @@ -161,7 +161,7 @@ switch ($mode) { // Log it add_to_log($course->id, 'lesson', 'view highscores', "highscores.php?id=$cm->id", $lesson->name, $cm->id); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); echo $lessonoutput->header($lesson, 'highscores'); switch ($mode) { diff --git a/mod/lesson/lesson.php b/mod/lesson/lesson.php index bab8733877..376aeed604 100644 --- a/mod/lesson/lesson.php +++ b/mod/lesson/lesson.php @@ -52,7 +52,7 @@ $context = get_context_instance(CONTEXT_MODULE, $cm->id); require_capability('mod/lesson:edit', $context); require_sesskey(); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); /// Process the action switch ($action) { diff --git a/mod/lesson/mediafile.php b/mod/lesson/mediafile.php index 8a1fb17ae2..73aeec7726 100644 --- a/mod/lesson/mediafile.php +++ b/mod/lesson/mediafile.php @@ -52,7 +52,7 @@ try { require_login($course, false, $cm); $context = get_context_instance(CONTEXT_MODULE, $cm->id); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); // Get the mimetype $mimetype = mimeinfo("type", $lesson->mediafile); diff --git a/mod/lesson/renderer.php b/mod/lesson/renderer.php index 1cce16a69a..9164f0a267 100644 --- a/mod/lesson/renderer.php +++ b/mod/lesson/renderer.php @@ -34,11 +34,10 @@ class mod_lesson_renderer extends renderer_base { /** * Contructor method, calls the parent constructor * @param moodle_page $page - * @param renderer_base $output Probably moodle_core_renderer */ - public function __construct($page, $output) { + public function __construct(moodle_page $page) { + $this->output = $page->find_renderer('core'); parent::__construct($page); - $this->output = $output; } /** diff --git a/mod/lesson/report.php b/mod/lesson/report.php index 5216adfd64..28895b79a9 100644 --- a/mod/lesson/report.php +++ b/mod/lesson/report.php @@ -75,7 +75,7 @@ if ($pageid !== NULL) { } $PAGE->set_url($url); $PAGE->navbar->add(get_string('reports', 'lesson'), new moodle_url($CFG->wwwroot.'/mod/lesson/report.php', array('id'=>$id))); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); /// Process any form data before fetching attempts, grades and times if (has_capability('mod/lesson:edit', $context) && $form = data_submitted() && confirm_sesskey()) { diff --git a/mod/lesson/view.php b/mod/lesson/view.php index 3f253f5d6c..a1aabcf67d 100644 --- a/mod/lesson/view.php +++ b/mod/lesson/view.php @@ -51,7 +51,7 @@ $PAGE->set_url($url); $context = get_context_instance(CONTEXT_MODULE, $cm->id); $canmanage = has_capability('mod/lesson:manage', $context); -$lessonoutput = $PAGE->theme->get_renderer('mod_lesson', $PAGE); +$lessonoutput = $PAGE->find_renderer('mod_lesson'); /// Check these for students only TODO: Find a better method for doing this! /// Check lesson availability diff --git a/theme/custom_corners/lib.php b/theme/custom_corners/lib.php index 91079b4f7c..668880df28 100644 --- a/theme/custom_corners/lib.php +++ b/theme/custom_corners/lib.php @@ -16,11 +16,12 @@ class custom_corners_renderer_factory extends standard_renderer_factory { global $CFG; require_once($CFG->themedir . '/custom_corners/renderers.php'); } + /* Implement the subclass method. */ - public function get_renderer($module, $page, $subtype=null) { + public function get_renderer(moodle_page $page, $module, $subtype=null) { if ($module == 'core') { return new custom_corners_core_renderer($page); } - return parent::get_renderer($module, $page, $subtype); + return parent::get_renderer($page, $module, $subtype); } } diff --git a/webservice/wsdocrenderer.php b/webservice/renderer.php similarity index 97% rename from webservice/wsdocrenderer.php rename to webservice/renderer.php index 0fd1ccf264..e837992c16 100644 --- a/webservice/wsdocrenderer.php +++ b/webservice/renderer.php @@ -29,6 +29,21 @@ class core_wsdoc_renderer extends renderer_base { + /** + * A reference to the current general renderer probably {@see core_renderer} + * @var renderer_base + */ + protected $output; + + /** + * Contructor method, calls the parent constructor + * @param moodle_page $page + */ + public function __construct(moodle_page $page) { + $this->output = $page->find_renderer('core'); + parent::__construct($page); + } + /** * Create documentation for a description object * @param object $params a part of parameter/return description diff --git a/webservice/wsdoc.php b/webservice/wsdoc.php index 07be2fa154..f0b10ef48c 100644 --- a/webservice/wsdoc.php +++ b/webservice/wsdoc.php @@ -25,7 +25,6 @@ define('NO_DEBUG_DISPLAY', true); define('NO_MOODLE_COOKIES', true); require_once('../config.php'); -require_once('./wsdocrenderer.php'); require_once('lib.php'); @@ -241,7 +240,7 @@ class webservice_documentation_generator { $USER->id = null; echo $OUTPUT->header(); $USER->id = $userid; - $renderer = $PAGE->theme->get_renderer('core_wsdoc',$OUTPUT); + $renderer = $PAGE->find_renderer('core', 'wsdoc'); echo $renderer->documentation_html($this->functions, $this->username); echo $OUTPUT->footer(); @@ -265,7 +264,7 @@ class webservice_documentation_generator { $PAGE->set_pagelayout('popup'); echo $OUTPUT->header(); - $renderer = $PAGE->theme->get_renderer('core_wsdoc',$OUTPUT); + $renderer = $PAGE->find_renderer('core', 'wsdoc'); echo $renderer->login_page_html($errormessage); echo $OUTPUT->footer(); -- 2.39.5