MDL-20636 Previewing a truefalse question in deferred feedback mode now works.
[moodle.git] / question / preview.php
CommitLineData
aeb15530 1<?php
c76145d3
TH
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18
516cf3eb 19/**
4323d029 20 * This page displays a preview of a question
21 *
22 * The preview uses the option settings from the activity within which the question
23 * is previewed or the default settings if no activity is specified. The question session
24 * information is stored in the session as an array of subsequent states rather
25 * than in the database.
26 *
c76145d3
TH
27 * @package moodlecore
28 * @subpackage questionbank
29 * @copyright Alex Smith {@link http://maths.york.ac.uk/serving_maths} and
30 * numerous contributors.
31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4323d029 32 */
516cf3eb 33
c76145d3
TH
34require_once(dirname(__FILE__) . '/../config.php');
35require_once($CFG->libdir . '/questionlib.php');
36require_once($CFG->libdir . '/formslib.php');
37require_once(dirname(__FILE__) . '/previewlib.php');
38
39// Get and validate question id.
40$id = required_param('id', PARAM_INT);
41$question = question_bank::load_question($id);
42require_login();
43$category = $DB->get_record('question_categories', array('id' => $question->category), '*', MUST_EXIST);
44question_require_capability_on($question, 'use');
45$PAGE->set_pagelayout('popup');
46$PAGE->set_context(get_context_instance_by_id($category->contextid));
47
48// Get and validate display options.
49$options = new question_preview_options($question);
50$options->load_user_defaults();
51$options->set_from_request();
52$PAGE->set_url(question_preview_url($id, $options->behaviour, $options->maxmark, $options));
53
54// Get and validate exitsing preview, or start a new one.
55$previewid = optional_param('previewid', 0, PARAM_ALPHANUM);
56if ($previewid) {
57 if (!isset($SESSION->question_previews[$previewid])) {
58 print_error('notyourpreview', 'question');
59 }
60 try {
61 $quba = question_engine::load_questions_usage_by_activity($previewid);
62 } catch (Exception $e){
63 print_error('submissionoutofsequencefriendlymessage', 'question',
64 question_preview_url($question->id, $options->behaviour,
65 $options->maxmark, $options), null, $e);
66 }
67 $slot = $quba->get_first_question_number();
68 $usedquestion = $quba->get_question($slot);
69 if ($usedquestion->id != $question->id) {
70 print_error('questionidmismatch', 'question');
71 }
72 $question = $usedquestion;
73
74} else {
75 $quba = question_engine::make_questions_usage_by_activity('core_question_preview',
76 get_context_instance_by_id($category->contextid));
77 $quba->set_preferred_behaviour($options->behaviour);
78 $slot = $quba->add_question($question, $options->maxmark);
79 $quba->start_all_questions();
80
81 $transaction = $DB->start_delegated_transaction();
82 question_engine::save_questions_usage_by_activity($quba);
83 $transaction->allow_commit();
84
85 $SESSION->question_previews[$quba->get_id()] = true;
86}
87$options->behaviour = $quba->get_preferred_behaviour();
88$options->maxmark = $quba->get_question_max_mark($slot);
89
90// Create the settings form, and initialise the fields.
91$optionsform = new preview_options_form($CFG->wwwroot . '/question/preview.php?id=' . $question->id, $quba);
92$optionsform->set_data($options);
93
94// Process change of settings, if that was requested.
95if ($newoptions = $optionsform->get_submitted_data()) {
96 // Set user preferences
97 $options->save_user_preview_options($newoptions);
98 restart_preview($previewid, $question->id, $newoptions);
99}
100
101// Prepare a URL that is used in various places.
102$actionurl = question_preview_action_url($question->id, $quba->get_id(), $options);
103
104// Process any actions from the buttons at the bottom of the form.
105if (data_submitted() && confirm_sesskey()) {
106 if (optional_param('restart', false, PARAM_BOOL)) {
107 restart_preview($previewid, $question->id, $options);
108
109 } else if (optional_param('fill', null, PARAM_BOOL)) {
110 $correctresponse = $quba->get_correct_response($slot);
111 $quba->process_action($slot, $correctresponse);
112
113 $transaction = $DB->start_delegated_transaction();
114 question_engine::save_questions_usage_by_activity($quba);
115 $transaction->allow_commit();
116
117 redirect($actionurl);
118
119 } else if (optional_param('finish', null, PARAM_BOOL)) {
120 try {
121 $quba->process_all_actions();
122 } catch (question_out_of_sequence_exception $e){
123 print_error('submissionoutofsequencefriendlymessage', 'question', $actionurl);
124 }
125 $quba->finish_all_questions();
516cf3eb 126
c76145d3
TH
127 $transaction = $DB->start_delegated_transaction();
128 question_engine::save_questions_usage_by_activity($quba);
129 $transaction->allow_commit();
130 redirect($actionurl);
516cf3eb 131
516cf3eb 132 } else {
c76145d3
TH
133 try {
134 $quba->process_all_actions();
135 } catch (question_out_of_sequence_exception $e){
136 print_error('submissionoutofsequencefriendlymessage', 'question', $actionurl);
516cf3eb 137 }
516cf3eb 138
c76145d3
TH
139 $transaction = $DB->start_delegated_transaction();
140 question_engine::save_questions_usage_by_activity($quba);
141 $transaction->allow_commit();
516cf3eb 142
c76145d3
TH
143 $scrollpos = optional_param('scrollpos', '', PARAM_RAW);
144 if ($scrollpos !== '') {
145 $actionurl .= '&scrollpos=' . ((int) $scrollpos);
146 }
147 redirect($actionurl);
148 }
149}
150
151if ($question->length) {
152 $displaynumber = '1';
153} else {
154 $displaynumber = 'i';
155}
156$restartdisabled = '';
157$finishdisabled = '';
158$filldisabled = '';
159if ($quba->get_question_state($slot)->is_finished()) {
160 $finishdisabled = ' disabled="disabled"';
161 $filldisabled = ' disabled="disabled"';
162}
163if (!$previewid) {
164 $restartdisabled = ' disabled="disabled"';
165}
166
167$PAGE->requires->js_init_call('M.core_question_preview.init', null, array(
168 'name' => 'core_question_preview',
169 'fullpath' => '/question/preview.js',
170 'requires' => array('base', 'dom', 'event-delegate', 'event-key', 'core_question_engine'),
171 'strings' => array(
172 array('question', 'closepreview'),
173 )));
174
175// Output
176$title = get_string('previewquestion', 'question', format_string($question->name));
177$headtags = question_engine::initialise_js() . $quba->render_question_head_html($slot);
178$PAGE->set_title($title);
179$PAGE->set_heading($title);
180echo $OUTPUT->header();
181
182// Start the question form.
183echo '<form method="post" action="' . s($actionurl) .
184 '" enctype="multipart/form-data" id="responseform">', "\n";
185echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />', "\n";
186echo '<input type="hidden" name="slots" value="' . $slot . '" />', "\n";
187
188// Output the question.
189echo $quba->render_question($slot, $options, $displaynumber);
190
191echo '<p class="notifytiny">' . get_string('behaviourbeingused', 'question',
192 question_engine::get_behaviour_name(
193 $quba->get_question_attempt($slot)->get_behaviour_name())) . '</p>';
194// Finish the question form.
195echo '<div id="previewcontrols" class="controls">';
196echo '<input type="submit" name="restart"' . $restartdisabled .
197 ' value="' . get_string('restart', 'question') . '" />', "\n";
198echo '<input type="submit" name="fill"' . $filldisabled .
199 ' value="' . get_string('fillincorrect', 'question') . '" />', "\n";
200echo '<input type="submit" name="finish"' . $finishdisabled .
201 ' value="' . get_string('submitandfinish', 'question') . '" />', "\n";
202echo '<input type="hidden" name="scrollpos" id="scrollpos" value="" />';
203echo '</div>';
204echo '</form>';
205
206// Display the settings form.
207$optionsform->display();
208
209echo '<script type="text/javascript">question_preview_init("' .
210 get_string('closepreview', 'question') . '", "previewcontrols");</script>', "\n";
211
212echo $OUTPUT->footer();
aeb15530 213