ILIAS  release_8 Revision v8.24
class.assOrderingQuestionExport.php
Go to the documentation of this file.
1<?php
18include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assQuestionExport.php";
19
30{
34 public $object;
35
41 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false): string
42 {
43 global $DIC;
44 $ilDB = $DIC['ilDB'];
45 $ilUser = $DIC['ilUser'];
46 $ilias = $DIC['ilias'];
47
48 include_once("./Services/Xml/classes/class.ilXmlWriter.php");
49 $a_xml_writer = new ilXmlWriter();
50 // set xml header
51 $a_xml_writer->xmlHeader();
52 $a_xml_writer->xmlStartTag("questestinterop");
53 $attrs = array(
54 "ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(),
55 "title" => $this->object->getTitle(),
56 "maxattempts" => $this->object->getNrOfTries()
57 );
58 $a_xml_writer->xmlStartTag("item", $attrs);
59 // add question description
60 $a_xml_writer->xmlElement("qticomment", null, $this->object->getComment());
61 $a_xml_writer->xmlStartTag("itemmetadata");
62 $a_xml_writer->xmlStartTag("qtimetadata");
63 $a_xml_writer->xmlStartTag("qtimetadatafield");
64 $a_xml_writer->xmlElement("fieldlabel", null, "ILIAS_VERSION");
65 $a_xml_writer->xmlElement("fieldentry", null, $ilias->getSetting("ilias_version"));
66 $a_xml_writer->xmlEndTag("qtimetadatafield");
67 $a_xml_writer->xmlStartTag("qtimetadatafield");
68 $a_xml_writer->xmlElement("fieldlabel", null, "QUESTIONTYPE");
69 $a_xml_writer->xmlElement("fieldentry", null, ORDERING_QUESTION_IDENTIFIER);
70 $a_xml_writer->xmlEndTag("qtimetadatafield");
71 $a_xml_writer->xmlStartTag("qtimetadatafield");
72 $a_xml_writer->xmlElement("fieldlabel", null, "AUTHOR");
73 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAuthor());
74 $a_xml_writer->xmlEndTag("qtimetadatafield");
75
76 // additional content editing information
78 $this->addGeneralMetadata($a_xml_writer);
79
80 $a_xml_writer->xmlStartTag("qtimetadatafield");
81 $a_xml_writer->xmlElement("fieldlabel", null, "thumb_geometry");
82 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getThumbSize());
83 $a_xml_writer->xmlEndTag("qtimetadatafield");
84 $a_xml_writer->xmlStartTag("qtimetadatafield");
85 $a_xml_writer->xmlElement("fieldlabel", null, "element_height");
86 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getElementHeight());
87 $a_xml_writer->xmlEndTag("qtimetadatafield");
88 $a_xml_writer->xmlStartTag("qtimetadatafield");
89 $a_xml_writer->xmlElement("fieldlabel", null, "points");
90 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getPoints());
91 $a_xml_writer->xmlEndTag("qtimetadatafield");
92 $a_xml_writer->xmlEndTag("qtimetadata");
93 $a_xml_writer->xmlEndTag("itemmetadata");
94
95 // PART I: qti presentation
96 $attrs = array(
97 "label" => $this->object->getTitle()
98 );
99 $a_xml_writer->xmlStartTag("presentation", $attrs);
100 // add flow to presentation
101 $a_xml_writer->xmlStartTag("flow");
102 // add material with question text to presentation
103 $this->object->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
104 // add answers to presentation
105 $attrs = array();
106
107 if ($this->object->getOrderingType() == OQ_PICTURES) {
108 $ordering_type = 'OQP';
109 } elseif ($this->object->getOrderingType() == OQ_NESTED_PICTURES) {
110 $ordering_type = 'OQNP';
111 } elseif ($this->object->getOrderingType() == OQ_NESTED_TERMS) {
112 $ordering_type = 'OQNT';
113 } elseif ($this->object->getOrderingType() == OQ_TERMS) {
114 $ordering_type = 'OQT';
115 }
116
117 $attrs = array(
118 "ident" => $ordering_type,
119 "rcardinality" => "Ordered"
120 );
121
122 if ($this->object->getOutputType() == OUTPUT_JAVASCRIPT) {
123 $attrs["output"] = "javascript";
124 }
125 $a_xml_writer->xmlStartTag("response_lid", $attrs);
126 $solution = $this->object->getSuggestedSolution(0);
127 if (count($solution)) {
128 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches)) {
129 $a_xml_writer->xmlStartTag("material");
130 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
131 if (strcmp($matches[1], "") != 0) {
132 $intlink = $solution["internal_link"];
133 }
134 $attrs = array(
135 "label" => "suggested_solution"
136 );
137 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
138 $a_xml_writer->xmlEndTag("material");
139 }
140 }
141 // shuffle output
142 $attrs = array();
143 if ($this->object->getShuffle()) {
144 $attrs = array(
145 "shuffle" => "Yes"
146 );
147 } else {
148 $attrs = array(
149 "shuffle" => "No"
150 );
151 }
152 $a_xml_writer->xmlStartTag("render_choice", $attrs);
153
154 // add answers
155 foreach ($this->object->getOrderingElementList() as $element) {
156 $attrs = array(
157 'ident' => $element->getExportIdent()
158 );
159 $a_xml_writer->xmlStartTag("response_label", $attrs);
160 if ($this->object->getOrderingType() == OQ_PICTURES
161 || $this->object->getOrderingType() == OQ_NESTED_PICTURES) {
162 $imagetype = "image/jpeg";
163
164 $a_xml_writer->xmlStartTag("material");
165 if ($force_image_references) {
166 $attrs = array(
167 "imagtype" => $imagetype,
168 "label" => $element->getContent(),
169 "uri" => $this->object->getImagePathWeb() . $element->getContent()
170 );
171 $a_xml_writer->xmlElement("matimage", $attrs);
172 } else {
173 $imagepath = $this->object->getImagePath() . $element->getContent();
174 if (file_exists($imagepath) && is_file($imagepath)) {
175 $fh = @fopen($imagepath, "rb");
176 if ($fh != false) {
177 $imagefile = fread($fh, filesize($imagepath));
178 fclose($fh);
179 $base64 = base64_encode($imagefile);
180
181 if (preg_match("/.*\.(png|gif)$/", $element->getContent(), $matches)) {
182 $imagetype = "image/" . $matches[1];
183 }
184 $attrs = array(
185 "imagtype" => $imagetype,
186 "label" => $element->getContent(),
187 "embedded" => "base64"
188 );
189 $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
190 }
191 }
192 }
193 $a_xml_writer->xmlEndTag("material");
194 } elseif ($this->object->getOrderingType() == OQ_TERMS
195 || $this->object->getOrderingType() == OQ_NESTED_TERMS) {
196 $a_xml_writer->xmlStartTag("material");
197 $this->object->addQTIMaterial($a_xml_writer, $element->getContent(), true, false);
198 $a_xml_writer->xmlEndTag("material");
199 $a_xml_writer->xmlStartTag("material");
200 $attrs = array("label" => "answerdepth");
201 $a_xml_writer->xmlElement("mattext", $attrs, $element->getIndentation());
202 $a_xml_writer->xmlEndTag("material");
203 }
204 $a_xml_writer->xmlEndTag("response_label");
205 }
206 $a_xml_writer->xmlEndTag("render_choice");
207 $a_xml_writer->xmlEndTag("response_lid");
208 $a_xml_writer->xmlEndTag("flow");
209 $a_xml_writer->xmlEndTag("presentation");
210
211 // PART II: qti resprocessing
212 $a_xml_writer->xmlStartTag("resprocessing");
213 $a_xml_writer->xmlStartTag("outcomes");
214 $a_xml_writer->xmlStartTag("decvar");
215 $a_xml_writer->xmlEndTag("decvar");
216 $a_xml_writer->xmlEndTag("outcomes");
217 // add response conditions
218 foreach ($this->object->getOrderingElementList() as $element) {
219 $attrs = array(
220 "continue" => "Yes"
221 );
222 $a_xml_writer->xmlStartTag("respcondition", $attrs);
223 // qti conditionvar
224 $a_xml_writer->xmlStartTag("conditionvar");
225 $attrs = array();
226
227 if ($this->object->getOrderingType() == OQ_PICTURES) {
228 $ordering_type = 'OQP';
229 } elseif ($this->object->getOrderingType() == OQ_NESTED_PICTURES) {
230 $ordering_type = 'OQNP';
231 } elseif ($this->object->getOrderingType() == OQ_NESTED_TERMS) {
232 $ordering_type = 'OQNT';
233 } elseif ($this->object->getOrderingType() == OQ_TERMS) {
234 $ordering_type = 'OQT';
235 }
236
237 $attrs = array("respident" => $ordering_type);
238
239 $attrs["index"] = $element->getPosition();
240 $a_xml_writer->xmlElement("varequal", $attrs, $element->getPosition());
241 $a_xml_writer->xmlEndTag("conditionvar");
242 // qti setvar
243 $attrs = array(
244 "action" => "Add"
245 );
246 $points = $this->object->getPoints() / $this->object->getOrderingElementList()->countElements();
247 $a_xml_writer->xmlElement("setvar", $attrs, $points);
248 // qti displayfeedback
249 $attrs = array(
250 "feedbacktype" => "Response",
251 "linkrefid" => "link_" . $element->getPosition()
252 );
253 $a_xml_writer->xmlElement("displayfeedback", $attrs);
254 $a_xml_writer->xmlEndTag("respcondition");
255 }
256
257 $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
258 $this->object->getId(),
259 true
260 );
261 if (strlen($feedback_allcorrect)) {
262 $attrs = array(
263 "continue" => "Yes"
264 );
265 $a_xml_writer->xmlStartTag("respcondition", $attrs);
266 // qti conditionvar
267 $a_xml_writer->xmlStartTag("conditionvar");
268
269 foreach ($this->object->getOrderingElementList() as $element) {
270 $attrs = array();
271
272 if ($this->object->getOrderingType() == OQ_PICTURES) {
273 $ordering_type = 'OQP';
274 } elseif ($this->object->getOrderingType() == OQ_NESTED_PICTURES) {
275 $ordering_type = 'OQNP';
276 } elseif ($this->object->getOrderingType() == OQ_NESTED_TERMS) {
277 $ordering_type = 'OQNT';
278 } elseif ($this->object->getOrderingType() == OQ_TERMS) {
279 $ordering_type = 'OQT';
280 }
281
282 $attrs = array("respident" => $ordering_type);
283
284 $attrs["index"] = $element->getPosition();
285 $a_xml_writer->xmlElement("varequal", $attrs, $element->getPosition());
286 }
287
288 $a_xml_writer->xmlEndTag("conditionvar");
289 // qti displayfeedback
290 $attrs = array(
291 "feedbacktype" => "Response",
292 "linkrefid" => "response_allcorrect"
293 );
294 $a_xml_writer->xmlElement("displayfeedback", $attrs);
295 $a_xml_writer->xmlEndTag("respcondition");
296 }
297
298 $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
299 $this->object->getId(),
300 false
301 );
302 if (strlen($feedback_onenotcorrect)) {
303 $attrs = array(
304 "continue" => "Yes"
305 );
306 $a_xml_writer->xmlStartTag("respcondition", $attrs);
307 // qti conditionvar
308 $a_xml_writer->xmlStartTag("conditionvar");
309 $a_xml_writer->xmlStartTag("not");
310
311 foreach ($this->object->getOrderingElementList() as $element) {
312 $attrs = array();
313 if ($this->object->getOrderingType() == OQ_PICTURES) {
314 $ordering_type = 'OQP';
315 } elseif ($this->object->getOrderingType() == OQ_NESTED_PICTURES) {
316 $ordering_type = 'OQNP';
317 } elseif ($this->object->getOrderingType() == OQ_NESTED_TERMS) {
318 $ordering_type = 'OQNT';
319 } elseif ($this->object->getOrderingType() == OQ_TERMS) {
320 $ordering_type = 'OQT';
321 }
322
323 $attrs = array("respident" => $ordering_type);
324
325 $attrs["index"] = $element->getPosition();
326 $a_xml_writer->xmlElement("varequal", $attrs, $element->getPosition());
327 }
328
329 $a_xml_writer->xmlEndTag("not");
330 $a_xml_writer->xmlEndTag("conditionvar");
331 // qti displayfeedback
332 $attrs = array(
333 "feedbacktype" => "Response",
334 "linkrefid" => "response_onenotcorrect"
335 );
336 $a_xml_writer->xmlElement("displayfeedback", $attrs);
337 $a_xml_writer->xmlEndTag("respcondition");
338 }
339
340 $a_xml_writer->xmlEndTag("resprocessing");
341
342 // PART III: qti itemfeedback
343 foreach ($this->object->getOrderingElementList() as $element) {
344 $attrs = array(
345 "ident" => "link_" . $element->getPosition(),
346 "view" => "All"
347 );
348 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
349 // qti flow_mat
350 $a_xml_writer->xmlStartTag("flow_mat");
351 $a_xml_writer->xmlStartTag("material");
352 $a_xml_writer->xmlElement("mattext", null, $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
353 $this->object->getId(),
354 0,
355 $element->getPosition()
356 ));
357 $a_xml_writer->xmlEndTag("material");
358 $a_xml_writer->xmlEndTag("flow_mat");
359 $a_xml_writer->xmlEndTag("itemfeedback");
360 }
361
362 if (strlen($feedback_allcorrect)) {
363 $attrs = array(
364 "ident" => "response_allcorrect",
365 "view" => "All"
366 );
367 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
368 // qti flow_mat
369 $a_xml_writer->xmlStartTag("flow_mat");
370 $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
371 $a_xml_writer->xmlEndTag("flow_mat");
372 $a_xml_writer->xmlEndTag("itemfeedback");
373 }
374 if (strlen($feedback_onenotcorrect)) {
375 $attrs = array(
376 "ident" => "response_onenotcorrect",
377 "view" => "All"
378 );
379 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
380 // qti flow_mat
381 $a_xml_writer->xmlStartTag("flow_mat");
382 $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
383 $a_xml_writer->xmlEndTag("flow_mat");
384 $a_xml_writer->xmlEndTag("itemfeedback");
385 }
386
387 $a_xml_writer = $this->addSolutionHints($a_xml_writer);
388
389 $a_xml_writer->xmlEndTag("item");
390 $a_xml_writer->xmlEndTag("questestinterop");
391
392 $xml = $a_xml_writer->xmlDumpMem(false);
393 if (!$a_include_header) {
394 $pos = strpos($xml, "?>");
395 $xml = substr($xml, $pos + 2);
396 }
397 return $xml;
398 }
399}
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...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addGeneralMetadata(ilXmlWriter $xmlwriter)
addSolutionHints(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
global $DIC
Definition: feed.php:28
$ilUser
Definition: imgupload.php:34
const OQ_NESTED_PICTURES
const OUTPUT_JAVASCRIPT
const OQ_TERMS
const OQ_NESTED_TERMS
const OQ_PICTURES
Ordering question constants.
const ORDERING_QUESTION_IDENTIFIER
$xml
Definition: metadata.php:351