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