ILIAS  release_4-4 Revision
class.assSingleChoiceExport.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  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, SINGLE_CHOICE_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, "thumb_size");
69  $a_xml_writer->xmlElement("fieldentry", NULL, $this->object->getThumbSize());
70  $a_xml_writer->xmlEndTag("qtimetadatafield");
71 
72  $a_xml_writer->xmlStartTag("qtimetadatafield");
73  $a_xml_writer->xmlElement("fieldlabel", NULL, "feedback_setting");
74  $a_xml_writer->xmlElement("fieldentry", NULL, $this->object->getSpecificFeedbackSetting());
75  $a_xml_writer->xmlEndTag("qtimetadatafield");
76 
77  $a_xml_writer->xmlEndTag("qtimetadata");
78  $a_xml_writer->xmlEndTag("itemmetadata");
79 
80  // PART I: qti presentation
81  $attrs = array(
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->object->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
89  // add answers to presentation
90  $attrs = array();
91  $attrs = array(
92  "ident" => "MCSR",
93  "rcardinality" => "Single"
94  );
95  $a_xml_writer->xmlStartTag("response_lid", $attrs);
96  $solution = $this->object->getSuggestedSolution(0);
97  if (count($solution))
98  {
99  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
100  {
101  $a_xml_writer->xmlStartTag("material");
102  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
103  if (strcmp($matches[1], "") != 0)
104  {
105  $intlink = $solution["internal_link"];
106  }
107  $attrs = array(
108  "label" => "suggested_solution"
109  );
110  $a_xml_writer->xmlElement("mattext", $attrs, $intlink);
111  $a_xml_writer->xmlEndTag("material");
112  }
113  }
114  // shuffle output
115  $attrs = array();
116  if ($this->object->getShuffle())
117  {
118  $attrs = array(
119  "shuffle" => "Yes"
120  );
121  }
122  else
123  {
124  $attrs = array(
125  "shuffle" => "No"
126  );
127  }
128  $a_xml_writer->xmlStartTag("render_choice", $attrs);
129  $answers =& $this->object->getAnswers();
130  $akeys = array_keys($answers);
131  if ($this->object->getShuffle() && $a_shuffle)
132  {
133  $akeys = $this->object->pcArrayShuffle($akeys);
134  }
135  // add answers
136  foreach ($akeys as $index)
137  {
138  $answer = $answers[$index];
139  $attrs = array(
140  "ident" => $index
141  );
142  $a_xml_writer->xmlStartTag("response_label", $attrs);
143 
144  if (strlen($answer->getImage()))
145  {
146  $this->object->addQTIMaterial($a_xml_writer, $answer->getAnswertext(), FALSE, FALSE);
147  $imagetype = "image/jpeg";
148  if (preg_match("/.*\.(png|gif)$/", $answer->getImage(), $matches))
149  {
150  $imagetype = "image/" . $matches[1];
151  }
152  if ($force_image_references)
153  {
154  $attrs = array(
155  "imagtype" => $imagetype,
156  "label" => $answer->getImage(),
157  "uri" => $this->object->getImagePathWeb() . $answer->getImage()
158  );
159  $a_xml_writer->xmlElement("matimage", $attrs);
160  }
161  else
162  {
163  $imagepath = $this->object->getImagePath() . $answer->getImage();
164  $fh = @fopen($imagepath, "rb");
165  if ($fh != false)
166  {
167  $imagefile = fread($fh, filesize($imagepath));
168  fclose($fh);
169  $base64 = base64_encode($imagefile);
170  $attrs = array(
171  "imagtype" => $imagetype,
172  "label" => $answer->getImage(),
173  "embedded" => "base64"
174  );
175  $a_xml_writer->xmlElement("matimage", $attrs, $base64, FALSE, FALSE);
176  }
177  }
178  $a_xml_writer->xmlEndTag("material");
179  }
180  else
181  {
182  $this->object->addQTIMaterial($a_xml_writer, $answer->getAnswertext());
183  }
184  $a_xml_writer->xmlEndTag("response_label");
185  }
186  $a_xml_writer->xmlEndTag("render_choice");
187  $a_xml_writer->xmlEndTag("response_lid");
188  $a_xml_writer->xmlEndTag("flow");
189  $a_xml_writer->xmlEndTag("presentation");
190 
191  // PART II: qti resprocessing
192  $a_xml_writer->xmlStartTag("resprocessing");
193  $a_xml_writer->xmlStartTag("outcomes");
194  $a_xml_writer->xmlStartTag("decvar");
195  $a_xml_writer->xmlEndTag("decvar");
196  $a_xml_writer->xmlEndTag("outcomes");
197  // add response conditions
198  foreach ($answers as $index => $answer)
199  {
200  $attrs = array(
201  "continue" => "Yes"
202  );
203  $a_xml_writer->xmlStartTag("respcondition", $attrs);
204  // qti conditionvar
205  $a_xml_writer->xmlStartTag("conditionvar");
206  $attrs = array();
207  $attrs = array(
208  "respident" => "MCSR"
209  );
210  $a_xml_writer->xmlElement("varequal", $attrs, $index);
211  $a_xml_writer->xmlEndTag("conditionvar");
212  // qti setvar
213  $attrs = array(
214  "action" => "Add"
215  );
216  $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
217  // qti displayfeedback
218  $linkrefid = "response_$index";
219  $attrs = array(
220  "feedbacktype" => "Response",
221  "linkrefid" => $linkrefid
222  );
223  $a_xml_writer->xmlElement("displayfeedback", $attrs);
224  $a_xml_writer->xmlEndTag("respcondition");
225  }
226 
227  $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
228  $this->object->getId(), true
229  );
230  if (strlen($feedback_allcorrect))
231  {
232  $attrs = array(
233  "continue" => "Yes"
234  );
235  $a_xml_writer->xmlStartTag("respcondition", $attrs);
236  // qti conditionvar
237  $a_xml_writer->xmlStartTag("conditionvar");
238  $bestindex = 0;
239  $maxpoints = 0;
240  foreach ($answers as $index => $answer)
241  {
242  if ($answer->getPoints() > $maxpoints)
243  {
244  $maxpoints = $answer->getPoints();
245  $bestindex = $index;
246  }
247  }
248  $attrs = array(
249  "respident" => "MCSR"
250  );
251  $a_xml_writer->xmlElement("varequal", $attrs, $bestindex);
252  $a_xml_writer->xmlEndTag("conditionvar");
253  // qti displayfeedback
254  $attrs = array(
255  "feedbacktype" => "Response",
256  "linkrefid" => "response_allcorrect"
257  );
258  $a_xml_writer->xmlElement("displayfeedback", $attrs);
259  $a_xml_writer->xmlEndTag("respcondition");
260  }
261 
262  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
263  $this->object->getId(), false
264  );
265  if (strlen($feedback_onenotcorrect))
266  {
267  $attrs = array(
268  "continue" => "Yes"
269  );
270  $a_xml_writer->xmlStartTag("respcondition", $attrs);
271  // qti conditionvar
272  $a_xml_writer->xmlStartTag("conditionvar");
273  $bestindex = 0;
274  $maxpoints = 0;
275  foreach ($answers as $index => $answer)
276  {
277  if ($answer->getPoints() > $maxpoints)
278  {
279  $maxpoints = $answer->getPoints();
280  $bestindex = $index;
281  }
282  }
283  $attrs = array(
284  "respident" => "MCSR"
285  );
286  $a_xml_writer->xmlStartTag("not");
287  $a_xml_writer->xmlElement("varequal", $attrs, $bestindex);
288  $a_xml_writer->xmlEndTag("not");
289  $a_xml_writer->xmlEndTag("conditionvar");
290  // qti displayfeedback
291  $attrs = array(
292  "feedbacktype" => "Response",
293  "linkrefid" => "response_onenotcorrect"
294  );
295  $a_xml_writer->xmlElement("displayfeedback", $attrs);
296  $a_xml_writer->xmlEndTag("respcondition");
297  }
298 
299  $a_xml_writer->xmlEndTag("resprocessing");
300 
301  // PART III: qti itemfeedback
302  foreach ($answers as $index => $answer)
303  {
304  $linkrefid = "response_$index";
305  $attrs = array(
306  "ident" => $linkrefid,
307  "view" => "All"
308  );
309  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
310  // qti flow_mat
311  $a_xml_writer->xmlStartTag("flow_mat");
312  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
313  $this->object->getId(), $index
314  );
315  $this->object->addQTIMaterial($a_xml_writer, $fb);
316  $a_xml_writer->xmlEndTag("flow_mat");
317  $a_xml_writer->xmlEndTag("itemfeedback");
318  }
319  if (strlen($feedback_allcorrect))
320  {
321  $attrs = array(
322  "ident" => "response_allcorrect",
323  "view" => "All"
324  );
325  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
326  // qti flow_mat
327  $a_xml_writer->xmlStartTag("flow_mat");
328  $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
329  $a_xml_writer->xmlEndTag("flow_mat");
330  $a_xml_writer->xmlEndTag("itemfeedback");
331  }
332  if (strlen($feedback_onenotcorrect))
333  {
334  $attrs = array(
335  "ident" => "response_onenotcorrect",
336  "view" => "All"
337  );
338  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
339  // qti flow_mat
340  $a_xml_writer->xmlStartTag("flow_mat");
341  $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
342  $a_xml_writer->xmlEndTag("flow_mat");
343  $a_xml_writer->xmlEndTag("itemfeedback");
344  }
345 
346  $a_xml_writer->xmlEndTag("item");
347  $a_xml_writer->xmlEndTag("questestinterop");
348 
349  $xml = $a_xml_writer->xmlDumpMem(FALSE);
350  if (!$a_include_header)
351  {
352  $pos = strpos($xml, "?>");
353  $xml = substr($xml, $pos + 2);
354  }
355  return $xml;
356  }
357 
358 }
359 
360 ?>
XML writer class.
Class for question exports.
addGeneralMetadata(ilXmlWriter $xmlwriter)
xmlHeader()
Writes xml header public.
Class for single choice question exports.
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.
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
const SINGLE_CHOICE_QUESTION_IDENTIFIER