ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilTestExportQTI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 
14 {
15  private $objTest;
16 
17  function __construct(&$tst_obj)
18  {
19  $this->objTest = $tst_obj;
20  }
21 
28  function toXML()
29  {
30  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
31  $a_xml_writer = new ilXmlWriter;
32  // set xml header
33  $a_xml_writer->xmlHeader();
34  $a_xml_writer->xmlSetDtdDef("<!DOCTYPE questestinterop SYSTEM \"ims_qtiasiv1p2p1.dtd\">");
35  $a_xml_writer->xmlStartTag("questestinterop");
36 
37  $attrs = array(
38  "ident" => "il_".IL_INST_ID."_tst_".$this->objTest->getTestId(),
39  "title" => $this->objTest->getTitle()
40  );
41  $a_xml_writer->xmlStartTag("assessment", $attrs);
42  // add qti comment
43  $a_xml_writer->xmlElement("qticomment", NULL, $this->objTest->getDescription());
44 
45  // add qti duration
46  if ($this->objTest->getEnableProcessingTime())
47  {
48  preg_match("/(\d+):(\d+):(\d+)/", $this->objTest->getProcessingTime(), $matches);
49  $a_xml_writer->xmlElement("duration", NULL, sprintf("P0Y0M0DT%dH%dM%dS", $matches[1], $matches[2], $matches[3]));
50  }
51 
52  // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
53  $a_xml_writer->xmlStartTag("qtimetadata");
54  $a_xml_writer->xmlStartTag("qtimetadatafield");
55  $a_xml_writer->xmlElement("fieldlabel", NULL, "ILIAS_VERSION");
56  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->ilias->getSetting("ilias_version"));
57  $a_xml_writer->xmlEndTag("qtimetadatafield");
58 
59  // anonymity
60  $a_xml_writer->xmlStartTag("qtimetadatafield");
61  $a_xml_writer->xmlElement("fieldlabel", NULL, "anonymity");
62  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getAnonymity()));
63  $a_xml_writer->xmlEndTag("qtimetadatafield");
64 
65  // random test
66  $a_xml_writer->xmlStartTag("qtimetadatafield");
67  $a_xml_writer->xmlElement("fieldlabel", NULL, "random_test");
68  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->isRandomTest()));
69  $a_xml_writer->xmlEndTag("qtimetadatafield");
70 
71  // sequence settings
72  $a_xml_writer->xmlStartTag("qtimetadatafield");
73  $a_xml_writer->xmlElement("fieldlabel", NULL, "sequence_settings");
74  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getSequenceSettings());
75  $a_xml_writer->xmlEndTag("qtimetadatafield");
76 
77  // author
78  $a_xml_writer->xmlStartTag("qtimetadatafield");
79  $a_xml_writer->xmlElement("fieldlabel", NULL, "author");
80  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getAuthor());
81  $a_xml_writer->xmlEndTag("qtimetadatafield");
82 
83  // reset processing time
84  $a_xml_writer->xmlStartTag("qtimetadatafield");
85  $a_xml_writer->xmlElement("fieldlabel", NULL, "reset_processing_time");
86  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getResetProcessingTime());
87  $a_xml_writer->xmlEndTag("qtimetadatafield");
88 
89  // count system
90  $a_xml_writer->xmlStartTag("qtimetadatafield");
91  $a_xml_writer->xmlElement("fieldlabel", NULL, "count_system");
92  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getCountSystem());
93  $a_xml_writer->xmlEndTag("qtimetadatafield");
94 
95  // multiple choice scoring
96  $a_xml_writer->xmlStartTag("qtimetadatafield");
97  $a_xml_writer->xmlElement("fieldlabel", NULL, "mc_scoring");
98  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getMCScoring());
99  $a_xml_writer->xmlEndTag("qtimetadatafield");
100 
101  // multiple choice scoring
102  $a_xml_writer->xmlStartTag("qtimetadatafield");
103  $a_xml_writer->xmlElement("fieldlabel", NULL, "score_cutting");
104  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getScoreCutting());
105  $a_xml_writer->xmlEndTag("qtimetadatafield");
106 
107  // multiple choice scoring
108  $a_xml_writer->xmlStartTag("qtimetadatafield");
109  $a_xml_writer->xmlElement("fieldlabel", NULL, "password");
110  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getPassword());
111  $a_xml_writer->xmlEndTag("qtimetadatafield");
112 
113  // allowed users
114  $a_xml_writer->xmlStartTag("qtimetadatafield");
115  $a_xml_writer->xmlElement("fieldlabel", NULL, "allowedUsers");
116  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getAllowedUsers());
117  $a_xml_writer->xmlEndTag("qtimetadatafield");
118 
119  // allowed users time gap
120  $a_xml_writer->xmlStartTag("qtimetadatafield");
121  $a_xml_writer->xmlElement("fieldlabel", NULL, "allowedUsersTimeGap");
122  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getAllowedUsersTimeGap());
123  $a_xml_writer->xmlEndTag("qtimetadatafield");
124 
125  // pass scoring
126  $a_xml_writer->xmlStartTag("qtimetadatafield");
127  $a_xml_writer->xmlElement("fieldlabel", NULL, "pass_scoring");
128  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getPassScoring());
129  $a_xml_writer->xmlEndTag("qtimetadatafield");
130 
131  // score reporting date
132  if ($this->objTest->getReportingDate())
133  {
134  $a_xml_writer->xmlStartTag("qtimetadatafield");
135  $a_xml_writer->xmlElement("fieldlabel", NULL, "reporting_date");
136  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->objTest->getReportingDate(), $matches);
137  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
138  $a_xml_writer->xmlEndTag("qtimetadatafield");
139  }
140  // number of tries
141  $a_xml_writer->xmlStartTag("qtimetadatafield");
142  $a_xml_writer->xmlElement("fieldlabel", NULL, "nr_of_tries");
143  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getNrOfTries()));
144  $a_xml_writer->xmlEndTag("qtimetadatafield");
145 
146  // kiosk
147  $a_xml_writer->xmlStartTag("qtimetadatafield");
148  $a_xml_writer->xmlElement("fieldlabel", NULL, "kiosk");
149  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getKiosk()));
150  $a_xml_writer->xmlEndTag("qtimetadatafield");
151 
152  // use previous answers
153  $a_xml_writer->xmlStartTag("qtimetadatafield");
154  $a_xml_writer->xmlElement("fieldlabel", NULL, "use_previous_answers");
155  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getUsePreviousAnswers());
156  $a_xml_writer->xmlEndTag("qtimetadatafield");
157 
158  // hide title points
159  $a_xml_writer->xmlStartTag("qtimetadatafield");
160  $a_xml_writer->xmlElement("fieldlabel", NULL, "title_output");
161  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getTitleOutput()));
162  $a_xml_writer->xmlEndTag("qtimetadatafield");
163 
164  // random question count
165  $a_xml_writer->xmlStartTag("qtimetadatafield");
166  $a_xml_writer->xmlElement("fieldlabel", NULL, "random_question_count");
167  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getRandomQuestionCount()));
168  $a_xml_writer->xmlEndTag("qtimetadatafield");
169 
170  // results presentation
171  $a_xml_writer->xmlStartTag("qtimetadatafield");
172  $a_xml_writer->xmlElement("fieldlabel", NULL, "results_presentation");
173  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getResultsPresentation()));
174  $a_xml_writer->xmlEndTag("qtimetadatafield");
175 
176  // solution details
177  $a_xml_writer->xmlStartTag("qtimetadatafield");
178  $a_xml_writer->xmlElement("fieldlabel", NULL, "show_summary");
179  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getListOfQuestionsSettings()));
180  $a_xml_writer->xmlEndTag("qtimetadatafield");
181 
182  // solution details
183  $a_xml_writer->xmlStartTag("qtimetadatafield");
184  $a_xml_writer->xmlElement("fieldlabel", NULL, "score_reporting");
185  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getScoreReporting()));
186  $a_xml_writer->xmlEndTag("qtimetadatafield");
187 
188  // solution details
189  $a_xml_writer->xmlStartTag("qtimetadatafield");
190  $a_xml_writer->xmlElement("fieldlabel", NULL, "instant_verification");
191  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getInstantFeedbackSolution()));
192  $a_xml_writer->xmlEndTag("qtimetadatafield");
193 
194  // answer specific feedback
195  $a_xml_writer->xmlStartTag("qtimetadatafield");
196  $a_xml_writer->xmlElement("fieldlabel", NULL, "answer_feedback");
197  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getAnswerFeedback()));
198  $a_xml_writer->xmlEndTag("qtimetadatafield");
199 
200  // answer specific feedback of reached points
201  $a_xml_writer->xmlStartTag("qtimetadatafield");
202  $a_xml_writer->xmlElement("fieldlabel", NULL, "answer_feedback_points");
203  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getAnswerFeedbackPoints()));
204  $a_xml_writer->xmlEndTag("qtimetadatafield");
205 
206  // show cancel
207  $a_xml_writer->xmlStartTag("qtimetadatafield");
208  $a_xml_writer->xmlElement("fieldlabel", NULL, "show_cancel");
209  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getShowCancel()));
210  $a_xml_writer->xmlEndTag("qtimetadatafield");
211 
212  // show marker
213  $a_xml_writer->xmlStartTag("qtimetadatafield");
214  $a_xml_writer->xmlElement("fieldlabel", NULL, "show_marker");
215  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getShowMarker()));
216  $a_xml_writer->xmlEndTag("qtimetadatafield");
217 
218  // fixed participants
219  $a_xml_writer->xmlStartTag("qtimetadatafield");
220  $a_xml_writer->xmlElement("fieldlabel", NULL, "fixed_participants");
221  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getFixedParticipants()));
222  $a_xml_writer->xmlEndTag("qtimetadatafield");
223 
224  // show final statement
225  $a_xml_writer->xmlStartTag("qtimetadatafield");
226  $a_xml_writer->xmlElement("fieldlabel", NULL, "showfinalstatement");
227  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", (($this->objTest->getShowFinalStatement()) ? "1" : "0")));
228  $a_xml_writer->xmlEndTag("qtimetadatafield");
229 
230  // redirect after exam
231  $a_xml_writer->xmlStartTag("qtimetadatafield");
232  $a_xml_writer->xmlElement("fieldlabel", NULL, "redirect_after_exam");
233  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getRedirectAfterExam());
234  $a_xml_writer->xmlEndTag("qtimetadatafield");
235 
236  // redirect only in kiosk mode
237  $a_xml_writer->xmlStartTag("qtimetadatafield");
238  $a_xml_writer->xmlElement("fieldlabel", NULL, "redirect_only_kiosk_mode");
239  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", (($this->objTest->getRedirectOnlyKioskMode()) ? "1" : "0")));
240  $a_xml_writer->xmlEndTag("qtimetadatafield");
241 
242  // save exam PDF for archive
243  $a_xml_writer->xmlStartTag("qtimetadatafield");
244  $a_xml_writer->xmlElement("fieldlabel", NULL, "exam_pdf");
245  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", (($this->objTest->getExamPdf()) ? "1" : "0")));
246  $a_xml_writer->xmlEndTag("qtimetadatafield");
247 
248  // show introduction only
249  $a_xml_writer->xmlStartTag("qtimetadatafield");
250  $a_xml_writer->xmlElement("fieldlabel", NULL, "showinfo");
251  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", (($this->objTest->getShowInfo()) ? "1" : "0")));
252  $a_xml_writer->xmlEndTag("qtimetadatafield");
253 
254  // mail notification
255  $a_xml_writer->xmlStartTag("qtimetadatafield");
256  $a_xml_writer->xmlElement("fieldlabel", NULL, "mailnotification");
257  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getMailNotification());
258  $a_xml_writer->xmlEndTag("qtimetadatafield");
259 
260  // mail notification type
261  $a_xml_writer->xmlStartTag("qtimetadatafield");
262  $a_xml_writer->xmlElement("fieldlabel", NULL, "mailnottype");
263  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getMailNotificationType());
264  $a_xml_writer->xmlEndTag("qtimetadatafield");
265 
266  // export settings
267  $a_xml_writer->xmlStartTag("qtimetadatafield");
268  $a_xml_writer->xmlElement("fieldlabel", NULL, "exportsettings");
269  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getExportSettings());
270  $a_xml_writer->xmlEndTag("qtimetadatafield");
271 
272  // force JavaScript
273  $a_xml_writer->xmlStartTag("qtimetadatafield");
274  $a_xml_writer->xmlElement("fieldlabel", NULL, "forcejs");
275  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", (($this->objTest->getForceJS()) ? "1" : "0")));
276  $a_xml_writer->xmlEndTag("qtimetadatafield");
277 
278  // custom style
279  $a_xml_writer->xmlStartTag("qtimetadatafield");
280  $a_xml_writer->xmlElement("fieldlabel", NULL, "customstyle");
281  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getCustomStyle());
282  $a_xml_writer->xmlEndTag("qtimetadatafield");
283 
284  // shuffle questions
285  $a_xml_writer->xmlStartTag("qtimetadatafield");
286  $a_xml_writer->xmlElement("fieldlabel", NULL, "shuffle_questions");
287  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("%d", $this->objTest->getShuffleQuestions()));
288  $a_xml_writer->xmlEndTag("qtimetadatafield");
289 
290  // processing time
291  $a_xml_writer->xmlStartTag("qtimetadatafield");
292  $a_xml_writer->xmlElement("fieldlabel", NULL, "processing_time");
293  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getProcessingTime());
294  $a_xml_writer->xmlEndTag("qtimetadatafield");
295 
296  // autosave
297  $a_xml_writer->xmlStartTag("qtimetadatafield");
298  $a_xml_writer->xmlElement("fieldlabel", NULL, "autosave");
299  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getAutosave());
300  $a_xml_writer->xmlEndTag("qtimetadatafield");
301 
302  // enable processing Time
303  $a_xml_writer->xmlStartTag("qtimetadatafield");
304  $a_xml_writer->xmlElement("fieldlabel", NULL, "enable_processing_time");
305  $a_xml_writer->xmlElement("fieldentry", NULL, $this->objTest->getEnableProcessingTime());
306  $a_xml_writer->xmlEndTag("qtimetadatafield");
307 
308  // starting time
309  if ($this->objTest->getStartingTime())
310  {
311  $a_xml_writer->xmlStartTag("qtimetadatafield");
312  $a_xml_writer->xmlElement("fieldlabel", NULL, "starting_time");
313  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->objTest->getStartingTime(), $matches);
314  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
315  $a_xml_writer->xmlEndTag("qtimetadatafield");
316  }
317  // ending time
318  if ($this->objTest->getEndingTime())
319  {
320  $a_xml_writer->xmlStartTag("qtimetadatafield");
321  $a_xml_writer->xmlElement("fieldlabel", NULL, "ending_time");
322  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->objTest->getEndingTime(), $matches);
323  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("P%dY%dM%dDT%dH%dM%dS", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
324  $a_xml_writer->xmlEndTag("qtimetadatafield");
325  }
326  foreach ($this->objTest->getMarkSchema()->getMarkSteps() as $index => $mark)
327  {
328  // mark steps
329  $a_xml_writer->xmlStartTag("qtimetadatafield");
330  $a_xml_writer->xmlElement("fieldlabel", NULL, "mark_step_$index");
331  $a_xml_writer->xmlElement("fieldentry", NULL, sprintf("<short>%s</short><official>%s</official><percentage>%.2f</percentage><passed>%d</passed>", $mark->getShortName(), $mark->getOfficialName(), $mark->getMinimumLevel(), $mark->getPassed()));
332  $a_xml_writer->xmlEndTag("qtimetadatafield");
333  }
334  $a_xml_writer->xmlEndTag("qtimetadata");
335 
336  // add qti objectives
337  $a_xml_writer->xmlStartTag("objectives");
338  $this->addQTIMaterial($a_xml_writer, $this->objTest->getIntroduction());
339  $a_xml_writer->xmlEndTag("objectives");
340 
341  // add qti assessmentcontrol
342  if ($this->objTest->getInstantFeedbackSolution() == 1)
343  {
344  $attrs = array(
345  "solutionswitch" => "Yes"
346  );
347  }
348  else
349  {
350  $attrs = NULL;
351  }
352  $a_xml_writer->xmlElement("assessmentcontrol", $attrs, NULL);
353 
354  if (strlen($this->objTest->getFinalStatement()))
355  {
356  // add qti presentation_material
357  $a_xml_writer->xmlStartTag("presentation_material");
358  $a_xml_writer->xmlStartTag("flow_mat");
359  $this->addQTIMaterial($a_xml_writer, $this->objTest->getFinalStatement());
360  $a_xml_writer->xmlEndTag("flow_mat");
361  $a_xml_writer->xmlEndTag("presentation_material");
362  }
363 
364  $attrs = array(
365  "ident" => "1"
366  );
367  $a_xml_writer->xmlElement("section", $attrs, NULL);
368  $a_xml_writer->xmlEndTag("assessment");
369  $a_xml_writer->xmlEndTag("questestinterop");
370 
371  $xml = $a_xml_writer->xmlDumpMem(FALSE);
372 
373  include_once "./Modules/Test/classes/class.ilObjTest.php";
374  foreach ($this->objTest->getQuestions() as $question_id)
375  {
376  $question =& ilObjTest::_instanciateQuestion($question_id);
377  $qti_question = $question->toXML(false);
378  $qti_question = preg_replace("/<questestinterop>/", "", $qti_question);
379  $qti_question = preg_replace("/<\/questestinterop>/", "", $qti_question);
380  if (strpos($xml, "</section>") !== false)
381  {
382  $xml = str_replace("</section>", "$qti_question</section>", $xml);
383  }
384  else
385  {
386  $xml = str_replace("<section ident=\"1\"/>", "<section ident=\"1\">\n$qti_question</section>", $xml);
387  }
388  }
389  return $xml;
390  }
391 
400  protected function addQTIMaterial(&$a_xml_writer, $a_material)
401  {
402  include_once "./Services/RTE/classes/class.ilRTE.php";
403  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
404 
405  $a_xml_writer->xmlStartTag("material");
406  $attrs = array(
407  "texttype" => "text/plain"
408  );
409  if ($this->objTest->isHTML($a_material))
410  {
411  $attrs["texttype"] = "text/xhtml";
412  }
413  $a_xml_writer->xmlElement("mattext", $attrs, ilRTE::_replaceMediaObjectImageSrc($a_material, 0));
414 
415  $mobs = ilObjMediaObject::_getMobsOfObject("tst:html", $this->objTest->getId());
416  foreach ($mobs as $mob)
417  {
418  $moblabel = "il_" . IL_INST_ID . "_mob_" . $mob;
419  if (strpos($a_material, "mm_$mob") !== FALSE)
420  {
421  if (ilObjMediaObject::_exists($mob))
422  {
423  $mob_obj =& new ilObjMediaObject($mob);
424  $imgattrs = array(
425  "label" => $moblabel,
426  "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle()
427  );
428  }
429  $a_xml_writer->xmlElement("matimage", $imgattrs, NULL);
430  }
431  }
432  $a_xml_writer->xmlEndTag("material");
433  }
434 
435 }
436 
437 ?>