ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  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
64  $this->addAdditionalContentEditingModeInformation($a_xml_writer);
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  {
100  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
101  {
102  $a_xml_writer->xmlStartTag("material");
103  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
104  if (strcmp($matches[1], "") != 0)
105  {
106  $intlink = $solution["internal_link"];
107  }
108  $attrs = array(
109  "label" => "suggested_solution"
110  );
111  $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
112  $a_xml_writer->xmlEndTag("material");
113  }
114  }
115  // shuffle output
116  $attrs = array();
117  if ($this->object->getShuffle())
118  {
119  $attrs = array(
120  "shuffle" => "Yes"
121  );
122  }
123  else
124  {
125  $attrs = array(
126  "shuffle" => "No"
127  );
128  }
129  $a_xml_writer->xmlStartTag("render_choice", $attrs);
130  // add answertext
131  $matchingtext_orders = array();
132  foreach ($this->object->getMatchingPairs() as $index => $matchingpair)
133  {
134  array_push($matchingtext_orders, $matchingpair->term->identifier);
135  }
136 
137  $termids = array();
138  foreach ($this->object->getTerms() as $term)
139  {
140  array_push($termids, $term->identifier);
141  }
142  // add answers
143  foreach ($this->object->getDefinitions() as $definition)
144  {
145  $attrs = array(
146  "ident" => $definition->identifier,
147  "match_max" => "1",
148  "match_group" => join($termids, ",")
149  );
150  $a_xml_writer->xmlStartTag("response_label", $attrs);
151  $a_xml_writer->xmlStartTag("material");
152  if (strlen($definition->picture))
153  {
154  if ($force_image_references)
155  {
156  $attrs = array(
157  "imagtype" => "image/jpeg",
158  "label" => $definition->picture,
159  "uri" => $this->object->getImagePathWeb() . $definition->picture
160  );
161  $a_xml_writer->xmlElement("matimage", $attrs);
162  }
163  else
164  {
165  $imagepath = $this->object->getImagePath() . $definition->picture;
166  $fh = @fopen($imagepath, "rb");
167  if ($fh != false)
168  {
169  $imagefile = fread($fh, filesize($imagepath));
170  fclose($fh);
171  $base64 = base64_encode($imagefile);
172  $attrs = array(
173  "imagtype" => "image/jpeg",
174  "label" => $definition->picture,
175  "embedded" => "base64"
176  );
177  $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
178  }
179  }
180  }
181  if (strlen($definition->text))
182  {
183  $attrs = array(
184  "texttype" => "text/plain"
185  );
186  if ($this->object->isHTML($definition->text))
187  {
188  $attrs["texttype"] = "text/xhtml";
189  }
190  $a_xml_writer->xmlElement("mattext", $attrs, $definition->text);
191  }
192  $a_xml_writer->xmlEndTag("material");
193  $a_xml_writer->xmlEndTag("response_label");
194  }
195  // add matchingtext
196  foreach ($this->object->getTerms() as $term)
197  {
198  $attrs = array(
199  "ident" => $term->identifier
200  );
201  $a_xml_writer->xmlStartTag("response_label", $attrs);
202  $a_xml_writer->xmlStartTag("material");
203  if (strlen($term->picture))
204  {
205  if ($force_image_references)
206  {
207  $attrs = array(
208  "imagtype" => "image/jpeg",
209  "label" => $term->picture,
210  "uri" => $this->object->getImagePathWeb() . $term->picture
211  );
212  $a_xml_writer->xmlElement("matimage", $attrs);
213  }
214  else
215  {
216  $imagepath = $this->object->getImagePath() . $term->picture;
217  $fh = @fopen($imagepath, "rb");
218  if ($fh != false)
219  {
220  $imagefile = fread($fh, filesize($imagepath));
221  fclose($fh);
222  $base64 = base64_encode($imagefile);
223  $attrs = array(
224  "imagtype" => "image/jpeg",
225  "label" => $term->picture,
226  "embedded" => "base64"
227  );
228  $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
229  }
230  }
231  }
232  if (strlen($term->text))
233  {
234  $attrs = array(
235  "texttype" => "text/plain"
236  );
237  if ($this->object->isHTML($term->text))
238  {
239  $attrs["texttype"] = "text/xhtml";
240  }
241  $a_xml_writer->xmlElement("mattext", $attrs, $term->text);
242  }
243  $a_xml_writer->xmlEndTag("material");
244  $a_xml_writer->xmlEndTag("response_label");
245  }
246  $a_xml_writer->xmlEndTag("render_choice");
247  $a_xml_writer->xmlEndTag("response_grp");
248  $a_xml_writer->xmlEndTag("flow");
249  $a_xml_writer->xmlEndTag("presentation");
250 
251  // PART II: qti resprocessing
252  $a_xml_writer->xmlStartTag("resprocessing");
253  $a_xml_writer->xmlStartTag("outcomes");
254  $a_xml_writer->xmlStartTag("decvar");
255  $a_xml_writer->xmlEndTag("decvar");
256  $a_xml_writer->xmlEndTag("outcomes");
257  // add response conditions
258  foreach ($this->object->getMatchingPairs() as $matchingpair)
259  {
260  $attrs = array(
261  "continue" => "Yes"
262  );
263  $a_xml_writer->xmlStartTag("respcondition", $attrs);
264  // qti conditionvar
265  $a_xml_writer->xmlStartTag("conditionvar");
266  $attrs = array(
267  "respident" => "MQ"
268  );
269  $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->term->identifier . "," . $matchingpair->definition->identifier);
270  $a_xml_writer->xmlEndTag("conditionvar");
271 
272  // qti setvar
273  $attrs = array(
274  "action" => "Add"
275  );
276  $a_xml_writer->xmlElement("setvar", $attrs, $matchingpair->points);
277  // qti displayfeedback
278  $attrs = array(
279  "feedbacktype" => "Response",
280  "linkrefid" => "correct_" . $matchingpair->term->identifier . "_" . $matchingpair->definition_identifier
281  );
282  $a_xml_writer->xmlElement("displayfeedback", $attrs);
283  $a_xml_writer->xmlEndTag("respcondition");
284  }
285 
286  $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
287  $this->object->getId(), true
288  );
289  if (strlen($feedback_allcorrect))
290  {
291  $attrs = array(
292  "continue" => "Yes"
293  );
294  $a_xml_writer->xmlStartTag("respcondition", $attrs);
295  // qti conditionvar
296  $a_xml_writer->xmlStartTag("conditionvar");
297 
298  foreach ($this->object->getMatchingPairs() as $matchingpair)
299  {
300  $attrs = array(
301  "respident" => "MQ"
302  );
303  $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->term->identifier . "," . $matchingpair->definition->identifier);
304  }
305  $a_xml_writer->xmlEndTag("conditionvar");
306  // qti displayfeedback
307  $attrs = array(
308  "feedbacktype" => "Response",
309  "linkrefid" => "response_allcorrect"
310  );
311  $a_xml_writer->xmlElement("displayfeedback", $attrs);
312  $a_xml_writer->xmlEndTag("respcondition");
313  }
314  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
315  $this->object->getId(), false
316  );
317  if (strlen($feedback_onenotcorrect))
318  {
319  $attrs = array(
320  "continue" => "Yes"
321  );
322  $a_xml_writer->xmlStartTag("respcondition", $attrs);
323  // qti conditionvar
324  $a_xml_writer->xmlStartTag("conditionvar");
325  $a_xml_writer->xmlStartTag("not");
326  foreach ($this->object->getMatchingPairs() as $matchingpair)
327  {
328  $attrs = array(
329  "respident" => "MQ"
330  );
331  $a_xml_writer->xmlElement("varsubset", $attrs, $matchingpair->term->identifier . "," . $matchingpair->definition->identifier);
332  }
333  $a_xml_writer->xmlEndTag("not");
334  $a_xml_writer->xmlEndTag("conditionvar");
335  // qti displayfeedback
336  $attrs = array(
337  "feedbacktype" => "Response",
338  "linkrefid" => "response_onenotcorrect"
339  );
340  $a_xml_writer->xmlElement("displayfeedback", $attrs);
341  $a_xml_writer->xmlEndTag("respcondition");
342  }
343 
344  $a_xml_writer->xmlEndTag("resprocessing");
345 
346  // PART III: qti itemfeedback
347  foreach ($this->object->getMatchingPairs() as $index => $matchingpair)
348  {
349  $attrs = array(
350  "ident" => "correct_" . $matchingpair->term->identifier . "_" . $matchingpair->definition->identifier,
351  "view" => "All"
352  );
353  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
354  // qti flow_mat
355  $a_xml_writer->xmlStartTag("flow_mat");
356  $a_xml_writer->xmlStartTag("material");
357  $a_xml_writer->xmlElement("mattext", null, $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
358  $this->object->getId(), $index
359  ));
360  $a_xml_writer->xmlEndTag("material");
361  $a_xml_writer->xmlEndTag("flow_mat");
362  $a_xml_writer->xmlEndTag("itemfeedback");
363  }
364 
365  if (strlen($feedback_allcorrect))
366  {
367  $attrs = array(
368  "ident" => "response_allcorrect",
369  "view" => "All"
370  );
371  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
372  // qti flow_mat
373  $a_xml_writer->xmlStartTag("flow_mat");
374  $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
375  $a_xml_writer->xmlEndTag("flow_mat");
376  $a_xml_writer->xmlEndTag("itemfeedback");
377  }
378  if (strlen($feedback_onenotcorrect))
379  {
380  $attrs = array(
381  "ident" => "response_onenotcorrect",
382  "view" => "All"
383  );
384  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
385  // qti flow_mat
386  $a_xml_writer->xmlStartTag("flow_mat");
387  $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
388  $a_xml_writer->xmlEndTag("flow_mat");
389  $a_xml_writer->xmlEndTag("itemfeedback");
390  }
391 
392  $a_xml_writer->xmlEndTag("item");
393  $a_xml_writer->xmlEndTag("questestinterop");
394 
395  $xml = $a_xml_writer->xmlDumpMem(FALSE);
396  if (!$a_include_header)
397  {
398  $pos = strpos($xml, "?>");
399  $xml = substr($xml, $pos + 2);
400  }
401  return $xml;
402  }
403 }
404 
405 ?>
const MATCHING_QUESTION_IDENTIFIER
XML writer class.
Class for question exports.
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.
Create styles array
The data for the language used.
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
Create new PHPExcel object
obj_idprivate
Class for matching question exports.