ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.assKprimChoiceExport.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 require_once 'Modules/TestQuestionPool/classes/export/qti12/class.assQuestionExport.php';
5 
13 {
17  public $object;
18 
19  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
20  {
21  global $DIC;
22  $ilias = $DIC['ilias'];
23 
24  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
25  $xml = new ilXmlWriter;
26  // set xml header
27  $xml->xmlHeader();
28  $xml->xmlStartTag("questestinterop");
29  $attrs = array(
30  "ident" => "il_" . IL_INST_ID . "_qst_" . $this->object->getId(),
31  "title" => $this->object->getTitle(),
32  "maxattempts" => $this->object->getNrOfTries()
33  );
34  $xml->xmlStartTag("item", $attrs);
35  // add question description
36  $xml->xmlElement("qticomment", null, $this->object->getComment());
37  // add estimated working time
38  $workingtime = $this->object->getEstimatedWorkingTime();
39  $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
40  $xml->xmlElement("duration", null, $duration);
41  // add ILIAS specific metadata
42  $xml->xmlStartTag("itemmetadata");
43  $xml->xmlStartTag("qtimetadata");
44  $xml->xmlStartTag("qtimetadatafield");
45  $xml->xmlElement("fieldlabel", null, "ILIAS_VERSION");
46  $xml->xmlElement("fieldentry", null, $ilias->getSetting("ilias_version"));
47  $xml->xmlEndTag("qtimetadatafield");
48  $xml->xmlStartTag("qtimetadatafield");
49  $xml->xmlElement("fieldlabel", null, "QUESTIONTYPE");
50  $xml->xmlElement("fieldentry", null, KPRIM_CHOICE_QUESTION_IDENTIFIER);
51  $xml->xmlEndTag("qtimetadatafield");
52  $xml->xmlStartTag("qtimetadatafield");
53  $xml->xmlElement("fieldlabel", null, "AUTHOR");
54  $xml->xmlElement("fieldentry", null, $this->object->getAuthor());
55  $xml->xmlEndTag("qtimetadatafield");
56 
57  // additional content editing information
59  $this->addGeneralMetadata($xml);
60 
61  $xml->xmlStartTag("qtimetadatafield");
62  $xml->xmlElement("fieldlabel", null, "answer_type");
63  $xml->xmlElement("fieldentry", null, $this->object->getAnswerType());
64  $xml->xmlEndTag("qtimetadatafield");
65 
66  $xml->xmlStartTag("qtimetadatafield");
67  $xml->xmlElement("fieldlabel", null, "thumb_size");
68  $xml->xmlElement("fieldentry", null, $this->object->getThumbSize());
69  $xml->xmlEndTag("qtimetadatafield");
70 
71  $xml->xmlStartTag("qtimetadatafield");
72  $xml->xmlElement("fieldlabel", null, "option_label_setting");
73  $xml->xmlElement("fieldentry", null, $this->object->getOptionLabel());
74  $xml->xmlEndTag("qtimetadatafield");
75  $xml->xmlStartTag("qtimetadatafield");
76  $xml->xmlElement("fieldlabel", null, "custom_true_option_label");
77  $xml->xmlElement("fieldentry", null, $this->object->getCustomTrueOptionLabel());
78  $xml->xmlEndTag("qtimetadatafield");
79  $xml->xmlStartTag("qtimetadatafield");
80  $xml->xmlElement("fieldlabel", null, "custom_false_option_label");
81  $xml->xmlElement("fieldentry", null, $this->object->getCustomFalseOptionLabel());
82  $xml->xmlEndTag("qtimetadatafield");
83 
84  $xml->xmlStartTag("qtimetadatafield");
85  $xml->xmlElement("fieldlabel", null, "feedback_setting");
86  $xml->xmlElement("fieldentry", null, $this->object->getSpecificFeedbackSetting());
87  $xml->xmlEndTag("qtimetadatafield");
88 
89  $xml->xmlEndTag("qtimetadata");
90  $xml->xmlEndTag("itemmetadata");
91 
92  // PART I: qti presentation
93  $attrs = array(
94  "label" => $this->object->getTitle()
95  );
96  $xml->xmlStartTag("presentation", $attrs);
97  // add flow to presentation
98  $xml->xmlStartTag("flow");
99  // add material with question text to presentation
100  $this->object->addQTIMaterial($xml, $this->object->getQuestion());
101  // add answers to presentation
102  $attrs = array(
103  "ident" => "MCMR",
104  "rcardinality" => "Multiple"
105  );
106  $xml->xmlStartTag("response_lid", $attrs);
107  $solution = $this->object->getSuggestedSolution(0);
108  if (count($solution)) {
109  if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches)) {
110  $xml->xmlStartTag("material");
111  $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
112  if (strcmp($matches[1], "") != 0) {
113  $intlink = $solution["internal_link"];
114  }
115  $attrs = array(
116  "label" => "suggested_solution"
117  );
118  $xml->xmlElement("mattext", $attrs, $intlink);
119  $xml->xmlEndTag("material");
120  }
121  }
122  // shuffle output
123  $attrs = array();
124  if ($this->object->isShuffleAnswersEnabled()) {
125  $attrs = array(
126  "shuffle" => "Yes"
127  );
128  } else {
129  $attrs = array(
130  "shuffle" => "No"
131  );
132  }
133  $xml->xmlStartTag("render_choice", $attrs);
134 
135  // add answers
136  $answers = &$this->object->getAnswers();
137  $akeys = array_keys($answers);
138  foreach ($akeys as $index) {
139  $answer = $this->object->getAnswer($index);
140 
141  $xml->xmlStartTag('response_label', array('ident' => $answer->getPosition()));
142 
143  if (strlen($answer->getImageFile())) {
144  $this->object->addQTIMaterial($xml, $answer->getAnswertext(), false, false);
145  $imagetype = "image/jpeg";
146  if (preg_match("/.*\.(png|gif)$/", $answer->getImageFile(), $matches)) {
147  $imagetype = "image/" . $matches[1];
148  }
149  if ($force_image_references) {
150  $attrs = array(
151  "imagtype" => $imagetype,
152  "label" => $answer->getImageFile(),
153  "uri" => $answer->getImageWebPath()
154  );
155  $xml->xmlElement("matimage", $attrs);
156  } else {
157  $imagepath = $answer->getImageFsPath();
158  $fh = @fopen($imagepath, "rb");
159  if ($fh != false) {
160  $imagefile = fread($fh, filesize($imagepath));
161  fclose($fh);
162  $base64 = base64_encode($imagefile);
163  $attrs = array(
164  "imagtype" => $imagetype,
165  "label" => $answer->getImageFile(),
166  "embedded" => "base64"
167  );
168  $xml->xmlElement("matimage", $attrs, $base64, false, false);
169  }
170  }
171  $xml->xmlEndTag("material");
172  } else {
173  $this->object->addQTIMaterial($xml, $answer->getAnswertext());
174  }
175  $xml->xmlEndTag("response_label");
176  }
177  $xml->xmlEndTag("render_choice");
178  $xml->xmlEndTag("response_lid");
179  $xml->xmlEndTag("flow");
180  $xml->xmlEndTag("presentation");
181 
182  // PART II: qti resprocessing
183 
184  $xml->xmlStartTag('resprocessing');
185 
186  $xml->xmlStartTag('outcomes');
187  $xml->xmlElement('decvar', array(
188  'varname' => 'SCORE', 'vartype' => 'Decimal', 'defaultval' => '0',
189  'minvalue' => $this->getMinPoints(), 'maxvalue' => $this->getMaxPoints()
190  ));
191  $xml->xmlEndTag('outcomes');
192 
193 
194  foreach ($answers as $answer) {
195  $xml->xmlStartTag('respcondition', array('continue' => 'Yes'));
196 
197  $xml->xmlStartTag('conditionvar');
198  $xml->xmlElement('varequal', array('respident' => $answer->getPosition()), $answer->getCorrectness());
199  $xml->xmlEndTag('conditionvar');
200 
201  $xml->xmlElement('displayfeedback', array(
202  'feedbacktype' => 'Response', 'linkrefid' => "response_{$answer->getPosition()}"
203  ));
204 
205  $xml->xmlEndTag('respcondition');
206  }
207 
208  $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
209  $this->object->getId(),
210  true
211  );
212 
213  $xml->xmlStartTag('respcondition', array('continue' => 'Yes'));
214 
215  $xml->xmlStartTag('conditionvar');
216  $xml->xmlStartTag('and');
217  foreach ($answers as $answer) {
218  $xml->xmlElement('varequal', array('respident' => $answer->getPosition()), $answer->getCorrectness());
219  }
220  $xml->xmlEndTag('and');
221  $xml->xmlEndTag('conditionvar');
222 
223  $xml->xmlElement('setvar', array('action' => 'Add'), $this->object->getPoints());
224 
225  if (strlen($feedback_allcorrect)) {
226  $xml->xmlElement('displayfeedback', array('feedbacktype' => 'Response', 'linkrefid' => 'response_allcorrect'));
227  }
228 
229  $xml->xmlEndTag('respcondition');
230 
231  $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
232  $this->object->getId(),
233  false
234  );
235 
236  $xml->xmlStartTag('respcondition', array('continue' => 'Yes'));
237 
238  $xml->xmlStartTag('conditionvar');
239  $xml->xmlStartTag('or');
240  foreach ($answers as $answer) {
241  $xml->xmlStartTag('not');
242  $xml->xmlElement('varequal', array('respident' => $answer->getPosition()), $answer->getCorrectness());
243  $xml->xmlEndTag('not');
244  }
245  $xml->xmlEndTag('or');
246  $xml->xmlEndTag('conditionvar');
247 
248  $xml->xmlElement('setvar', array('action' => 'Add'), 0);
249 
250  if (strlen($feedback_onenotcorrect)) {
251  $xml->xmlElement('displayfeedback', array('feedbacktype' => 'Response', 'linkrefid' => 'response_onenotcorrect'));
252  }
253 
254  $xml->xmlEndTag('respcondition');
255 
256  $xml->xmlEndTag('resprocessing');
257 
258  foreach ($answers as $answer) {
259  $xml->xmlStartTag('itemfeedback', array('ident' => "response_{$answer->getPosition()}", 'view' => 'All'));
260  $xml->xmlStartTag('flow_mat');
261 
262  $this->object->addQTIMaterial($xml, $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
263  $this->object->getId(),
264  0,
265  $answer->getPosition()
266  ));
267 
268  $xml->xmlEndTag('flow_mat');
269  $xml->xmlEndTag('itemfeedback');
270  }
271  if (strlen($feedback_allcorrect)) {
272  $xml->xmlStartTag('itemfeedback', array('ident' => 'response_allcorrect', 'view' => 'All'));
273  $xml->xmlStartTag('flow_mat');
274 
275  $this->object->addQTIMaterial($xml, $feedback_allcorrect);
276 
277  $xml->xmlEndTag('flow_mat');
278  $xml->xmlEndTag('itemfeedback');
279  }
280  if (strlen($feedback_onenotcorrect)) {
281  $xml->xmlStartTag('itemfeedback', array('ident' => 'response_onenotcorrect', 'view' => 'All'));
282  $xml->xmlStartTag('flow_mat');
283 
284  $this->object->addQTIMaterial($xml, $feedback_onenotcorrect);
285 
286  $xml->xmlEndTag('flow_mat');
287  $xml->xmlEndTag('itemfeedback');
288  }
289 
290  $xml->xmlEndTag("item");
291  $xml->xmlEndTag("questestinterop");
292 
293  $xml = $xml->xmlDumpMem(false);
294  if (!$a_include_header) {
295  $pos = strpos($xml, "?>");
296  $xml = substr($xml, $pos + 2);
297  }
298  return $xml;
299  }
300 
301  private function getMinPoints()
302  {
303  if ($this->object->isScorePartialSolutionEnabled()) {
304  return ($this->object->getPoints() / 2);
305  }
306 
307  return 0;
308  }
309 
310  private function getMaxPoints()
311  {
312  return $this->object->getPoints();
313  }
314 }
global $DIC
Definition: saml.php:7
const KPRIM_CHOICE_QUESTION_IDENTIFIER
XML writer class.
Class for question exports.
$index
Definition: metadata.php:60
addGeneralMetadata(ilXmlWriter $xmlwriter)
addAdditionalContentEditingModeInformation(ilXmlWriter $a_xml_writer)
adds a qti meta data field for ilias specific information of "additional content editing mode" (xml w...
toXML($a_include_header=true, $a_include_binary=true, $a_shuffle=false, $test_output=false, $force_image_references=false)