Automatic installer.php lang files by installer_builder (20061110)
[moodle.git] / question / preview.php
blobf8e628acba0b97206a1ecac25e56c29e6ac6c5be
1 <?php // $Id$
2 /**
3 * This page displays a preview of a question
5 * The preview uses the option settings from the activity within which the question
6 * is previewed or the default settings if no activity is specified. The question session
7 * information is stored in the session as an array of subsequent states rather
8 * than in the database.
10 * TODO: make this work with activities other than quiz
12 * @version $Id$
13 * @author Alex Smith as part of the Serving Mathematics project
14 * {@link http://maths.york.ac.uk/serving_maths}
15 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
16 * @package question
19 require_once("../config.php");
20 require_once($CFG->libdir.'/questionlib.php');
21 require_once($CFG->dirroot.'/mod/quiz/locallib.php'); // We really want to get rid of this
23 $id = required_param('id', PARAM_INT); // question id
24 // if no quiz id is specified then a dummy quiz with default options is used
25 $quizid = optional_param('quizid', 0, PARAM_INT);
26 // Test if we are continuing an attempt at a question
27 $continue = optional_param('continue', 0, PARAM_BOOL);
28 // Check for any of the submit buttons
29 $fillcorrect = optional_param('fillcorrect', 0, PARAM_BOOL);
30 $markall = optional_param('markall', 0, PARAM_BOOL);
31 $finishattempt = optional_param('finishattempt', 0, PARAM_BOOL);
32 $back = optional_param('back', 0, PARAM_BOOL);
33 $startagain = optional_param('startagain', 0, PARAM_BOOL);
34 // We are always continuing an attempt if a submit button was pressed with the
35 // exception of the start again button
36 if ($fillcorrect || $markall || $finishattempt || $back) {
37 $continue = true;
38 } else if ($startagain) {
39 $continue = false;
42 require_login();
44 // this might break things in the future
45 if (!isteacherinanycourse()) {
46 error('This page is for teachers only');
49 if (!$continue) {
50 // Start a new attempt; delete the old session
51 unset($SESSION->quizpreview);
52 // Redirect to ourselves but with continue=1; prevents refreshing the page
53 // from restarting an attempt (needed so that random questions don't change)
54 $quizid = $quizid ? '&amp;quizid=' . $quizid : '';
55 redirect($CFG->wwwroot . '/question/preview.php?id=' . $id . $quizid .
56 '&amp;continue=1');
59 if (empty($quizid)) {
60 $quiz = new cmoptions;
61 $quiz->id = 0;
62 $quiz->review = $CFG->quiz_review;
64 } else if (!$quiz = get_record('quiz', 'id', $quizid)) {
65 error("Quiz id $quizid does not exist");
68 // Load the question information
69 if (!$questions = get_records('question', 'id', $id)) {
70 error('Could not load question');
72 if ($maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $id)) {
73 $questions[$id]->maxgrade = $maxgrade;
74 } else {
75 $questions[$id]->maxgrade = $questions[$id]->defaultgrade;
78 $quiz->id = 0; // just for safety
79 $quiz->questions = $id;
81 if (!$category = get_record("question_categories", "id", $questions[$id]->category)) {
82 error("This question doesn't belong to a valid category!");
85 if (!has_capability('moodle/question:manage', get_context_instance(CONTEXT_COURSE, $category->course)) and !$category->publish) {
86 error("You can't preview these questions!");
88 $quiz->course = $category->course;
90 // Load the question type specific information
91 if (!get_question_options($questions)) {
92 error(get_string('newattemptfail', 'quiz'));
95 // Create a dummy quiz attempt
96 // TODO: find out what of the following we really need. What is $attempt
97 // really used for?
98 $timenow = time();
99 $attempt->quiz = $quiz->id;
100 $attempt->userid = $USER->id;
101 $attempt->attempt = 0;
102 $attempt->sumgrades = 0;
103 $attempt->timestart = $timenow;
104 $attempt->timefinish = 0;
105 $attempt->timemodified = $timenow;
106 $attempt->uniqueid = 0;
107 $attempt->id = 0;
109 // Restore the history of question sessions from the moodle session or create
110 // new sessions. Make $states a reference to the states array in the moodle
111 // session.
112 if (isset($SESSION->quizpreview->states) and $SESSION->quizpreview->questionid
113 == $id) {
114 // Reload the question session history from the moodle session
115 $states =& $SESSION->quizpreview->states;
116 $historylength = count($states) - 1;
117 if ($back && $historylength > 0) {
118 // Go back one step in the history
119 unset($states[$historylength]);
120 $historylength--;
122 } else {
123 // Record the question id in the moodle session
124 $SESSION->quizpreview->questionid = $id;
125 // Create an empty session for the question
126 if (!$newstates =
127 get_question_states($questions, $quiz, $attempt)) {
128 error(get_string('newattemptfail', 'quiz'));
130 $SESSION->quizpreview->states = array($newstates);
131 $states =& $SESSION->quizpreview->states;
132 $historylength = 0;
135 if (!$fillcorrect && !$back && ($form = data_submitted())) {
136 $form = (array)$form;
137 $submitted = true;
139 // Create a new item in the history of question states (don't simplify!)
140 $states[$historylength + 1] = array();
141 $states[$historylength + 1][$id] = clone($states[$historylength][$id]);
142 $historylength++;
143 $curstate =& $states[$historylength][$id];
144 $curstate->changed = false;
146 // Process the responses
147 unset($form['id']);
148 unset($form['quizid']);
149 unset($form['continue']);
150 unset($form['markall']);
151 unset($form['finishattempt']);
152 unset($form['back']);
153 unset($form['startagain']);
155 $event = $finishattempt ? QUESTION_EVENTCLOSE : QUESTION_EVENTSUBMIT;
156 if ($actions = question_extract_responses($questions, $form, $event)) {
157 $actions[$id]->timestamp = 0; // We do not care about timelimits here
158 question_process_responses($questions[$id], $curstate, $actions[$id], $quiz, $attempt);
159 if (!$curstate->changed) {
160 // Update the current state rather than creating a new one
161 $historylength--;
162 unset($states[$historylength]);
163 $states = array_values($states);
164 $curstate =& $states[$historylength][$id];
167 } else {
168 $submitted = false;
169 $curstate =& $states[$historylength][$id];
172 // TODO: should not use quiz-specific function here
173 $options = quiz_get_renderoptions($quiz->review, $curstate);
175 // Fill in the correct responses (unless the question is in readonly mode)
176 if ($fillcorrect && !$options->readonly) {
177 $curstate->responses = $QTYPES[$questions[$id]->qtype]
178 ->get_correct_responses($questions[$id], $curstate);
181 $strpreview = get_string('preview', 'quiz').' '.s($questions[$id]->name);
182 print_header($strpreview);
183 print_heading($strpreview);
185 if (!empty($quizid)) {
186 echo '<p align="center">'.get_string('modulename', 'quiz') . ': ';
187 p($quiz->name);
188 echo "</p>\n";
190 $number = 1;
191 echo "<form method=\"post\" action=\"preview.php\" autocomplete=\"off\">\n";
192 echo "<input type=\"hidden\" name=\"id\" value=\"$id\" />\n";
193 echo "<input type=\"hidden\" name=\"quizid\" value=\"$quizid\" />\n";
194 echo "<input type=\"hidden\" name=\"continue\" value=\"1\" />\n";
196 print_question($questions[$id], $curstate, $number, $quiz, $options);
198 echo '<br />';
199 echo '<center>';
201 // Print the mark and finish attempt buttons
202 echo '<input name="markall" type="submit" value="' . get_string('markall',
203 'quiz') . "\" />\n";
204 echo '<input name="finishattempt" type="submit" value="' .
205 get_string('finishattempt', 'quiz') . "\" />\n";
206 echo '<br />';
207 echo '<br />';
208 // Print the fill correct button (unless the question is in readonly mode)
209 if (!$options->readonly) {
210 echo '<input name="fillcorrect" type="submit" value="' .
211 get_string('fillcorrect', 'quiz') . "\" />\n";
213 // Print the navigation buttons
214 if ($historylength > 0) {
215 echo '<input name="back" type="submit" value="' . get_string('previous',
216 'quiz') . "\" />\n";
218 // Print the start again button
219 echo '<input name="startagain" type="submit" value="' .
220 get_string('startagain', 'quiz') . "\" />\n";
221 // Print the close window button
222 echo '<input type="button" onclick="window.close()" value="' .
223 get_string('closepreview', 'quiz') . "\" />";
224 echo '</center>';
225 echo '</form>';
226 print_footer();