ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilQuestionPageParser.php
Go to the documentation of this file.
1 <?php
2 
20 
28 {
32  protected bool $in_properties;
36  protected bool $in_glossary_definition = false;
37  protected array $media_meta_cache = [];
38  protected bool $media_meta_start = false;
39  protected array $pg_mapping = [];
40  protected array $mobs_with_int_links = [];
41  protected bool $inside_code = false;
42  protected string $coType = "";
43  protected string $import_dir = "";
44  public ilTree $tree;
45  public array $cnt = []; // counts open elements
46  public array $current_element = []; // store current element type
47  public ?ilObjLearningModule $learning_module = null; // current learning module
48  public ?ilPageObject $page_object = null; // current page object
50  public array $structure_objects = []; // array of current structure objects
52  public ?object $current_object = null; // at the time a LearningModule, PageObject or StructureObject
53  public ?ilLMTree $lm_tree = null;
54  public array $pg_into_tree = [];
55  public array $st_into_tree = [];
56  public array $container = [];
57  public bool $in_page_object = false; // are we currently within a PageObject? true/false
58  public bool $in_meta_data = false; // are we currently within MetaData? true/false
59  public bool $in_media_object = false;
60  public bool $in_file_item = false;
61  public bool $in_glossary = false;
62  public bool $in_map_area = false;
63  public ?ilObject $content_object = null;
65  public ?ilObjFile $file_item = null;
66  public array $pages_to_parse = [];
67  public array $mob_mapping = [];
68  public array $file_item_mapping = [];
69  public string $subdir = "";
70  public ?ilMediaItem $media_item = null; // current media item
71  public string $loc_type = ""; // current location type
72  public ?ilMapArea $map_area = null; // current map area
73  public array $link_targets = []; // stores all objects by import id
74  public array $qst_mapping = [];
75  public bool $metadata_parsing_disabled = false;
76  public bool $in_meta_meta_data = false;
77  protected array $glossary_term_map = [];
78  protected ilLogger $log;
79  protected ?ilGlossaryTerm $glossary_term = null;
80  protected ?ilImportMapping $mapping = null;
81  protected string $cur_qid = "";
82  protected string $chr_data = "";
83  protected bool $in_media_item = false;
84 
85  public function __construct(
86  ilObject $a_content_object,
87  string $a_xml_file,
88  string $a_subdir,
89  string $a_import_dir = ""
90  ) {
91  global $DIC;
92 
93  $this->log = $DIC["ilLog"];
94  $lng = $DIC->language();
95  $tree = $DIC->repositoryTree();
96 
97  $this->log = ilLoggerFactory::getLogger('lm');
98 
99  $this->import_dir = ($a_import_dir != "")
100  ? $a_import_dir
101  : $a_content_object->getImportDirectory();
102 
103  parent::__construct($a_xml_file);
104  $this->cnt = [];
105  $this->current_element = [];
106  $this->structure_objects = [];
107  $this->content_object = $a_content_object;
108  $this->st_into_tree = [];
109  $this->pg_into_tree = [];
110  $this->pages_to_parse = [];
111  $this->mobs_with_int_links = [];
112  $this->mob_mapping = [];
113  $this->file_item_mapping = [];
114  $this->pg_mapping = [];
115  $this->link_targets = [];
116  $this->subdir = $a_subdir;
117  $this->lng = $lng;
118  $this->tree = $tree;
119  $this->inside_code = false;
120  $this->qst_mapping = [];
121  $this->coType = $this->content_object->getType();
122  $this->metadata_parsing_disabled = false;
123 
124  if (($this->coType != "tst") && ($this->coType != "qpl")) {
125  $this->lm_tree = new ilLMTree($this->content_object->getId());
126  }
127  }
128 
132  public function setHandlers($a_xml_parser): void
133  {
134  xml_set_object($a_xml_parser, $this);
135  xml_set_element_handler($a_xml_parser, 'handlerBeginTag', 'handlerEndTag');
136  xml_set_character_data_handler($a_xml_parser, 'handlerCharacterData');
137  }
138 
139  public function setImportMapping(ilImportMapping $mapping = null): void
140  {
141  $this->mapping = $mapping;
142  }
143 
144  public function startParsing(): void
145  {
146  $this->log->debug("start");
147 
148  //echo "<b>start parsing</b><br>";
149  parent::startParsing();
150  //echo "<b>storeTree</b><br>";
151  $this->storeTree();
152  //echo "<b>processPagesToParse</b><br>";
153  $this->processPagesToParse();
154  //echo "<b>copyMobFiles</b><br>";
155  $this->copyMobFiles();
156  //echo "<b>copyFileItems</b><br>";
157  $this->copyFileItems();
158  //echo "<br>END Parsing"; exit;
159  }
160 
164  public function storeTree(): void
165  {
166  $ilLog = $this->log;
167 
168  foreach ($this->st_into_tree as $st) {
169  $this->lm_tree->insertNode($st["id"], $st["parent"]);
170  if (is_array($this->pg_into_tree[$st["id"]])) {
171  foreach ($this->pg_into_tree[$st["id"]] as $pg) {
172  $pg_id = 0;
173  switch ($pg["type"]) {
174  case "pg_alias":
175  if ($this->pg_mapping[$pg["id"]] == "") {
176  $ilLog->write("LM Import: No PageObject for PageAlias " .
177  $pg["id"] . " found! (Please update export installation to ILIAS 3.3.0)");
178 
179  // Jump two levels up. First level is switch
180  continue 2;
181  }
182  $pg_id = $this->pg_mapping[$pg["id"]];
183  break;
184 
185  case "pg":
186  $pg_id = $pg["id"];
187  break;
188  }
189  if (!$this->lm_tree->isInTree($pg_id)) {
190  $this->lm_tree->insertNode($pg_id, $st["id"]);
191  }
192  }
193  }
194  }
195  }
196 
200  public function processPagesToParse(): void
201  {
202  // outgoin internal links
203  foreach ($this->pages_to_parse as $page_id) {
204  $page_arr = explode(":", $page_id);
205  $page_obj = null;
206  //echo "<br>resolve:".$this->content_object->getType().":".$page_id; flush();
207  switch ($page_arr[0]) {
208  case "lm":
209  switch ($this->content_object->getType()) {
210  case "lm":
211  $page_obj = new ilLMPage($page_arr[1]);
212  break;
213 
214  default:
215  die("Unknown content type " . $this->content_object->getType());
216  }
217 
218  break;
219 
220  case "term":
221  $page_obj = new ilGlossaryDefPage($page_arr[1]);
222  break;
223 
224  case "qpl":
225  $page_obj = new ilAssQuestionPage($page_arr[1]);
226  break;
227  }
228  $page_obj->buildDom();
229  $page_obj->resolveIntLinks();
230  $page_obj->resolveIIMMediaAliases($this->mob_mapping);
231  if ($this->coType == "lm") {
232  $page_obj->resolveQuestionReferences($this->qst_mapping);
233  }
234  $page_obj->update(false);
235 
236  if ($page_arr[0] == "term") {
237  $term = new ilGlossaryTerm($page_arr[1]);
238  $term->updateShortText();
239  }
240 
241  unset($page_obj);
242  }
243 
244  //echo "<br><b>map area internal links</b>"; flush();
245  // outgoins map area (mob) internal links
246  foreach ($this->mobs_with_int_links as $mob_id) {
248  }
249 
250  //echo "<br><b>incoming interna links</b>"; flush();
251  // incoming internal links
252  $done = [];
253  foreach ($this->link_targets as $link_target) {
254  $parsed = $this->parseLinkTarget((string) $link_target);
255  if (!isset($parsed)) {
256  continue;
257  }
258  //echo "doin link target:".$link_target.":<br>";
260  $parsed['target_type'],
261  $parsed['target_id'],
262  $parsed['target_inst']
263  );
264 
265  foreach ($sources as $key => $source) {
266  //echo "got source:".$key.":<br>";
267  if (in_array($key, $done)) {
268  continue;
269  }
270  $type_arr = explode(":", $source["type"]);
271 
272  // content object pages
273  if ($type_arr[1] == "pg") {
274  if (ilPageObject::_exists($type_arr[0], $source["id"])) {
275  $page_object = ilPageObjectFactory::getInstance($type_arr[0], $source["id"]);
276  $page_object->buildDom();
277  $page_object->resolveIntLinks();
278  $page_object->update();
279  unset($page_object);
280  }
281  }
282 
283  // eventually correct links in questions to learning modules
284  if ($type_arr[0] == "qst") {
285  assQuestion::instantiateQuestion($source['id'])->resolveSuggestedSolutionLinks();
286  }
287  // eventually correct links in survey questions to learning modules
288  if ($type_arr[0] == "sqst") {
289  SurveyQuestion::_resolveIntLinks($source["id"]);
290  }
291  $done[$key] = $key;
292  }
293  }
294  }
295 
296 
300  public function copyMobFiles(): void
301  {
302  $imp_dir = $this->import_dir;
303  foreach ($this->mob_mapping as $origin_id => $mob_id) {
304  if (empty($origin_id)) {
305  continue;
306  }
307 
308  $obj_dir = $origin_id;
309  $source_dir = $imp_dir . "/" . $this->subdir . "/objects/" . $obj_dir;
310  $target_dir = ilFileUtils::getWebspaceDir() . "/mobs/mm_" . $mob_id;
311 
312  if (is_dir($source_dir)) {
313  ilFileUtils::makeDir($target_dir);
314 
315  if (is_dir($target_dir)) {
316  ilLoggerFactory::getLogger("mob")->debug("s:-$source_dir-,t:-$target_dir-");
317  ilFileUtils::rCopy(realpath($source_dir), realpath($target_dir));
318  }
319  }
320  }
321  }
322 
326  public function copyFileItems(): void
327  {
328  $imp_dir = $this->import_dir;
329  foreach ($this->file_item_mapping as $origin_id => $file_id) {
330  if (empty($origin_id)) {
331  continue;
332  }
333  $obj_dir = $origin_id;
334  $source_dir = $imp_dir . "/" . $this->subdir . "/objects/" . $obj_dir;
335 
336  $file_obj = new ilObjFile($file_id, false);
337  if (is_dir($source_dir)) {
338  $files = scandir($source_dir, SCANDIR_SORT_DESCENDING);
339  if ($files !== false && $files !== [] && is_file($source_dir . '/' . $files[0])) {
340  $file = fopen($source_dir . '/' . $files[0], 'rb');
341  $file_stream = Streams::ofResource($file);
342  $file_obj->appendStream($file_stream, $files[0]);
343  }
344  }
345  $file_obj->update();
346  }
347  }
348 
353  public function setQuestionMapping(array $a_map): void
354  {
355  $this->qst_mapping = $a_map;
356  }
357 
358  public function beginElement(string $a_name): void
359  {
360  if (!isset($this->status["$a_name"])) {
361  $this->cnt[$a_name] = 1;
362  } else {
363  $this->cnt[$a_name]++;
364  }
365  $this->current_element[count($this->current_element)] = $a_name;
366  }
367 
368  public function endElement(string $a_name): void
369  {
370  $this->cnt[$a_name]--;
371  unset($this->current_element[count($this->current_element) - 1]);
372  }
373 
374  public function getCurrentElement(): string
375  {
376  return ($this->current_element[count($this->current_element) - 1] ?? "");
377  }
378 
379  public function getOpenCount(string $a_name): int
380  {
381  if (isset($this->cnt[$a_name])) {
382  return $this->cnt[$a_name];
383  }
384  return 0;
385  }
386 
387  public function buildTag(
388  string $type,
389  string $name,
390  array $attr = []
391  ): string {
392  $tag = "<";
393 
394  if ($type == "end") {
395  $tag .= "/";
396  }
397 
398  $tag .= $name;
399 
400  if (is_array($attr)) {
401  foreach ($attr as $k => $v) {
402  $tag .= " " . $k . "=\"$v\"";
403  }
404  }
405 
406  $tag .= ">";
407 
408  return $tag;
409  }
410 
411  public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs): void
412  {
413  switch ($a_name) {
414  case "ContentObject":
415  $this->current_object = $this->content_object;
416  if ($a_attribs["Type"] == "Glossary") {
417  $this->glossary_object = $this->content_object;
418  }
419  break;
420 
421  case "StructureObject":
423  $lm = $this->content_object;
424  $this->structure_objects[count($this->structure_objects)]
425  = new ilStructureObject($lm);
426  $this->current_object = $this->structure_objects[count($this->structure_objects) - 1];
427  $this->current_object->setLMId($this->content_object->getId());
428  // new meta data handling: we create the structure
429  // object already here, this should also create a
430  // md entry
431  $this->current_object->create(true);
432  break;
433 
434  case "PageObject":
435  $this->in_page_object = true;
436  $this->cur_qid = "";
437  if (($this->coType != "tst") && ($this->coType != "qpl")) {
439  $lm = $this->content_object;
440  $this->lm_page_object = new ilLMPageObject($lm);
441  $this->page_object = new ilLMPage();
442  $this->lm_page_object->setLMId($this->content_object->getId());
443  $this->lm_page_object->assignPageObject($this->page_object);
444  $this->current_object = $this->lm_page_object;
445  } else {
446  $this->page_object = new ilAssQuestionPage();
447  }
448  break;
449 
450  case "PageAlias":
451  throw new ilLMException("Page Alias not supported.");
452 
453  case "MediaObject":
454  case "InteractiveImage":
455  if ($a_name == "MediaObject") {
456  $this->in_media_object = true;
457  }
458  $this->media_meta_start = true;
459  $this->media_meta_cache = [];
460  $this->media_object = new ilObjMediaObject();
461  break;
462 
463  case "MediaAlias":
464  $this->media_object->setAlias(true);
465  $this->media_object->setImportId($a_attribs["OriginId"]);
466  if (is_object($this->page_object)) {
467  $this->page_object->needsImportParsing(true);
468  }
469  break;
470 
471  case "MediaItem":
472  case "MediaAliasItem":
473  $this->in_media_item = true;
474  $this->media_item = new ilMediaItem();
475  $this->media_item->setPurpose($a_attribs["Purpose"]);
476  break;
477 
478  case "Layout":
479  if (is_object($this->media_object) && $this->in_media_object) {
480  $this->media_item->setWidth($a_attribs["Width"] ?? '');
481  $this->media_item->setHeight($a_attribs["Height"] ?? '');
482  $this->media_item->setHAlign($a_attribs["HorizontalAlign"] ?? '');
483  }
484  break;
485 
486  case "Parameter":
487  if (is_object($this->media_object) && $this->in_media_object) {
488  $this->media_item->setParameter($a_attribs["Name"], $a_attribs["Value"]);
489  }
490  break;
491 
492  case "MapArea":
493  $this->in_map_area = true;
494  $this->map_area = new ilMapArea();
495  $this->map_area->setShape($a_attribs["Shape"]);
496  $this->map_area->setCoords($a_attribs["Coords"]);
497  $this->map_area->setHighlightMode($a_attribs["HighlightMode"]);
498  $this->map_area->setHighlightClass($a_attribs["HighlightClass"]);
499  break;
500 
501  case "Glossary":
502  $this->in_glossary = true;
503  if ($this->content_object->getType() != "glo") {
504  $this->glossary_object = new ilObjGlossary();
505  $this->glossary_object->setTitle("");
506  $this->glossary_object->setDescription("");
507  $this->glossary_object->create(true);
508  $this->glossary_object->createReference();
509  $parent = $this->tree->getParentNodeData($this->content_object->getRefId());
510  $this->glossary_object->putInTree($parent["child"]);
511  $this->glossary_object->setPermissions($parent["child"]);
512  }
513  $this->current_object = $this->glossary_object;
514  break;
515 
516  case "GlossaryItem":
517  $this->glossary_term = new ilGlossaryTerm();
518  $this->glossary_term->setGlossaryId($this->glossary_object->getId());
519  $this->glossary_term->setLanguage($a_attribs["Language"]);
520  $this->glossary_term->setImportId($a_attribs["Id"]);
521  $parsed = $this->parseLinkTarget((string) $a_attribs["Id"]);
522  if (isset($parsed)) {
523  $this->link_targets[$a_attribs["Id"]] = $a_attribs["Id"];
524  }
525  break;
526 
527  case "Definition":
528  $this->in_glossary_definition = true;
529  $this->page_object = new ilGlossaryDefPage();
530  $this->page_object->setParentId($this->glossary_term->getGlossaryId());
531  $this->glossary_term->assignPageObject($this->page_object);
532  $this->current_object = $this->glossary_term;
533  // see bug #12465, we need to clear xml after creation, since it will be <PageObject></PageObject>
534  // otherwise, and appendXML calls will lead to "<PageObject></PageObject><PageObject>....</PageObject>"
535  $this->page_object->setXMLContent("");
536  break;
537 
538  case "FileItem":
539  $this->in_file_item = true;
540  $this->file_item = new ilObjFile();
541  $this->file_item->setTitle("dummy");
542  $this->file_item->setMode("filelist");
543  if (is_object($this->page_object)) {
544  $this->page_object->needsImportParsing(true);
545  }
546  break;
547 
548  case "Paragraph":
549  if ($a_attribs["Characteristic"] == "Code") {
550  $this->inside_code = true;
551  }
552  break;
553 
554  case "Properties":
555  $this->in_properties = true;
556  break;
557 
558  case "Property":
559  if ($this->content_object->getType() == "lm") {
560  switch ($a_attribs["Name"]) {
561  case "Layout":
562  $this->content_object->setLayout($a_attribs["Value"]);
563  break;
564 
565  case "PageHeader":
566  $this->content_object->setPageHeader($a_attribs["Value"]);
567  break;
568 
569  case "TOCMode":
570  $this->content_object->setTOCMode($a_attribs["Value"]);
571  break;
572 
573  case "ActiveLMMenu":
574  $this->content_object->setActiveLMMenu(
575  ilUtil::yn2tf($a_attribs["Value"])
576  );
577  break;
578 
579  case "ActiveNumbering":
580  $this->content_object->setActiveNumbering(
581  ilUtil::yn2tf($a_attribs["Value"])
582  );
583  break;
584 
585  case "ActiveTOC":
586  $this->content_object->setActiveTOC(
587  ilUtil::yn2tf($a_attribs["Value"])
588  );
589  break;
590 
591  case "ActivePrintView":
592  $this->content_object->setActivePrintView(
593  ilUtil::yn2tf($a_attribs["Value"])
594  );
595  break;
596 
597  case "CleanFrames":
598  $this->content_object->setCleanFrames(
599  ilUtil::yn2tf($a_attribs["Value"])
600  );
601  break;
602 
603  case "PublicNotes":
604  $this->content_object->setPublicNotes(
605  ilUtil::yn2tf($a_attribs["Value"])
606  );
607  break;
608 
609  case "HistoryUserComments":
610  $this->content_object->setHistoryUserComments(
611  ilUtil::yn2tf($a_attribs["Value"])
612  );
613  break;
614 
615  case "Rating":
616  $this->content_object->setRating(
617  ilUtil::yn2tf($a_attribs["Value"])
618  );
619  break;
620 
621  case "RatingPages":
622  $this->content_object->setRatingPages(
623  ilUtil::yn2tf($a_attribs["Value"])
624  );
625  break;
626 
627  case "HeaderPage":
628  if ($a_attribs["Value"] != "") {
629  if ($this->pg_mapping[$a_attribs["Value"]] > 0) {
630  $this->content_object->setHeaderPage(
631  $this->pg_mapping[$a_attribs["Value"]]
632  );
633  }
634  }
635  break;
636 
637  case "FooterPage":
638  if ($a_attribs["Value"] != "") {
639  if ($this->pg_mapping[$a_attribs["Value"]] > 0) {
640  $this->content_object->setFooterPage(
641  $this->pg_mapping[$a_attribs["Value"]]
642  );
643  }
644  }
645  break;
646 
647  case "LayoutPerPage":
648  $this->content_object->setLayoutPerPage($a_attribs["Value"]);
649  break;
650 
651  case "ProgressIcons":
652  $this->content_object->setProgressIcons($a_attribs["Value"]);
653  break;
654 
655  case "StoreTries":
656  $this->content_object->setStoreTries($a_attribs["Value"]);
657  break;
658 
659  case "RestrictForwardNavigation":
660  $this->content_object->setRestrictForwardNavigation($a_attribs["Value"]);
661  break;
662 
663  case "DisableDefaultFeedback":
664  $this->content_object->setDisableDefaultFeedback($a_attribs["Value"]);
665  break;
666  }
667  }
668  break;
669 
673  case "MetaData":
674  $this->in_meta_data = true;
675  // media obejct meta data handling
676  // is done in the "Identifier" begin tag processing
677  // the rest is done here
678  if (!$this->in_media_object) {
679  if (($this->coType != "tst") && ($this->coType != "qpl")) {
680  // type pg/st
681  if ($this->current_object->getType() == "st" ||
682  $this->current_object->getType() == "pg") {
683  // late creation of page object
684  if ($this->current_object->getType() == "pg") {
685  $this->lm_page_object->create(true);
686  }
687  $this->md = new ilMD(
688  $this->content_object->getId(),
689  $this->current_object->getId(),
690  $this->current_object->getType()
691  );
692  }
693  // type term
694  elseif ($this->current_object->getType() == "term") {
695  $this->md = new ilMD(
696  $this->glossary_object->getId(),
697  $this->current_object->getId(),
698  $this->current_object->getType()
699  );
700  }
701  // type lm, dbk, glo
702  else {
703  if ($this->processMeta()) {
704  $this->md = new ilMD(
705  $this->current_object->getId(),
706  0,
707  $this->current_object->getType()
708  );
709  }
710  }
711  } else {
712  // type qpl or tst
713  $this->md = new ilMD(
714  $this->content_object->getId(),
715  0,
716  $this->current_object->getType()
717  );
718  if ($this->md->getGeneral() != false) {
719  $this->metadata_parsing_disabled = true;
720  $this->enableMDParsing(false);
721  }
722  }
723  }
724  break;
725 
726  // Identifier
727  case "Identifier":
728 
729  // begin-patch optes_lok_export
730  if ($this->in_meta_data && $this->current_object instanceof ilStructureObject) {
731  if ($this->mapping instanceof ilImportMapping) {
732  $import_id_parsed = ilUtil::parseImportId($a_attribs['Entry']);
733  if ($import_id_parsed['type'] == 'st') {
734  $this->mapping->addMapping(
735  'Modules/LearningModule',
736  'lm_tree',
737  $import_id_parsed['id'],
738  $this->current_object->getId()
739  );
740  }
741  }
742  }
743  // end-patch optes_lok_export
744 
745  // please note: Meta-Metadata and MetaData are different tags!
746  if (!$this->in_meta_meta_data) {
747  if ($this->in_meta_data && !$this->in_glossary_definition) {
748  if (!$this->in_media_object) {
749  $this->current_object->setImportId($a_attribs["Entry"]);
750  }
751  // #40680 add a link target only if it is an internal ILIAS link
752  // Export from IMS UCAN sets something like 'IMSm-i1e79762'
753  $parsed = $this->parseLinkTarget($a_attribs["Entry"]);
754  if (isset($parsed)) {
755  $this->link_targets[$a_attribs["Entry"]] = $a_attribs["Entry"];
756  }
757  }
758  if ($this->in_file_item) {
759  if (!isset($this->file_item_mapping[$a_attribs["Entry"]])
760  || $this->file_item_mapping[$a_attribs["Entry"]] === "") {
761  $this->file_item->create();
762  $this->file_item->setImportId($a_attribs["Entry"]);
763  $this->file_item_mapping[$a_attribs["Entry"]] = $this->file_item->getId();
764  }
765  }
766  if ($this->in_meta_data && $this->in_media_object) {
767  //echo "looking for -".$a_attribs["Entry"]."-<br>";
768 
769  $mob_id = $this->mob_mapping[$a_attribs["Entry"]];
770 
771  // within learning module import, usually a media object
772  // has already been created with a media alias tag
773  if ($mob_id > 0) {
774  $this->media_object = new ilObjMediaObject($mob_id);
775  } else { // in glossaries the media objects precede the definitions
776  // so we don't have an object already
777  $this->media_object = new ilObjMediaObject();
778  $this->media_object->create(true, false);
779  $this->mob_mapping[$a_attribs["Entry"]]
780  = $this->media_object->getId();
781  }
782  $this->media_object->setImportId($a_attribs["Entry"]);
783  $this->md = new ilMD(
784  0,
785  $this->media_object->getId(),
786  "mob"
787  );
788  $this->emptyMediaMetaCache($a_xml_parser);
789  }
790  }
791  break;
792 
793  case "Meta-Metadata":
794  $this->in_meta_meta_data = true;
795  break;
796 
797  // Internal Link
798  case "IntLink":
799  if (is_object($this->page_object)) {
800  $this->page_object->setContainsIntLink(true);
801  }
802  if ($this->in_map_area) {
803  //echo "intlink:maparea:<br>";
804  $this->map_area->setLinkType(IL_INT_LINK);
805  $this->map_area->setTarget($a_attribs["Target"]);
806  $this->map_area->setType($a_attribs["Type"]);
807  $this->map_area->setTargetFrame($a_attribs["TargetFrame"]);
808  if (is_object($this->media_object)) {
809  //echo ":setContainsLink:<br>";
810  $this->media_object->setContainsIntLink(true);
811  }
812  }
813  break;
814 
815  // External Link
816  case "ExtLink":
817  if ($this->in_map_area) {
818  $this->map_area->setLinkType(IL_EXT_LINK);
819  $this->map_area->setHref($a_attribs["Href"]);
820  $this->map_area->setExtTitle($a_attribs["Title"]);
821  }
822  break;
823 
824  // Question
825  case "Question":
826  $this->cur_qid = $a_attribs["QRef"];
827  $this->page_object->setContainsQuestion(true);
828  break;
829 
830  case "Location":
831  $this->loc_type = $a_attribs["Type"];
832  break;
833  }
834  $this->beginElement($a_name);
835 
836  // append content to page xml content
837  if (($this->in_page_object || $this->in_glossary_definition)
838  && !$this->in_meta_data && !$this->in_media_object) {
839  if ($a_name == "Definition") {
840  $app_name = "PageObject";
841  $app_attribs = [];
842  } else {
843  $app_name = $a_name;
844  $app_attribs = $a_attribs;
845  }
846 
847  // change identifier entry of file items to new local file id
848  if ($this->in_file_item && $app_name == "Identifier") {
849  $app_attribs["Entry"] = "il__file_" . $this->file_item_mapping[$a_attribs["Entry"]];
850  }
851 
852  $this->page_object->appendXMLContent($this->buildTag("start", $app_name, $app_attribs));
853  }
854 
855 
856  // call meta data handler
857  if ($this->in_meta_data && $this->processMeta()) {
858  // cache beginning of meta data within media object tags
859  // (we need to know the id at the begin of meta elements within
860  // media objects, after the "Identifier" tag has been processed
861  // we send the cached data to the meta xml handler)
862  if ($this->in_media_object && $this->media_meta_start) {
863  $this->media_meta_cache[] =
864  ["type" => "handlerBeginTag", "par1" => $a_name, "par2" => $a_attribs];
865  } else {
866  if ($a_name == "Identifier") {
867  if (!$this->in_media_object) {
868  $a_attribs["Entry"] = "il__" . $this->current_object->getType() .
869  "_" . $this->current_object->getId();
870  } else {
871  $a_attribs["Entry"] = "il__mob" .
872  "_" . $this->media_object->getId();
873  }
874  $a_attribs["Catalog"] = "ILIAS";
875  }
876 
877  parent::handlerBeginTag($a_xml_parser, $a_name, $a_attribs);
878  }
879  }
880  }
881 
882  public function processMeta(): bool
883  {
884  // do not process second meta block in (ilias3) glossaries
885  // which comes right after the "Glossary" tag
886  if ($this->content_object->getType() == "glo" &&
887  $this->in_glossary && !$this->in_media_object
889  return false;
890  }
891 
892  return true;
893  }
894 
895 
896  public function handlerEndTag($a_xml_parser, string $a_name): void
897  {
898  // call meta data handler
899  if ($this->in_meta_data && $this->processMeta()) {
900  // cache beginning of meta data within media object tags
901  // (we need to know the id, after that we send the cached data
902  // to the meta xml handler)
903  if ($this->in_media_object && $this->media_meta_start) {
904  $this->media_meta_cache[] =
905  ["type" => "handlerEndTag", "par1" => $a_name];
906  } else {
907  parent::handlerEndTag($a_xml_parser, $a_name);
908  }
909  }
910 
911  // append content to page xml content
912  if (($this->in_page_object || $this->in_glossary_definition)
913  && !$this->in_meta_data && !$this->in_media_object) {
914  $app_name = ($a_name == "Definition")
915  ? "PageObject"
916  : $a_name;
917  $this->page_object->appendXMLContent($this->buildTag("end", $app_name));
918  }
919 
920  switch ($a_name) {
921  case "StructureObject":
922  unset($this->structure_objects[count($this->structure_objects) - 1]);
923  break;
924 
925  case "PageObject":
926 
927  $this->in_page_object = false;
928  if (($this->coType != "tst") && ($this->coType != "qpl")) {
929  //if (!$this->lm_page_object->isAlias()) {
930  $this->page_object->updateFromXML();
931  $this->pg_mapping[$this->lm_page_object->getImportId()]
932  = $this->lm_page_object->getId();
933 
934  if ($this->mapping instanceof ilImportMapping) {
935  $import_id_parsed = ilUtil::parseImportId($this->lm_page_object->getImportId());
936  if ($import_id_parsed['type'] == 'pg') {
937  $this->mapping->addMapping(
938  'Modules/LearningModule',
939  'pg',
940  $import_id_parsed['id'],
941  $this->lm_page_object->getId()
942  );
943  }
944  }
945 
946  // collect pages with internal links
947  if ($this->page_object->containsIntLink()) {
948  $this->pages_to_parse["lm:" . $this->page_object->getId()] = "lm:" . $this->page_object->getId();
949  }
950 
951  // collect pages with mobs or files
952  if ($this->page_object->needsImportParsing()) {
953  $this->pages_to_parse["lm:" . $this->page_object->getId()] = "lm:" . $this->page_object->getId();
954  }
955 
956  // collect pages with questions
957  if ($this->page_object->getContainsQuestion()) {
958  $this->pages_to_parse["lm:" . $this->page_object->getId()] = "lm:" . $this->page_object->getId();
959  }
960  //}
961  } else {
962  $xml = $this->page_object->getXMLContent();
963  if ($this->cur_qid != "") {
964  $ids = $this->qst_mapping[$this->cur_qid] ?? ['pool' => 0, 'test' => 0];
965  if ($ids["pool"] > 0) {
966  // question pool question
967  $page = new ilAssQuestionPage($ids["pool"]);
968  $xmlcontent = str_replace(
969  $this->cur_qid,
970  "il__qst_" . $ids["pool"],
971  $xml
972  );
973  $page->setXMLContent($xmlcontent);
974  $page->updateFromXML();
975  if ($this->page_object->needsImportParsing()) {
976  $this->pages_to_parse["qpl:" . $page->getId()] = "qpl:" . $page->getId();
977  }
978  unset($page);
979  }
980  if ($ids["test"] > 0) {
981  // test question
982  $page = new ilAssQuestionPage($ids["test"]);
983  $xmlcontent = str_replace(
984  $this->cur_qid,
985  "il__qst_" . $ids["test"],
986  $xml
987  );
988  $page->setXMLContent($xmlcontent);
989  $page->updateFromXML();
990  if ($this->page_object->needsImportParsing()) {
991  $this->pages_to_parse["qpl:" . $page->getId()] = "qpl:" . $page->getId();
992  }
993  unset($page);
994  }
995  }
996  }
997 
998  // if we are within a structure object: put page in tree
999  $cnt = count($this->structure_objects);
1000  if ($cnt > 0) {
1001  $parent_id = $this->structure_objects[$cnt - 1]->getId();
1002  //if ($this->lm_page_object->isAlias()) {
1003  // $this->pg_into_tree[$parent_id][] = array("type" => "pg_alias", "id" => $this->lm_page_object->getOriginId());
1004  //} else {
1005  $this->pg_into_tree[$parent_id][] = ["type" => "pg", "id" => $this->lm_page_object->getId()];
1006  //}
1007  }
1008 
1009  unset($this->page_object);
1010  unset($this->lm_page_object);
1011  unset($this->container[count($this->container) - 1]);
1012  break;
1013 
1014  case "MediaObject":
1015  case "InteractiveImage":
1016  if ($a_name == "MediaObject") {
1017  $this->in_media_object = false;
1018  }
1019 
1020  if (empty($this->mob_mapping[$this->media_object->getImportId()])) {
1021  // create media object
1022  // media items are saves for mobs outside of
1023  // pages only
1024  $this->media_object->create(true, false);
1025 
1026  // collect mobs with internal links
1027  if ($this->media_object->containsIntLink()) {
1028  //echo "got int link :".$this->media_object->getId().":<br>";
1029  $this->mobs_with_int_links[] = $this->media_object->getId();
1030  }
1031 
1032  $this->mob_mapping[$this->media_object->getImportId()]
1033  = $this->media_object->getId();
1034  } else {
1035  // get the id from mapping
1036  $this->media_object->setId($this->mob_mapping[$this->media_object->getImportId()]);
1037 
1038  // update "real" (no alias) media object
1039  // (note: we overwrite any data from the media object
1040  // created by an MediaAlias, only the data of the real
1041  // object is stored in db separately; data of the
1042  // MediaAliases are within the page XML
1043  if (!$this->media_object->isAlias()) {
1044  // now the media items are saved within the db
1045  $this->media_object->update();
1046 
1047  //echo "<br>update media object :".$this->media_object->getId().":";
1048 
1049  // collect mobs with internal links
1050  if ($this->media_object->containsIntLink()) {
1051  //echo "got int link :".$this->media_object->getId().":<br>";
1052  $this->mobs_with_int_links[] = $this->media_object->getId();
1053  }
1054  }
1055  }
1056 
1057  // append media alias to page, if we are in a page
1058  if ($this->in_page_object || $this->in_glossary_definition) {
1059  if ($a_name != "InteractiveImage") {
1060  $this->page_object->appendXMLContent($this->media_object->getXML(IL_MODE_ALIAS));
1061  //echo "Appending:".htmlentities($this->media_object->getXML(IL_MODE_ALIAS))."<br>";
1062  }
1063  }
1064 
1065  break;
1066 
1067  case "MediaItem":
1068  case "MediaAliasItem":
1069  $this->in_media_item = false;
1070  $this->media_object->addMediaItem($this->media_item);
1071  break;
1072 
1073  case "MapArea":
1074  $this->in_map_area = false;
1075  $this->media_item->addMapArea($this->map_area);
1076  break;
1077 
1078  case "Properties":
1079  $this->in_properties = false;
1080  if ($this->content_object->getType() == "lm") {
1081  $this->content_object->update();
1082  }
1083  break;
1084 
1085  case "MetaData":
1086  $this->in_meta_data = false;
1087  if (strtolower(get_class($this->current_object)) == "illmpageobject" && !$this->in_media_object) {
1088  // Metadaten eines PageObjects sichern in NestedSet
1089  if (is_object($this->lm_page_object)) {
1090  // update title/description of page object
1091  $this->current_object->MDUpdateListener('General');
1093  $this->current_object->getId(),
1094  $this->current_object->getImportId()
1095  );
1096  }
1097  } elseif ((strtolower(get_class($this->current_object)) == "ilobjquestionpool" ||
1098  strtolower(get_class($this->current_object)) == "ilobjtest") &&
1099  !$this->in_media_object) {
1100  // !$this->in_media_object && !$this->in_page_object)
1101  // changed for imports of ILIAS 2 Tests where PageObjects could have
1102  // Metadata sections (Helmut Schottmüller, 2005-12-02)
1103  if ($this->metadata_parsing_disabled) {
1104  $this->enableMDParsing(true);
1105  } else {
1106  if ($this->in_page_object && !is_null($this->page_object)) {
1107  /*
1108  $this->page_object->MDUpdateListener('General');
1109  ilLMObject::_writeImportId(
1110  $this->page_object->getId(),
1111  $this->page_object->getImportId()
1112  );*/
1113  } else {
1114  $this->current_object->MDUpdateListener('General');
1116  $this->current_object->getId(),
1117  $this->current_object->getImportId()
1118  );
1119  }
1120  }
1121  } elseif (strtolower(get_class($this->current_object)) == "ilstructureobject") { // save structure object at the end of its meta block
1122  // determine parent
1123  $cnt = count($this->structure_objects);
1124  if ($cnt > 1) {
1125  $parent_id = $this->structure_objects[$cnt - 2]->getId();
1126  } else {
1127  $parent_id = $this->lm_tree->getRootId();
1128  }
1129 
1130  $this->st_into_tree[] = ["id" => $this->current_object->getId(),
1131  "parent" => $parent_id];
1132 
1133  // update title/description of structure object
1134  $this->current_object->MDUpdateListener('General');
1136  $this->current_object->getId(),
1137  $this->current_object->getImportId()
1138  );
1139  } elseif (strtolower(get_class($this->current_object)) == "ilobjlearningmodule" ||
1140  strtolower(get_class($this->current_object)) == "ilobjcontentobject" ||
1141  (strtolower(get_class($this->current_object)) == "ilobjglossary" && $this->in_glossary)) {
1142  // todo: saving of md? getting title/descr and
1143  // set it for current object
1144  } elseif (strtolower(get_class($this->current_object)) == "ilglossaryterm" && !$this->in_media_object) {
1145  // now on top
1146 
1147  $this->page_object->setId($this->glossary_term->getId());
1148  $this->page_object->updateFromXML();
1149 
1150  // todo: saving of md? getting title/descr and
1151  // set it for current object
1152  }
1153 
1154 
1155  if (strtolower(get_class($this->current_object)) == "ilobjlearningmodule" ||
1156  strtolower(get_class($this->current_object)) == "ilobjglossary") {
1157  if (strtolower(get_class($this->current_object)) == "ilobjglossary" &&
1158  $this->content_object->getType() != "glo") {
1159  //echo "<br><b>getting2: ".$this->content_object->getTitle()."</b>";
1160  $this->current_object->setTitle($this->content_object->getTitle() . " - " .
1161  $this->lng->txt("glossary"));
1162  }
1163 
1164  $this->current_object->MDUpdateListener('General');
1165  /*
1166  if (!$this->in_media_object && $this->processMeta())
1167  {
1168  $this->current_object->update();
1169  }
1170  */
1171  }
1172 
1173  if ($this->in_media_object) {
1174  //echo "<br>call media object update listener";
1175  $this->media_object->MDUpdateListener('General');
1176  }
1177 
1178  break;
1179 
1180  case "Meta-Metadata":
1181  $this->in_meta_meta_data = false;
1182  break;
1183 
1184  case "FileItem":
1185  $this->in_file_item = false;
1186  // only update new file items
1187  if ($this->file_item->getImportId()) {
1188  $this->file_item->update();
1189  }
1190  break;
1191 
1192 
1193  case "Table":
1194  unset($this->container[count($this->container) - 1]);
1195  break;
1196 
1197  case "Glossary":
1198  $this->in_glossary = false;
1199  break;
1200 
1201  case "GlossaryTerm":
1202  $term = trim($this->chr_data);
1203  $term = str_replace("&lt;", "<", $term);
1204  $term = str_replace("&gt;", ">", $term);
1205  $this->glossary_term->setTerm($term);
1206  $this->glossary_term->create();
1207  $iia = explode("_", $this->glossary_term->getImportId());
1208  $this->glossary_term_map[(int) $iia[count($iia) - 1]] = $this->glossary_term->getId();
1209  break;
1210 
1211  case "Paragraph":
1212  $this->inside_code = false;
1213  break;
1214 
1215  case "Definition":
1216  $this->in_glossary_definition = false;
1217  $this->page_object->updateFromXML();
1218  $this->page_object->buildDom();
1219  $this->glossary_term->setShortText($this->page_object->getFirstParagraphText());
1220  $this->glossary_term->update();
1221  if ($this->page_object->containsIntLink()) {
1222  $this->pages_to_parse["term:" . $this->page_object->getId()] = "term:" . $this->page_object->getId();
1223  }
1224  if ($this->page_object->needsImportParsing()) {
1225  $this->pages_to_parse["term:" . $this->page_object->getId()] = "term:" . $this->page_object->getId();
1226  }
1227  break;
1228 
1229  case "Format":
1230  if ($this->in_media_item) {
1231  $this->media_item->setFormat(trim($this->chr_data));
1232  }
1233  break;
1234 
1235  case "Title":
1236  if ($this->in_meta_data && !$this->in_media_object) {
1237  $this->current_object->setTitle(trim($this->chr_data));
1238  }
1239  if ($this->in_media_object) {
1240  $this->media_object->setTitle(trim($this->chr_data));
1241  }
1242  break;
1243 
1244  case "Description":
1245  case "Language":
1246  break;
1247 
1248  case "Caption":
1249  if ($this->in_media_object) {
1250  $this->media_item->setCaption(trim($this->chr_data));
1251  }
1252  break;
1253 
1254  case "TextRepresentation":
1255  if ($this->in_media_object) {
1256  $this->media_item->setTextRepresentation(trim($this->chr_data));
1257  }
1258  break;
1259 
1260  // Location
1261  case "Location":
1262  // TODO: adapt for files in "real" subdirectories
1263  if ($this->in_media_item) {
1264  $this->media_item->setLocationType($this->loc_type);
1265  if ($this->loc_type == "Reference") {
1266  $this->media_item->setLocation(str_replace("&", "&amp;", trim($this->chr_data)));
1267  } else {
1268  $this->media_item->setLocation(trim($this->chr_data));
1269  }
1270  }
1271  if ($this->in_file_item) {
1272  // set file name from xml file
1273  $this->file_item->setFileName(trim($this->chr_data));
1274 
1275  // special handling for file names with special characters
1276  // (e.g. "&gt;")
1277  if ($this->file_item->getType() == "file" &&
1278  is_int(strpos($this->chr_data, "&")) &&
1279  is_int(strpos($this->chr_data, ";"))) {
1280  $imp_dir = $this->import_dir;
1281  $source_dir = $imp_dir . "/" . $this->subdir . "/objects/" .
1282  $this->file_item->getImportId();
1283 
1284  // read "physical" file name from directory
1285  if ($dir = opendir($source_dir)) {
1286  while (false !== ($file = readdir($dir))) {
1287  if ($file != "." && $file != "..") {
1288  $this->file_item->setFileName($file);
1289  }
1290  }
1291  closedir($dir);
1292  }
1293  }
1294 
1295  // set file item title
1296  $this->file_item->setTitle(trim($this->chr_data));
1297  }
1298  break;
1299  }
1300  $this->endElement($a_name);
1301  $this->chr_data = "";
1302  }
1303 
1304  public function handlerCharacterData($a_xml_parser, string $a_data): void
1305  {
1306  // call meta data handler
1307  if ($this->in_meta_data && $this->processMeta()) {
1308  // cache beginning of meta data within media object tags
1309  // (we need to know the id, after that we send the cached data
1310  // to the meta xml handler)
1311  if ($this->in_media_object && $this->media_meta_start) {
1312  $this->media_meta_cache[] =
1313  ["type" => "handlerCharacterData", "par1" => $a_data];
1314  } else {
1315  parent::handlerCharacterData($a_xml_parser, $a_data);
1316  }
1317  }
1318 
1319  // the parser converts "&gt;" to ">" and "&lt;" to "<"
1320  // in character data, but we don't want that, because it's the
1321  // way we mask user html in our content, so we convert back...
1322 
1323  $a_data = str_replace("<", "&lt;", $a_data);
1324  $a_data = str_replace(">", "&gt;", $a_data);
1325 
1326 
1327  // DELETE WHITESPACES AND NEWLINES OF CHARACTER DATA
1328  $a_data = preg_replace("/\n/", "", $a_data);
1329  if (!$this->inside_code) {
1330  $a_data = preg_replace("/\t+/", "", $a_data);
1331  }
1332 
1333  $this->chr_data .= $a_data;
1334 
1335  if (!empty($a_data) || $a_data === "0") {
1336  // append all data to page, if we are within PageObject,
1337  // but not within MetaData or MediaObject
1338  if (($this->in_page_object || $this->in_glossary_definition)
1339  && !$this->in_meta_data && !$this->in_media_object) {
1340  $this->page_object->appendXMLContent($a_data);
1341  }
1342 
1343  switch ($this->getCurrentElement()) {
1344  case "IntLink":
1345  case "ExtLink":
1346  if ($this->in_map_area) {
1347  $this->map_area->appendTitle($a_data);
1348  }
1349  break;
1350  }
1351  }
1352  }
1353 
1357  public function emptyMediaMetaCache($a_xml_parser): void
1358  {
1359  foreach ($this->media_meta_cache as $cache_entry) {
1360  switch ($cache_entry["type"]) {
1361  case "handlerBeginTag":
1362  parent::handlerBeginTag(
1363  $a_xml_parser,
1364  $cache_entry["par1"],
1365  $cache_entry["par2"]
1366  );
1367  break;
1368 
1369  case "handlerEndTag":
1370  parent::handlerEndTag(
1371  $a_xml_parser,
1372  $cache_entry["par1"]
1373  );
1374  break;
1375 
1376  case "handlerCharacterData":
1377  parent::handlerCharacterData(
1378  $a_xml_parser,
1379  $cache_entry["par1"]
1380  );
1381  break;
1382  }
1383  }
1384 
1385  $this->media_meta_start = false;
1386  $this->media_meta_cache[] = [];
1387  }
1388 
1392  public function getGlossaryTermMap(): array
1393  {
1394  return $this->glossary_term_map;
1395  }
1396 
1402  private function parseLinkTarget(string $identifier): ?array
1403  {
1404  $link_arr = explode('_', $identifier);
1405 
1406  if (count($link_arr) !== 4
1407  || $link_arr[0] !== 'il'
1408  || !is_numeric($link_arr[1])
1409  || !is_numeric($link_arr[3])
1410  ) {
1411  return null;
1412  }
1413 
1414  return [
1415  'target_inst' => (int) $link_arr[1],
1416  'target_type' => (string) $link_arr[2],
1417  'target_id' => (int) $link_arr[3]
1418  ];
1419  }
1420 }
static getWebspaceDir(string $mode="filesystem")
get webspace directory
processPagesToParse()
parse pages that contain files, mobs and/or internal links
enableMDParsing(bool $a_status)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
buildDom(bool $a_force=false)
static getLogger(string $a_component_id)
Get component logger.
buildTag(string $type, string $name, array $attr=[])
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
handlerEndTag($a_xml_parser, string $a_name)
write(string $message, $level=ilLogLevel::INFO, array $context=[])
write log message
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs)
resolveIntLinks(array $a_link_map=null)
Resolves all internal link targets of the page, if targets are available (after import) ...
update(bool $a_validate=true, bool $a_no_history=false)
update complete page content in db (dom xml content is used)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static rCopy(string $a_sdir, string $a_tdir, bool $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
setImportMapping(ilImportMapping $mapping=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
copyMobFiles()
copy multimedia object files from import zip file to mob directory
ilLanguage $lng
parseLinkTarget(string $identifier)
Parse a string the get the elements of a link target Return null if the string is not a link target...
global $DIC
Definition: feed.php:28
static instantiateQuestion(int $question_id)
setQuestionMapping(array $a_map)
set question import ident to pool/test question id mapping
__construct(VocabulariesInterface $vocabularies)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(ilObject $a_content_object, string $a_xml_file, string $a_subdir, string $a_import_dir="")
const IL_INT_LINK
handlerCharacterData($a_xml_parser, string $a_data)
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
Class ilPageObject Handles PageObjects of ILIAS Learning Modules (see ILIAS DTD)
Class ilObjFile.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $key
Consumer key/client ID value.
Definition: System.php:193
Legacy Content Object Parser.
static _resolveIntLinks(int $question_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static parseImportId(string $a_import_id)
Parse an ilias import id Typically of type il_[IL_INST_ID]_[OBJ_TYPE]_[OBJ_ID] returns array( &#39;orig&#39; ...
const IL_MODE_ALIAS
static _writeImportId(int $a_id, string $a_import_id)
static _resolveMapAreaLinks(int $a_mob_id)
resolve internal links of all media items of a media object
ilObjLearningModule $learning_module
copyFileItems()
copy files of file items
const IL_EXT_LINK
Class ilMapArea.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static yn2tf(string $a_yn)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstance(string $a_parent_type, int $a_id=0, int $a_old_nr=0, string $a_lang="-")
Get page object instance.
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
storeTree()
insert StructureObjects and PageObjects into tree