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