ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.assImagemapQuestionExport.php
Go to the documentation of this file.
1 <?php
2 
29 {
37  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false): string
38  {
39  global $DIC;
40  $ilias = $DIC['ilias'];
41 
42  $a_xml_writer = new ilXmlWriter();
43  // set xml header
44  $a_xml_writer->xmlHeader();
45  $a_xml_writer->xmlStartTag("questestinterop");
46  $attrs = [
47  "ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(),
48  "title" => $this->object->getTitle(),
49  "maxattempts" => $this->object->getNrOfTries()
50  ];
51  $a_xml_writer->xmlStartTag("item", $attrs);
52  // add question description
53  $a_xml_writer->xmlElement("qticomment", null, $this->object->getComment());
54  $a_xml_writer->xmlStartTag("itemmetadata");
55  $a_xml_writer->xmlStartTag("qtimetadata");
56  $a_xml_writer->xmlStartTag("qtimetadatafield");
57  $a_xml_writer->xmlElement("fieldlabel", null, "ILIAS_VERSION");
58  $a_xml_writer->xmlElement("fieldentry", null, $ilias->getSetting("ilias_version"));
59  $a_xml_writer->xmlEndTag("qtimetadatafield");
60  $a_xml_writer->xmlStartTag("qtimetadatafield");
61  $a_xml_writer->xmlElement("fieldlabel", null, "QUESTIONTYPE");
62  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getQuestionType());
63  $a_xml_writer->xmlEndTag("qtimetadatafield");
64  $a_xml_writer->xmlStartTag("qtimetadatafield");
65  $a_xml_writer->xmlElement("fieldlabel", null, "IS_MULTIPLE_CHOICE");
66  $a_xml_writer->xmlElement("fieldentry", null, ($this->object->getIsMultipleChoice()) ? "1" : "0");
67  $a_xml_writer->xmlEndTag("qtimetadatafield");
68  $a_xml_writer->xmlStartTag("qtimetadatafield");
69  $a_xml_writer->xmlElement("fieldlabel", null, "AUTHOR");
70  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAuthor());
71  $a_xml_writer->xmlEndTag("qtimetadatafield");
72 
73  // additional content editing information
74  $this->addAdditionalContentEditingModeInformation($a_xml_writer);
75  $this->addGeneralMetadata($a_xml_writer);
76 
77  $a_xml_writer->xmlEndTag("qtimetadata");
78  $a_xml_writer->xmlEndTag("itemmetadata");
79 
80  // PART I: qti presentation
81  $attrs = [
82  "label" => $this->object->getTitle()
83  ];
84  $a_xml_writer->xmlStartTag("presentation", $attrs);
85  // add flow to presentation
86  $a_xml_writer->xmlStartTag("flow");
87  // add material with question text to presentation
88  $this->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
89  // add answers to presentation
90  $attrs = [
91  "ident" => "IM",
92  "rcardinality" => "Single"
93  ];
94  $a_xml_writer->xmlStartTag("response_xy", $attrs);
95  $a_xml_writer = $this->addSuggestedSolution($a_xml_writer);
96  $a_xml_writer->xmlStartTag("render_hotspot");
97  $a_xml_writer->xmlStartTag("material");
98  $imagetype = "image/jpeg";
99  if (preg_match("/.*\.(png|gif)$/i", $this->object->getImageFilename(), $matches)) {
100  $imagetype = "image/" . strtolower($matches[1]);
101  }
102  $attrs = [
103  "imagtype" => $imagetype,
104  "label" => $this->object->getImageFilename()
105  ];
106  if ($a_include_binary) {
107  if ($force_image_references) {
108  $attrs["uri"] = $this->object->getImagePathWeb() . $this->object->getImageFilename();
109  $a_xml_writer->xmlElement("matimage", $attrs);
110  } else {
111  $attrs["embedded"] = "base64";
112  $imagepath = $this->object->getImagePath() . $this->object->getImageFilename();
113  $fh = fopen($imagepath, "rb");
114  if ($fh == false) {
115  global $DIC;
116  $ilErr = $DIC['ilErr'];
117  $ilErr->raiseError($GLOBALS['DIC']['lng']->txt("error_open_image_file"), $ilErr->MESSAGE);
118  }
119  $imagefile = fread($fh, filesize($imagepath));
120  fclose($fh);
121  $base64 = base64_encode($imagefile);
122  $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
123  }
124  } else {
125  $a_xml_writer->xmlElement("matimage", $attrs);
126  }
127  $a_xml_writer->xmlEndTag("material");
128 
129  // add answers
130  foreach ($this->object->getAnswers() as $index => $answer) {
131  $rared = "";
132  switch ($answer->getArea()) {
133  case "rect":
134  $rarea = "Rectangle";
135  break;
136  case "circle":
137  $rarea = "Ellipse";
138  break;
139  case "poly":
140  $rarea = "Bounded";
141  break;
142  }
143  $attrs = [
144  "ident" => $index,
145  "rarea" => $rarea
146  ];
147  $a_xml_writer->xmlStartTag("response_label", $attrs);
148  $a_xml_writer->xmlData($answer->getCoords());
149  $a_xml_writer->xmlStartTag("material");
150  $a_xml_writer->xmlElement("mattext", null, $answer->getAnswertext());
151  $a_xml_writer->xmlEndTag("material");
152  $a_xml_writer->xmlEndTag("response_label");
153  }
154  $a_xml_writer->xmlEndTag("render_hotspot");
155  $a_xml_writer->xmlEndTag("response_xy");
156  $a_xml_writer->xmlEndTag("flow");
157  $a_xml_writer->xmlEndTag("presentation");
158 
159  // PART II: qti resprocessing
160  $a_xml_writer->xmlStartTag("resprocessing");
161  $a_xml_writer->xmlStartTag("outcomes");
162  $a_xml_writer->xmlStartTag("decvar");
163  $a_xml_writer->xmlEndTag("decvar");
164  $a_xml_writer->xmlEndTag("outcomes");
165  // add response conditions
166  foreach ($this->object->getAnswers() as $index => $answer) {
167  $attrs = [
168  "continue" => "Yes"
169  ];
170  $a_xml_writer->xmlStartTag("respcondition", $attrs);
171  // qti conditionvar
172  $a_xml_writer->xmlStartTag("conditionvar");
173  if (!$answer->isStateSet()) {
174  $a_xml_writer->xmlStartTag("not");
175  }
176  $areatype = "";
177  switch ($answer->getArea()) {
178  case "rect":
179  $areatype = "Rectangle";
180  break;
181  case "circle":
182  $areatype = "Ellipse";
183  break;
184  case "poly":
185  $areatype = "Bounded";
186  break;
187  }
188  $attrs = [
189  "respident" => "IM",
190  "areatype" => $areatype
191  ];
192  $a_xml_writer->xmlElement("varequal", $attrs, $answer->getCoords());
193  if (!$answer->isStateSet()) {
194  $a_xml_writer->xmlEndTag("not");
195  }
196  $a_xml_writer->xmlEndTag("conditionvar");
197  // qti setvar
198  $attrs = [
199  "action" => "Add"
200  ];
201  $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
202  $linkrefid = "response_$index";
203  $attrs = [
204  "feedbacktype" => "Response",
205  "linkrefid" => $linkrefid
206  ];
207  $a_xml_writer->xmlElement("displayfeedback", $attrs);
208  $a_xml_writer->xmlEndTag("respcondition");
209  $attrs = [
210  "continue" => "Yes"
211  ];
212  $a_xml_writer->xmlStartTag("respcondition", $attrs);
213  // qti conditionvar
214  $a_xml_writer->xmlStartTag("conditionvar");
215  $attrs = [
216  "respident" => "IM"
217  ];
218  $a_xml_writer->xmlStartTag("not");
219  $a_xml_writer->xmlElement("varequal", $attrs, $answer->getCoords());
220  $a_xml_writer->xmlEndTag("not");
221  $a_xml_writer->xmlEndTag("conditionvar");
222  // qti setvar
223  $attrs = [
224  "action" => "Add"
225  ];
226  $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPointsUnchecked());
227  $a_xml_writer->xmlEndTag("respcondition");
228  }
229 
230  $answers = $this->object->getAnswers();
231  $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
232  $this->object->getId(),
233  true
234  );
235  if (strlen($feedback_allcorrect) && count($answers) > 0) {
236  $attrs = [
237  "continue" => "Yes"
238  ];
239  $a_xml_writer->xmlStartTag("respcondition", $attrs);
240  // qti conditionvar
241  $a_xml_writer->xmlStartTag("conditionvar");
242  if (!$this->object->getIsMultipleChoice()) {
243  $bestindex = 0;
244  $maxpoints = 0;
245  foreach ($answers as $index => $answer) {
246  if ($answer->getPoints() > $maxpoints) {
247  $maxpoints = $answer->getPoints();
248  $bestindex = $index;
249  }
250  }
251 
252  $areatype = "";
253  $answer = $answers[$bestindex];
254  switch ($answer->getArea()) {
255  case "rect":
256  $areatype = "Rectangle";
257  break;
258  case "circle":
259  $areatype = "Ellipse";
260  break;
261  case "poly":
262  $areatype = "Bounded";
263  break;
264  }
265  $attrs = [
266  "respident" => "IM",
267  "areatype" => $areatype
268  ];
269  $a_xml_writer->xmlElement("varinside", $attrs, $answer->getCoords());
270  } else {
271  foreach ($answers as $index => $answer) {
272  if ($answer->getPoints() < $answer->getPointsUnchecked()) {
273  $a_xml_writer->xmlStartTag("not");
274  }
275  switch ($answer->getArea()) {
276  case "rect":
277  $areatype = "Rectangle";
278  break;
279  case "circle":
280  $areatype = "Ellipse";
281  break;
282  case "poly":
283  $areatype = "Bounded";
284  break;
285  }
286  $attrs = [
287  "respident" => "IM",
288  "areatype" => $areatype
289  ];
290  $a_xml_writer->xmlElement("varequal", $attrs, $index);
291  if ($answer->getPoints() < $answer->getPointsUnchecked()) {
292  $a_xml_writer->xmlEndTag("not");
293  }
294  }
295  }
296 
297  $a_xml_writer->xmlEndTag("conditionvar");
298  // qti displayfeedback
299  $attrs = [
300  "feedbacktype" => "Response",
301  "linkrefid" => "response_allcorrect"
302  ];
303  $a_xml_writer->xmlElement("displayfeedback", $attrs);
304  $a_xml_writer->xmlEndTag("respcondition");
305  }
306 
307  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
308  $this->object->getId(),
309  false
310  );
311  if (strlen($feedback_onenotcorrect) && count($answers) > 0) {
312  $attrs = [
313  "continue" => "Yes"
314  ];
315  $a_xml_writer->xmlStartTag("respcondition", $attrs);
316  // qti conditionvar
317  $a_xml_writer->xmlStartTag("conditionvar");
318  if (!$this->object->getIsMultipleChoice()) {
319  $bestindex = 0;
320  $maxpoints = 0;
321  foreach ($answers as $index => $answer) {
322  if ($answer->getPoints() > $maxpoints) {
323  $maxpoints = $answer->getPoints();
324  $bestindex = $index;
325  }
326  }
327  $attrs = [
328  "respident" => "IM"
329  ];
330  $a_xml_writer->xmlStartTag("not");
331 
332  $areatype = "";
333  $answer = $answers[$bestindex];
334  switch ($answer->getArea()) {
335  case "rect":
336  $areatype = "Rectangle";
337  break;
338  case "circle":
339  $areatype = "Ellipse";
340  break;
341  case "poly":
342  $areatype = "Bounded";
343  break;
344  }
345  $attrs = [
346  "respident" => "IM",
347  "areatype" => $areatype
348  ];
349  $a_xml_writer->xmlElement("varinside", $attrs, $answer->getCoords());
350 
351  $a_xml_writer->xmlEndTag("not");
352  } else {
353  foreach ($answers as $index => $answer) {
354  if ($index > 0) {
355  $a_xml_writer->xmlStartTag("or");
356  }
357  if ($answer->getPoints() >= $answer->getPointsUnchecked()) {
358  $a_xml_writer->xmlStartTag("not");
359  }
360  switch ($answer->getArea()) {
361  case "rect":
362  $areatype = "Rectangle";
363  break;
364  case "circle":
365  $areatype = "Ellipse";
366  break;
367  case "poly":
368  $areatype = "Bounded";
369  break;
370  }
371  $attrs = [
372  "respident" => "IM",
373  "areatype" => $areatype
374  ];
375  $a_xml_writer->xmlElement("varequal", $attrs, $index);
376  if ($answer->getPoints() >= $answer->getPointsUnchecked()) {
377  $a_xml_writer->xmlEndTag("not");
378  }
379  if ($index > 0) {
380  $a_xml_writer->xmlEndTag("or");
381  }
382  }
383  }
384  $a_xml_writer->xmlEndTag("conditionvar");
385  // qti displayfeedback
386  $attrs = [
387  "feedbacktype" => "Response",
388  "linkrefid" => "response_onenotcorrect"
389  ];
390  $a_xml_writer->xmlElement("displayfeedback", $attrs);
391  $a_xml_writer->xmlEndTag("respcondition");
392  }
393 
394  $a_xml_writer->xmlEndTag("resprocessing");
395 
396  // PART III: qti itemfeedback
397  foreach ($this->object->getAnswers() as $index => $answer) {
398  $linkrefid = "response_$index";
399  $attrs = [
400  "ident" => $linkrefid,
401  "view" => "All"
402  ];
403  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
404  // qti flow_mat
405  $a_xml_writer->xmlStartTag("flow_mat");
406  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
407  $this->object->getId(),
408  0,
409  $index
410  );
411  $this->addQTIMaterial($a_xml_writer, $fb);
412  $a_xml_writer->xmlEndTag("flow_mat");
413  $a_xml_writer->xmlEndTag("itemfeedback");
414  }
415  if (strlen($feedback_allcorrect)) {
416  $attrs = [
417  "ident" => "response_allcorrect",
418  "view" => "All"
419  ];
420  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
421  // qti flow_mat
422  $a_xml_writer->xmlStartTag("flow_mat");
423  $this->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
424  $a_xml_writer->xmlEndTag("flow_mat");
425  $a_xml_writer->xmlEndTag("itemfeedback");
426  }
427  if (strlen($feedback_onenotcorrect)) {
428  $attrs = [
429  "ident" => "response_onenotcorrect",
430  "view" => "All"
431  ];
432  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
433  // qti flow_mat
434  $a_xml_writer->xmlStartTag("flow_mat");
435  $this->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
436  $a_xml_writer->xmlEndTag("flow_mat");
437  $a_xml_writer->xmlEndTag("itemfeedback");
438  }
439 
440  $a_xml_writer->xmlEndTag("item");
441  $a_xml_writer->xmlEndTag("questestinterop");
442 
443  $xml = $a_xml_writer->xmlDumpMem(false);
444  if (!$a_include_header) {
445  $pos = strpos($xml, "?>");
446  $xml = substr($xml, $pos + 2);
447  }
448  return $xml;
449  }
450 }
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 Returns a QTI xml representation of the question and...
const IL_INST_ID
Definition: constants.php:40
addQTIMaterial(ilXmlWriter $a_xml_writer, string $a_material, bool $close_material_tag=true, bool $add_mobs=true)
Class for question exports.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addGeneralMetadata(ilXmlWriter $xmlwriter)
$ilErr
Definition: raiseError.php:33
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$GLOBALS["DIC"]
Definition: wac.php:53
global $DIC
Definition: shib_login.php:26
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
addSuggestedSolution(ilXmlWriter $writer)