ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.assMatchingQuestionExport.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assQuestionExport.php";
5
16{
26 public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
27 {
28 global $ilias;
29
30 include_once("./Services/Xml/classes/class.ilXmlWriter.php");
31 $a_xml_writer = new ilXmlWriter;
32 // set xml header
33 $a_xml_writer->xmlHeader();
34 $a_xml_writer->xmlStartTag("questestinterop");
35 $attrs = array(
36 "ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(),
37 "title" => $this->object->getTitle(),
38 "maxattempts" => $this->object->getNrOfTries()
39 );
40 $a_xml_writer->xmlStartTag("item", $attrs);
41 // add question description
42 $a_xml_writer->xmlElement("qticomment", null, $this->object->getComment());
43 // add estimated working time
44 $workingtime = $this->object->getEstimatedWorkingTime();
45 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
46 $a_xml_writer->xmlElement("duration", null, $duration);
47 // add ILIAS specific metadata
48 $a_xml_writer->xmlStartTag("itemmetadata");
49 $a_xml_writer->xmlStartTag("qtimetadata");
50 $a_xml_writer->xmlStartTag("qtimetadatafield");
51 $a_xml_writer->xmlElement("fieldlabel", null, "ILIAS_VERSION");
52 $a_xml_writer->xmlElement("fieldentry", null, $ilias->getSetting("ilias_version"));
53 $a_xml_writer->xmlEndTag("qtimetadatafield");
54 $a_xml_writer->xmlStartTag("qtimetadatafield");
55 $a_xml_writer->xmlElement("fieldlabel", null, "QUESTIONTYPE");
56 $a_xml_writer->xmlElement("fieldentry", null, MATCHING_QUESTION_IDENTIFIER);
57 $a_xml_writer->xmlEndTag("qtimetadatafield");
58 $a_xml_writer->xmlStartTag("qtimetadatafield");
59 $a_xml_writer->xmlElement("fieldlabel", null, "AUTHOR");
60 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAuthor());
61 $a_xml_writer->xmlEndTag("qtimetadatafield");
62
63 // additional content editing information
65 $this->addGeneralMetadata($a_xml_writer);
66
67 $a_xml_writer->xmlStartTag("qtimetadatafield");
68 $a_xml_writer->xmlElement("fieldlabel", null, "shuffle");
69 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getShuffle());
70 $a_xml_writer->xmlEndTag("qtimetadatafield");
71 $a_xml_writer->xmlStartTag("qtimetadatafield");
72 $a_xml_writer->xmlElement("fieldlabel", null, "thumb_geometry");
73 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getThumbGeometry());
74 $a_xml_writer->xmlEndTag("qtimetadatafield");
75 $a_xml_writer->xmlStartTag("qtimetadatafield");
76 $a_xml_writer->xmlElement("fieldlabel", null, 'matching_mode');
77 $a_xml_writer->xmlElement("fieldentry", null, $this->object->getMatchingMode());
78 $a_xml_writer->xmlEndTag("qtimetadatafield");
79 $a_xml_writer->xmlEndTag("qtimetadata");
80 $a_xml_writer->xmlEndTag("itemmetadata");
81
82 // PART I: qti presentation
83 $attrs = array(
84 "label" => $this->object->getTitle()
85 );
86 $a_xml_writer->xmlStartTag("presentation", $attrs);
87 // add flow to presentation
88 $a_xml_writer->xmlStartTag("flow");
89 // add material with question text to presentation
90 $this->object->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
91 // add answers to presentation
92 $attrs = array(
93 "ident" => "MQ",
94 "rcardinality" => "Multiple"
95 );
96 $a_xml_writer->xmlStartTag("response_grp", $attrs);
97 $solution = $this->object->getSuggestedSolution(0);
98 if (count($solution)) {
99 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches)) {
100 $a_xml_writer->xmlStartTag("material");
101 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
102 if (strcmp($matches[1], "") != 0) {
103 $intlink = $solution["internal_link"];
104 }
105 $attrs = array(
106 "label" => "suggested_solution"
107 );
108 $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
109 $a_xml_writer->xmlEndTag("material");
110 }
111 }
112 // shuffle output
113 $attrs = array();
114 if ($this->object->getShuffle()) {
115 $attrs = array(
116 "shuffle" => "Yes"
117 );
118 } else {
119 $attrs = array(
120 "shuffle" => "No"
121 );
122 }
123 $a_xml_writer->xmlStartTag("render_choice", $attrs);
124 // add answertext
125 $matchingtext_orders = array();
126 foreach ($this->object->getMatchingPairs() as $index => $matchingpair) {
127 array_push($matchingtext_orders, $matchingpair->term->identifier);
128 }
129
130 $termids = array();
131 foreach ($this->object->getTerms() as $term) {
132 array_push($termids, $term->identifier);
133 }
134 // add answers
135 foreach ($this->object->getDefinitions() as $definition) {
136 $attrs = array(
137 "ident" => $definition->identifier,
138 "match_max" => "1",
139 "match_group" => join($termids, ",")
140 );
141 $a_xml_writer->xmlStartTag("response_label", $attrs);
142 $a_xml_writer->xmlStartTag("material");
143 if (strlen($definition->picture)) {
144 if ($force_image_references) {
145 $attrs = array(
146 "imagtype" => "image/jpeg",
147 "label" => $definition->picture,
148 "uri" => $this->object->getImagePathWeb() . $definition->picture
149 );
150 $a_xml_writer->xmlElement("matimage", $attrs);
151 } else {
152 $imagepath = $this->object->getImagePath() . $definition->picture;
153 $fh = @fopen($imagepath, "rb");
154 if ($fh != false) {
155 $imagefile = fread($fh, filesize($imagepath));
156 fclose($fh);
157 $base64 = base64_encode($imagefile);
158 $attrs = array(
159 "imagtype" => "image/jpeg",
160 "label" => $definition->picture,
161 "embedded" => "base64"
162 );
163 $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
164 }
165 }
166 }
167 if (strlen($definition->text)) {
168 $attrs = array(
169 "texttype" => "text/plain"
170 );
171 if ($this->object->isHTML($definition->text)) {
172 $attrs["texttype"] = "text/xhtml";
173 }
174 $a_xml_writer->xmlElement("mattext", $attrs, $definition->text);
175 }
176 $a_xml_writer->xmlEndTag("material");
177 $a_xml_writer->xmlEndTag("response_label");
178 }
179 // add matchingtext
180 foreach ($this->object->getTerms() as $term) {
181 $attrs = array(
182 "ident" => $term->identifier
183 );
184 $a_xml_writer->xmlStartTag("response_label", $attrs);
185 $a_xml_writer->xmlStartTag("material");
186 if (strlen($term->picture)) {
187 if ($force_image_references) {
188 $attrs = array(
189 "imagtype" => "image/jpeg",
190 "label" => $term->picture,
191 "uri" => $this->object->getImagePathWeb() . $term->picture
192 );
193 $a_xml_writer->xmlElement("matimage", $attrs);
194 } else {
195 $imagepath = $this->object->getImagePath() . $term->picture;
196 $fh = @fopen($imagepath, "rb");
197 if ($fh != false) {
198 $imagefile = fread($fh, filesize($imagepath));
199 fclose($fh);
200 $base64 = base64_encode($imagefile);
201 $attrs = array(
202 "imagtype" => "image/jpeg",
203 "label" => $term->picture,
204 "embedded" => "base64"
205 );
206 $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
207 }
208 }
209 }
210 if (strlen($term->text)) {
211 $attrs = array(
212 "texttype" => "text/plain"
213 );
214 if ($this->object->isHTML($term->text)) {
215 $attrs["texttype"] = "text/xhtml";
216 }
217 $a_xml_writer->xmlElement("mattext", $attrs, $term->text);
218 }
219 $a_xml_writer->xmlEndTag("material");
220 $a_xml_writer->xmlEndTag("response_label");
221 }
222 $a_xml_writer->xmlEndTag("render_choice");
223 $a_xml_writer->xmlEndTag("response_grp");
224 $a_xml_writer->xmlEndTag("flow");
225 $a_xml_writer->xmlEndTag("presentation");
226
227 // PART II: qti resprocessing
228 $a_xml_writer->xmlStartTag("resprocessing");
229 $a_xml_writer->xmlStartTag("outcomes");
230 $a_xml_writer->xmlStartTag("decvar");
231 $a_xml_writer->xmlEndTag("decvar");
232 $a_xml_writer->xmlEndTag("outcomes");
233 // add response conditions
234 foreach ($this->object->getMatchingPairs() as $matchingpair) {
235 $attrs = array(
236 "continue" => "Yes"
237 );
238 $a_xml_writer->xmlStartTag("respcondition", $attrs);
239 // qti conditionvar
240 $a_xml_writer->xmlStartTag("conditionvar");
241 $attrs = array(
242 "respident" => "MQ"
243 );
244 $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->term->identifier . "," . $matchingpair->definition->identifier);
245 $a_xml_writer->xmlEndTag("conditionvar");
246
247 // qti setvar
248 $attrs = array(
249 "action" => "Add"
250 );
251 $a_xml_writer->xmlElement("setvar", $attrs, $matchingpair->points);
252 // qti displayfeedback
253 $attrs = array(
254 "feedbacktype" => "Response",
255 "linkrefid" => "correct_" . $matchingpair->term->identifier . "_" . $matchingpair->definition_identifier
256 );
257 $a_xml_writer->xmlElement("displayfeedback", $attrs);
258 $a_xml_writer->xmlEndTag("respcondition");
259 }
260
261 $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
262 $this->object->getId(),
263 true
264 );
265 if (strlen($feedback_allcorrect)) {
266 $attrs = array(
267 "continue" => "Yes"
268 );
269 $a_xml_writer->xmlStartTag("respcondition", $attrs);
270 // qti conditionvar
271 $a_xml_writer->xmlStartTag("conditionvar");
272
273 foreach ($this->object->getMatchingPairs() as $matchingpair) {
274 $attrs = array(
275 "respident" => "MQ"
276 );
277 $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->term->identifier . "," . $matchingpair->definition->identifier);
278 }
279 $a_xml_writer->xmlEndTag("conditionvar");
280 // qti displayfeedback
281 $attrs = array(
282 "feedbacktype" => "Response",
283 "linkrefid" => "response_allcorrect"
284 );
285 $a_xml_writer->xmlElement("displayfeedback", $attrs);
286 $a_xml_writer->xmlEndTag("respcondition");
287 }
288 $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
289 $this->object->getId(),
290 false
291 );
292 if (strlen($feedback_onenotcorrect)) {
293 $attrs = array(
294 "continue" => "Yes"
295 );
296 $a_xml_writer->xmlStartTag("respcondition", $attrs);
297 // qti conditionvar
298 $a_xml_writer->xmlStartTag("conditionvar");
299 $a_xml_writer->xmlStartTag("not");
300 foreach ($this->object->getMatchingPairs() as $matchingpair) {
301 $attrs = array(
302 "respident" => "MQ"
303 );
304 $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->term->identifier . "," . $matchingpair->definition->identifier);
305 }
306 $a_xml_writer->xmlEndTag("not");
307 $a_xml_writer->xmlEndTag("conditionvar");
308 // qti displayfeedback
309 $attrs = array(
310 "feedbacktype" => "Response",
311 "linkrefid" => "response_onenotcorrect"
312 );
313 $a_xml_writer->xmlElement("displayfeedback", $attrs);
314 $a_xml_writer->xmlEndTag("respcondition");
315 }
316
317 $a_xml_writer->xmlEndTag("resprocessing");
318
319 // PART III: qti itemfeedback
320 foreach ($this->object->getMatchingPairs() as $index => $matchingpair) {
321 $attrs = array(
322 "ident" => "correct_" . $matchingpair->term->identifier . "_" . $matchingpair->definition->identifier,
323 "view" => "All"
324 );
325 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
326 // qti flow_mat
327 $a_xml_writer->xmlStartTag("flow_mat");
328 $a_xml_writer->xmlStartTag("material");
329 $a_xml_writer->xmlElement("mattext", null, $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
330 $this->object->getId(),
331 $index
332 ));
333 $a_xml_writer->xmlEndTag("material");
334 $a_xml_writer->xmlEndTag("flow_mat");
335 $a_xml_writer->xmlEndTag("itemfeedback");
336 }
337
338 if (strlen($feedback_allcorrect)) {
339 $attrs = array(
340 "ident" => "response_allcorrect",
341 "view" => "All"
342 );
343 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
344 // qti flow_mat
345 $a_xml_writer->xmlStartTag("flow_mat");
346 $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
347 $a_xml_writer->xmlEndTag("flow_mat");
348 $a_xml_writer->xmlEndTag("itemfeedback");
349 }
350 if (strlen($feedback_onenotcorrect)) {
351 $attrs = array(
352 "ident" => "response_onenotcorrect",
353 "view" => "All"
354 );
355 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
356 // qti flow_mat
357 $a_xml_writer->xmlStartTag("flow_mat");
358 $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
359 $a_xml_writer->xmlEndTag("flow_mat");
360 $a_xml_writer->xmlEndTag("itemfeedback");
361 }
362
363 $a_xml_writer->xmlEndTag("item");
364 $a_xml_writer->xmlEndTag("questestinterop");
365
366 $xml = $a_xml_writer->xmlDumpMem(false);
367 if (!$a_include_header) {
368 $pos = strpos($xml, "?>");
369 $xml = substr($xml, $pos + 2);
370 }
371 return $xml;
372 }
373}
sprintf('%.4f', $callTime)
An exception for terminatinating execution or to throw for unit testing.
Class for matching question exports.
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.
Class for question exports.
addGeneralMetadata(ilXmlWriter $xmlwriter)
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
XML writer class.
xmlHeader()
Writes xml header @access public.
const MATCHING_QUESTION_IDENTIFIER
$index
Definition: metadata.php:60
$xml
Definition: metadata.php:240