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 
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 $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  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 }
const MATCHING_QUESTION_IDENTIFIER
XML writer class.
Class for question exports.
$index
Definition: metadata.php:60
addGeneralMetadata(ilXmlWriter $xmlwriter)
$xml
Definition: metadata.php:240
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.