Returns a QTI xml representation of the question.
Returns a QTI xml representation of the question and sets the internal domxml variable with the DOM XML representation of the QTI xml representation
27 {
28 global $ilias;
29
30 include_once "./Services/Math/classes/class.EvalMath.php";
32 $eval->suppress_errors = TRUE;
33 include_once("./Services/Xml/classes/class.ilXmlWriter.php");
35
37 $a_xml_writer->xmlStartTag("questestinterop");
38 $attrs = array(
39 "ident" => "il_".IL_INST_ID."_qst_".$this->object->getId(),
40 "title" => $this->object->getTitle(),
41 "maxattempts" => $this->object->getNrOfTries()
42 );
43 $a_xml_writer->xmlStartTag("item", $attrs);
44
45 $a_xml_writer->xmlElement("qticomment", NULL, $this->object->getComment());
46
47 $workingtime = $this->object->getEstimatedWorkingTime();
48 $duration = sprintf("P0Y0M0DT%dH%dM%dS", $workingtime["h"], $workingtime["m"], $workingtime["s"]);
49 $a_xml_writer->xmlElement("duration", NULL, $duration);
50
51 $a_xml_writer->xmlStartTag("itemmetadata");
52 $a_xml_writer->xmlStartTag("qtimetadata");
53 $a_xml_writer->xmlStartTag("qtimetadatafield");
54 $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
55 $a_xml_writer->xmlElement("fieldentry", NULL, $ilias->getSetting("ilias_version"));
56 $a_xml_writer->xmlEndTag("qtimetadatafield");
57 $a_xml_writer->xmlStartTag("qtimetadatafield");
58 $a_xml_writer->xmlElement("fieldlabel", NULL, "QUESTIONTYPE");
60 $a_xml_writer->xmlEndTag("qtimetadatafield");
61 $a_xml_writer->xmlStartTag("qtimetadatafield");
62 $a_xml_writer->xmlElement("fieldlabel", NULL, "AUTHOR");
63 $a_xml_writer->xmlElement("fieldentry", NULL, $this->object->getAuthor());
64 $a_xml_writer->xmlEndTag("qtimetadatafield");
65
66
69
70 $a_xml_writer->xmlStartTag("qtimetadatafield");
71 $a_xml_writer->xmlElement("fieldlabel", NULL, "textgaprating");
72 $a_xml_writer->xmlElement("fieldentry", NULL, $this->object->getTextgapRating());
73 $a_xml_writer->xmlEndTag("qtimetadatafield");
74
75 $a_xml_writer->xmlStartTag("qtimetadatafield");
76 $a_xml_writer->xmlElement("fieldlabel", NULL, "fixedTextLength");
77 $a_xml_writer->xmlElement("fieldentry", NULL, $this->object->getFixedTextLength());
78 $a_xml_writer->xmlEndTag("qtimetadatafield");
79
80 $a_xml_writer->xmlStartTag("qtimetadatafield");
81 $a_xml_writer->xmlElement("fieldlabel", NULL, "identicalScoring");
82 $a_xml_writer->xmlElement("fieldentry", NULL, $this->object->getIdenticalScoring());
83 $a_xml_writer->xmlEndTag("qtimetadatafield");
84
85 $a_xml_writer->xmlStartTag("qtimetadatafield");
86 $a_xml_writer->xmlElement("fieldlabel", NULL, "combinations");
87 $a_xml_writer->xmlElement("fieldentry", NULL, base64_encode(json_encode($this->object->getGapCombinations())));
88 $a_xml_writer->xmlEndTag("qtimetadatafield");
89
90 $a_xml_writer->xmlEndTag("qtimetadata");
91 $a_xml_writer->xmlEndTag("itemmetadata");
92
93
94 $attrs = array(
95 "label" => $this->object->getTitle()
96 );
97 $a_xml_writer->xmlStartTag("presentation", $attrs);
98
99 $a_xml_writer->xmlStartTag("flow");
100
101 $questionText = $this->object->getQuestion() ? $this->object->getQuestion() : ' ';
102 $this->object->addQTIMaterial($a_xml_writer, $questionText);
103
104 $text_parts = preg_split("/\[gap.*?\[\/gap\]/", $this->object->getClozeText());
105
106
107 for ($i = 0; $i <= $this->object->getGapCount(); $i++)
108 {
109 $this->object->addQTIMaterial($a_xml_writer, $text_parts[$i]);
110
111 if ($i < $this->object->getGapCount())
112 {
113
114 $gap = $this->object->getGap($i);
115 switch ($gap->getType())
116 {
118
119 $attrs = array(
120 "ident" => "gap_$i",
121 "rcardinality" => "Single"
122 );
123 $a_xml_writer->xmlStartTag("response_str", $attrs);
124 $solution = $this->object->getSuggestedSolution($i);
125 if (count($solution))
126 {
127 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
128 {
129 $attrs = array(
130 "label" => "suggested_solution"
131 );
132 $a_xml_writer->xmlStartTag("material", $attrs);
133 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
134 if (strcmp($matches[1], "") != 0)
135 {
136 $intlink = $solution["internal_link"];
137 }
138 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
139 $a_xml_writer->xmlEndTag("material");
140 }
141 }
142
143 $attrs = array("shuffle" => ($gap->getShuffle() ? "Yes" : "No"));
144 $a_xml_writer->xmlStartTag("render_choice", $attrs);
145
146
147 $shuffleState = $gap->getShuffle();
148 $gap->setShuffle(false);
149 $items = $gap->getItems();
150 $gap->setShuffle($shuffleState);
151 foreach ($items as $answeritem)
152 {
153 $attrs = array(
154 "ident" => $answeritem->getOrder()
155 );
156 $a_xml_writer->xmlStartTag("response_label", $attrs);
157 $a_xml_writer->xmlStartTag("material");
158 $a_xml_writer->xmlElement("mattext", NULL, $answeritem->getAnswertext());
159 $a_xml_writer->xmlEndTag("material");
160 $a_xml_writer->xmlEndTag("response_label");
161 }
162 $a_xml_writer->xmlEndTag("render_choice");
163 $a_xml_writer->xmlEndTag("response_str");
164 break;
166
167 $attrs = array(
168 "ident" => "gap_$i",
169 "rcardinality" => "Single"
170 );
171 $a_xml_writer->xmlStartTag("response_str", $attrs);
172 $solution = $this->object->getSuggestedSolution($i);
173 if (count($solution))
174 {
175 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
176 {
177 $attrs = array(
178 "label" => "suggested_solution"
179 );
180 $a_xml_writer->xmlStartTag("material", $attrs);
181 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
182 if (strcmp($matches[1], "") != 0)
183 {
184 $intlink = $solution["internal_link"];
185 }
186 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
187 $a_xml_writer->xmlEndTag("material");
188 }
189 }
190 $attrs = array(
191 "fibtype" => "String",
192 "prompt" => "Box",
193 "columns" => $gap->getMaxWidth(),
194 "maxchars" => $gap->getGapSize()
195 );
196 $a_xml_writer->xmlStartTag("render_fib", $attrs);
197 $a_xml_writer->xmlEndTag("render_fib");
198 $a_xml_writer->xmlEndTag("response_str");
199 break;
201
202 $attrs = array(
203 "ident" => "gap_$i",
204 "numtype" => "Decimal",
205 "rcardinality" => "Single"
206 );
207 $a_xml_writer->xmlStartTag("response_num", $attrs);
208 $solution = $this->object->getSuggestedSolution($i);
209 if (count($solution))
210 {
211 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
212 {
213 $attrs = array(
214 "label" => "suggested_solution"
215 );
216 $a_xml_writer->xmlStartTag("material", $attrs);
217 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
218 if (strcmp($matches[1], "") != 0)
219 {
220 $intlink = $solution["internal_link"];
221 }
222 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
223 $a_xml_writer->xmlEndTag("material");
224 }
225 }
226 $answeritem = $gap->getItem(0);
227 $attrs = array(
228 "fibtype" => "Decimal",
229 "prompt" => "Box",
230 "columns" => $gap->getMaxWidth(),
231 "maxchars" => $gap->getGapSize()
232 );
233 if (is_object($answeritem))
234 {
235 if ($eval->e($answeritem->getLowerBound()) !== FALSE)
236 {
237 $attrs["minnumber"] = $answeritem->getLowerBound();
238 }
239 if ($eval->e($answeritem->getUpperBound()) !== FALSE)
240 {
241 $attrs["maxnumber"] = $answeritem->getUpperBound();
242 }
243 }
244 $a_xml_writer->xmlStartTag("render_fib", $attrs);
245 $a_xml_writer->xmlEndTag("render_fib");
246 $a_xml_writer->xmlEndTag("response_num");
247 break;
248 }
249 }
250 }
251 $a_xml_writer->xmlEndTag("flow");
252 $a_xml_writer->xmlEndTag("presentation");
253
254
255 $a_xml_writer->xmlStartTag("resprocessing");
256 $a_xml_writer->xmlStartTag("outcomes");
257 $a_xml_writer->xmlStartTag("decvar");
258 $a_xml_writer->xmlEndTag("decvar");
259 $a_xml_writer->xmlEndTag("outcomes");
260
261
262 for ($i = 0; $i < $this->object->getGapCount(); $i++)
263 {
264 $gap = $this->object->getGap($i);
265 switch ($gap->getType())
266 {
268 $shuffleState = $gap->getShuffle();
269 $gap->setShuffle(false);
270 $items = $gap->getItems();
271 $gap->setShuffle($shuffleState);
272 foreach ($items as $answer)
273 {
274 $attrs = array(
275 "continue" => "Yes"
276 );
277 $a_xml_writer->xmlStartTag("respcondition", $attrs);
278
279 $a_xml_writer->xmlStartTag("conditionvar");
280
281 $attrs = array(
282 "respident" => "gap_$i"
283 );
284 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
285 $a_xml_writer->xmlEndTag("conditionvar");
286
287 $attrs = array(
288 "action" => "Add"
289 );
290 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
291
292 $linkrefid = "";
293 $linkrefid = "$i" . "_Response_" . $answer->getOrder();
294 $attrs = array(
295 "feedbacktype" => "Response",
296 "linkrefid" => $linkrefid
297 );
298 $a_xml_writer->xmlElement("displayfeedback", $attrs);
299 $a_xml_writer->xmlEndTag("respcondition");
300 }
301 break;
303 foreach ($gap->getItems() as $answer)
304 {
305 $attrs = array(
306 "continue" => "Yes"
307 );
308 $a_xml_writer->xmlStartTag("respcondition", $attrs);
309
310 $a_xml_writer->xmlStartTag("conditionvar");
311 $attrs = array(
312 "respident" => "gap_$i"
313 );
314 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
315 $a_xml_writer->xmlEndTag("conditionvar");
316
317 $attrs = array(
318 "action" => "Add"
319 );
320 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
321
322 $linkrefid = "$i" . "_Response_" . $answer->getOrder();
323 $attrs = array(
324 "feedbacktype" => "Response",
325 "linkrefid" => $linkrefid
326 );
327 $a_xml_writer->xmlElement("displayfeedback", $attrs);
328 $a_xml_writer->xmlEndTag("respcondition");
329 }
330 break;
332 foreach ($gap->getItems() as $answer)
333 {
334 $attrs = array(
335 "continue" => "Yes"
336 );
337 $a_xml_writer->xmlStartTag("respcondition", $attrs);
338
339 $a_xml_writer->xmlStartTag("conditionvar");
340 $attrs = array(
341 "respident" => "gap_$i"
342 );
343 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
344 $a_xml_writer->xmlEndTag("conditionvar");
345
346 $attrs = array(
347 "action" => "Add"
348 );
349 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
350
351 $linkrefid = "$i" . "_Response_" . $answer->getOrder();
352 $attrs = array(
353 "feedbacktype" => "Response",
354 "linkrefid" => $linkrefid
355 );
356 $a_xml_writer->xmlElement("displayfeedback", $attrs);
357 $a_xml_writer->xmlEndTag("respcondition");
358 }
359 break;
360 }
361 }
362
363 $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
364 $this->object->getId(), true
365 );
366 if (strlen($feedback_allcorrect))
367 {
368 $attrs = array(
369 "continue" => "Yes"
370 );
371 $a_xml_writer->xmlStartTag("respcondition", $attrs);
372
373 $a_xml_writer->xmlStartTag("conditionvar");
374
375 for ($i = 0; $i < $this->object->getGapCount(); $i++)
376 {
377 $gap = $this->object->getGap($i);
378 $indexes = $gap->getBestSolutionIndexes();
379 if ($i > 0)
380 {
381 $a_xml_writer->xmlStartTag("and");
382 }
383 switch ($gap->getType())
384 {
386 $k = 0;
387 foreach ($indexes as $key)
388 {
389 if ($k > 0)
390 {
391 $a_xml_writer->xmlStartTag("or");
392 }
393 $attrs = array(
394 "respident" => "gap_$i"
395 );
396 $answer = $gap->getItem($key);
397 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
398 if ($k > 0)
399 {
400 $a_xml_writer->xmlEndTag("or");
401 }
402 $k++;
403 }
404 break;
406 $k = 0;
407 foreach ($indexes as $key)
408 {
409 if ($k > 0)
410 {
411 $a_xml_writer->xmlStartTag("or");
412 }
413 $attrs = array(
414 "respident" => "gap_$i"
415 );
416 $answer = $gap->getItem($key);
417 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
418 if ($k > 0)
419 {
420 $a_xml_writer->xmlEndTag("or");
421 }
422 $k++;
423 }
424 break;
426 $k = 0;
427 foreach ($indexes as $key)
428 {
429 if ($k > 0)
430 {
431 $a_xml_writer->xmlStartTag("or");
432 }
433 $attrs = array(
434 "respident" => "gap_$i"
435 );
436 $answer = $gap->getItem($key);
437 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
438 if ($k > 0)
439 {
440 $a_xml_writer->xmlEndTag("or");
441 }
442 $k++;
443 }
444 break;
445 }
446 if ($i > 0)
447 {
448 $a_xml_writer->xmlEndTag("and");
449 }
450 }
451 $a_xml_writer->xmlEndTag("conditionvar");
452
453 $attrs = array(
454 "feedbacktype" => "Response",
455 "linkrefid" => "response_allcorrect"
456 );
457 $a_xml_writer->xmlElement("displayfeedback", $attrs);
458 $a_xml_writer->xmlEndTag("respcondition");
459 }
460 $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
461 $this->object->getId(), false
462 );
463 if (strlen($feedback_onenotcorrect))
464 {
465 $attrs = array(
466 "continue" => "Yes"
467 );
468 $a_xml_writer->xmlStartTag("respcondition", $attrs);
469
470 $a_xml_writer->xmlStartTag("conditionvar");
471
472 $a_xml_writer->xmlStartTag("not");
473 for ($i = 0; $i < $this->object->getGapCount(); $i++)
474 {
475 $gap = $this->object->getGap($i);
476 $indexes = $gap->getBestSolutionIndexes();
477 if ($i > 0)
478 {
479 $a_xml_writer->xmlStartTag("and");
480 }
481 switch ($gap->getType())
482 {
484 $k = 0;
485 foreach ($indexes as $key)
486 {
487 if ($k > 0)
488 {
489 $a_xml_writer->xmlStartTag("or");
490 }
491 $attrs = array(
492 "respident" => "gap_$i"
493 );
494 $answer = $gap->getItem($key);
495 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
496 if ($k > 0)
497 {
498 $a_xml_writer->xmlEndTag("or");
499 }
500 $k++;
501 }
502 break;
504 $k = 0;
505 foreach ($indexes as $key)
506 {
507 if ($k > 0)
508 {
509 $a_xml_writer->xmlStartTag("or");
510 }
511 $attrs = array(
512 "respident" => "gap_$i"
513 );
514 $answer = $gap->getItem($key);
515 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
516 if ($k > 0)
517 {
518 $a_xml_writer->xmlEndTag("or");
519 }
520 $k++;
521 }
522 break;
524 $k = 0;
525 foreach ($indexes as $key)
526 {
527 if ($k > 0)
528 {
529 $a_xml_writer->xmlStartTag("or");
530 }
531 $attrs = array(
532 "respident" => "gap_$i"
533 );
534 $answer = $gap->getItem($key);
535 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
536 if ($k > 0)
537 {
538 $a_xml_writer->xmlEndTag("or");
539 }
540 $k++;
541 }
542 break;
543 }
544 if ($i > 0)
545 {
546 $a_xml_writer->xmlEndTag("and");
547 }
548 }
549 $a_xml_writer->xmlEndTag("not");
550 $a_xml_writer->xmlEndTag("conditionvar");
551
552 $attrs = array(
553 "feedbacktype" => "Response",
554 "linkrefid" => "response_onenotcorrect"
555 );
556 $a_xml_writer->xmlElement("displayfeedback", $attrs);
557 $a_xml_writer->xmlEndTag("respcondition");
558 }
559
560 $a_xml_writer->xmlEndTag("resprocessing");
561
562
563 for ($i = 0; $i < $this->object->getGapCount(); $i++)
564 {
565 $gap = $this->object->getGap($i);
566 switch ($gap->getType())
567 {
569 break;
571 break;
573 break;
574 }
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596 $attrs = array(
597 "ident" => $i,
598 "view" => "All"
599 );
600 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
601
602 $a_xml_writer->xmlStartTag("flow_mat");
603
604
605
606 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
607 $this->object->getId(), $i
608 );
609 $this->object->addQTIMaterial($a_xml_writer, $fb);
610 $a_xml_writer->xmlEndTag("flow_mat");
611 $a_xml_writer->xmlEndTag("itemfeedback");
612 }
613
614 if (strlen($feedback_allcorrect))
615 {
616 $attrs = array(
617 "ident" => "response_allcorrect",
618 "view" => "All"
619 );
620 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
621
622 $a_xml_writer->xmlStartTag("flow_mat");
623 $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
624 $a_xml_writer->xmlEndTag("flow_mat");
625 $a_xml_writer->xmlEndTag("itemfeedback");
626 }
627 if (strlen($feedback_onenotcorrect))
628 {
629 $attrs = array(
630 "ident" => "response_onenotcorrect",
631 "view" => "All"
632 );
633 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
634
635 $a_xml_writer->xmlStartTag("flow_mat");
636 $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
637 $a_xml_writer->xmlEndTag("flow_mat");
638 $a_xml_writer->xmlEndTag("itemfeedback");
639 }
640
641 $a_xml_writer->xmlEndTag("item");
642 $a_xml_writer->xmlEndTag("questestinterop");
643
644 $xml = $a_xml_writer->xmlDumpMem(FALSE);
645 if (!$a_include_header)
646 {
647 $pos = strpos($xml, "?>");
648 $xml = substr($xml, $pos + 2);
649 }
650 return $xml;
651 }
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...
xmlHeader()
Writes xml header @access public.
const CLOZE_TEST_IDENTIFIER
Question identifier constants.
const CLOZE_TEXT
Cloze question constants.