ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.assMultipleChoiceExport.php
Go to the documentation of this file.
1 <?php
2 
30 {
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, MULTIPLE_CHOICE_QUESTION_IDENTIFIER);
63  $a_xml_writer->xmlEndTag("qtimetadatafield");
64  $a_xml_writer->xmlStartTag("qtimetadatafield");
65  $a_xml_writer->xmlElement("fieldlabel", null, "AUTHOR");
66  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getAuthor());
67  $a_xml_writer->xmlEndTag("qtimetadatafield");
68 
69  // additional content editing information
70  $this->addAdditionalContentEditingModeInformation($a_xml_writer);
71  $this->addGeneralMetadata($a_xml_writer);
72 
73  $a_xml_writer->xmlStartTag("qtimetadatafield");
74  $a_xml_writer->xmlElement("fieldlabel", null, "thumb_size");
75  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getThumbSize());
76  $a_xml_writer->xmlEndTag("qtimetadatafield");
77 
78  $a_xml_writer->xmlStartTag("qtimetadatafield");
79  $a_xml_writer->xmlElement("fieldlabel", null, "feedback_setting");
80  $a_xml_writer->xmlElement("fieldentry", null, $this->object->getSpecificFeedbackSetting());
81  $a_xml_writer->xmlEndTag("qtimetadatafield");
82 
83  $this->addQtiMetaDataField($a_xml_writer, 'singleline', $this->object->isSingleline() ? 1 : 0);
84 
85  $a_xml_writer->xmlEndTag("qtimetadata");
86  $a_xml_writer->xmlEndTag("itemmetadata");
87 
88  // PART I: qti presentation
89  $attrs = [
90  "label" => $this->object->getTitle()
91  ];
92  $a_xml_writer->xmlStartTag("presentation", $attrs);
93  // add flow to presentation
94  $a_xml_writer->xmlStartTag("flow");
95  // add material with question text to presentation
96  $this->addQTIMaterial($a_xml_writer, $this->object->getQuestion());
97  // add answers to presentation
98  $attrs = [
99  "ident" => "MCMR",
100  "rcardinality" => "Multiple"
101  ];
102  $a_xml_writer->xmlStartTag("response_lid", $attrs);
103  $a_xml_writer = $this->addSuggestedSolution($a_xml_writer);
104  // shuffle output and max choice
105  $attrs = ['shuffle' => $this->object->getShuffle() ? 'Yes' : 'No'];
106  if ($this->object->getSelectionLimit()) {
107  $attrs['minnumber'] = '0';
108  $attrs['maxnumber'] = (string) $this->object->getSelectionLimit();
109  }
110  $a_xml_writer->xmlStartTag("render_choice", $attrs);
111  $answers = &$this->object->getAnswers();
112  $akeys = array_keys($answers);
113  if ($this->object->getShuffle() && $a_shuffle) {
114  $akeys = shuffle($akeys);
115  }
116  // add answers
117  foreach ($akeys as $index) {
118  $answer = $answers[$index];
119  $attrs = [
120  "ident" => $index
121  ];
122  $a_xml_writer->xmlStartTag("response_label", $attrs);
123 
124  if ($answer->hasImage()) {
125  $this->addQTIMaterial($a_xml_writer, $answer->getAnswertext(), false, false);
126  $imagetype = "image/jpeg";
127  if (preg_match("/.*\.(png|gif)$/", $answer->getImage(), $matches)) {
128  $imagetype = "image/" . $matches[1];
129  }
130  if ($force_image_references) {
131  $attrs = [
132  "imagtype" => $imagetype,
133  "label" => $answer->getImage(),
134  "uri" => $this->object->getImagePathWeb() . $answer->getImage()
135  ];
136  $a_xml_writer->xmlElement("matimage", $attrs);
137  } else {
138  $imagepath = $this->object->getImagePath() . $answer->getImage();
139  $fh = @fopen($imagepath, "rb");
140  if ($fh != false) {
141  $imagefile = fread($fh, filesize($imagepath));
142  fclose($fh);
143  $base64 = base64_encode($imagefile);
144  $attrs = [
145  "imagtype" => $imagetype,
146  "label" => $answer->getImage(),
147  "embedded" => "base64"
148  ];
149  $a_xml_writer->xmlElement("matimage", $attrs, $base64, false, false);
150  }
151  }
152  $a_xml_writer->xmlEndTag("material");
153  } else {
154  $this->addQTIMaterial($a_xml_writer, $answer->getAnswertext());
155  }
156  $a_xml_writer->xmlEndTag("response_label");
157  }
158  $a_xml_writer->xmlEndTag("render_choice");
159  $a_xml_writer->xmlEndTag("response_lid");
160  $a_xml_writer->xmlEndTag("flow");
161  $a_xml_writer->xmlEndTag("presentation");
162 
163  // PART II: qti resprocessing
164  $a_xml_writer->xmlStartTag("resprocessing");
165  $a_xml_writer->xmlStartTag("outcomes");
166  $a_xml_writer->xmlStartTag("decvar");
167  $a_xml_writer->xmlEndTag("decvar");
168  $a_xml_writer->xmlEndTag("outcomes");
169  // add response conditions
170  foreach ($answers as $index => $answer) {
171  $attrs = [
172  "continue" => "Yes"
173  ];
174  $a_xml_writer->xmlStartTag("respcondition", $attrs);
175  // qti conditionvar
176  $a_xml_writer->xmlStartTag("conditionvar");
177  $attrs = [
178  "respident" => "MCMR"
179  ];
180  $a_xml_writer->xmlElement("varequal", $attrs, $index);
181  $a_xml_writer->xmlEndTag("conditionvar");
182  // qti setvar
183  $attrs = [
184  "action" => "Add"
185  ];
186  $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
187  // qti displayfeedback
188  $linkrefid = "response_$index";
189  $attrs = [
190  "feedbacktype" => "Response",
191  "linkrefid" => $linkrefid
192  ];
193  $a_xml_writer->xmlElement("displayfeedback", $attrs);
194  $a_xml_writer->xmlEndTag("respcondition");
195  $attrs = [
196  "continue" => "Yes"
197  ];
198  $a_xml_writer->xmlStartTag("respcondition", $attrs);
199 
200  // qti conditionvar
201  $a_xml_writer->xmlStartTag("conditionvar");
202  $attrs = [
203  "respident" => "MCMR"
204  ];
205  $a_xml_writer->xmlStartTag("not");
206  $a_xml_writer->xmlElement("varequal", $attrs, $index);
207  $a_xml_writer->xmlEndTag("not");
208  $a_xml_writer->xmlEndTag("conditionvar");
209  // qti setvar
210  $attrs = [
211  "action" => "Add"
212  ];
213  $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPointsUnchecked());
214  $a_xml_writer->xmlEndTag("respcondition");
215  }
216  $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
217  $this->object->getId(),
218  true
219  );
220  if (strlen($feedback_allcorrect)) {
221  $attrs = [
222  "continue" => "Yes"
223  ];
224  $a_xml_writer->xmlStartTag("respcondition", $attrs);
225  // qti conditionvar
226  $a_xml_writer->xmlStartTag("conditionvar");
227  foreach ($answers as $index => $answer) {
228  if ($answer->getPointsChecked() < $answer->getPointsUnchecked()) {
229  $a_xml_writer->xmlStartTag("not");
230  }
231  $attrs = [
232  "respident" => "MCMR"
233  ];
234  $a_xml_writer->xmlElement("varequal", $attrs, $index);
235  if ($answer->getPointsChecked() < $answer->getPointsUnchecked()) {
236  $a_xml_writer->xmlEndTag("not");
237  }
238  }
239  $a_xml_writer->xmlEndTag("conditionvar");
240  // qti displayfeedback
241  $attrs = [
242  "feedbacktype" => "Response",
243  "linkrefid" => "response_allcorrect"
244  ];
245  $a_xml_writer->xmlElement("displayfeedback", $attrs);
246  $a_xml_writer->xmlEndTag("respcondition");
247  }
248  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
249  $this->object->getId(),
250  false
251  );
252  if (strlen($feedback_onenotcorrect)) {
253  $attrs = [
254  "continue" => "Yes"
255  ];
256  $a_xml_writer->xmlStartTag("respcondition", $attrs);
257  // qti conditionvar
258  $a_xml_writer->xmlStartTag("conditionvar");
259  foreach ($answers as $index => $answer) {
260  if ($index > 0) {
261  $a_xml_writer->xmlStartTag("or");
262  }
263  if ($answer->getPointsChecked() >= $answer->getPointsUnchecked()) {
264  $a_xml_writer->xmlStartTag("not");
265  }
266  $attrs = [
267  "respident" => "MCMR"
268  ];
269  $a_xml_writer->xmlElement("varequal", $attrs, $index);
270  if ($answer->getPointsChecked() >= $answer->getPointsUnchecked()) {
271  $a_xml_writer->xmlEndTag("not");
272  }
273  if ($index > 0) {
274  $a_xml_writer->xmlEndTag("or");
275  }
276  }
277  $a_xml_writer->xmlEndTag("conditionvar");
278  // qti displayfeedback
279  $attrs = [
280  "feedbacktype" => "Response",
281  "linkrefid" => "response_onenotcorrect"
282  ];
283  $a_xml_writer->xmlElement("displayfeedback", $attrs);
284  $a_xml_writer->xmlEndTag("respcondition");
285  }
286  $a_xml_writer->xmlEndTag("resprocessing");
287 
288  // PART III: qti itemfeedback
289  foreach ($answers as $index => $answer) {
290  $linkrefid = "response_$index";
291  $attrs = [
292  "ident" => $linkrefid,
293  "view" => "All"
294  ];
295  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
296  // qti flow_mat
297  $a_xml_writer->xmlStartTag("flow_mat");
298  $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
299  $this->object->getId(),
300  0,
301  $index
302  );
303  $this->addQTIMaterial($a_xml_writer, $fb);
304  $a_xml_writer->xmlEndTag("flow_mat");
305  $a_xml_writer->xmlEndTag("itemfeedback");
306  }
307  if (strlen($feedback_allcorrect)) {
308  $attrs = [
309  "ident" => "response_allcorrect",
310  "view" => "All"
311  ];
312  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
313  // qti flow_mat
314  $a_xml_writer->xmlStartTag("flow_mat");
315  $this->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
316  $a_xml_writer->xmlEndTag("flow_mat");
317  $a_xml_writer->xmlEndTag("itemfeedback");
318  }
319  if (strlen($feedback_onenotcorrect)) {
320  $attrs = [
321  "ident" => "response_onenotcorrect",
322  "view" => "All"
323  ];
324  $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
325  // qti flow_mat
326  $a_xml_writer->xmlStartTag("flow_mat");
327  $this->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
328  $a_xml_writer->xmlEndTag("flow_mat");
329  $a_xml_writer->xmlEndTag("itemfeedback");
330  }
331 
332  $a_xml_writer = $this->addSolutionHints($a_xml_writer);
333 
334  $a_xml_writer->xmlEndTag("item");
335  $a_xml_writer->xmlEndTag("questestinterop");
336 
337  $xml = $a_xml_writer->xmlDumpMem(false);
338  if (!$a_include_header) {
339  $pos = strpos($xml, "?>");
340  $xml = substr($xml, $pos + 2);
341  }
342  return $xml;
343  }
344 }
const MULTIPLE_CHOICE_QUESTION_IDENTIFIER
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)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class for question exports.
addGeneralMetadata(ilXmlWriter $xmlwriter)
addQtiMetaDataField(ilXmlWriter $a_xml_writer, $fieldLabel, $fieldValue)
adds a qti meta data field with given name and value to the passed xml writer (xml writer must be in ...
global $DIC
Definition: feed.php:28
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)
addSolutionHints(ilXmlWriter $writer)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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...