ILIAS  release_5-0 Revision 5.0.0-1144-gc4397b1f870
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilQTIParser.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 include_once("./Services/Xml/classes/class.ilSaxParser.php");
25 include_once 'Modules/TestQuestionPool/classes/questions/LogicalAnswerCompare/class.ilAssQuestionTypeList.php';
26 
27 define ("IL_MO_PARSE_QTI", 1);
28 define ("IL_MO_VERIFY_QTI", 2);
29 
39 class ilQTIParser extends ilSaxParser
40 {
41  var $lng;
43  var $path;
44  var $items;
45  var $item;
46  var $depth;
52  var $material;
53 
57  var $matimage;
58 
59  var $response;
61  var $outcomes;
62  var $decvar;
64  var $setvar;
67  var $flow_mat;
68  var $flow;
70  var $mattext;
71  var $sametag;
76  var $qpl_id;
77  var $tst_id;
85  var $in_assessment = FALSE;
86  var $section;
90  var $in_objectives = FALSE;
91 
92  var $founditems = array();
93  var $verifyroot = false;
100 
108  protected $in_prensentation_material = false;
109 
117  // TODO: The following line gets me an parse error in PHP 4, but I found no hint that pass-by-reference is forbidden in PHP 4 ????
118  function ilQTIParser($a_xml_file, $a_mode = IL_MO_PARSE_QTI, $a_qpl_id = 0, $a_import_idents = "")
119  {
120  global $lng;
121 
122  $this->setParserMode($a_mode);
123 
124  parent::ilSaxParser($a_xml_file);
125 
126  $this->qpl_id = $a_qpl_id;
127  $this->import_idents = array();
128  if (is_array($a_import_idents))
129  {
130  $this->import_idents =& $a_import_idents;
131  }
132 
133  $this->lng =& $lng;
134  $this->hasRootElement = FALSE;
135  $this->import_mapping = array();
136  $this->assessments = array();
137  $this->assessment = NULL;
138  $this->section = NULL;
139  $this->path = array();
140  $this->items = array();
141  $this->item = NULL;
142  $this->depth = array();
143  $this->do_nothing = FALSE;
144  $this->qti_element = "";
145  $this->in_presentation = FALSE;
146  $this->in_objectives = FALSE;
147  $this->in_reponse = FALSE;
148  $this->render_type = NULL;
149  $this->render_hotspot = NULL;
150  $this->response_label = NULL;
151  $this->material = NULL;
152  $this->response = NULL;
153  $this->assessmentcontrol = NULL;
154  $this->objectives = NULL;
155  $this->matimage = NULL;
156  $this->resprocessing = NULL;
157  $this->outcomes = NULL;
158  $this->decvar = NULL;
159  $this->respcondition = NULL;
160  $this->setvar = NULL;
161  $this->displayfeedback = NULL;
162  $this->itemfeedback = NULL;
163  $this->flow_mat = array();
164  $this->question_counter = 1;
165  $this->flow = 0;
166  $this->gap_index = 0;
167  $this->presentation = NULL;
168  $this->mattext = NULL;
169  $this->matapplet = NULL;
170  $this->sametag = FALSE;
171  $this->in_assessment = FALSE;
172  $this->characterbuffer = "";
173  $this->metadata = array("label" => "", "entry" => "");
174  }
175 
176  function setTestObject(&$a_tst_object)
177  {
178  $this->tst_object =& $a_tst_object;
179  if (is_object($a_tst_object))
180  {
181  $this->tst_id = $this->tst_object->getId();
182  }
183  }
184 
185  function setParserMode($a_mode = IL_MO_PARSE_QTI)
186  {
187  $this->parser_mode = $a_mode;
188  $this->founditems = array();
189  $this->verifyroot = false;
190  $this->verifyqticomment = 0;
191  $this->verifymetadatafield = 0;
192  $this->verifyfieldlabel = 0;
193  $this->verifyfieldentry = 0;
194  $this->verifyfieldlabeltext = "";
195  $this->verifyfieldentrytext = "";
196  $this->question_counter = 1;
197  }
198 
204  function setHandlers($a_xml_parser)
205  {
206  xml_set_object($a_xml_parser,$this);
207  xml_set_element_handler($a_xml_parser,'handlerBeginTag','handlerEndTag');
208  xml_set_character_data_handler($a_xml_parser,'handlerCharacterData');
209  }
210 
211  function startParsing()
212  {
213  $this->question_counter = 1;
214  parent::startParsing();
215  return FALSE;
216  }
217 
218  function getParent($a_xml_parser)
219  {
220  if ($this->depth[$a_xml_parser] > 0)
221  {
222  return $this->path[$this->depth[$a_xml_parser]-1];
223  }
224  else
225  {
226  return "";
227  }
228  }
229 
233  function handlerBeginTag($a_xml_parser,$a_name,$a_attribs)
234  {
235  switch ($this->parser_mode)
236  {
237  case IL_MO_PARSE_QTI:
238  $this->handlerParseBeginTag($a_xml_parser, $a_name, $a_attribs);
239  break;
240  case IL_MO_VERIFY_QTI:
241  $this->handlerVerifyBeginTag($a_xml_parser, $a_name, $a_attribs);
242  break;
243  }
244  }
245 
249  function handlerParseBeginTag($a_xml_parser,$a_name,$a_attribs)
250  {
251  if ($this->do_nothing) return;
252  $this->sametag = FALSE;
253  $this->characterbuffer = "";
254  $this->depth[$a_xml_parser]++;
255  $this->path[$this->depth[$a_xml_parser]] = strtolower($a_name);
256  $this->qti_element = $a_name;
257 
258  switch (strtolower($a_name))
259  {
260  case "assessment":
261  include_once ("./Services/QTI/classes/class.ilQTIAssessment.php");
262  $this->assessment =& $this->assessments[array_push($this->assessments, new ilQTIAssessment())-1];
263  $this->in_assessment = TRUE;
264  if (is_array($a_attribs))
265  {
266  foreach ($a_attribs as $attribute => $value)
267  {
268  switch (strtolower($attribute))
269  {
270  case "title":
271  $this->assessment->setTitle($value);
272  break;
273  case "ident":
274  $this->assessment->setIdent($value);
275  break;
276  }
277  }
278  }
279  break;
280  case "assessmentcontrol":
281  include_once ("./Services/QTI/classes/class.ilQTIAssessmentcontrol.php");
282  $this->assessmentcontrol = new ilQTIAssessmentcontrol();
283  if (is_array($a_attribs))
284  {
285  foreach ($a_attribs as $attribute => $value)
286  {
287  switch (strtolower($attribute))
288  {
289  case "solutionswitch":
290  $this->assessmentcontrol->setSolutionswitch($value);
291  break;
292  case "hintswitch":
293  $this->assessmentcontrol->setHintswitch($value);
294  break;
295  case "feedbackswitch":
296  $this->assessmentcontrol->setFeedbackswitch($value);
297  break;
298  }
299  }
300  }
301  break;
302  case "objectives":
303  include_once ("./Services/QTI/classes/class.ilQTIObjectives.php");
304  $this->objectives = new ilQTIObjectives();
305  $this->in_objectives = TRUE;
306  break;
307  case 'presentation_material':
308  require_once 'Services/QTI/classes/class.ilQTIPresentationMaterial.php';
309  $this->prensentation_material = new ilQTIPresentationMaterial();
310  $this->in_prensentation_material = TRUE;
311  break;
312  case "section":
313  include_once ("./Services/QTI/classes/class.ilQTISection.php");
314  $this->section = new ilQTISection();
315  break;
316  case "itemmetadata":
317  $this->in_itemmetadata = TRUE;
318  break;
319  case "qtimetadatafield":
320  $this->metadata = array("label" => "", "entry" => "");
321  break;
322  case "flow":
323  include_once ("./Services/QTI/classes/class.ilQTIFlow.php");
324  $this->flow++;
325  break;
326  case "flow_mat":
327  include_once ("./Services/QTI/classes/class.ilQTIFlowMat.php");
328  array_push($this->flow_mat, new ilQTIFlowMat());
329  break;
330  case "itemfeedback":
331  include_once ("./Services/QTI/classes/class.ilQTIItemfeedback.php");
332  $this->itemfeedback = new ilQTIItemfeedback();
333  if (is_array($a_attribs))
334  {
335  foreach ($a_attribs as $attribute => $value)
336  {
337  switch (strtolower($attribute))
338  {
339  case "ident":
340  $this->itemfeedback->setIdent($value);
341  break;
342  case "view":
343  $this->itemfeedback->setView($value);
344  break;
345  }
346  }
347  }
348  break;
349  case "displayfeedback":
350  include_once ("./Services/QTI/classes/class.ilQTIDisplayfeedback.php");
351  $this->displayfeedback = new ilQTIDisplayfeedback();
352  if (is_array($a_attribs))
353  {
354  foreach ($a_attribs as $attribute => $value)
355  {
356  switch (strtolower($attribute))
357  {
358  case "feedbacktype":
359  $this->displayfeedback->setFeedbacktype($value);
360  break;
361  case "linkrefid":
362  $this->displayfeedback->setLinkrefid($value);
363  break;
364  }
365  }
366  }
367  break;
368  case "setvar":
369  include_once ("./Services/QTI/classes/class.ilQTISetvar.php");
370  $this->setvar = new ilQTISetvar();
371  if (is_array($a_attribs))
372  {
373  foreach ($a_attribs as $attribute => $value)
374  {
375  switch (strtolower($attribute))
376  {
377  case "action":
378  $this->setvar->setAction($value);
379  break;
380  case "varname":
381  $this->setvar->setVarname($value);
382  break;
383  }
384  }
385  }
386  break;
387  case "conditionvar":
388  include_once ("./Services/QTI/classes/class.ilQTIConditionvar.php");
389  $this->conditionvar = new ilQTIConditionvar();
390  break;
391  case "not":
392  if ($this->conditionvar != NULL)
393  {
394  $this->conditionvar->addNot();
395  }
396  break;
397  case "and":
398  if ($this->conditionvar != NULL)
399  {
400  $this->conditionvar->addAnd();
401  }
402  break;
403  case "or":
404  if ($this->conditionvar != NULL)
405  {
406  $this->conditionvar->addOr();
407  }
408  break;
409  case "varequal":
410  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
411  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_EQUAL);
412  if (is_array($a_attribs))
413  {
414  foreach ($a_attribs as $attribute => $value)
415  {
416  switch (strtolower($attribute))
417  {
418  case "case":
419  $this->responsevar->setCase($value);
420  break;
421  case "respident":
422  $this->responsevar->setRespident($value);
423  break;
424  case "index":
425  $this->responsevar->setIndex($value);
426  break;
427  }
428  }
429  }
430  break;
431  case "varlt":
432  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
433  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_LT);
434  if (is_array($a_attribs))
435  {
436  foreach ($a_attribs as $attribute => $value)
437  {
438  switch (strtolower($attribute))
439  {
440  case "respident":
441  $this->responsevar->setRespident($value);
442  break;
443  case "index":
444  $this->responsevar->setIndex($value);
445  break;
446  }
447  }
448  }
449  break;
450  case "varlte":
451  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
452  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_LTE);
453  if (is_array($a_attribs))
454  {
455  foreach ($a_attribs as $attribute => $value)
456  {
457  switch (strtolower($attribute))
458  {
459  case "respident":
460  $this->responsevar->setRespident($value);
461  break;
462  case "index":
463  $this->responsevar->setIndex($value);
464  break;
465  }
466  }
467  }
468  break;
469  case "vargt":
470  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
471  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_GT);
472  if (is_array($a_attribs))
473  {
474  foreach ($a_attribs as $attribute => $value)
475  {
476  switch (strtolower($attribute))
477  {
478  case "respident":
479  $this->responsevar->setRespident($value);
480  break;
481  case "index":
482  $this->responsevar->setIndex($value);
483  break;
484  }
485  }
486  }
487  break;
488  case "vargte":
489  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
490  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_GTE);
491  if (is_array($a_attribs))
492  {
493  foreach ($a_attribs as $attribute => $value)
494  {
495  switch (strtolower($attribute))
496  {
497  case "respident":
498  $this->responsevar->setRespident($value);
499  break;
500  case "index":
501  $this->responsevar->setIndex($value);
502  break;
503  }
504  }
505  }
506  break;
507  case "varsubset":
508  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
509  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_SUBSET);
510  if (is_array($a_attribs))
511  {
512  foreach ($a_attribs as $attribute => $value)
513  {
514  switch (strtolower($attribute))
515  {
516  case "respident":
517  $this->responsevar->setRespident($value);
518  break;
519  case "setmatch":
520  $this->responsevar->setSetmatch($value);
521  break;
522  case "index":
523  $this->responsevar->setIndex($value);
524  break;
525  }
526  }
527  }
528  break;
529  case "varinside":
530  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
531  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_INSIDE);
532  if (is_array($a_attribs))
533  {
534  foreach ($a_attribs as $attribute => $value)
535  {
536  switch (strtolower($attribute))
537  {
538  case "respident":
539  $this->responsevar->setRespident($value);
540  break;
541  case "areatype":
542  $this->responsevar->setAreatype($value);
543  break;
544  case "index":
545  $this->responsevar->setIndex($value);
546  break;
547  }
548  }
549  }
550  break;
551  case "varsubstring":
552  include_once("./Services/QTI/classes/class.ilQTIResponseVar.php");
553  $this->responsevar = new ilQTIResponseVar(RESPONSEVAR_SUBSTRING);
554  if (is_array($a_attribs))
555  {
556  foreach ($a_attribs as $attribute => $value)
557  {
558  switch (strtolower($attribute))
559  {
560  case "case":
561  $this->responsevar->setCase($value);
562  break;
563  case "respident":
564  $this->responsevar->setRespident($value);
565  break;
566  case "index":
567  $this->responsevar->setIndex($value);
568  break;
569  }
570  }
571  }
572  break;
573  case "respcondition":
574  include_once("./Services/QTI/classes/class.ilQTIRespcondition.php");
575  $this->respcondition = new ilQTIRespcondition();
576  if (is_array($a_attribs))
577  {
578  foreach ($a_attribs as $attribute => $value)
579  {
580  switch (strtolower($attribute))
581  {
582  case "continue":
583  $this->respcondition->setContinue($value);
584  break;
585  case "title":
586  $this->respcondition->setTitle($value);
587  break;
588  }
589  }
590  }
591  break;
592  case "outcomes":
593  include_once("./Services/QTI/classes/class.ilQTIOutcomes.php");
594  $this->outcomes = new ilQTIOutcomes();
595  break;
596  case "decvar":
597  include_once("./Services/QTI/classes/class.ilQTIDecvar.php");
598  $this->decvar = new ilQTIDecvar();
599  if (is_array($a_attribs))
600  {
601  foreach ($a_attribs as $attribute => $value)
602  {
603  switch (strtolower($attribute))
604  {
605  case "varname":
606  $this->decvar->setVarname($value);
607  break;
608  case "vartype":
609  $this->decvar->setVartype($value);
610  break;
611  case "defaultval":
612  $this->decvar->setDefaultval($value);
613  break;
614  case "minvalue":
615  $this->decvar->setMinvalue($value);
616  break;
617  case "maxvalue":
618  $this->decvar->setMaxvalue($value);
619  break;
620  case "members":
621  $this->decvar->setMembers($value);
622  break;
623  case "cutvalue":
624  $this->decvar->setCutvalue($value);
625  break;
626  }
627  }
628  }
629  break;
630  case "matimage":
631  include_once("./Services/QTI/classes/class.ilQTIMatimage.php");
632  $this->matimage = new ilQTIMatimage();
633  if (is_array($a_attribs))
634  {
635  foreach ($a_attribs as $attribute => $value)
636  {
637  switch (strtolower($attribute))
638  {
639  case "imagtype":
640  $this->matimage->setImagetype($value);
641  break;
642  case "label":
643  $this->matimage->setLabel($value);
644  break;
645  case "height":
646  $this->matimage->setHeight($value);
647  break;
648  case "width":
649  $this->matimage->setWidth($value);
650  break;
651  case "uri":
652  $this->matimage->setUri($value);
653  break;
654  case "embedded":
655  $this->matimage->setEmbedded($value);
656  break;
657  case "x0":
658  $this->matimage->setX0($value);
659  break;
660  case "y0":
661  $this->matimage->setY0($value);
662  break;
663  case "entityref":
664  $this->matimage->setEntityref($value);
665  break;
666  }
667  }
668  }
669  if (!$this->matimage->getEmbedded() && strlen($this->matimage->getUri()))
670  {
671  $this->matimage->setContent(@file_get_contents(dirname($this->xml_file) . '/'. $this->matimage->getUri()));
672  }
673  break;
674  case "material":
675  include_once("./Services/QTI/classes/class.ilQTIMaterial.php");
676  $this->material = new ilQTIMaterial();
677  $this->material->setFlow($this->flow);
678  if (is_array($a_attribs))
679  {
680  foreach ($a_attribs as $attribute => $value)
681  {
682  switch (strtolower($attribute))
683  {
684  case "label":
685  $this->material->setLabel($value);
686  break;
687  }
688  }
689  }
690  break;
691  case "mattext":
692  include_once ("./Services/QTI/classes/class.ilQTIMattext.php");
693  $this->mattext = new ilQTIMattext();
694  if (is_array($a_attribs))
695  {
696  foreach ($a_attribs as $attribute => $value)
697  {
698  switch (strtolower($attribute))
699  {
700  case "texttype":
701  $this->mattext->setTexttype($value);
702  break;
703  case "label":
704  $this->mattext->setLabel($value);
705  break;
706  case "charset":
707  $this->mattext->setCharset($value);
708  break;
709  case "uri":
710  $this->mattext->setUri($value);
711  break;
712  case "xml:space":
713  $this->mattext->setXmlspace($value);
714  break;
715  case "xml:lang":
716  $this->mattext->setXmllang($value);
717  break;
718  case "entityref":
719  $this->mattext->setEntityref($value);
720  break;
721  case "height":
722  $this->mattext->setHeight($value);
723  break;
724  case "width":
725  $this->mattext->setWidth($value);
726  break;
727  case "x0":
728  $this->mattext->setX0($value);
729  break;
730  case "y0":
731  $this->mattext->setY0($value);
732  break;
733  }
734  }
735  }
736  break;
737  case "matapplet":
738  include_once ("./Services/QTI/classes/class.ilQTIMatapplet.php");
739  $this->matapplet = New ilQTIMatapplet();
740  if (is_array($a_attribs))
741  {
742  foreach ($a_attribs as $attribute => $value)
743  {
744  switch (strtolower($attribute))
745  {
746  case "label":
747  $this->matapplet->setLabel($value);
748  break;
749  case "uri":
750  $this->matapplet->setUri($value);
751  break;
752  case "y0":
753  $this->matapplet->setY0($value);
754  break;
755  case "height":
756  $this->matapplet->setHeight($value);
757  break;
758  case "width":
759  $this->matapplet->setWidth($value);
760  break;
761  case "x0":
762  $this->matapplet->setX0($value);
763  break;
764  case "embedded":
765  $this->matapplet->setEmbedded($value);
766  break;
767  case "entityref":
768  $this->matapplet->setEntityref($value);
769  break;
770  }
771  }
772  }
773  break;
774  case "questestinterop":
775  $this->hasRootElement = TRUE;
776  break;
777  case "qticomment":
778  break;
779  case "objectbank":
780  // not implemented yet
781  break;
782  case "section":
783  if ($this->assessment != NULL)
784  {
785  $this->assessment->addSection($this->section);
786  }
787  $this->section = NULL;
788  break;
789  case "presentation":
790  $this->in_presentation = TRUE;
791  include_once ("./Services/QTI/classes/class.ilQTIPresentation.php");
792  $this->presentation = new ilQTIPresentation();
793  break;
794  case "response_label":
795  if ($this->render_type != NULL)
796  {
797  include_once("./Services/QTI/classes/class.ilQTIResponseLabel.php");
798  $this->response_label = new ilQTIResponseLabel();
799  foreach ($a_attribs as $attribute => $value)
800  {
801  switch (strtolower($attribute))
802  {
803  case "rshuffle":
804  $this->response_label->setRshuffle($value);
805  break;
806  case "rarea":
807  $this->response_label->setRarea($value);
808  break;
809  case "rrange":
810  $this->response_label->setRrange($value);
811  break;
812  case "labelrefid":
813  $this->response_label->setLabelrefid($value);
814  break;
815  case "ident":
816  $this->response_label->setIdent($value);
817  break;
818  case "match_group":
819  $this->response_label->setMatchGroup($value);
820  break;
821  case "match_max":
822  $this->response_label->setMatchMax($value);
823  break;
824  }
825  }
826  }
827  break;
828  case "render_choice":
829  if ($this->in_response)
830  {
831  include_once("./Services/QTI/classes/class.ilQTIRenderChoice.php");
832  $this->render_type = new ilQTIRenderChoice();
833  foreach ($a_attribs as $attribute => $value)
834  {
835  switch (strtolower($attribute))
836  {
837  case "shuffle":
838  $this->render_type->setShuffle($value);
839  break;
840  }
841  }
842  }
843  break;
844  case "render_hotspot":
845  if ($this->in_response)
846  {
847  include_once("./Services/QTI/classes/class.ilQTIRenderHotspot.php");
848  $this->render_type = new ilQTIRenderHotspot();
849  foreach ($a_attribs as $attribute => $value)
850  {
851  switch (strtolower($attribute))
852  {
853  case "showdraw":
854  $this->render_type->setShuffle($value);
855  break;
856  case "minnumber":
857  $this->render_type->setMinnumber($value);
858  break;
859  case "maxnumber":
860  $this->render_type->setMaxnumber($value);
861  break;
862  }
863  }
864  }
865  break;
866  case "render_fib":
867  if ($this->in_response)
868  {
869  include_once("./Services/QTI/classes/class.ilQTIRenderFib.php");
870  $this->render_type = new ilQTIRenderFib();
871  foreach ($a_attribs as $attribute => $value)
872  {
873  switch (strtolower($attribute))
874  {
875  case "encoding":
876  $this->render_type->setEncoding($value);
877  break;
878  case "fibtype":
879  $this->render_type->setFibtype($value);
880  break;
881  case "rows":
882  $this->render_type->setRows($value);
883  break;
884  case "maxchars":
885  $this->render_type->setMaxchars($value);
886  break;
887  case "prompt":
888  $this->render_type->setPrompt($value);
889  break;
890  case "columns":
891  $this->render_type->setColumns($value);
892  break;
893  case "charset":
894  $this->render_type->setCharset($value);
895  break;
896  case "maxnumber":
897  $this->render_type->setMaxnumber($value);
898  break;
899  case "minnumber":
900  $this->render_type->setMinnumber($value);
901  break;
902  }
903  }
904  }
905  break;
906  case "response_lid":
907  // Ordering Terms and Definitions or
908  // Ordering Terms and Pictures or
909  // Multiple choice single response or
910  // Multiple choice multiple response
911  case "response_xy":
912  // Imagemap question
913  case "response_str":
914  // Close question
915  case "response_num":
916  case "response_grp":
917  // Matching terms and definitions
918  // Matching terms and images
919  include_once "./Services/QTI/classes/class.ilQTIResponse.php";
920  switch (strtolower($a_name))
921  {
922  case "response_lid":
923  $response_type = RT_RESPONSE_LID;
924  break;
925  case "response_xy":
926  $response_type = RT_RESPONSE_XY;
927  break;
928  case "response_str":
929  $response_type = RT_RESPONSE_STR;
930  break;
931  case "response_num":
932  $response_type = RT_RESPONSE_NUM;
933  break;
934  case "response_grp":
935  $response_type = RT_RESPONSE_GRP;
936  break;
937  }
938  $this->in_response = TRUE;
939  $this->response = new ilQTIResponse($response_type);
940  $this->response->setFlow($this->flow);
941  if (is_array($a_attribs))
942  {
943  foreach ($a_attribs as $attribute => $value)
944  {
945  switch (strtolower($attribute))
946  {
947  case "ident":
948  $this->response->setIdent($value);
949  break;
950  case "rtiming":
951  $this->response->setRTiming($value);
952  break;
953  case "rcardinality":
954  $this->response->setRCardinality($value);
955  break;
956  case "numtype":
957  $this->response->setNumtype($value);
958  break;
959  }
960  }
961  }
962  break;
963  case "item":
964  include_once("./Services/QTI/classes/class.ilQTIItem.php");
965  $this->gap_index = 0;
966  $this->item =& $this->items[array_push($this->items, new ilQTIItem())-1];
967  if (is_array($a_attribs))
968  {
969  foreach ($a_attribs as $attribute => $value)
970  {
971  switch (strtolower($attribute))
972  {
973  case "ident":
974  $this->item->setIdent($value);
975  $this->item->setIliasSourceNic(
976  $this->fetchSourceNicFromItemIdent($value)
977  );
978  if (count($this->import_idents) > 0)
979  {
980  if (!in_array($value, $this->import_idents))
981  {
982  $this->do_nothing = TRUE;
983  }
984  }
985  break;
986  case "title":
987  $this->item->setTitle($value);
988  break;
989  case "maxattempts":
990  $this->item->setMaxattempts($value);
991  break;
992  }
993  }
994  }
995  break;
996  case "resprocessing":
997  include_once("./Services/QTI/classes/class.ilQTIResprocessing.php");
998  $this->resprocessing = new ilQTIResprocessing();
999  if (is_array($a_attribs))
1000  {
1001  foreach ($a_attribs as $attribute => $value)
1002  {
1003  switch (strtolower($attribute))
1004  {
1005  case "scoremodel":
1006  $this->resprocessing->setScoremodel($value);
1007  break;
1008  }
1009  }
1010  }
1011  break;
1012  }
1013  }
1014 
1018  function handlerEndTag($a_xml_parser,$a_name)
1019  {
1020  switch ($this->parser_mode)
1021  {
1022  case IL_MO_PARSE_QTI:
1023  $this->handlerParseEndTag($a_xml_parser, $a_name);
1024  break;
1025  case IL_MO_VERIFY_QTI:
1026  $this->handlerVerifyEndTag($a_xml_parser, $a_name);
1027  break;
1028  }
1029  }
1030 
1034  function handlerParseEndTag($a_xml_parser,$a_name)
1035  {
1036  if (($this->do_nothing) && (strcmp(strtolower($a_name), "item") != 0)) return;
1037  switch (strtolower($a_name))
1038  {
1039  case "assessment":
1040  if (is_object($this->tst_object))
1041  {
1042  $this->tst_object->fromXML($this->assessment);
1043  }
1044  $this->in_assessment = FALSE;
1045  break;
1046  case "assessmentcontrol":
1047  $this->assessment->addAssessmentcontrol($this->assessmentcontrol);
1048  $this->assessmentcontrol = NULL;
1049  break;
1050  case "objectives":
1051  if (strcmp(strtolower($this->getParent($a_xml_parser)), "assessment") == 0)
1052  {
1053  $this->assessment->addObjectives($this->objectives);
1054  }
1055  $this->in_objectives = FALSE;
1056  break;
1057  case 'presentation_material':
1058  $this->assessment->setPresentationMaterial($this->prensentation_material);
1059  $this->in_prensentation_material = FALSE;
1060  break;
1061  case "itemmetadata":
1062  $this->in_itemmetadata = FALSE;
1063  break;
1064  case "qtimetadatafield":
1065  // handle only specific ILIAS metadata
1066  switch ($this->metadata["label"])
1067  {
1068  case "ILIAS_VERSION":
1069  if ($this->item != NULL)
1070  {
1071  $this->item->setIliasSourceVersion(
1072  $this->fetchNumericVersionFromVersionDateString($this->metadata["entry"])
1073  );
1074  }
1075  break;
1076  case "QUESTIONTYPE":
1077  if ($this->item != NULL)
1078  {
1079  $this->item->setQuestiontype($this->metadata["entry"]);
1080  }
1081  break;
1082  case "AUTHOR":
1083  if ($this->item != NULL)
1084  {
1085  $this->item->setAuthor($this->metadata["entry"]);
1086  }
1087  default:
1088  if ($this->item != NULL)
1089  {
1090  $this->item->addMetadata($this->metadata);
1091  }
1092  break;
1093  }
1094  if ($this->in_assessment)
1095  {
1096  $this->assessment->addQtiMetadata($this->metadata);
1097  }
1098  $this->metadata = array("label" => "", "entry" => "");
1099  break;
1100  case "flow":
1101  $this->flow--;
1102  break;
1103  case "flow_mat":
1104  if (count($this->flow_mat))
1105  {
1106  $flow_mat = array_pop($this->flow_mat);
1107  if (count($this->flow_mat))
1108  {
1109  $this->flow_mat[count($this->flow_mat)-1]->addFlow_mat($flow_mat);
1110  }
1111  else if($this->in_prensentation_material)
1112  {
1113  $this->prensentation_material->addFlowMat($flow_mat);
1114  }
1115  else if ($this->itemfeedback != NULL)
1116  {
1117  $this->itemfeedback->addFlow_mat($flow_mat);
1118  }
1119  else if ($this->response_label != NULL)
1120  {
1121  $this->response_label->addFlow_mat($flow_mat);
1122  }
1123  }
1124  break;
1125  case "itemfeedback":
1126  if ($this->item != NULL)
1127  {
1128  if ($this->itemfeedback != NULL)
1129  {
1130  $this->item->addItemfeedback($this->itemfeedback);
1131  }
1132  }
1133  $this->itemfeedback = NULL;
1134  break;
1135  case "displayfeedback":
1136  if ($this->respcondition != NULL)
1137  {
1138  if ($this->displayfeedback != NULL)
1139  {
1140  $this->respcondition->addDisplayfeedback($this->displayfeedback);
1141  }
1142  }
1143  $this->displayfeedback = NULL;
1144  break;
1145  case "setvar":
1146  if ($this->respcondition != NULL)
1147  {
1148  if ($this->setvar != NULL)
1149  {
1150  $this->respcondition->addSetvar($this->setvar);
1151  }
1152  }
1153  $this->setvar = NULL;
1154  break;
1155  case "conditionvar":
1156  if ($this->respcondition != NULL)
1157  {
1158  $this->respcondition->setConditionvar($this->conditionvar);
1159  }
1160  $this->conditionvar = NULL;
1161  break;
1162  case "varequal":
1163  case "varlt":
1164  case "varlte":
1165  case "vargt":
1166  case "vargte":
1167  case "varsubset":
1168  case "varinside":
1169  case "varsubstring":
1170  if ($this->conditionvar != NULL)
1171  {
1172  if ($this->responsevar != NULL)
1173  {
1174  $this->conditionvar->addResponseVar($this->responsevar);
1175  }
1176  }
1177  $this->responsevar = NULL;
1178  break;
1179  case "respcondition":
1180  if ($this->resprocessing != NULL)
1181  {
1182  $this->resprocessing->addRespcondition($this->respcondition);
1183  }
1184  $this->respcondition = NULL;
1185  break;
1186  case "outcomes":
1187  if ($this->resprocessing != NULL)
1188  {
1189  $this->resprocessing->setOutcomes($this->outcomes);
1190  }
1191  $this->outcomes = NULL;
1192  break;
1193  case "decvar":
1194  if ($this->outcomes != NULL)
1195  {
1196  $this->outcomes->addDecvar($this->decvar);
1197  }
1198  $this->decvar = NULL;
1199  break;
1200  case "presentation":
1201  $this->in_presentation = FALSE;
1202  if ($this->presentation != NULL)
1203  {
1204  if ($this->item != NULL)
1205  {
1206  $this->item->setPresentation($this->presentation);
1207  }
1208  }
1209  $this->presentation = NULL;
1210  break;
1211  case "response_label":
1212  if ($this->render_type != NULL)
1213  {
1214  $this->render_type->addResponseLabel($this->response_label);
1215  $this->response_label = NULL;
1216  }
1217  break;
1218  case "render_choice":
1219  case "render_hotspot":
1220  case "render_fib":
1221  if ($this->in_response)
1222  {
1223  if ($this->response != NULL)
1224  {
1225  if ($this->render_type != NULL)
1226  {
1227  $this->response->setRenderType($this->render_type);
1228  $this->render_type = NULL;
1229  }
1230  }
1231  }
1232  break;
1233  case "response_lid":
1234  case "response_xy":
1235  case "response_str":
1236  case "response_num":
1237  case "response_grp":
1238  $this->gap_index++;
1239  if ($this->presentation != NULL)
1240  {
1241  if ($this->response != NULL)
1242  {
1243  $this->presentation->addResponse($this->response);
1244  if ($this->item != NULL)
1245  {
1246  $this->item->addPresentationitem($this->response);
1247  }
1248  }
1249  }
1250  $this->response = NULL;
1251  $this->in_response = FALSE;
1252  break;
1253  case "item":
1254  if ($this->do_nothing)
1255  {
1256  $this->do_nothing = FALSE;
1257  return;
1258  }
1259  if (strlen($this->item->getQuestionType()))
1260  {
1261  // this is an ILIAS QTI question
1262  }
1263  else
1264  {
1265  // this is a QTI question which wasn't generated by ILIAS
1266  }
1267  global $ilDB;
1268  global $ilUser;
1269  // save the item directly to save memory
1270  // the database id's of the created items are exported. if the import fails
1271  // ILIAS can delete the already imported items
1272 
1273  // problems: the object id of the parent questionpool is not yet known. must be set later
1274  // the complete flag must be calculated?
1275  $qt = $this->item->determineQuestionType();
1276  $presentation = $this->item->getPresentation();
1277 
1279  {
1280  return;
1281  }
1282 
1283  include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
1285  $question = new $qt();
1286  $fbt = str_replace('ass', 'ilAss', $qt).'Feedback';
1287  $question->feedbackOBJ = new $fbt(
1288  $question, $GLOBALS['ilCtrl'], $GLOBALS['ilDB'], $GLOBALS['lng']
1289  );
1290  $question->fromXML($this->item, $this->qpl_id, $this->tst_id, $this->tst_object, $this->question_counter, $this->import_mapping);
1291  break;
1292  case "material":
1293  if ($this->material)
1294  {
1295  $mat = $this->material->getMaterial(0);
1296  if ((strcmp($mat["type"], "mattext") == 0) && (strcmp($mat["material"]->getLabel(), "suggested_solution") == 0))
1297  {
1298  $this->item->addSuggestedSolution($mat["material"], $this->gap_index);
1299  }
1300  if ($this->in_objectives)
1301  {
1302  $this->objectives->addMaterial($this->material);
1303  }
1304  else if (($this->render_type != NULL) && (strcmp(strtolower($this->getParent($a_xml_parser)), "render_hotspot") == 0))
1305  {
1306  $this->render_type->addMaterial($this->material);
1307  }
1308  else if (count($this->flow_mat) && (strcmp(strtolower($this->getParent($a_xml_parser)), "flow_mat") == 0))
1309  {
1310  $this->flow_mat[count($this->flow_mat)-1]->addMaterial($this->material);
1311  }
1312  else if ($this->itemfeedback != NULL)
1313  {
1314  $this->itemfeedback->addMaterial($this->material);
1315  }
1316  else if ($this->response_label != NULL)
1317  {
1318  $this->response_label->addMaterial($this->material);
1319  }
1320  else if ($this->response != NULL)
1321  {
1322  if ($this->response->hasRendering())
1323  {
1324  $this->response->setMaterial2($this->material);
1325  }
1326  else
1327  {
1328  $this->response->setMaterial1($this->material);
1329  }
1330  }
1331  elseif (($this->in_presentation) && (!$this->in_response))
1332  {
1333  if (!is_object($this->item->getQuestiontext()))
1334  {
1335  $this->item->setQuestiontext($this->material);
1336  }
1337  $this->presentation->addMaterial($this->material);
1338  }
1339  else if ($this->presentation != NULL)
1340  {
1341  $this->presentation->addMaterial($this->material);
1342  if ($this->item != NULL)
1343  {
1344  $this->item->addPresentationitem($this->material);
1345  }
1346  }
1347  }
1348  $this->material = NULL;
1349  break;
1350  case "matimage";
1351 
1352  if( !$this->isMatImageAvailable() )
1353  {
1354  break;
1355  }
1356 
1357  if( $this->virusDetected($this->matimage->getRawContent()) )
1358  {
1359  break;
1360  }
1361 
1362  require_once 'Services/QTI/classes/class.ilQtiMatImageSecurity.php';
1363  $matImageSecurity = new ilQtiMatImageSecurity($this->matimage);
1364  $matImageSecurity->sanitizeLabel();
1365 
1366  if( !$matImageSecurity->validate() )
1367  {
1368  break;
1369  }
1370 
1371  $this->material->addMatimage($this->matimage);
1372  $this->matimage = NULL;
1373  break;
1374 
1375  // add support for matbreak element
1376  case "matbreak":
1377  $this->mattext = new ilQTIMattext();
1378  $this->mattext->setContent('<br />');
1379  $this->material->addMattext($this->mattext);
1380  $this->mattext = NULL;
1381  break;
1382  case "resprocessing":
1383  if ($this->item != NULL)
1384  {
1385  $this->item->addResprocessing($this->resprocessing);
1386  }
1387  $this->resprocessing = NULL;
1388  break;
1389  case "mattext":
1390  if ($this->material != NULL)
1391  {
1392  $this->material->addMattext($this->mattext);
1393  }
1394  $this->mattext = NULL;
1395  break;
1396  case "matapplet":
1397  if ($this->material != NULL)
1398  {
1399  $this->material->addMatapplet($this->matapplet);
1400  }
1401  $this->matapplet = NULL;
1402  break;
1403  }
1404  $this->depth[$a_xml_parser]--;
1405  }
1406 
1410  function handlerCharacterData($a_xml_parser,$a_data)
1411  {
1412  switch ($this->parser_mode)
1413  {
1414  case IL_MO_PARSE_QTI:
1415  $this->handlerParseCharacterData($a_xml_parser, $a_data);
1416  break;
1417  case IL_MO_VERIFY_QTI:
1418  $this->handlerVerifyCharacterData($a_xml_parser, $a_data);
1419  break;
1420  }
1421  }
1422 
1426  function handlerParseCharacterData($a_xml_parser,$a_data)
1427  {
1428  if ($this->do_nothing) return;
1429  $this->characterbuffer .= $a_data;
1430  $a_data = $this->characterbuffer;
1431  switch ($this->qti_element)
1432  {
1433  case "fieldlabel":
1434  $this->metadata["label"] = $a_data;
1435  break;
1436  case "fieldentry":
1437  $this->metadata["entry"] = $a_data;
1438  break;
1439  case "response_label":
1440  if ($this->response_label != NULL)
1441  {
1442  $this->response_label->setContent($a_data);
1443  }
1444  break;
1445  case "setvar":
1446  if ($this->setvar != NULL)
1447  {
1448  $this->setvar->setContent($a_data);
1449  }
1450  break;
1451  case "displayfeedback":
1452  if ($this->displayfeedback != NULL)
1453  {
1454  $this->displayfeedback->setContent($a_data);
1455  }
1456  break;
1457  case "varequal":
1458  case "varlt":
1459  case "varlte":
1460  case "vargt":
1461  case "vargte":
1462  case "varsubset":
1463  case "varinside":
1464  case "varsubstring":
1465  if ($this->responsevar != NULL)
1466  {
1467  $this->responsevar->setContent($a_data);
1468  }
1469  break;
1470  case "decvar":
1471  if (strlen($a_data))
1472  {
1473  if ($this->decvar != NULL)
1474  {
1475  $this->decvar->setContent($a_data);
1476  }
1477  }
1478  break;
1479  case "mattext":
1480  if ($this->mattext != NULL)
1481  {
1482  $this->mattext->setContent($a_data);
1483  }
1484  break;
1485  case "matapplet":
1486  if ($this->matapplet != NULL)
1487  {
1488  $this->matapplet->setContent($a_data);
1489  }
1490  break;
1491  case "matimage":
1492  if ($this->matimage != NULL)
1493  {
1494  $this->matimage->setContent($a_data);
1495  }
1496  break;
1497  case "duration":
1498  switch ($this->getParent($a_xml_parser))
1499  {
1500  case "assessment":
1501  // to be done
1502  break;
1503  case "section":
1504  // to be done
1505  break;
1506  case "item":
1507  $this->item->setDuration($a_data);
1508  break;
1509  }
1510  break;
1511  case "qticomment":
1512  switch ($this->getParent($a_xml_parser))
1513  {
1514  case "item":
1515  $this->item->setComment($a_data);
1516  break;
1517  case "assessment":
1518  $this->assessment->setComment($a_data);
1519  break;
1520  default:
1521  break;
1522  }
1523  break;
1524  }
1525  $this->sametag = TRUE;
1526  }
1527 
1531  function handlerVerifyBeginTag($a_xml_parser,$a_name,$a_attribs)
1532  {
1533  switch (strtolower($a_name))
1534  {
1535  case "questestinterop":
1536  $this->verifyroot = true;
1537  break;
1538  case "qtimetadatafield":
1539  $this->verifymetadatafield = 1;
1540  break;
1541  case "fieldlabel":
1542  $this->verifyfieldlabeltext = "";
1543  if ($this->verifymetadatafield == 1) $this->verifyfieldlabel = 1;
1544  break;
1545  case "fieldentry":
1546  $this->verifyfieldentrytext = "";
1547  if ($this->verifymetadatafield == 1) $this->verifyfieldentry = 1;
1548  break;
1549  case "item":
1550  $title = "";
1551  if (is_array($a_attribs))
1552  {
1553  foreach ($a_attribs as $attribute => $value)
1554  {
1555  switch (strtolower($attribute))
1556  {
1557  case "title":
1558  $title = $value;
1559  break;
1560  }
1561  }
1562  }
1563  array_push($this->founditems, array("title" => "$title", "type" => "", "ident" => $a_attribs["ident"]));
1564  break;
1565  case "response_lid":
1566  if (strlen($this->founditems[count($this->founditems)-1]["type"]) == 0)
1567  {
1568  // test for non ILIAS generated question types
1569  if (is_array($a_attribs))
1570  {
1571  foreach ($a_attribs as $attribute => $value)
1572  {
1573  switch (strtolower($attribute))
1574  {
1575  case "rcardinality":
1576  include_once "./Services/QTI/classes/class.ilQTIItem.php";
1577  switch (strtolower($value))
1578  {
1579  case "single":
1580  $this->founditems[count($this->founditems)-1]["type"] = QT_MULTIPLE_CHOICE_SR;
1581  break;
1582  case "multiple":
1583  $this->founditems[count($this->founditems)-1]["type"] = QT_MULTIPLE_CHOICE_MR;
1584  break;
1585  case "ordered":
1586  $this->founditems[count($this->founditems)-1]["type"] = QT_ORDERING;
1587  break;
1588  }
1589  break;
1590  }
1591  }
1592  }
1593  }
1594  break;
1595  case "response_str":
1596  if (strlen($this->founditems[count($this->founditems)-1]["type"]) == 0)
1597  {
1598  // test for non ILIAS generated question types
1599  if (is_array($a_attribs))
1600  {
1601  foreach ($a_attribs as $attribute => $value)
1602  {
1603  switch (strtolower($attribute))
1604  {
1605  case "rcardinality":
1606  include_once "./Services/QTI/classes/class.ilQTIItem.php";
1607  switch (strtolower($value))
1608  {
1609  case "single":
1610  $this->founditems[count($this->founditems)-1]["type"] = QT_CLOZE;
1611  break;
1612  case "ordered":
1613  $this->founditems[count($this->founditems)-1]["type"] = QT_TEXT;
1614  break;
1615  }
1616  break;
1617  }
1618  }
1619  }
1620  }
1621  break;
1622  case "response_xy":
1623  if (strlen($this->founditems[count($this->founditems)-1]["type"]) == 0)
1624  {
1625  $this->founditems[count($this->founditems)-1]["type"] = QT_IMAGEMAP;
1626  }
1627  break;
1628  case "response_num":
1629  if (strlen($this->founditems[count($this->founditems)-1]["type"]) == 0)
1630  {
1631  $this->founditems[count($this->founditems)-1]["type"] = QT_NUMERIC;
1632  }
1633  break;
1634  case "response_grp":
1635  if (strlen($this->founditems[count($this->founditems)-1]["type"]) == 0)
1636  {
1637  $this->founditems[count($this->founditems)-1]["type"] = QT_MATCHING;
1638  }
1639  break;
1640  case "qticomment":
1641  // check for "old" ILIAS qti format (not well formed)
1642  $this->verifyqticomment = 1;
1643  break;
1644  case "presentation":
1645  if (is_array($a_attribs))
1646  {
1647  foreach ($a_attribs as $attribute => $value)
1648  {
1649  switch (strtolower($attribute))
1650  {
1651  case "label":
1652  $this->founditems[count($this->founditems)-1]["title"] = $value;
1653  break;
1654  }
1655  }
1656  }
1657  break;
1658  }
1659  }
1660 
1664  function handlerVerifyEndTag($a_xml_parser,$a_name)
1665  {
1666  switch (strtolower($a_name))
1667  {
1668  case "qticomment":
1669  // check for "old" ILIAS qti format (not well formed)
1670  $this->verifyqticomment = 0;
1671  break;
1672  case "qtimetadatafield":
1673  $this->verifymetadatafield = 0;
1674  if (strcmp($this->verifyfieldlabeltext, "QUESTIONTYPE") == 0)
1675  {
1676  $this->founditems[count($this->founditems)-1]["type"] = $this->verifyfieldentrytext;
1677  }
1678  break;
1679  case "fieldlabel":
1680  $this->verifyfieldlabel = 0;
1681  break;
1682  case "fieldentry":
1683  $this->verifyfieldentry = 0;
1684  break;
1685  }
1686  }
1687 
1691  function handlerVerifyCharacterData($a_xml_parser,$a_data)
1692  {
1693  if ($this->verifyqticomment == 1)
1694  {
1695  if (preg_match("/Questiontype\=(.*)/", $a_data, $matches))
1696  {
1697  if (count($this->founditems))
1698  {
1699  $this->founditems[count($this->founditems)-1]["type"] = $matches[1];
1700  }
1701  }
1702  }
1703  else if ($this->verifyfieldlabel == 1)
1704  {
1705  $this->verifyfieldlabeltext = $a_data;
1706  }
1707  else if ($this->verifyfieldentry == 1)
1708  {
1709  $this->verifyfieldentrytext = $a_data;
1710  }
1711  }
1712 
1713  function &getFoundItems()
1714  {
1715  return $this->founditems;
1716  }
1717 
1722  function getImportMapping()
1723  {
1724  if (!is_array($this->import_mapping))
1725  {
1726  return array();
1727  }
1728  else
1729  {
1730  return $this->import_mapping;
1731  }
1732  }
1733 
1734  function setXMLContent($a_xml_content)
1735  {
1736  $a_xml_content = $this->cleanInvalidXmlChars($a_xml_content);
1737 
1738  return parent::setXMLContent($a_xml_content);
1739  }
1740 
1741  function openXMLFile()
1742  {
1743  $xmlContent = file_get_contents($this->xml_file);
1744  $xmlContent = $this->cleanInvalidXmlChars($xmlContent);
1745  file_put_contents($this->xml_file, $xmlContent);
1746 
1747  return parent::openXMLFile();
1748  }
1749 
1750  protected function fetchNumericVersionFromVersionDateString($versionDateString)
1751  {
1752  $matches = null;
1753 
1754  if( preg_match('/^(\d+\.\d+\.\d+) .*$/', $versionDateString, $matches) )
1755  {
1756  return $matches[1];
1757  }
1758 
1759  return null;
1760  }
1761 
1762  protected function fetchSourceNicFromItemIdent($itemIdent)
1763  {
1764  $matches = null;
1765 
1766  if( preg_match('/^il_(\d+?)_qst_\d+$/', $itemIdent, $matches) )
1767  {
1768  return $matches[1];
1769  }
1770 
1771  return null;
1772  }
1773 
1774  protected function cleanInvalidXmlChars($xmlContent)
1775  {
1776  // http://www.w3.org/TR/xml/#charsets
1777 
1778  // DOES ACTUALLY KILL CONTENT, SHOULD CLEAN NON ESCAPED ILLEGAL CHARS, DON'T KNOW
1779  //$reg = '/[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]/';
1780  //$xmlContent = preg_replace($reg, '', $xmlContent);
1781 
1782  // remove illegal chars escaped to html entities
1783  $needles = array();
1784  for($i = 0x00, $max = 0x08; $i <= $max; $i += 0x01)
1785  {
1786  $needles[] = "&#{$i};";
1787  }
1788  for($i = 0x0b, $max = 0x0c; $i <= $max; $i += 0x01)
1789  {
1790  $needles[] = "&#{$i};";
1791  }
1792  for($i = 0x0e, $max = 0x1f; $i <= $max; $i += 0x01)
1793  {
1794  $needles[] = "&#{$i};";
1795  }
1796  for($i = 0xd800, $max = 0xdfff; $i <= $max; $i += 0x0001)
1797  {
1798  $needles[] = "&#{$i};";
1799  }
1800  for($i = 0xfffe, $max = 0xffff; $i <= $max; $i += 0x0001)
1801  {
1802  $needles[] = "&#{$i};";
1803  }
1804  $reg = '/('.implode('|', $needles).')/';
1805  $xmlContent = preg_replace($reg, '', $xmlContent);
1806 
1807  return $xmlContent;
1808  }
1809 
1810  protected function isMatImageAvailable()
1811  {
1812  if( !$this->material )
1813  {
1814  return false;
1815  }
1816 
1817  if( !$this->matimage )
1818  {
1819  return false;
1820  }
1821 
1822  return true;
1823  }
1824 
1825  protected function virusDetected($buffer)
1826  {
1827  require_once 'Services/VirusScanner/classes/class.ilVirusScannerFactory.php';
1829 
1830  if( $vs === null )
1831  {
1832  return false; // no virus scan, no virus detected
1833  }
1834 
1835  return (bool)$vs->scanBuffer($buffer);
1836  }
1837 }
QTI assessment class.
const QT_MATCHING
setHandlers($a_xml_parser)
set event handler should be overwritten by inherited class private
Class ilQTIPresentationMaterial.
fetchSourceNicFromItemIdent($itemIdent)
const RESPONSEVAR_LTE
const RT_RESPONSE_LID
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
virusDetected($buffer)
const QT_TEXT
handlerParseCharacterData($a_xml_parser, $a_data)
handler for character data
const RT_RESPONSE_STR
const RESPONSEVAR_INSIDE
const RESPONSEVAR_SUBSTRING
const RT_RESPONSE_GRP
setXMLContent($a_xml_content)
fetchNumericVersionFromVersionDateString($versionDateString)
const QT_IMAGEMAP
const RESPONSEVAR_LT
const RESPONSEVAR_GT
const QT_MULTIPLE_CHOICE_SR
Base class for sax-based expat parsing extended classes need to overwrite the method setHandlers and ...
static isImportable($questionTypeTag)
handlerVerifyEndTag($a_xml_parser, $a_name)
handler for end of element verification
const RESPONSEVAR_GTE
handlerCharacterData($a_xml_parser, $a_data)
handler for character data
ilQTIParser($a_xml_file, $a_mode=IL_MO_PARSE_QTI, $a_qpl_id=0, $a_import_idents="")
Constructor.
$GLOBALS['ct_recipient']
const IL_MO_PARSE_QTI
const RESPONSEVAR_EQUAL
setTestObject(&$a_tst_object)
handlerVerifyBeginTag($a_xml_parser, $a_name, $a_attribs)
handler for begin of element verification
setParserMode($a_mode=IL_MO_PARSE_QTI)
handlerEndTag($a_xml_parser, $a_name)
handler for end of element
handlerParseEndTag($a_xml_parser, $a_name)
handler for end of element parser
const RESPONSEVAR_SUBSET
cleanInvalidXmlChars($xmlContent)
const QT_NUMERIC
handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
handler for begin of element
handlerVerifyCharacterData($a_xml_parser, $a_data)
handler for character data verification
& _getInstance()
Constructor public.
global $ilUser
Definition: imgupload.php:15
const RT_RESPONSE_XY
global $ilDB
getImportMapping()
get array of new created questions for import id
getParent($a_xml_parser)
const RT_RESPONSE_NUM
const QT_CLOZE
const QT_MULTIPLE_CHOICE_MR
const IL_MO_VERIFY_QTI
const QT_ORDERING
handlerParseBeginTag($a_xml_parser, $a_name, $a_attribs)
handler for begin of element parser