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