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