MDL-70153 qtype_essay: Add behat test for attachments max size
[moodle.git] / question / type / ddimageortext / rendererbase.php
1 <?php
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/>.
17 /**
18  * Drag-and-drop onto image question renderer class.
19  *
20  * @package    qtype_ddimageortext
21  * @copyright  2010 The Open University
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
26 defined('MOODLE_INTERNAL') || die();
28 /**
29  * Generates the output for drag-and-drop onto image questions.
30  *
31  * @copyright  2010 The Open University
32  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33  */
34 class qtype_ddtoimage_renderer_base extends qtype_with_combined_feedback_renderer {
36     public function clear_wrong(question_attempt $qa) {
37         $question = $qa->get_question();
38         $response = $qa->get_last_qt_data();
40         if (!empty($response)) {
41             $cleanresponse = $question->clear_wrong_from_response($response);
42         } else {
43             $cleanresponse = $response;
44         }
45         $cleanresponsehtml = '';
46         foreach ($cleanresponse as $fieldname => $value) {
47             list (, $html) = $this->hidden_field_for_qt_var($qa, $fieldname, $value);
48             $cleanresponsehtml .= $html;
49         }
50         return $cleanresponsehtml;
51     }
53     public function formulation_and_controls(question_attempt $qa,
54             question_display_options $options) {
56         $question = $qa->get_question();
57         $response = $qa->get_last_qt_data();
59         $questiontext = $question->format_questiontext($qa);
61         $dropareaclass = 'droparea';
62         $draghomesclass = 'draghomes';
63         if ($options->readonly) {
64             $dropareaclass .= ' readonly';
65             $draghomesclass .= ' readonly';
66         }
68         $output = html_writer::div($questiontext, 'qtext');
70         $output .= html_writer::start_div('ddarea');
71         $output .= html_writer::start_div($dropareaclass);
72         $output .= html_writer::img(self::get_url_for_image($qa, 'bgimage'), get_string('dropbackground', 'qtype_ddmarker'),
73                 ['class' => 'dropbackground img-fluid w-100']);
75         $output .= html_writer::div('', 'dropzones');
76         $output .= html_writer::end_div();
77         $output .= html_writer::start_div($draghomesclass);
79         $dragimagehomes = '';
80         foreach ($question->choices as $groupno => $group) {
81             $dragimagehomesgroup = '';
82             $orderedgroup = $question->get_ordered_choices($groupno);
83             foreach ($orderedgroup as $choiceno => $dragimage) {
84                 $dragimageurl = self::get_url_for_image($qa, 'dragimage', $dragimage->id);
85                 $classes = [
86                         'group' . $groupno,
87                         'draghome',
88                         'choice' . $choiceno
89                 ];
90                 if ($dragimage->infinite) {
91                     $classes[] = 'infinite';
92                 }
93                 if ($dragimageurl === null) {
94                     $dragimagehomesgroup .= html_writer::div($dragimage->text, join(' ', $classes), ['src' => $dragimageurl]);
95                 } else {
96                     $dragimagehomesgroup .= html_writer::img($dragimageurl, $dragimage->text, ['class' => join(' ', $classes)]);
97                 }
98             }
99             $dragimagehomes .= html_writer::div($dragimagehomesgroup, 'dragitemgroup' . $groupno);
100         }
102         $output .= $dragimagehomes;
103         $output .= html_writer::end_div();
105         foreach ($question->places as $placeno => $place) {
106             $varname = $question->field($placeno);
107             list($fieldname, $html) = $this->hidden_field_for_qt_var($qa, $varname, null,
108                     ['placeinput', 'place' . $placeno, 'group' . $place->group]);
109             $output .= $html;
110             $question->places[$placeno]->fieldname = $fieldname;
111         }
113         $output .= html_writer::end_div();
115         $this->page->requires->string_for_js('blank', 'qtype_ddimageortext');
116         $this->page->requires->js_call_amd('qtype_ddimageortext/question', 'init',
117                 [$qa->get_outer_question_div_unique_id(), $options->readonly, $question->places]);
119         if ($qa->get_state() == question_state::$invalid) {
120             $output .= html_writer::div($question->get_validation_error($qa->get_last_qt_data()), 'validationerror');
121         }
122         return $output;
123     }
125     /**
126      * Returns the URL for an image
127      *
128      * @param object $qa Question attempt object
129      * @param string $filearea File area descriptor
130      * @param int $itemid Item id to get
131      * @return string Output url, or null if not found
132      */
133     protected static function get_url_for_image(question_attempt $qa, $filearea, $itemid = 0) {
134         $question = $qa->get_question();
135         $qubaid = $qa->get_usage_id();
136         $slot = $qa->get_slot();
137         $fs = get_file_storage();
138         if ($filearea == 'bgimage') {
139             $itemid = $question->id;
140         }
141         $componentname = $question->qtype->plugin_name();
142         $draftfiles = $fs->get_area_files($question->contextid, $componentname,
143                                                                         $filearea, $itemid, 'id');
144         if ($draftfiles) {
145             foreach ($draftfiles as $file) {
146                 if ($file->is_directory()) {
147                     continue;
148                 }
149                 $url = moodle_url::make_pluginfile_url($question->contextid, $componentname,
150                                             $filearea, "$qubaid/$slot/{$itemid}", '/',
151                                             $file->get_filename());
152                 return $url->out();
153             }
154         }
155         return null;
156     }
158     /**
159      * Returns a hidden field for a qt variable
160      *
161      * @param object $qa Question attempt object
162      * @param string $varname The hidden var name
163      * @param string $value The hidden value
164      * @param array $classes Any additional css classes to apply
165      * @return array Array with field name and the html of the tag
166      */
167     protected function hidden_field_for_qt_var(question_attempt $qa, $varname, $value = null,
168                                                 $classes = null) {
169         if ($value === null) {
170             $value = $qa->get_last_qt_var($varname);
171         }
172         $fieldname = $qa->get_qt_field_name($varname);
173         $attributes = array('type' => 'hidden',
174                                 'id' => str_replace(':', '_', $fieldname),
175                                 'name' => $fieldname,
176                                 'value' => $value);
177         if ($classes !== null) {
178             $attributes['class'] = join(' ', $classes);
179         }
180         return array($fieldname, html_writer::empty_tag('input', $attributes)."\n");
181     }
183     public function specific_feedback(question_attempt $qa) {
184         return $this->combined_feedback($qa);
185     }
187     public function correct_response(question_attempt $qa) {
188         return '';
189     }