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