MDL-47494 ddimageortext: MDL-29058 change in api related to fix for saving feedback...
[moodle.git] / question / type / ddimageortext / questiontypebase.php
CommitLineData
d2c112fd
JP
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 * Question type class for the drag-and-drop images onto images question type.
19 *
20 * @package qtype
21 * @subpackage ddimageortext
22 * @copyright 2009 The Open University
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26
27defined('MOODLE_INTERNAL') || die();
28
29require_once($CFG->libdir . '/questionlib.php');
30require_once($CFG->dirroot . '/question/engine/lib.php');
31require_once($CFG->dirroot . '/question/format/xml/format.php');
32require_once($CFG->dirroot . '/question/type/gapselect/questiontypebase.php');
33
34/**
35 * The drag-and-drop words into sentences question type class.
36 *
37 * @copyright 2009 The Open University
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 */
40class qtype_ddtoimage_base extends question_type {
41 protected function choice_group_key() {
42 return 'draggroup';
43 }
44
d2c112fd
JP
45 public function get_question_options($question) {
46 global $DB;
eaabb891
JP
47 $dbprefix = 'qtype_'.$this->name();
48 $question->options = $DB->get_record($dbprefix,
d2c112fd 49 array('questionid' => $question->id), '*', MUST_EXIST);
eaabb891 50 $question->options->drags = $DB->get_records($dbprefix.'_drags',
d2c112fd 51 array('questionid' => $question->id), 'no ASC', '*');
eaabb891 52 $question->options->drops = $DB->get_records($dbprefix.'_drops',
d2c112fd
JP
53 array('questionid' => $question->id), 'no ASC', '*');
54 parent::get_question_options($question);
55 }
56
d2c112fd
JP
57 protected function initialise_question_instance(question_definition $question, $questiondata) {
58 parent::initialise_question_instance($question, $questiondata);
59 $question->shufflechoices = $questiondata->options->shuffleanswers;
60
61 $this->initialise_combined_feedback($question, $questiondata, true);
62
63 $question->choices = array();
64 $choiceindexmap= array();
65
66 // Store the choices in arrays by group.
67 foreach ($questiondata->options->drags as $dragdata) {
68
69 $choice = $this->make_choice($dragdata);
70
71 if (array_key_exists($choice->choice_group(), $question->choices)) {
72 $question->choices[$choice->choice_group()][$dragdata->no] = $choice;
73 } else {
74 $question->choices[$choice->choice_group()][1] = $choice;
75 }
76
77 end($question->choices[$choice->choice_group()]);
78 $choiceindexmap[$dragdata->no] = array($choice->choice_group(),
79 key($question->choices[$choice->choice_group()]));
80 }
81
82 $question->places = array();
83 $question->rightchoices = array();
84
85 $i = 1;
86
87 foreach ($questiondata->options->drops as $dropdata) {
88 list($group, $choiceindex) = $choiceindexmap[$dropdata->choice];
89 $dropdata->group = $group;
90 $question->places[$dropdata->no] = $this->make_place($dropdata);
91 $question->rightchoices[$dropdata->no] = $choiceindex;
92 }
93 }
94
d2c112fd
JP
95 public static function constrain_image_size_in_draft_area($draftitemid, $maxwidth, $maxheight) {
96 global $USER;
97 $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
98 $fs = get_file_storage();
99 $draftfiles = $fs->get_area_files($usercontext->id, 'user', 'draft', $draftitemid, 'id');
100 if ($draftfiles) {
101 foreach ($draftfiles as $file) {
102 if ($file->is_directory()) {
103 continue;
104 }
105 $imageinfo = $file->get_imageinfo();
106 $width = $imageinfo['width'];
107 $height = $imageinfo['height'];
108 $mimetype = $imageinfo['mimetype'];
109 switch ($mimetype) {
110 case 'image/jpeg' :
111 $quality = 80;
112 break;
113 case 'image/png' :
114 $quality = 8;
115 break;
116 default :
117 $quality = null;
118 }
119 $newwidth = min($maxwidth, $width);
120 $newheight = min($maxheight, $height);
121 if ($newwidth != $width || $newheight != $height) {
122 $newimagefilename = $file->get_filename();
123 $newimagefilename =
124 preg_replace('!\.!', "_{$newwidth}x{$newheight}.", $newimagefilename, 1);
125 $newrecord = new stdClass();
126 $newrecord->contextid = $usercontext->id;
127 $newrecord->component = 'user';
128 $newrecord->filearea = 'draft';
129 $newrecord->itemid = $draftitemid;
130 $newrecord->filepath = '/';
131 $newrecord->filename = $newimagefilename;
132 $fs->convert_image($newrecord, $file, $newwidth, $newheight, true, $quality);
133 $file->delete();
134 }
135 }
136 }
137 }
d2c112fd 138
d2c112fd
JP
139
140
141 /**
142 * Create a draft files area, import files into it and return the draft item id.
143 * @param qformat_xml $format
144 * @param array $xml an array of <file> nodes from the the parsed XML.
145 * @return integer draftitemid
146 */
147 public function import_files_to_draft_file_area($format, $xml) {
148 global $USER;
149 $fs = get_file_storage();
150 $files = $format->import_files($xml);
151 $usercontext = get_context_instance(CONTEXT_USER, $USER->id);
152 $draftitemid = file_get_unused_draft_itemid();
153 foreach ($files as $file) {
154 $record = new stdClass();
155 $record->contextid = $usercontext->id;
156 $record->component = 'user';
157 $record->filearea = 'draft';
158 $record->itemid = $draftitemid;
159 $record->filename = $file->name;
160 $record->filepath = '/';
161 $fs->create_file_from_string($record, $this->decode_file($file));
162 }
163 return $draftitemid;
164 }
165
166 /**
167 * Convert files into text output in the given format.
168 * This method is copied from qformat_default as a quick fix, as the method there is
169 * protected.
170 * @param array
171 * @param string encoding method
172 * @return string $string
173 */
174 public function write_files($files, $indent) {
175 if (empty($files)) {
176 return '';
177 }
178 $string = '';
179 foreach ($files as $file) {
180 if ($file->is_directory()) {
181 continue;
182 }
183 $string .= str_repeat(' ', $indent);
184 $string .= '<file name="' . $file->get_filename() . '" encoding="base64">';
185 $string .= base64_encode($file->get_content());
186 $string .= "</file>\n";
187 }
188 return $string;
189 }
190
191 public function get_possible_responses($questiondata) {
192 $question = $this->make_question($questiondata);
193
194 $parts = array();
195 foreach ($question->places as $placeno => $place) {
196 $group = $place->group;
197 $choices = array();
198
199 foreach ($question->choices[$group] as $i => $choice) {
200 $summarisechoice = $choice->summarise();
201
202 $correct = $question->rightchoices[$placeno] == $i;
b9640ba5
JP
203 if ($correct) {
204 $choices[$choice->no] = new question_possible_response(
205 $summarisechoice,
206 $correct?1:0);
207 }
d2c112fd
JP
208 }
209 $choices[null] = question_possible_response::no_response();
210
211 $parts[$placeno] = $choices;
212 }
213
214 return $parts;
215 }
216
217 public function get_random_guess_score($questiondata) {
218 $question = $this->make_question($questiondata);
219 return $question->get_random_guess_score();
220 }
221
222}