ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 
4 include_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
65  $this->addAdditionalContentEditingModeInformation($a_xml_writer);
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->xmlEndTag("item");
366  $a_xml_writer->xmlEndTag("questestinterop");
367 
368  $xml = $a_xml_writer->xmlDumpMem(false);
369  if (!$a_include_header) {
370  $pos = strpos($xml, "?>");
371  $xml = substr($xml, $pos + 2);
372  }
373  return $xml;
374  }
375 }
const MATCHING_QUESTION_IDENTIFIER
global $DIC
Definition: saml.php:7
XML writer class.
Class for question exports.
$index
Definition: metadata.php:60
addGeneralMetadata(ilXmlWriter $xmlwriter)
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.
xmlHeader()
Writes xml header public.
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
Class for matching question exports.