MDL-70153 qtype_essay: Add behat test for attachments max size
[moodle.git] / question / type / ddimageortext / edit_ddimageortext_form.php
CommitLineData
a2bb148a 1<?php
a2bb148a
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
d2c112fd 17
a2bb148a 18/**
e79dad73 19 * Defines the editing form for the drag-and-drop images onto images question type.
a2bb148a 20 *
81c87fa7
TH
21 * @package qtype_ddimageortext
22 * @copyright 2009 The Open University
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
a2bb148a
TH
24 */
25
42536280
TH
26defined('MOODLE_INTERNAL') || die();
27
81c87fa7
TH
28require_once($CFG->dirroot . '/question/type/ddimageortext/edit_ddtoimage_form_base.php');
29
30
a2bb148a 31/**
e79dad73 32 * Drag-and-drop images onto images editing form definition.
a2bb148a 33 *
81c87fa7
TH
34 * @copyright 2009 The Open University
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
a2bb148a 36 */
d2c112fd 37class qtype_ddimageortext_edit_form extends qtype_ddtoimage_edit_form_base {
bc1bcf6e
JP
38 public function qtype() {
39 return 'ddimageortext';
40 }
41
3597982a
JP
42 public function data_preprocessing($question) {
43 $question = parent::data_preprocessing($question);
44 $question = $this->data_preprocessing_combined_feedback($question, true);
45 $question = $this->data_preprocessing_hints($question, true, true);
46
81c87fa7 47 $dragids = array(); // Drag no -> dragid.
3597982a
JP
48 if (!empty($question->options)) {
49 $question->shuffleanswers = $question->options->shuffleanswers;
50 $question->drags = array();
51 foreach ($question->options->drags as $drag) {
51c3521a 52 $dragindex = $drag->no - 1;
3597982a 53 $question->drags[$dragindex] = array();
4139151f 54 $question->draglabel[$dragindex] = $drag->label;
3597982a
JP
55 $question->drags[$dragindex]['infinite'] = $drag->infinite;
56 $question->drags[$dragindex]['draggroup'] = $drag->draggroup;
57 $dragids[$dragindex] = $drag->id;
58 }
59 $question->drops = array();
60 foreach ($question->options->drops as $drop) {
51c3521a
TH
61 $question->drops[$drop->no - 1] = array();
62 $question->drops[$drop->no - 1]['choice'] = $drop->choice;
63 $question->drops[$drop->no - 1]['droplabel'] = $drop->label;
64 $question->drops[$drop->no - 1]['xleft'] = $drop->xleft;
65 $question->drops[$drop->no - 1]['ytop'] = $drop->ytop;
3597982a
JP
66 }
67 }
81c87fa7 68 // Initialise file picker for bgimage.
3597982a
JP
69 $draftitemid = file_get_submitted_draft_itemid('bgimage');
70
71 file_prepare_draft_area($draftitemid, $this->context->id, 'qtype_ddimageortext',
72 'bgimage', !empty($question->id) ? (int) $question->id : null,
73 self::file_picker_options());
74 $question->bgimage = $draftitemid;
75
81c87fa7 76 // Initialise file picker for dragimages.
3597982a
JP
77 list(, $imagerepeats) = $this->get_drag_item_repeats();
78 $draftitemids = optional_param_array('dragitem', array(), PARAM_INT);
79 for ($imageindex = 0; $imageindex < $imagerepeats; $imageindex++) {
51c3521a 80 $draftitemid = isset($draftitemids[$imageindex]) ? $draftitemids[$imageindex] : 0;
81c87fa7 81 // Numbers not allowed in filearea name.
3597982a
JP
82 $itemid = isset($dragids[$imageindex]) ? $dragids[$imageindex] : null;
83 file_prepare_draft_area($draftitemid, $this->context->id, 'qtype_ddimageortext',
84 'dragimage', $itemid, self::file_picker_options());
85 $question->dragitem[$imageindex] = $draftitemid;
86 }
87 if (!empty($question->options)) {
88 foreach ($question->options->drags as $drag) {
51c3521a 89 $dragindex = $drag->no - 1;
3597982a
JP
90 if (!isset($question->dragitem[$dragindex])) {
91 $fileexists = false;
92 } else {
93 $fileexists = self::file_uploaded($question->dragitem[$dragindex]);
94 }
4139151f 95 $labelexists = (trim($question->draglabel[$dragindex]) != '');
3597982a 96 if ($labelexists && !$fileexists) {
4139151f 97 $question->drags[$dragindex]['dragitemtype'] = 'word';
3597982a 98 } else {
4139151f 99 $question->drags[$dragindex]['dragitemtype'] = 'image';
3597982a
JP
100 }
101 }
102 }
103 $this->js_call();
104
105 return $question;
106 }
107
108
bc1bcf6e
JP
109 public function js_call() {
110 global $PAGE;
d0311165 111 $PAGE->requires->js_call_amd('qtype_ddimageortext/form', 'init');
bc1bcf6e
JP
112 }
113
81c87fa7 114 // Drag items.
bc1bcf6e
JP
115
116 protected function definition_draggable_items($mform, $itemrepeatsatstart) {
4139151f
CC
117 $mform->addElement('header', 'draggableitemheader',
118 get_string('draggableitems', 'qtype_ddimageortext'));
119 $mform->addElement('advcheckbox', 'shuffleanswers', ' ',
e9a2711b 120 get_string('shuffleimages', 'qtype_'.$this->qtype()));
4139151f 121 $mform->setDefault('shuffleanswers', 0);
bc1bcf6e
JP
122 $this->repeat_elements($this->draggable_item($mform), $itemrepeatsatstart,
123 $this->draggable_items_repeated_options(),
124 'noitems', 'additems', self::ADD_NUM_ITEMS,
4139151f 125 get_string('addmoreimages', 'qtype_ddimageortext'), true);
bc1bcf6e
JP
126 }
127
128 protected function draggable_item($mform) {
129 $draggableimageitem = array();
130
4139151f 131 $grouparray = array();
bc1bcf6e
JP
132 $dragitemtypes = array('image' => get_string('draggableimage', 'qtype_ddimageortext'),
133 'word' => get_string('draggableword', 'qtype_ddimageortext'));
4139151f 134 $grouparray[] = $mform->createElement('select', 'dragitemtype',
bc1bcf6e
JP
135 get_string('draggableitemtype', 'qtype_ddimageortext'),
136 $dragitemtypes,
137 array('class' => 'dragitemtype'));
bc1bcf6e
JP
138 $options = array();
139 for ($i = 1; $i <= self::MAX_GROUPS; $i += 1) {
5179a01a 140 $options[$i] = question_utils::int_to_letter($i);
bc1bcf6e 141 }
bc1bcf6e
JP
142 $grouparray[] = $mform->createElement('select', 'draggroup',
143 get_string('group', 'qtype_gapselect'),
144 $options,
145 array('class' => 'draggroup'));
146 $grouparray[] = $mform->createElement('advcheckbox', 'infinite', ' ',
147 get_string('infinite', 'qtype_ddimageortext'));
148 $draggableimageitem[] = $mform->createElement('group', 'drags',
4139151f
CC
149 get_string('draggableitemheader', 'qtype_ddimageortext', '{no}'), $grouparray);
150
151 $draggableimageitem[] = $mform->createElement('filepicker', 'dragitem', '', null,
152 self::file_picker_options());
153
154 $draggableimageitem[] = $mform->createElement('text', 'draglabel',
155 get_string('label', 'qtype_ddimageortext'),
ebf91776 156 array('size' => 30, 'class' => 'tweakcss draglabel'));
e7a04b04 157 $mform->setType('draglabel', PARAM_RAW); // These are validated manually.
bc1bcf6e
JP
158 return $draggableimageitem;
159 }
160
161 protected function draggable_items_repeated_options() {
162 $repeatedoptions = array();
163 $repeatedoptions['draggroup']['default'] = '1';
164 return $repeatedoptions;
165 }
166
81c87fa7 167 // Drop zones.
bc1bcf6e
JP
168
169 protected function drop_zone($mform, $imagerepeats) {
170 $dropzoneitem = array();
171
172 $grouparray = array();
bc1bcf6e
JP
173 $grouparray[] = $mform->createElement('text', 'xleft',
174 get_string('xleft', 'qtype_ddimageortext'),
51c3521a 175 array('size' => 5, 'class' => 'tweakcss'));
bc1bcf6e
JP
176 $grouparray[] = $mform->createElement('text', 'ytop',
177 get_string('ytop', 'qtype_ddimageortext'),
51c3521a 178 array('size' => 5, 'class' => 'tweakcss'));
bc1bcf6e
JP
179 $options = array();
180
181 $options[0] = '';
182 for ($i = 1; $i <= $imagerepeats; $i += 1) {
183 $options[$i] = $i;
184 }
bc1bcf6e
JP
185 $grouparray[] = $mform->createElement('select', 'choice',
186 get_string('draggableitem', 'qtype_ddimageortext'), $options);
bc1bcf6e
JP
187 $grouparray[] = $mform->createElement('text', 'droplabel',
188 get_string('label', 'qtype_ddimageortext'),
51c3521a 189 array('size' => 10, 'class' => 'tweakcss'));
bc1bcf6e
JP
190 $mform->setType('droplabel', PARAM_NOTAGS);
191 $dropzone = $mform->createElement('group', 'drops',
192 get_string('dropzone', 'qtype_ddimageortext', '{no}'), $grouparray);
193 return array($dropzone);
194 }
195
196 protected function drop_zones_repeated_options() {
197 $repeatedoptions = array();
4139151f
CC
198 // The next two are PARAM_RAW becuase we need to distinguish 0 and ''.
199 // We do the necessary validation in the validation method.
200 $repeatedoptions['drops[xleft]']['type'] = PARAM_RAW;
201 $repeatedoptions['drops[ytop]']['type'] = PARAM_RAW;
874104d5 202 $repeatedoptions['drops[droplabel]']['type'] = PARAM_RAW;
bc1bcf6e
JP
203 $repeatedoptions['choice']['default'] = '0';
204 return $repeatedoptions;
205 }
3597982a 206
81c87fa7 207 public function validation($data, $files) {
3597982a
JP
208 $errors = parent::validation($data, $files);
209 if (!self::file_uploaded($data['bgimage'])) {
210 $errors["bgimage"] = get_string('formerror_nobgimage', 'qtype_'.$this->qtype());
211 }
212
213 $allchoices = array();
51c3521a 214 for ($i = 0; $i < $data['nodropzone']; $i++) {
3597982a 215 $ytoppresent = (trim($data['drops'][$i]['ytop']) !== '');
ae64c686
TH
216 $xleftpresent = (trim($data['drops'][$i]['xleft']) !== '');
217 $ytopisint = (string) clean_param($data['drops'][$i]['ytop'], PARAM_INT) === trim($data['drops'][$i]['ytop']);
218 $xleftisint = (string) clean_param($data['drops'][$i]['xleft'], PARAM_INT) === trim($data['drops'][$i]['xleft']);
3597982a
JP
219 $labelpresent = (trim($data['drops'][$i]['droplabel']) !== '');
220 $choice = $data['drops'][$i]['choice'];
221 $imagechoicepresent = ($choice !== '0');
222
223 if ($imagechoicepresent) {
224 if (!$ytoppresent) {
ae64c686
TH
225 $errors["drops[$i]"] = get_string('formerror_noytop', 'qtype_ddimageortext');
226 } else if (!$ytopisint) {
227 $errors["drops[$i]"] = get_string('formerror_notintytop', 'qtype_ddimageortext');
3597982a
JP
228 }
229 if (!$xleftpresent) {
ae64c686
TH
230 $errors["drops[$i]"] = get_string('formerror_noxleft', 'qtype_ddimageortext');
231 } else if (!$xleftisint) {
232 $errors["drops[$i]"] = get_string('formerror_notintxleft', 'qtype_ddimageortext');
3597982a
JP
233 }
234
4139151f 235 if ($data['drags'][$choice - 1]['dragitemtype'] != 'word' &&
3597982a
JP
236 !self::file_uploaded($data['dragitem'][$choice - 1])) {
237 $errors['dragitem['.($choice - 1).']'] =
238 get_string('formerror_nofile', 'qtype_ddimageortext', $i);
239 }
240
51c3521a 241 if (isset($allchoices[$choice]) && !$data['drags'][$choice - 1]['infinite']) {
3597982a 242 $errors["drops[$i]"] =
ae64c686 243 get_string('formerror_multipledraginstance', 'qtype_ddimageortext', $choice);
3597982a 244 $errors['drops['.($allchoices[$choice]).']'] =
ae64c686 245 get_string('formerror_multipledraginstance', 'qtype_ddimageortext', $choice);
51c3521a 246 $errors['drags['.($choice - 1).']'] =
ae64c686 247 get_string('formerror_multipledraginstance2', 'qtype_ddimageortext', $choice);
3597982a
JP
248 }
249 $allchoices[$choice] = $i;
250 } else {
251 if ($ytoppresent || $xleftpresent || $labelpresent) {
252 $errors["drops[$i]"] =
ae64c686 253 get_string('formerror_noimageselected', 'qtype_ddimageortext');
3597982a
JP
254 }
255 }
256 }
51c3521a 257 for ($dragindex = 0; $dragindex < $data['noitems']; $dragindex++) {
4139151f
CC
258 $label = $data['draglabel'][$dragindex];
259 if ($data['drags'][$dragindex]['dragitemtype'] == 'word') {
096a5b99
TH
260 $allowedtags = '<br><sub><sup><b><i><strong><em><span>';
261 $errormessage = get_string('formerror_disallowedtags', 'qtype_ddimageortext', s($allowedtags));
3597982a
JP
262 } else {
263 $allowedtags = '';
264 $errormessage = get_string('formerror_noallowedtags', 'qtype_ddimageortext');
265 }
266 if ($label != strip_tags($label, $allowedtags)) {
267 $errors["drags[{$dragindex}]"] = $errormessage;
268 }
269
270 }
271 return $errors;
272 }
a2bb148a 273}