ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
All Data Structures Namespaces Files Functions Variables Modules Pages
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) && count($answers) > 0) {
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 
262  $areatype = "";
263  $answer = $answers[$bestindex];
264  switch ($answer->getArea()) {
265  case "rect":
266  $areatype = "Rectangle";
267  break;
268  case "circle":
269  $areatype = "Ellipse";
270  break;
271  case "poly":
272  $areatype = "Bounded";
273  break;
274  }
275  $attrs = array(
276  "respident" => "IM",
277  "areatype" => $areatype
278  );
279  $a_xml_writer->xmlElement("varinside", $attrs, $answer->getCoords());
280  } else {
281  foreach ($answers as $index => $answer) {
282  if ($answer->getPoints() < $answer->getPointsUnchecked()) {
283  $a_xml_writer->xmlStartTag("not");
284  }
285  switch ($answer->getArea()) {
286  case "rect":
287  $areatype = "Rectangle";
288  break;
289  case "circle":
290  $areatype = "Ellipse";
291  break;
292  case "poly":
293  $areatype = "Bounded";
294  break;
295  }
296  $attrs = array(
297  "respident" => "IM",
298  "areatype" => $areatype
299  );
300  $a_xml_writer->xmlElement("varequal", $attrs, $index);
301  if ($answer->getPoints() < $answer->getPointsUnchecked()) {
302  $a_xml_writer->xmlEndTag("not");
303  }
304  }
305  }
306 
307  $a_xml_writer->xmlEndTag("conditionvar");
308  // qti displayfeedback
309  $attrs = array(
310  "feedbacktype" => "Response",
311  "linkrefid" => "response_allcorrect"
312  );
313  $a_xml_writer->xmlElement("displayfeedback", $attrs);
314  $a_xml_writer->xmlEndTag("respcondition");
315  }
316 
317  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
318  $this->object->getId(),
319  false
320  );
321  if (strlen($feedback_onenotcorrect) && count($answers) > 0) {
322  $attrs = array(
323  "continue" => "Yes"
324  );
325  $a_xml_writer->xmlStartTag("respcondition", $attrs);
326  // qti conditionvar
327  $a_xml_writer->xmlStartTag("conditionvar");
328  if (!$this->object->getIsMultipleChoice()) {
329  $bestindex = 0;
330  $maxpoints = 0;
331  foreach ($answers as $index => $answer) {
332  if ($answer->getPoints() > $maxpoints) {
333  $maxpoints = $answer->getPoints();
334  $bestindex = $index;
335  }
336  }
337  $attrs = array(
338  "respident" => "IM"
339  );
340  $a_xml_writer->xmlStartTag("not");
341 
342  $areatype = "";
343  $answer = $answers[$bestindex];
344  switch ($answer->getArea()) {
345  case "rect":
346  $areatype = "Rectangle";
347  break;
348  case "circle":
349  $areatype = "Ellipse";
350  break;
351  case "poly":
352  $areatype = "Bounded";
353  break;
354  }
355  $attrs = array(
356  "respident" => "IM",
357  "areatype" => $areatype
358  );
359  $a_xml_writer->xmlElement("varinside", $attrs, $answer->getCoords());
360 
361  $a_xml_writer->xmlEndTag("not");
362  } else {
363  foreach ($answers as $index => $answer) {
364  if ($index > 0) {
365  $a_xml_writer->xmlStartTag("or");
366  }
367  if ($answer->getPoints() >= $answer->getPointsUnchecked()) {
368  $a_xml_writer->xmlStartTag("not");
369  }
370  switch ($answer->getArea()) {
371  case "rect":
372  $areatype = "Rectangle";
373  break;
374  case "circle":
375  $areatype = "Ellipse";
376  break;
377  case "poly":
378  $areatype = "Bounded";
379  break;
380  }
381  $attrs = array(
382  "respident" => "IM",
383  "areatype" => $areatype
384  );
385  $a_xml_writer->xmlElement("varequal", $attrs, $index);
386  if ($answer->getPoints() >= $answer->getPointsUnchecked()) {
387  $a_xml_writer->xmlEndTag("not");
388  }
389  if ($index > 0) {
390  $a_xml_writer->xmlEndTag("or");
391  }
392  }
393  }
394  $a_xml_writer->xmlEndTag("conditionvar");
395  // qti displayfeedback
396  $attrs = array(
397  "feedbacktype" => "Response",
398  "linkrefid" => "response_onenotcorrect"
399  );
400  $a_xml_writer->xmlElement("displayfeedback", $attrs);
401  $a_xml_writer->xmlEndTag("respcondition");
402  }
403 
404  $a_xml_writer->xmlEndTag("resprocessing");
405 
406  // PART III: qti itemfeedback
407  foreach ($this->object->getAnswers() as $index => $answer) {
408  $linkrefid = "";
409  $linkrefid = "response_$index";
410  $attrs = array(
411  "ident" => $linkrefid,
412  "view" => "All"
413  );
414  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
415  // qti flow_mat
416  $a_xml_writer->xmlStartTag("flow_mat");
417  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
418  $this->object->getId(),
419  0,
420  $index
421  );
422  $this->object->addQTIMaterial($a_xml_writer, $fb);
423  $a_xml_writer->xmlEndTag("flow_mat");
424  $a_xml_writer->xmlEndTag("itemfeedback");
425  }
426  if (strlen($feedback_allcorrect)) {
427  $attrs = array(
428  "ident" => "response_allcorrect",
429  "view" => "All"
430  );
431  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
432  // qti flow_mat
433  $a_xml_writer->xmlStartTag("flow_mat");
434  $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
435  $a_xml_writer->xmlEndTag("flow_mat");
436  $a_xml_writer->xmlEndTag("itemfeedback");
437  }
438  if (strlen($feedback_onenotcorrect)) {
439  $attrs = array(
440  "ident" => "response_onenotcorrect",
441  "view" => "All"
442  );
443  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
444  // qti flow_mat
445  $a_xml_writer->xmlStartTag("flow_mat");
446  $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
447  $a_xml_writer->xmlEndTag("flow_mat");
448  $a_xml_writer->xmlEndTag("itemfeedback");
449  }
450 
451  $a_xml_writer->xmlEndTag("item");
452  $a_xml_writer->xmlEndTag("questestinterop");
453 
454  $xml = $a_xml_writer->xmlDumpMem(false);
455  if (!$a_include_header) {
456  $pos = strpos($xml, "?>");
457  $xml = substr($xml, $pos + 2);
458  }
459  return $xml;
460  }
461 }
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.
XML writer class.
Class for question exports.
Class for imagemap question exports.
addGeneralMetadata(ilXmlWriter $xmlwriter)
$index
Definition: metadata.php:128
$ilErr
Definition: raiseError.php:18
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
xmlHeader()
Writes xml header public.
$xml
Definition: metadata.php:332
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
$DIC
Definition: xapitoken.php:46
const IMAGEMAP_QUESTION_IDENTIFIER