Fixed the redirection url to edit.php
[moodle.git] / question / preview.php
CommitLineData
516cf3eb 1<?php // $Id$
2/**
3* This page displays a preview of a question
4*
e586cfb4 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
516cf3eb 7* information is stored in the session as an array of subsequent states rather
8* than in the database.
e586cfb4 9*
10* TODO: make this work with activities other than quiz
11*
516cf3eb 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
e586cfb4 16* @package question
516cf3eb 17*/
18
e586cfb4 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
516cf3eb 22
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;
40 }
41
42 require_login();
43
44 if (!isteacherinanycourse()) {
45 error('This page is for teachers only');
46 }
47
48 if (!$continue) {
49 // Start a new attempt; delete the old session
50 unset($SESSION->quizpreview);
51 // Redirect to ourselves but with continue=1; prevents refreshing the page
52 // from restarting an attempt (needed so that random questions don't change)
53 $quizid = $quizid ? '&amp;quizid=' . $quizid : '';
e586cfb4 54 redirect($CFG->wwwroot . '/question/preview.php?id=' . $id . $quizid .
516cf3eb 55 '&amp;continue=1');
56 }
57
58 if (empty($quizid)) {
59 // get a sample quiz to be used as a skeleton
60 // this should really be done properly by instantiating a quiz object
61 if (!$quiz = get_records('quiz')) {
62 error('You have to create at least one quiz before using this preview');
63 }
64 $quiz = array_values($quiz);
65 $quiz = $quiz[0];
66
67 // set everything to the default values
68 foreach($quiz as $field => $value) {
69 $quizfield = "quiz_".$field;
70 if(isset($CFG->$quizfield)) {
71 $quiz->$field = $CFG->$quizfield;
72 }
73 else {
74 $quiz->$field = 0;
75 }
76 }
77
78 } else if (!$quiz = get_record('quiz', 'id', $quizid)) {
79 error("Quiz id $quizid does not exist");
80 }
81
82 // Load the question information
83 if (!$questions = get_records('quiz_questions', 'id', $id)) {
84 error('Could not load question');
85 }
86 if ($maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $id)) {
87 $questions[$id]->maxgrade = $maxgrade;
88 } else {
89 $questions[$id]->maxgrade = $questions[$id]->defaultgrade;
90 }
91
92 $quiz->id = 0; // just for safety
93 $quiz->questions = $id;
94
95 if (!$category = get_record("quiz_categories", "id", $questions[$id]->category)) {
96 error("This question doesn't belong to a valid category!");
97 }
98
99 if (!isteacher($category->course) and !$category->publish) {
100 error("You can't preview these questions!");
101 }
102 $quiz->course = $category->course;
103
104 // Load the question type specific information
105 if (!quiz_get_question_options($questions)) {
106 error(get_string('newattemptfail', 'quiz'));
107 }
108
109 // Create a dummy quiz attempt
110 $attempt = quiz_create_attempt($quiz, 0);
111 $attempt->id = 0;
112
113 // Restore the history of question sessions from the moodle session or create
114 // new sessions. Make $states a reference to the states array in the moodle
115 // session.
116 if (isset($SESSION->quizpreview->states) and $SESSION->quizpreview->questionid
117 == $id) {
118 // Reload the question session history from the moodle session
119 $states =& $SESSION->quizpreview->states;
120 $historylength = count($states) - 1;
121 if ($back && $historylength > 0) {
122 // Go back one step in the history
123 unset($states[$historylength]);
124 $historylength--;
125 }
126 } else {
127 // Record the question id in the moodle session
128 $SESSION->quizpreview->questionid = $id;
129 // Create an empty session for the question
130 if (!$newstates =
131 quiz_get_states($questions, $quiz, $attempt)) {
132 error(get_string('newattemptfail', 'quiz'));
133 }
134 $SESSION->quizpreview->states = array($newstates);
135 $states =& $SESSION->quizpreview->states;
136 $historylength = 0;
137 }
138
139 if (!$fillcorrect && !$back && ($form = data_submitted())) {
140 $form = (array)$form;
141 $submitted = true;
142
143 // Create a new item in the history of question states (don't simplify!)
144 $states[$historylength + 1] = array();
145 $states[$historylength + 1][$id] = clone($states[$historylength][$id]);
146 $historylength++;
147 $curstate =& $states[$historylength][$id];
148
149 // Process the responses
150 unset($form['id']);
151 unset($form['quizid']);
152 unset($form['continue']);
153 unset($form['markall']);
154 unset($form['finishattempt']);
155 unset($form['back']);
156 unset($form['startagain']);
157
158 $event = $finishattempt ? QUIZ_EVENTCLOSE : ($markall ? QUIZ_EVENTGRADE : QUIZ_EVENTSAVE);
159 if ($actions = quiz_extract_responses($questions, $form, $event)) {
160 $actions[$id]->timestamp = 0; // We do not care about timelimits here
161 quiz_process_responses($questions[$id], $states[$historylength][$id], $actions[$id], $quiz, $attempt);
162 if (QUIZ_EVENTGRADE != $curstate->event && QUIZ_EVENTCLOSE != $curstate->event) {
163 // Update the current state rather than creating a new one
164 $historylength--;
165 unset($states[$historylength]);
166 $states = array_values($states);
167 $curstate =& $states[$historylength][$id];
168 }
169 }
170 } else {
171 $submitted = false;
172 $curstate =& $states[$historylength][$id];
173 }
174
175 $options = quiz_get_renderoptions($quiz, $curstate);
176
177 // Fill in the correct responses (unless the question is in readonly mode)
178 if ($fillcorrect && !$options->readonly) {
179 $curstate->responses = $QUIZ_QTYPES[$questions[$id]->qtype]
180 ->get_correct_responses($questions[$id], $curstate);
181 }
182
183 $strpreview = get_string('previewquestion', 'quiz');
184 print_header($strpreview);
185 print_heading($strpreview);
186
187 echo '<p align="center">' . get_string('modulename', 'quiz') . ': ';
188 if (empty($quizid)) {
189 echo '[' . get_string('default', 'quiz') . ']';
190 } else {
191 p($quiz->name);
192 }
193 echo '<br />'.get_string('question', 'quiz').': ';
194 p($questions[$id]->name);
195 echo "</p>\n";
196 $number = 1;
197 echo "<form method=\"post\" action=\"preview.php\" autocomplete=\"off\">\n";
198 echo "<input type=\"hidden\" name=\"id\" value=\"$id\" />\n";
199 echo "<input type=\"hidden\" name=\"quizid\" value=\"$quizid\" />\n";
200 echo "<input type=\"hidden\" name=\"continue\" value=\"1\" />\n";
201
202 quiz_print_quiz_question($questions[$id], $curstate, $number, $quiz, $options);
203
204 echo '<br />';
205 echo '<center>';
206
207 // Print the mark and finish attempt buttons
208 echo '<input name="markall" type="submit" value="' . get_string('markall',
209 'quiz') . "\" />\n";
210 echo '<input name="finishattempt" type="submit" value="' .
211 get_string('finishattempt', 'quiz') . "\" />\n";
212 echo '<br />';
213 echo '<br />';
214 // Print the fill correct button (unless the question is in readonly mode)
215 if (!$options->readonly) {
216 echo '<input name="fillcorrect" type="submit" value="' .
217 get_string('fillcorrect', 'quiz') . "\" />\n";
218 }
219 // Print the navigation buttons
220 if ($historylength > 0) {
221 echo '<input name="back" type="submit" value="' . get_string('previous',
222 'quiz') . "\" />\n";
223 }
224 // Print the start again button
225 echo '<input name="startagain" type="submit" value="' .
226 get_string('startagain', 'quiz') . "\" />\n";
227 // Print the close window button
228 echo '<input type="button" onclick="window.close()" value="' .
229 get_string('closepreview', 'quiz') . "\" />";
230 echo '</center>';
231 echo '</form>';
232 print_footer();
233?>