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
148 {
149 $attrs = array(
150 "ident" => $answeritem->getOrder()
151 );
152 $a_xml_writer->xmlStartTag("response_label", $attrs);
153 $a_xml_writer->xmlStartTag("material");
154 $a_xml_writer->xmlElement("mattext", NULL, $answeritem->getAnswertext());
155 $a_xml_writer->xmlEndTag("material");
156 $a_xml_writer->xmlEndTag("response_label");
157 }
158 $a_xml_writer->xmlEndTag("render_choice");
159 $a_xml_writer->xmlEndTag("response_str");
160 break;
162
163 $attrs = array(
164 "ident" => "gap_$i",
165 "rcardinality" => "Single"
166 );
167 $a_xml_writer->xmlStartTag("response_str", $attrs);
168 $solution = $this->object->getSuggestedSolution($i);
169 if (count($solution))
170 {
171 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
172 {
173 $attrs = array(
174 "label" => "suggested_solution"
175 );
176 $a_xml_writer->xmlStartTag("material", $attrs);
177 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
178 if (strcmp($matches[1], "") != 0)
179 {
180 $intlink = $solution["internal_link"];
181 }
182 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
183 $a_xml_writer->xmlEndTag("material");
184 }
185 }
186 $attrs = array(
187 "fibtype" => "String",
188 "prompt" => "Box",
189 "columns" => $gap->getMaxWidth(),
190 "maxchars" => $gap->getGapSize()
191 );
192 $a_xml_writer->xmlStartTag("render_fib", $attrs);
193 $a_xml_writer->xmlEndTag("render_fib");
194 $a_xml_writer->xmlEndTag("response_str");
195 break;
197
198 $attrs = array(
199 "ident" => "gap_$i",
200 "numtype" => "Decimal",
201 "rcardinality" => "Single"
202 );
203 $a_xml_writer->xmlStartTag("response_num", $attrs);
204 $solution = $this->object->getSuggestedSolution($i);
205 if (count($solution))
206 {
207 if (preg_match("/il_(\d*?)_(\w+)_(\d+)/", $solution["internal_link"], $matches))
208 {
209 $attrs = array(
210 "label" => "suggested_solution"
211 );
212 $a_xml_writer->xmlStartTag("material", $attrs);
213 $intlink = "il_" . IL_INST_ID . "_" . $matches[2] . "_" . $matches[3];
214 if (strcmp($matches[1], "") != 0)
215 {
216 $intlink = $solution["internal_link"];
217 }
218 $a_xml_writer->xmlElement("mattext", NULL, $intlink);
219 $a_xml_writer->xmlEndTag("material");
220 }
221 }
222 $answeritem = $gap->getItem(0);
223 $attrs = array(
224 "fibtype" => "Decimal",
225 "prompt" => "Box",
226 "columns" => $gap->getMaxWidth(),
227 "maxchars" => $gap->getGapSize()
228 );
229 if (is_object($answeritem))
230 {
231 if ($eval->e($answeritem->getLowerBound()) !== FALSE)
232 {
233 $attrs["minnumber"] = $answeritem->getLowerBound();
234 }
235 if ($eval->e($answeritem->getUpperBound()) !== FALSE)
236 {
237 $attrs["maxnumber"] = $answeritem->getUpperBound();
238 }
239 }
240 $a_xml_writer->xmlStartTag("render_fib", $attrs);
241 $a_xml_writer->xmlEndTag("render_fib");
242 $a_xml_writer->xmlEndTag("response_num");
243 break;
244 }
245 }
246 }
247 $a_xml_writer->xmlEndTag("flow");
248 $a_xml_writer->xmlEndTag("presentation");
249
250
251 $a_xml_writer->xmlStartTag("resprocessing");
252 $a_xml_writer->xmlStartTag("outcomes");
253 $a_xml_writer->xmlStartTag("decvar");
254 $a_xml_writer->xmlEndTag("decvar");
255 $a_xml_writer->xmlEndTag("outcomes");
256
257
258 for ($i = 0; $i < $this->object->getGapCount(); $i++)
259 {
260 $gap = $this->object->getGap($i);
261 switch ($gap->getType())
262 {
265 {
266 $attrs = array(
267 "continue" => "Yes"
268 );
269 $a_xml_writer->xmlStartTag("respcondition", $attrs);
270
271 $a_xml_writer->xmlStartTag("conditionvar");
272
273 $attrs = array(
274 "respident" => "gap_$i"
275 );
276 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
277 $a_xml_writer->xmlEndTag("conditionvar");
278
279 $attrs = array(
280 "action" => "Add"
281 );
282 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
283
284 $linkrefid = "";
285 $linkrefid = "$i" . "_Response_" . $answer->getOrder();
286 $attrs = array(
287 "feedbacktype" => "Response",
288 "linkrefid" => $linkrefid
289 );
290 $a_xml_writer->xmlElement("displayfeedback", $attrs);
291 $a_xml_writer->xmlEndTag("respcondition");
292 }
293 break;
296 {
297 $attrs = array(
298 "continue" => "Yes"
299 );
300 $a_xml_writer->xmlStartTag("respcondition", $attrs);
301
302 $a_xml_writer->xmlStartTag("conditionvar");
303 $attrs = array(
304 "respident" => "gap_$i"
305 );
306 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
307 $a_xml_writer->xmlEndTag("conditionvar");
308
309 $attrs = array(
310 "action" => "Add"
311 );
312 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
313
314 $linkrefid = "$i" . "_Response_" . $answer->getOrder();
315 $attrs = array(
316 "feedbacktype" => "Response",
317 "linkrefid" => $linkrefid
318 );
319 $a_xml_writer->xmlElement("displayfeedback", $attrs);
320 $a_xml_writer->xmlEndTag("respcondition");
321 }
322 break;
325 {
326 $attrs = array(
327 "continue" => "Yes"
328 );
329 $a_xml_writer->xmlStartTag("respcondition", $attrs);
330
331 $a_xml_writer->xmlStartTag("conditionvar");
332 $attrs = array(
333 "respident" => "gap_$i"
334 );
335 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
336 $a_xml_writer->xmlEndTag("conditionvar");
337
338 $attrs = array(
339 "action" => "Add"
340 );
341 $a_xml_writer->xmlElement("setvar", $attrs, $answer->getPoints());
342
343 $linkrefid = "$i" . "_Response_" . $answer->getOrder();
344 $attrs = array(
345 "feedbacktype" => "Response",
346 "linkrefid" => $linkrefid
347 );
348 $a_xml_writer->xmlElement("displayfeedback", $attrs);
349 $a_xml_writer->xmlEndTag("respcondition");
350 }
351 break;
352 }
353 }
354
355 $feedback_allcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
356 $this->object->getId(), true
357 );
358 if (strlen($feedback_allcorrect))
359 {
360 $attrs = array(
361 "continue" => "Yes"
362 );
363 $a_xml_writer->xmlStartTag("respcondition", $attrs);
364
365 $a_xml_writer->xmlStartTag("conditionvar");
366
367 for ($i = 0; $i < $this->object->getGapCount(); $i++)
368 {
369 $gap = $this->object->getGap($i);
370 $indexes = $gap->getBestSolutionIndexes();
371 if ($i > 0)
372 {
373 $a_xml_writer->xmlStartTag("and");
374 }
375 switch ($gap->getType())
376 {
378 $k = 0;
379 foreach ($indexes as $key)
380 {
381 if ($k > 0)
382 {
383 $a_xml_writer->xmlStartTag("or");
384 }
385 $attrs = array(
386 "respident" => "gap_$i"
387 );
388 $answer = $gap->getItem($key);
389 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
390 if ($k > 0)
391 {
392 $a_xml_writer->xmlEndTag("or");
393 }
394 $k++;
395 }
396 break;
398 $k = 0;
399 foreach ($indexes as $key)
400 {
401 if ($k > 0)
402 {
403 $a_xml_writer->xmlStartTag("or");
404 }
405 $attrs = array(
406 "respident" => "gap_$i"
407 );
408 $answer = $gap->getItem($key);
409 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
410 if ($k > 0)
411 {
412 $a_xml_writer->xmlEndTag("or");
413 }
414 $k++;
415 }
416 break;
418 $k = 0;
419 foreach ($indexes as $key)
420 {
421 if ($k > 0)
422 {
423 $a_xml_writer->xmlStartTag("or");
424 }
425 $attrs = array(
426 "respident" => "gap_$i"
427 );
428 $answer = $gap->getItem($key);
429 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
430 if ($k > 0)
431 {
432 $a_xml_writer->xmlEndTag("or");
433 }
434 $k++;
435 }
436 break;
437 }
438 if ($i > 0)
439 {
440 $a_xml_writer->xmlEndTag("and");
441 }
442 }
443 $a_xml_writer->xmlEndTag("conditionvar");
444
445 $attrs = array(
446 "feedbacktype" => "Response",
447 "linkrefid" => "response_allcorrect"
448 );
449 $a_xml_writer->xmlElement("displayfeedback", $attrs);
450 $a_xml_writer->xmlEndTag("respcondition");
451 }
452 $feedback_onenotcorrect = $this->object->feedbackOBJ->getGenericFeedbackExportPresentation(
453 $this->object->getId(), false
454 );
455 if (strlen($feedback_onenotcorrect))
456 {
457 $attrs = array(
458 "continue" => "Yes"
459 );
460 $a_xml_writer->xmlStartTag("respcondition", $attrs);
461
462 $a_xml_writer->xmlStartTag("conditionvar");
463
464 $a_xml_writer->xmlStartTag("not");
465 for ($i = 0; $i < $this->object->getGapCount(); $i++)
466 {
467 $gap = $this->object->getGap($i);
468 $indexes = $gap->getBestSolutionIndexes();
469 if ($i > 0)
470 {
471 $a_xml_writer->xmlStartTag("and");
472 }
473 switch ($gap->getType())
474 {
476 $k = 0;
477 foreach ($indexes as $key)
478 {
479 if ($k > 0)
480 {
481 $a_xml_writer->xmlStartTag("or");
482 }
483 $attrs = array(
484 "respident" => "gap_$i"
485 );
486 $answer = $gap->getItem($key);
487 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
488 if ($k > 0)
489 {
490 $a_xml_writer->xmlEndTag("or");
491 }
492 $k++;
493 }
494 break;
496 $k = 0;
497 foreach ($indexes as $key)
498 {
499 if ($k > 0)
500 {
501 $a_xml_writer->xmlStartTag("or");
502 }
503 $attrs = array(
504 "respident" => "gap_$i"
505 );
506 $answer = $gap->getItem($key);
507 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
508 if ($k > 0)
509 {
510 $a_xml_writer->xmlEndTag("or");
511 }
512 $k++;
513 }
514 break;
516 $k = 0;
517 foreach ($indexes as $key)
518 {
519 if ($k > 0)
520 {
521 $a_xml_writer->xmlStartTag("or");
522 }
523 $attrs = array(
524 "respident" => "gap_$i"
525 );
526 $answer = $gap->getItem($key);
527 $a_xml_writer->xmlElement("varequal", $attrs, $answer->getAnswertext());
528 if ($k > 0)
529 {
530 $a_xml_writer->xmlEndTag("or");
531 }
532 $k++;
533 }
534 break;
535 }
536 if ($i > 0)
537 {
538 $a_xml_writer->xmlEndTag("and");
539 }
540 }
541 $a_xml_writer->xmlEndTag("not");
542 $a_xml_writer->xmlEndTag("conditionvar");
543
544 $attrs = array(
545 "feedbacktype" => "Response",
546 "linkrefid" => "response_onenotcorrect"
547 );
548 $a_xml_writer->xmlElement("displayfeedback", $attrs);
549 $a_xml_writer->xmlEndTag("respcondition");
550 }
551
552 $a_xml_writer->xmlEndTag("resprocessing");
553
554
555 for ($i = 0; $i < $this->object->getGapCount(); $i++)
556 {
557 $gap = $this->object->getGap($i);
558 switch ($gap->getType())
559 {
561 break;
563 break;
565 break;
566 }
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588 $attrs = array(
589 "ident" => $i,
590 "view" => "All"
591 );
592 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
593
594 $a_xml_writer->xmlStartTag("flow_mat");
595
596
597
598 $fb = $this->object->feedbackOBJ->getSpecificAnswerFeedbackExportPresentation(
599 $this->object->getId(), $i
600 );
601 $this->object->addQTIMaterial($a_xml_writer, $fb);
602 $a_xml_writer->xmlEndTag("flow_mat");
603 $a_xml_writer->xmlEndTag("itemfeedback");
604 }
605
606 if (strlen($feedback_allcorrect))
607 {
608 $attrs = array(
609 "ident" => "response_allcorrect",
610 "view" => "All"
611 );
612 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
613
614 $a_xml_writer->xmlStartTag("flow_mat");
615 $this->object->addQTIMaterial($a_xml_writer, $feedback_allcorrect);
616 $a_xml_writer->xmlEndTag("flow_mat");
617 $a_xml_writer->xmlEndTag("itemfeedback");
618 }
619 if (strlen($feedback_onenotcorrect))
620 {
621 $attrs = array(
622 "ident" => "response_onenotcorrect",
623 "view" => "All"
624 );
625 $a_xml_writer->xmlStartTag("itemfeedback", $attrs);
626
627 $a_xml_writer->xmlStartTag("flow_mat");
628 $this->object->addQTIMaterial($a_xml_writer, $feedback_onenotcorrect);
629 $a_xml_writer->xmlEndTag("flow_mat");
630 $a_xml_writer->xmlEndTag("itemfeedback");
631 }
632
633 $a_xml_writer->xmlEndTag("item");
634 $a_xml_writer->xmlEndTag("questestinterop");
635
636 $xml = $a_xml_writer->xmlDumpMem(FALSE);
637 if (!$a_include_header)
638 {
639 $pos = strpos($xml, "?>");
640 $xml = substr($xml, $pos + 2);
641 }
642 return $xml;
643 }
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.