ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.assImagemapQuestionExport.php
Go to the documentation of this file.
1<?php
2
29{
37 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false): string
38 {
39 global $DIC;
40 $ilias = $DIC['ilias'];
41
42 $a_xml_writer = new ilXmlWriter();
43 // set xml header
44 $a_xml_writer->xmlHeader();
45 $a_xml_writer->xmlStartTag("questestinterop");
46 $attrs = [
47 "ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(),
48 "title" => $this->object->getTitle(),
49 "maxattempts" => $this->object->getNrOfTries()
50 ];
51 $a_xml_writer->xmlStartTag("item", $attrs);
52 // add question description
53 $a_xml_writer->xmlElement("qticomment", null, $this->object->getComment());
54 $a_xml_writer->xmlStartTag("itemmetadata");
55 $a_xml_writer->xmlStartTag("qtimetadata");
56 $a_xml_writer->xmlStartTag("qtimetadatafield");
57 $a_xml_writer->xmlElement("fieldlabel", null, "ILIAS_VERSION");
58 $a_xml_writer->xmlElement("fieldentry", null, $ilias->getSetting("ilias_version"));
59 $a_xml_writer->xmlEndTag("qtimetadatafield");
60 $a_xml_writer->xmlStartTag("qtimetadatafield");
61 $a_xml_writer->xmlElement("fieldlabel", null, "QUESTIONTYPE");
62 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getQuestionType());
63 $a_xml_writer->xmlEndTag("qtimetadatafield");
64 $a_xml_writer->xmlStartTag("qtimetadatafield");
65 $a_xml_writer->xmlElement("fieldlabel", null, "IS_MULTIPLE_CHOICE");
66 $a_xml_writer->xmlElement("fieldentry", null, ($this->object->getIsMultipleChoice()) ? "1" : "0");
67 $a_xml_writer->xmlEndTag("qtimetadatafield");
68 $a_xml_writer->xmlStartTag("qtimetadatafield");
69 $a_xml_writer->xmlElement("fieldlabel", null, "AUTHOR");
70 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAuthor());
71 $a_xml_writer->xmlEndTag("qtimetadatafield");
72
73 // additional content editing information
75 $this->addGeneralMetadata($a_xml_writer);
76
77 $a_xml_writer->xmlEndTag("qtimetadata");
78 $a_xml_writer->xmlEndTag("itemmetadata");
79
80 // PART I: qti presentation
81 $attrs = [
82 "label" => $this->object->getTitle()
83 ];
84 $a_xml_writer->xmlStartTag("presentation", $attrs);
85 // add flow to presentation
86 $a_xml_writer->xmlStartTag("flow");
87 // add material with question text to presentation
88 $this->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
89 // add answers to presentation
90 $attrs = [
91 "ident" => "IM",
92 "rcardinality" => "Single"
93 ];
94 $a_xml_writer->xmlStartTag("response_xy", $attrs);
95 $a_xml_writer = $this->addSuggestedSolution($a_xml_writer);
96 $a_xml_writer->xmlStartTag("render_hotspot");
97 $a_xml_writer->xmlStartTag("material");
98 $imagetype = "image/jpeg";
99 if (preg_match("/.*\.(png|gif)$/i", $this->object->getImageFilename(), $matches)) {
100 $imagetype = "image/" . strtolower($matches[1]);
101 }
102 $attrs = [
103 "imagtype" => $imagetype,
104 "label" => $this->object->getImageFilename()
105 ];
106 if ($a_include_binary) {
107 if ($force_image_references) {
108 $attrs["uri"] = $this->object->getImagePathWeb() . $this->object->getImageFilename();
109 $a_xml_writer->xmlElement("matimage", $attrs);
110 } else {
111 $attrs["embedded"] = "base64";
112 $imagepath = $this->object->getImagePath() . $this->object->getImageFilename();
113 $fh = fopen($imagepath, "rb");
114 if ($fh == false) {
115 global $DIC;
116 $ilErr = $DIC['ilErr'];
117 $ilErr->raiseError($GLOBALS['DIC']['lng']->txt("error_open_image_file"), $ilErr->MESSAGE);
118 }
119 $imagefile = fread($fh, filesize($imagepath));
120 fclose($fh);
121 $base64 = base64_encode($imagefile);
122 $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
123 }
124 } else {
125 $a_xml_writer->xmlElement("matimage", $attrs);
126 }
127 $a_xml_writer->xmlEndTag("material");
128
129 // add answers
130 foreach ($this->object->getAnswers() as $index => $answer) {
131 $rared = "";
132 switch ($answer->getArea()) {
133 case "rect":
134 $rarea = "Rectangle";
135 break;
136 case "circle":
137 $rarea = "Ellipse";
138 break;
139 case "poly":
140 $rarea = "Bounded";
141 break;
142 }
143 $attrs = [
144 "ident" => $index,
145 "rarea" => $rarea
146 ];
147 $a_xml_writer->xmlStartTag("response_label", $attrs);
148 $a_xml_writer->xmlData($answer->getCoords());
149 $a_xml_writer->xmlStartTag("material");
150 $a_xml_writer->xmlElement("mattext", null, $answer->getAnswertext());
151 $a_xml_writer->xmlEndTag("material");
152 $a_xml_writer->xmlEndTag("response_label");
153 }
154 $a_xml_writer->xmlEndTag("render_hotspot");
155 $a_xml_writer->xmlEndTag("response_xy");
156 $a_xml_writer->xmlEndTag("flow");
157 $a_xml_writer->xmlEndTag("presentation");
158
159 // PART II: qti resprocessing
160 $a_xml_writer->xmlStartTag("resprocessing");
161 $a_xml_writer->xmlStartTag("outcomes");
162 $a_xml_writer->xmlStartTag("decvar");
163 $a_xml_writer->xmlEndTag("decvar");
164 $a_xml_writer->xmlEndTag("outcomes");
165 // add response conditions
166 foreach ($this->object->getAnswers() as $index => $answer) {
167 $attrs = [
168 "continue" => "Yes"
169 ];
170 $a_xml_writer->xmlStartTag("respcondition", $attrs);
171 // qti conditionvar
172 $a_xml_writer->xmlStartTag("conditionvar");
173 if (!$answer->isStateSet()) {
174 $a_xml_writer->xmlStartTag("not");
175 }
176 $areatype = "";
177 switch ($answer->getArea()) {
178 case "rect":
179 $areatype = "Rectangle";
180 break;
181 case "circle":
182 $areatype = "Ellipse";
183 break;
184 case "poly":
185 $areatype = "Bounded";
186 break;
187 }
188 $attrs = [
189 "respident" => "IM",
190 "areatype" => $areatype
191 ];
192 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getCoords());
193 if (!$answer->isStateSet()) {
194 $a_xml_writer->xmlEndTag("not");
195 }
196 $a_xml_writer->xmlEndTag("conditionvar");
197 // qti setvar
198 $attrs = [
199 "action" => "Add"
200 ];
201 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
202 $linkrefid = "response_$index";
203 $attrs = [
204 "feedbacktype" => "Response",
205 "linkrefid" => $linkrefid
206 ];
207 $a_xml_writer->xmlElement("displayfeedback", $attrs);
208 $a_xml_writer->xmlEndTag("respcondition");
209 $attrs = [
210 "continue" => "Yes"
211 ];
212 $a_xml_writer->xmlStartTag("respcondition", $attrs);
213 // qti conditionvar
214 $a_xml_writer->xmlStartTag("conditionvar");
215 $attrs = [
216 "respident" => "IM"
217 ];
218 $a_xml_writer->xmlStartTag("not");
219 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getCoords());
220 $a_xml_writer->xmlEndTag("not");
221 $a_xml_writer->xmlEndTag("conditionvar");
222 // qti setvar
223 $attrs = [
224 "action" => "Add"
225 ];
226 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPointsUnchecked());
227 $a_xml_writer->xmlEndTag("respcondition");
228 }
229
230 $answers = $this->object->getAnswers();
231 $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
232 $this->object->getId(),
233 true
234 );
235 if (strlen($feedback_allcorrect) && count($answers) > 0) {
236 $attrs = [
237 "continue" => "Yes"
238 ];
239 $a_xml_writer->xmlStartTag("respcondition", $attrs);
240 // qti conditionvar
241 $a_xml_writer->xmlStartTag("conditionvar");
242 if (!$this->object->getIsMultipleChoice()) {
243 $bestindex = 0;
244 $maxpoints = 0;
245 foreach ($answers as $index => $answer) {
246 if ($answer->getPoints() > $maxpoints) {
247 $maxpoints = $answer->getPoints();
248 $bestindex = $index;
249 }
250 }
251
252 $areatype = "";
253 $answer = $answers[$bestindex];
254 switch ($answer->getArea()) {
255 case "rect":
256 $areatype = "Rectangle";
257 break;
258 case "circle":
259 $areatype = "Ellipse";
260 break;
261 case "poly":
262 $areatype = "Bounded";
263 break;
264 }
265 $attrs = [
266 "respident" => "IM",
267 "areatype" => $areatype
268 ];
269 $a_xml_writer->xmlElement("varinside", $attrs, $answer->getCoords());
270 } else {
271 foreach ($answers as $index => $answer) {
272 if ($answer->getPoints() < $answer->getPointsUnchecked()) {
273 $a_xml_writer->xmlStartTag("not");
274 }
275 switch ($answer->getArea()) {
276 case "rect":
277 $areatype = "Rectangle";
278 break;
279 case "circle":
280 $areatype = "Ellipse";
281 break;
282 case "poly":
283 $areatype = "Bounded";
284 break;
285 }
286 $attrs = [
287 "respident" => "IM",
288 "areatype" => $areatype
289 ];
290 $a_xml_writer->xmlElement("varequal", $attrs, $index);
291 if ($answer->getPoints() < $answer->getPointsUnchecked()) {
292 $a_xml_writer->xmlEndTag("not");
293 }
294 }
295 }
296
297 $a_xml_writer->xmlEndTag("conditionvar");
298 // qti displayfeedback
299 $attrs = [
300 "feedbacktype" => "Response",
301 "linkrefid" => "response_allcorrect"
302 ];
303 $a_xml_writer->xmlElement("displayfeedback", $attrs);
304 $a_xml_writer->xmlEndTag("respcondition");
305 }
306
307 $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
308 $this->object->getId(),
309 false
310 );
311 if (strlen($feedback_onenotcorrect) && count($answers) > 0) {
312 $attrs = [
313 "continue" => "Yes"
314 ];
315 $a_xml_writer->xmlStartTag("respcondition", $attrs);
316 // qti conditionvar
317 $a_xml_writer->xmlStartTag("conditionvar");
318 if (!$this->object->getIsMultipleChoice()) {
319 $bestindex = 0;
320 $maxpoints = 0;
321 foreach ($answers as $index => $answer) {
322 if ($answer->getPoints() > $maxpoints) {
323 $maxpoints = $answer->getPoints();
324 $bestindex = $index;
325 }
326 }
327 $attrs = [
328 "respident" => "IM"
329 ];
330 $a_xml_writer->xmlStartTag("not");
331
332 $areatype = "";
333 $answer = $answers[$bestindex];
334 switch ($answer->getArea()) {
335 case "rect":
336 $areatype = "Rectangle";
337 break;
338 case "circle":
339 $areatype = "Ellipse";
340 break;
341 case "poly":
342 $areatype = "Bounded";
343 break;
344 }
345 $attrs = [
346 "respident" => "IM",
347 "areatype" => $areatype
348 ];
349 $a_xml_writer->xmlElement("varinside", $attrs, $answer->getCoords());
350
351 $a_xml_writer->xmlEndTag("not");
352 } else {
353 foreach ($answers as $index => $answer) {
354 if ($index > 0) {
355 $a_xml_writer->xmlStartTag("or");
356 }
357 if ($answer->getPoints() >= $answer->getPointsUnchecked()) {
358 $a_xml_writer->xmlStartTag("not");
359 }
360 switch ($answer->getArea()) {
361 case "rect":
362 $areatype = "Rectangle";
363 break;
364 case "circle":
365 $areatype = "Ellipse";
366 break;
367 case "poly":
368 $areatype = "Bounded";
369 break;
370 }
371 $attrs = [
372 "respident" => "IM",
373 "areatype" => $areatype
374 ];
375 $a_xml_writer->xmlElement("varequal", $attrs, $index);
376 if ($answer->getPoints() >= $answer->getPointsUnchecked()) {
377 $a_xml_writer->xmlEndTag("not");
378 }
379 if ($index > 0) {
380 $a_xml_writer->xmlEndTag("or");
381 }
382 }
383 }
384 $a_xml_writer->xmlEndTag("conditionvar");
385 // qti displayfeedback
386 $attrs = [
387 "feedbacktype" => "Response",
388 "linkrefid" => "response_onenotcorrect"
389 ];
390 $a_xml_writer->xmlElement("displayfeedback", $attrs);
391 $a_xml_writer->xmlEndTag("respcondition");
392 }
393
394 $a_xml_writer->xmlEndTag("resprocessing");
395
396 // PART III: qti itemfeedback
397 foreach ($this->object->getAnswers() as $index => $answer) {
398 $linkrefid = "response_$index";
399 $attrs = [
400 "ident" => $linkrefid,
401 "view" => "All"
402 ];
403 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
404 // qti flow_mat
405 $a_xml_writer->xmlStartTag("flow_mat");
406 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
407 $this->object->getId(),
408 0,
409 $index
410 );
411 $this->addQTIMaterial($a_xml_writer, $fb);
412 $a_xml_writer->xmlEndTag("flow_mat");
413 $a_xml_writer->xmlEndTag("itemfeedback");
414 }
415 if (strlen($feedback_allcorrect)) {
416 $attrs = [
417 "ident" => "response_allcorrect",
418 "view" => "All"
419 ];
420 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
421 // qti flow_mat
422 $a_xml_writer->xmlStartTag("flow_mat");
423 $this->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
424 $a_xml_writer->xmlEndTag("flow_mat");
425 $a_xml_writer->xmlEndTag("itemfeedback");
426 }
427 if (strlen($feedback_onenotcorrect)) {
428 $attrs = [
429 "ident" => "response_onenotcorrect",
430 "view" => "All"
431 ];
432 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
433 // qti flow_mat
434 $a_xml_writer->xmlStartTag("flow_mat");
435 $this->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
436 $a_xml_writer->xmlEndTag("flow_mat");
437 $a_xml_writer->xmlEndTag("itemfeedback");
438 }
439
440 $a_xml_writer->xmlEndTag("item");
441 $a_xml_writer->xmlEndTag("questestinterop");
442
443 $xml = $a_xml_writer->xmlDumpMem(false);
444 if (!$a_include_header) {
445 $pos = strpos($xml, "?>");
446 $xml = substr($xml, $pos + 2);
447 }
448 return $xml;
449 }
450}
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)
Returns a QTI xml representation of the question Returns a QTI xml representation of the question and...
Class for question exports.
addGeneralMetadata(ilXmlWriter $xmlwriter)
addQTIMaterial(ilXmlWriter $a_xml_writer, string $a_material, bool $close_material_tag=true, bool $add_mobs=true)
addSuggestedSolution(ilXmlWriter $writer)
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const IL_INST_ID
Definition: constants.php:40
$ilErr
Definition: raiseError.php:33
global $DIC
Definition: shib_login.php:26
$GLOBALS["DIC"]
Definition: wac.php:54