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