From 50da63ebd90247819619b80de9d9e40f93e9982b Mon Sep 17 00:00:00 2001 From: tjhunt Date: Mon, 30 Mar 2009 09:15:46 +0000 Subject: [PATCH] qtypes: MDL-18711 Allow qtype plugins to have custom CSS and JavaScript on the editing page. --- lib/questionlib.php | 13 ++++++++ question/question.php | 5 +-- question/type/questiontype.php | 58 ++++++++++++++++++++++++++-------- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/lib/questionlib.php b/lib/questionlib.php index c46c77af70..caec2422b7 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -2084,6 +2084,19 @@ function get_html_head_contributions($questionlist, &$questions, &$states) { return implode("\n", array_unique($contributions)); } +/** + * Like @see{get_html_head_contributions} but for the editing page + * question/question.php. + * + * @param $question A question object. Only $question->qtype is used. + * @return string some HTML code that can go inside the head tag. + */ +function get_editing_head_contributions($question) { + global $QTYPES; + $contributions = $QTYPES[$question->qtype]->get_editing_head_contributions(); + return implode("\n", array_unique($contributions)); +} + /** * Prints a question * diff --git a/question/question.php b/question/question.php index 7bb670fc0c..dd04a6fd63 100644 --- a/question/question.php +++ b/question/question.php @@ -239,6 +239,7 @@ if ($mform->is_cancelled()){ } else { $streditingquestion = $QTYPES[$question->qtype]->get_heading(); + $headtags = get_editing_head_contributions($question); if ($cm !== null) { $strmodule = get_string('modulename', $cm->modname); $strupdatemodule = has_capability('moodle/course:manageactivities', get_context_instance(CONTEXT_COURSE, $COURSE->id)) @@ -256,7 +257,7 @@ if ($mform->is_cancelled()){ } $navlinks[] = array('name' => $streditingquestion, 'link' => '', 'type' => 'title'); $navigation = build_navigation($navlinks); - print_header_simple($streditingquestion, '', $navigation, "", "", true, $strupdatemodule); + print_header_simple($streditingquestion, '', $navigation, '', $headtags, true, $strupdatemodule); } else { $navlinks = array(); @@ -265,7 +266,7 @@ if ($mform->is_cancelled()){ $strediting = ''. get_string("editquestions", "quiz").' -> '.$streditingquestion; $navigation = build_navigation($navlinks); - print_header_simple($streditingquestion, '', $navigation); + print_header_simple($streditingquestion, '', $navigation, '', $headtags); } // Display a heading, question editing form and possibly some extra content needed for diff --git a/question/type/questiontype.php b/question/type/questiontype.php index e7c018c4ea..630822dbdf 100644 --- a/question/type/questiontype.php +++ b/question/type/questiontype.php @@ -804,13 +804,16 @@ class default_questiontype { } // Used by the following function, so that it only returns results once per quiz page. - var $already_done = false; + private $htmlheadalreadydone = false; /** * If this question type requires extra CSS or JavaScript to function, * then this method will return an array of tags that reference * those stylesheets. This function will also call require_js() * from ajaxlib.php, to get any necessary JavaScript linked in too. * + * Remember that there may be more than one question of this type on a page. + * try to avoid including JS and CSS more than once. + * * The two parameters match the first two parameters of print_question. * * @param object $question The question object. @@ -821,20 +824,55 @@ class default_questiontype { * integer array keys, which have no significance. */ function get_html_head_contributions(&$question, &$state) { + // We only do this once for this question type, no matter how often this + // method is called on one page. + if ($this->htmlheadalreadydone) { + return array(); + } + $this->htmlheadalreadydone = true; + // By default, we link to any of the files styles.css, styles.php, // script.js or script.php that exist in the plugin folder. // Core question types should not use this mechanism. Their styles // should be included in the standard theme. + return $this->find_standard_scripts_and_css(); + } - // We only do this once - // for this question type, no matter how often this method is called. - if ($this->already_done) { - return array(); - } - $this->already_done = true; + /** + * Like @see{get_html_head_contributions}, but this method is for CSS and + * JavaScript required on the question editing page question/question.php. + * + * @return an array of bits of HTML to add to the head of pages where + * this question is print_question-ed in the body. The array should use + * integer array keys, which have no significance. + */ + function get_editing_head_contributions() { + // By default, we link to any of the files styles.css, styles.php, + // script.js or script.php that exist in the plugin folder. + // Core question types should not use this mechanism. Their styles + // should be included in the standard theme. + return $this->find_standard_scripts_and_css(); + } + /** + * Utility method used by @see{get_html_head_contributions} and + * @see{get_editing_head_contributions}. This looks for any of the files + * styles.css, styles.php, script.js or script.php that exist in the plugin + * folder and ensures they get included. + * + * @return array as required by get_html_head_contributions or get_editing_head_contributions. + */ + protected function find_standard_scripts_and_css() { $plugindir = $this->plugin_dir(); $baseurl = $this->plugin_baseurl(); + + if (file_exists($plugindir . '/script.js')) { + require_js($baseurl . '/script.js'); + } + if (file_exists($plugindir . '/script.php')) { + require_js($baseurl . '/script.php'); + } + $stylesheets = array(); if (file_exists($plugindir . '/styles.css')) { $stylesheets[] = 'styles.css'; @@ -842,12 +880,6 @@ class default_questiontype { if (file_exists($plugindir . '/styles.php')) { $stylesheets[] = 'styles.php'; } - if (file_exists($plugindir . '/script.js')) { - require_js($baseurl . '/script.js'); - } - if (file_exists($plugindir . '/script.php')) { - require_js($baseurl . '/script.php'); - } $contributions = array(); foreach ($stylesheets as $stylesheet) { $contributions[] = '