MDL-33356 fixed a regression after function form_filemanager_redner() was deleted
[moodle.git] / question / type / essay / renderer.php
CommitLineData
6d03299d 1<?php
6d03299d
TH
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
6d03299d
TH
17/**
18 * Essay question renderer class.
19 *
7764183a
TH
20 * @package qtype
21 * @subpackage essay
22 * @copyright 2009 The Open University
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
6d03299d
TH
24 */
25
26
a17b297d
TH
27defined('MOODLE_INTERNAL') || die();
28
29
6d03299d
TH
30/**
31 * Generates the output for essay questions.
32 *
7764183a
TH
33 * @copyright 2009 The Open University
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
6d03299d
TH
35 */
36class qtype_essay_renderer extends qtype_renderer {
37 public function formulation_and_controls(question_attempt $qa,
38 question_display_options $options) {
39
40 $question = $qa->get_question();
b36d2d06 41 $responseoutput = $question->get_format_renderer($this->page);
6d03299d
TH
42
43 // Answer field.
48d9c17d 44 $step = $qa->get_last_step_with_qt_var('answer');
6d03299d 45 if (empty($options->readonly)) {
48d9c17d
TH
46 $answer = $responseoutput->response_area_input('answer', $qa,
47 $step, $question->responsefieldlines, $options->context);
6d03299d
TH
48
49 } else {
48d9c17d
TH
50 $answer = $responseoutput->response_area_read_only('answer', $qa,
51 $step, $question->responsefieldlines, $options->context);
b36d2d06
TH
52 }
53
54 $files = '';
d42dbe87
TH
55 if ($question->attachments) {
56 if (empty($options->readonly)) {
57 $files = $this->files_input($qa, $question->attachments, $options);
b36d2d06 58
d42dbe87
TH
59 } else {
60 $files = $this->files_read_only($qa, $options);
61 }
6d03299d
TH
62 }
63
64 $result = '';
65 $result .= html_writer::tag('div', $question->format_questiontext($qa),
66 array('class' => 'qtext'));
67
b36d2d06 68 $result .= html_writer::start_tag('div', array('class' => 'ablock'));
6d03299d 69 $result .= html_writer::tag('div', $answer, array('class' => 'answer'));
caeeff07 70 $result .= html_writer::tag('div', $files, array('class' => 'attachments'));
6d03299d
TH
71 $result .= html_writer::end_tag('div');
72
73 return $result;
74 }
b36d2d06
TH
75
76 /**
77 * Displays any attached files when the question is in read-only mode.
d42dbe87
TH
78 * @param question_attempt $qa the question attempt to display.
79 * @param question_display_options $options controls what should and should
80 * not be displayed. Used to get the context.
b36d2d06 81 */
caeeff07 82 public function files_read_only(question_attempt $qa, question_display_options $options) {
8026d4aa 83 $files = $qa->get_last_qt_files('attachments', $options->context->id);
caeeff07
TH
84 $output = array();
85
86 foreach ($files as $file) {
caeeff07 87 $output[] = html_writer::tag('p', html_writer::link($qa->get_response_file_url($file),
559276b1 88 $this->output->pix_icon(file_file_icon($file), get_mimetype_description($file),
caeeff07
TH
89 'moodle', array('class' => 'icon')) . ' ' . s($file->get_filename())));
90 }
91 return implode($output);
b36d2d06
TH
92 }
93
94 /**
95 * Displays the input control for when the student should upload a single file.
d42dbe87
TH
96 * @param question_attempt $qa the question attempt to display.
97 * @param int $numallowed the maximum number of attachments allowed. -1 = unlimited.
98 * @param question_display_options $options controls what should and should
99 * not be displayed. Used to get the context.
b36d2d06 100 */
121fd4c1
TH
101 public function files_input(question_attempt $qa, $numallowed,
102 question_display_options $options) {
8026d4aa
TH
103 global $CFG;
104 require_once($CFG->dirroot . '/lib/form/filemanager.php');
105
106 $pickeroptions = new stdClass();
107 $pickeroptions->mainfile = null;
d42dbe87 108 $pickeroptions->maxfiles = $numallowed;
8026d4aa
TH
109 $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid(
110 'attachments', $options->context->id);
111 $pickeroptions->context = $options->context;
112
48d9c17d
TH
113 $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid(
114 'attachments', $options->context->id);
115
6adb5f13
MG
116 $fm = new form_filemanager($pickeroptions);
117 $filesrenderer = $this->page->get_renderer('core', 'files');
118 return $filesrenderer->render($fm). html_writer::empty_tag(
217f9a61
TH
119 'input', array('type' => 'hidden', 'name' => $qa->get_qt_field_name('attachments'),
120 'value' => $pickeroptions->itemid));
b36d2d06
TH
121 }
122
783af252
TH
123 public function manual_comment(question_attempt $qa, question_display_options $options) {
124 if ($options->manualcomment != question_display_options::EDITABLE) {
125 return '';
126 }
127
128 $question = $qa->get_question();
129 return html_writer::nonempty_tag('div', $question->format_text(
130 $question->graderinfo, $question->graderinfo, $qa, 'qtype_essay',
131 'graderinfo', $question->id), array('class' => 'graderinfo'));
132 }
b36d2d06
TH
133}
134
135
136/**
137 * A base class to abstract out the differences between different type of
138 * response format.
139 *
140 * @copyright 2011 The Open University
141 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
142 */
143abstract class qtype_essay_format_renderer_base extends plugin_renderer_base {
144 /**
145 * Render the students respone when the question is in read-only mode.
48d9c17d
TH
146 * @param string $name the variable name this input edits.
147 * @param question_attempt $qa the question attempt being display.
148 * @param question_attempt_step $step the current step.
b36d2d06 149 * @param int $lines approximate size of input box to display.
48d9c17d
TH
150 * @param object $context the context teh output belongs to.
151 * @return string html to display the response.
b36d2d06 152 */
48d9c17d
TH
153 public abstract function response_area_read_only($name, question_attempt $qa,
154 question_attempt_step $step, $lines, $context);
b36d2d06
TH
155
156 /**
157 * Render the students respone when the question is in read-only mode.
48d9c17d
TH
158 * @param string $name the variable name this input edits.
159 * @param question_attempt $qa the question attempt being display.
160 * @param question_attempt_step $step the current step.
b36d2d06 161 * @param int $lines approximate size of input box to display.
48d9c17d
TH
162 * @param object $context the context teh output belongs to.
163 * @return string html to display the response for editing.
164 */
165 public abstract function response_area_input($name, question_attempt $qa,
166 question_attempt_step $step, $lines, $context);
167
168 /**
169 * @return string specific class name to add to the input element.
b36d2d06 170 */
48d9c17d 171 protected abstract function class_name();
b36d2d06
TH
172}
173
174
175/**
176 * An essay format renderer for essays where the student should use the HTML
177 * editor without the file picker.
178 *
179 * @copyright 2011 The Open University
180 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
181 */
182class qtype_essay_format_editor_renderer extends plugin_renderer_base {
48d9c17d
TH
183 protected function class_name() {
184 return 'qtype_essay_editor';
b36d2d06
TH
185 }
186
48d9c17d
TH
187 public function response_area_read_only($name, $qa, $step, $lines, $context) {
188 return html_writer::tag('div', $this->prepare_response($name, $qa, $step, $context),
9199e7a5 189 array('class' => $this->class_name() . ' qtype_essay_response readonly'));
48d9c17d
TH
190 }
191
192 public function response_area_input($name, $qa, $step, $lines, $context) {
2d682972
TH
193 global $CFG;
194 require_once($CFG->dirroot . '/repository/lib.php');
a54ecbbb 195
48d9c17d
TH
196 $inputname = $qa->get_qt_field_name($name);
197 $responseformat = $step->get_qt_var($name . 'format');
a54ecbbb
TH
198 $id = $inputname . '_id';
199
200 $editor = editors_get_preferred_editor($responseformat);
201 $strformats = format_text_menu();
202 $formats = $editor->get_supported_formats();
203 foreach ($formats as $fid) {
204 $formats[$fid] = $strformats[$fid];
205 }
206
48d9c17d
TH
207 list($draftitemid, $reponse) = $this->prepare_response_for_editing(
208 $name, $step, $context);
209
a54ecbbb 210 $editor->use_editor($id, $this->get_editor_options($context),
48d9c17d 211 $this->get_filepicker_options($context, $draftitemid));
a54ecbbb
TH
212
213 $output = '';
48d9c17d
TH
214 $output .= html_writer::start_tag('div', array('class' =>
215 $this->class_name() . ' qtype_essay_response'));
a54ecbbb 216
48d9c17d 217 $output .= html_writer::tag('div', html_writer::tag('textarea', s($reponse),
dbf76faf 218 array('id' => $id, 'name' => $inputname, 'rows' => $lines, 'cols' => 60)));
a54ecbbb
TH
219
220 $output .= html_writer::start_tag('div');
221 if (count($formats == 1)) {
222 reset($formats);
223 $output .= html_writer::empty_tag('input', array('type' => 'hidden',
224 'name' => $inputname . 'format', 'value' => key($formats)));
225
226 } else {
227 $output .= html_writer::select($formats, $inputname . 'format', $responseformat, '');
228 }
229 $output .= html_writer::end_tag('div');
230
48d9c17d 231 $output .= $this->filepicker_html($inputname, $draftitemid);
a54ecbbb
TH
232
233 $output .= html_writer::end_tag('div');
234 return $output;
235 }
236
237 /**
48d9c17d
TH
238 * Prepare the response for read-only display.
239 * @param string $name the variable name this input edits.
240 * @param question_attempt $qa the question attempt being display.
241 * @param question_attempt_step $step the current step.
242 * @param object $context the context the attempt belongs to.
243 * @return string the response prepared for display.
a54ecbbb 244 */
48d9c17d
TH
245 protected function prepare_response($name, question_attempt $qa,
246 question_attempt_step $step, $context) {
247 if (!$step->has_qt_var($name)) {
248 return '';
249 }
250
251 $formatoptions = new stdClass();
252 $formatoptions->para = false;
253 return format_text($step->get_qt_var($name), $step->get_qt_var($name . 'format'),
254 $formatoptions);
a54ecbbb
TH
255 }
256
257 /**
48d9c17d
TH
258 * Prepare the response for editing.
259 * @param string $name the variable name this input edits.
260 * @param question_attempt_step $step the current step.
261 * @param object $context the context the attempt belongs to.
262 * @return string the response prepared for display.
a54ecbbb 263 */
48d9c17d
TH
264 protected function prepare_response_for_editing($name,
265 question_attempt_step $step, $context) {
266 return array(0, $step->get_qt_var($name));
a54ecbbb
TH
267 }
268
269 /**
48d9c17d 270 * @param object $context the context the attempt belongs to.
a54ecbbb
TH
271 * @return array options for the editor.
272 */
273 protected function get_editor_options($context) {
274 return array('context' => $context);
275 }
276
277 /**
48d9c17d
TH
278 * @param object $context the context the attempt belongs to.
279 * @param int $draftitemid draft item id.
280 * @return array filepicker options for the editor.
281 */
282 protected function get_filepicker_options($context, $draftitemid) {
283 return array();
284 }
285
286 /**
287 * @param string $inputname input field name.
288 * @param int $draftitemid draft file area itemid.
289 * @return string HTML for the filepicker, if used.
a54ecbbb 290 */
48d9c17d 291 protected function filepicker_html($inputname, $draftitemid) {
a54ecbbb 292 return '';
b36d2d06
TH
293 }
294}
295
296
297/**
298 * An essay format renderer for essays where the student should use the HTML
299 * editor with the file picker.
300 *
301 * @copyright 2011 The Open University
302 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
303 */
a54ecbbb 304class qtype_essay_format_editorfilepicker_renderer extends qtype_essay_format_editor_renderer {
48d9c17d
TH
305 protected function class_name() {
306 return 'qtype_essay_editorfilepicker';
307 }
308
309 protected function prepare_response($name, question_attempt $qa,
310 question_attempt_step $step, $context) {
311 if (!$step->has_qt_var($name)) {
312 return '';
313 }
a54ecbbb 314
48d9c17d
TH
315 $formatoptions = new stdClass();
316 $formatoptions->para = false;
317 $text = $qa->rewrite_response_pluginfile_urls($step->get_qt_var($name),
318 $context->id, 'answer', $step);
319 return format_text($text, $step->get_qt_var($name . 'format'), $formatoptions);
a54ecbbb
TH
320 }
321
48d9c17d
TH
322 protected function prepare_response_for_editing($name,
323 question_attempt_step $step, $context) {
324 return $step->prepare_response_files_draft_itemid_with_text(
325 $name, $context->id, $step->get_qt_var($name));
b36d2d06
TH
326 }
327
48d9c17d
TH
328 protected function get_editor_options($context) {
329 return array(
330 'subdirs' => 0,
331 'maxbytes' => 0,
332 'maxfiles' => -1,
333 'context' => $context,
334 'noclean' => 0,
335 'trusttext'=>0
336 );
337 }
338
339 /**
340 * Get the options required to configure the filepicker for one of the editor
341 * toolbar buttons.
342 * @param mixed $acceptedtypes array of types of '*'.
343 * @param int $draftitemid the draft area item id.
344 * @param object $context the context.
345 * @return object the required options.
346 */
347 protected function specific_filepicker_options($acceptedtypes, $draftitemid, $context) {
348 $filepickeroptions = new stdClass();
349 $filepickeroptions->accepted_types = $acceptedtypes;
350 $filepickeroptions->return_types = FILE_INTERNAL | FILE_EXTERNAL;
351 $filepickeroptions->context = $context;
352 $filepickeroptions->env = 'filepicker';
353
354 $options = initialise_filepicker($filepickeroptions);
355 $options->context = $context;
356 $options->client_id = uniqid();
357 $options->env = 'editor';
358 $options->itemid = $draftitemid;
359
360 return $options;
361 }
362
363 protected function get_filepicker_options($context, $draftitemid) {
364 global $CFG;
365
366 return array(
367 'image' => $this->specific_filepicker_options(array('image'),
368 $draftitemid, $context),
369 'media' => $this->specific_filepicker_options(array('video', 'audio'),
370 $draftitemid, $context),
371 'link' => $this->specific_filepicker_options('*',
372 $draftitemid, $context),
373 );
374 }
375
376 protected function filepicker_html($inputname, $draftitemid) {
377 $nonjspickerurl = new moodle_url('/repository/draftfiles_manager.php', array(
378 'action' => 'browse',
379 'env' => 'editor',
380 'itemid' => $draftitemid,
381 'subdirs' => false,
382 'maxfiles' => -1,
383 'sesskey' => sesskey(),
384 ));
385
386 return html_writer::empty_tag('input', array('type' => 'hidden',
387 'name' => $inputname . ':itemid', 'value' => $draftitemid)) .
388 html_writer::tag('noscript', html_writer::tag('div',
389 html_writer::tag('object', '', array('type' => 'text/html',
390 'data' => $nonjspickerurl, 'height' => 160, 'width' => 600,
391 'style' => 'border: 1px solid #000;'))));
b36d2d06
TH
392 }
393}
394
395
396/**
397 * An essay format renderer for essays where the student should use a plain
398 * input box, but with a normal, proportional font.
399 *
400 * @copyright 2011 The Open University
401 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
402 */
403class qtype_essay_format_plain_renderer extends plugin_renderer_base {
404 /**
405 * @return string the HTML for the textarea.
406 */
407 protected function textarea($response, $lines, $attributes) {
408 $attributes['class'] = $this->class_name() . ' qtype_essay_response';
409 $attributes['rows'] = $lines;
dbf76faf 410 $attributes['cols'] = 60;
b36d2d06
TH
411 return html_writer::tag('textarea', s($response), $attributes);
412 }
413
414 protected function class_name() {
415 return 'qtype_essay_plain';
416 }
417
48d9c17d
TH
418 public function response_area_read_only($name, $qa, $step, $lines, $context) {
419 return $this->textarea($step->get_qt_var($name), $lines, array('readonly' => 'readonly'));
b36d2d06
TH
420 }
421
48d9c17d
TH
422 public function response_area_input($name, $qa, $step, $lines, $context) {
423 $inputname = $qa->get_qt_field_name($name);
424 return $this->textarea($step->get_qt_var($name), $lines, array('name' => $inputname)) .
a54ecbbb
TH
425 html_writer::empty_tag('input', array('type' => 'hidden',
426 'name' => $inputname . 'format', 'value' => FORMAT_PLAIN));
b36d2d06
TH
427 }
428}
429
430
431/**
432 * An essay format renderer for essays where the student should use a plain
433 * input box with a monospaced font. You might use this, for example, for a
434 * question where the students should type computer code.
435 *
436 * @copyright 2011 The Open University
437 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
438 */
439class qtype_essay_format_monospaced_renderer extends qtype_essay_format_plain_renderer {
440 protected function class_name() {
441 return 'qtype_essay_monospaced';
442 }
6d03299d 443}