/// 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.
$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;
/// 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]);
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.
}
/**
- * 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.