]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-6368 and MDL-6369 - allow question type plugins to easily provide some bits of...
authortjhunt <tjhunt>
Thu, 12 Apr 2007 15:58:32 +0000 (15:58 +0000)
committertjhunt <tjhunt>
Thu, 12 Apr 2007 15:58:32 +0000 (15:58 +0000)
If there are any of the files styles.css, styles.php, script.js or script.php in the plugin folder, they will be linked to in the head of the quiz attempt page (only for the question types used on that page).

If you need to do something more complicated in your question type, you can override the get_html_head_contributions method instead.

lib/questionlib.php
mod/quiz/attempt.php
question/type/questiontype.php
question/type/random/questiontype.php

index a735f350ae18c2e5a4ad77d16daf469efaba3bb4..21411cc1cf588497bb5700fb1b05c2429c4e1c77 100644 (file)
@@ -1428,8 +1428,32 @@ function question_hash($question) {
 
 
 /// FUNCTIONS THAT SIMPLY WRAP QUESTIONTYPE METHODS //////////////////////////////////
+/**
+ * Get the HTML that needs to be included in the head tag when the
+ * questions in $questionlist are printed in the gives states.
+ *
+ * @param array $questionlist a list of questionids of the questions what will appear on this page.
+ * @param array $questions an array of question objects, whose keys are question ids.
+ *      Must contain all the questions in $questionlist
+ * @param array $states an array of question state objects, whose keys are question ids.
+ *      Must contain the state of all the questions in $questionlist
+ *
+ * @return string some HTML code that can go inside the head tag.
+ */
+function get_html_head_contributions(&$questionlist, &$questions, &$states) {
+    global $QTYPES;
 
- /**
+    $contributions = array();
+    foreach ($questionlist as $questionid) {
+        $question = $questions[$questionid];
+        $contributions = array_merge($contributions,
+                $QTYPES[$question->qtype]->get_html_head_contributions(
+                $question, $states[$questionid]));
+    }
+    return implode("\n", array_unique($contributions));
+}
+
+/**
  * Prints a question
  *
  * Simply calls the question type specific print_question() method.
@@ -1446,10 +1470,10 @@ function print_question(&$question, &$state, $number, $cmoptions, $options=null)
      $cmoptions, $options);
 }
 /**
-* Saves question options
-*
-* Simply calls the question type specific save_question_options() method.
-*/
+ * Saves question options
+ *
+ * Simply calls the question type specific save_question_options() method.
+ */
 function save_question_options($question) {
     global $QTYPES;
 
index 583f0762fc904460e96a0ddeeb9f653a98da0a64..9b2030138d36bf4e381390b7efe71f0d63c207a7 100644 (file)
 /// Print the quiz page ////////////////////////////////////////////////////////
 
     // Print the page header
+    $pagequestions = explode(',', $pagelist);
+    $headtags = get_html_head_contributions($pagequestions, $questions, $states);
     if (!empty($popup)) {
         define('MESSAGE_WINDOW', true);  // This prevents the message window coming up
-        print_header($course->shortname.': '.format_string($quiz->name), '', '', '', '', false, '', '', false, '');
+        print_header($course->shortname.': '.format_string($quiz->name), '', '', '', $headtags, false, '', '', false, '');
         include('protect_js.php');
     } else {
         $strupdatemodule = has_capability('moodle/course:manageactivities', $coursecontext)
         print_header_simple(format_string($quiz->name), "",
                  "<a href=\"index.php?id=$course->id\">$strquizzes</a> ->
                   <a href=\"view.php?id=$cm->id\">".format_string($quiz->name)."</a> -> $strattemptnum",
-                  "", "", true, $strupdatemodule);
+                  "", $headtags, true, $strupdatemodule);
     }
 
     echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
     // Add a hidden field with questionids
     echo '<input type="hidden" name="questionids" value="'.$pagelist."\" />\n";
 
-    $pagequestions = explode(',', $pagelist);
     $number = quiz_first_questionnumber($attempt->layout, $pagelist);
     foreach ($pagequestions as $i) {
         $options = quiz_get_renderoptions($quiz->review, $states[$i]);
index 1bd6b57578e7caa0b2aafdf058be1f5dd63afb6a..61dbcc13e9e6e8f13225eda0e711db994ab36aec 100644 (file)
@@ -98,6 +98,22 @@ class default_questiontype {
         return new $classname($submiturl, $question);
     }
 
+    /**
+     * @return string the full path of the folder this plugin's files live in.
+     */
+    function plugin_dir() {
+        global $CFG;
+        return $CFG->dirroot . '/question/type/' . $this->name();
+    }
+
+    /**
+     * @return string the URL of the folder this plugin's files live in.
+     */
+    function plugin_baseurl() {
+        global $CFG;
+        return $CFG->wwwroot . '/question/type/' . $this->name();
+    }
+
     /**
      * This method should be overriden if you want to include a special heading or some other
      * html on a question editing page besides the question editing form.
@@ -542,32 +558,84 @@ class default_questiontype {
     }
 
     /**
-    * Prints the question including the number, grading details, content,
-    * feedback and interactions
-    *
-    * This function prints the question including the question number,
-    * grading details, content for the question, any feedback for the previously
-    * submitted responses and the interactions. The default implementation calls
-    * various other methods to print each of these parts and most question types
-    * will just override those methods.
-    * @param object $question The question to be rendered. Question type
-    *                         specific information is included. The
-    *                         maximum possible grade is in ->maxgrade. The name
-    *                         prefix for any named elements is in ->name_prefix.
-    * @param object $state    The state to render the question in. The grading
-    *                         information is in ->grade, ->raw_grade and
-    *                         ->penalty. The current responses are in
-    *                         ->responses. This is an associative array (or the
-    *                         empty string or null in the case of no responses
-    *                         submitted). The last graded state is in
-    *                         ->last_graded (hence the most recently graded
-    *                         responses are in ->last_graded->responses). The
-    *                         question type specific information is also
-    *                         included.
-    * @param integer $number  The number for this question.
-    * @param object $cmoptions
-    * @param object $options  An object describing the rendering options.
-    */
+     * If this question type requires extra CSS or JavaScript to function,
+     * then this method will return an array of <link ...> tags that reference
+     * those stylesheets. This function will also call require_js()
+     * from ajaxlib.php, to get any necessary JavaScript linked in too.
+     * 
+     * The two parameters match the first two parameters of print_question.
+     * 
+     * @param object $question The question object.
+     * @param object $state    The state object.
+     * 
+     * @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_html_head_contributions(&$question, &$state) {
+        // 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.
+        
+        // We only do this once 
+        // for this question type, no matter how often this method is called.
+        static $already_done = false;
+        if ($already_done) {
+            return array();
+        }
+        $already_done = true;
+        
+        $plugindir = $this->plugin_dir();
+        $baseurl = $this->plugin_baseurl();
+        $stylesheets = array();
+        if (file_exists($plugindir . '/styles.css')) {
+            $stylesheets[] = 'styles.css';
+        }
+        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[] = '<link rel="stylesheet" type="text/css" href="' .
+                    $baseurl . '/' . $stylesheet . '" />"';
+        }
+        return $contributions;
+    }
+    
+    /**
+     * Prints the question including the number, grading details, content,
+     * feedback and interactions
+     *
+     * This function prints the question including the question number,
+     * grading details, content for the question, any feedback for the previously
+     * submitted responses and the interactions. The default implementation calls
+     * various other methods to print each of these parts and most question types
+     * will just override those methods.
+     * @param object $question The question to be rendered. Question type
+     *                         specific information is included. The
+     *                         maximum possible grade is in ->maxgrade. The name
+     *                         prefix for any named elements is in ->name_prefix.
+     * @param object $state    The state to render the question in. The grading
+     *                         information is in ->grade, ->raw_grade and
+     *                         ->penalty. The current responses are in
+     *                         ->responses. This is an associative array (or the
+     *                         empty string or null in the case of no responses
+     *                         submitted). The last graded state is in
+     *                         ->last_graded (hence the most recently graded
+     *                         responses are in ->last_graded->responses). The
+     *                         question type specific information is also
+     *                         included.
+     * @param integer $number  The number for this question.
+     * @param object $cmoptions
+     * @param object $options  An object describing the rendering options.
+     */
     function print_question(&$question, &$state, $number, $cmoptions, $options) {
         /* The default implementation should work for most question types
         provided the member functions it calls are overridden where required.
index fb96a22a44b4ecc3e4216d245f6fbc6faf060bbb..7f1765507cd9bc282da60976d66c8c48a7140d4c 100644 (file)
@@ -218,6 +218,12 @@ class random_qtype extends default_questiontype {
          ->get_actual_response($wrappedquestion, $state);
     }
 
+    function get_html_head_contributions(&$question, &$state) {
+        global $QTYPES;
+        $wrappedquestion = &$state->options->question;
+        return $QTYPES[$wrappedquestion->qtype]
+                ->get_html_head_contributions($wrappedquestion, $state);
+    }
 
     function print_question(&$question, &$state, &$number, $cmoptions, $options) {
         global $QTYPES;