1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5/**
6 * Class ilObjGlossary
7 *
8 * @author Alex Killing <alex.killing@gmx.de>
9 */
10class ilObjGlossary extends ilObject implements ilAdvancedMetaDataSubItems
11{
12    /**
13     * @var ilTemplate
14     */
15    protected $tpl;
16
17
18    /**
19     * @var ilDB
20     */
21    protected $db;
22
23    /**
24     * @var array
25     */
26    public $auto_glossaries = array();
27
28    /**
29     * @var ilObjUser
30     */
31    protected $user;
32
33    /**
34    * Constructor
35    * @access	public
36    */
37    public function __construct($a_id = 0, $a_call_by_reference = true)
38    {
39        global $DIC;
40        $this->error = $DIC["ilErr"];
41        $this->tpl = $DIC["tpl"];
42
43        $this->db = $DIC->database();
44        $this->user = $DIC->user();
45        $this->type = "glo";
46        parent::__construct($a_id, $a_call_by_reference);
47    }
48
49    /**
50    * create glossary object
51    */
52    public function create($a_upload = false)
53    {
54        parent::create();
55
56        // meta data will be created by
57        // import parser
58        if (!$a_upload) {
59            $this->createMetaData();
60        }
61        $this->db->insert(
62            'glossary',
63            array(
64                'id' => array('integer', $this->getId()),
65                'is_online' => array('text', 'n'),
66                'virtual' => array('text', $this->getVirtualMode()),
67                'pres_mode' => array('text', 'table'),
68                'snippet_length' => array('integer', 200)
69            )
70        );
71
72        $this->setPresentationMode("table");
73        $this->setSnippetLength(200);
74
75        $this->updateAutoGlossaries();
76
77        if (((int) $this->getStyleSheetId()) > 0) {
78            ilObjStyleSheet::writeStyleUsage($this->getId(), $this->getStyleSheetId());
79        }
80    }
81
82    /**
83    * read data of content object
84    */
85    public function read()
86    {
87        parent::read();
88        #		echo "Glossary<br>\n";
89
90        $q = "SELECT * FROM glossary WHERE id = " .
91            $this->db->quote($this->getId(), "integer");
92        $gl_set = $this->db->query($q);
93        $gl_rec = $this->db->fetchAssoc($gl_set);
94        $this->setOnline(ilUtil::yn2tf($gl_rec["is_online"]));
95        $this->setVirtualMode($gl_rec["virtual"]);
96        $this->setPublicExportFile("xml", $gl_rec["public_xml_file"]);
97        $this->setPublicExportFile("html", $gl_rec["public_html_file"]);
98        $this->setActiveGlossaryMenu(ilUtil::yn2tf($gl_rec["glo_menu_active"]));
99        $this->setActiveDownloads(ilUtil::yn2tf($gl_rec["downloads_active"]));
100        $this->setPresentationMode($gl_rec["pres_mode"]);
101        $this->setSnippetLength($gl_rec["snippet_length"]);
102        $this->setShowTaxonomy($gl_rec["show_tax"]);
103
104        $this->setStyleSheetId((int) ilObjStyleSheet::lookupObjectStyle($this->getId()));
105
106        // read auto glossaries
107        $set = $this->db->query(
108            "SELECT * FROM glo_glossaries " .
109            " WHERE id = " . $this->db->quote($this->getId(), "integer")
110        );
111        $glos = array();
112        while ($rec = $this->db->fetchAssoc($set)) {
113            $glos[] = $rec["glo_id"];
114        }
115        $this->setAutoGlossaries($glos);
116    }
117
118    /**
119    * get description of glossary object
120    *
121    * @return	string		description
122    */
123    public function getDescription()
124    {
125        return parent::getDescription();
126    }
127
128    /**
129    * set description of glossary object
130    */
131    public function setDescription($a_description)
132    {
133        parent::setDescription($a_description);
134    }
135
136
137    /**
138    * set glossary type (virtual: fixed/level/subtree, normal:none)
139    */
140    public function setVirtualMode($a_mode)
141    {
142        switch ($a_mode) {
143            case "level":
144            case "subtree":
145            // case "fixed":
146                $this->virtual_mode = $a_mode;
147                $this->virtual = true;
148                break;
149
150            default:
151                $this->virtual_mode = "none";
152                $this->virtual = false;
153                break;
154        }
155    }
156
157    /**
158    * get glossary type (normal or virtual)
159    */
160    public function getVirtualMode()
161    {
162        return $this->virtual_mode;
163    }
164
165    /**
166     * returns true if glossary type is virtual (any mode)
167     */
168    public function isVirtual()
169    {
170        return $this->virtual;
171    }
172
173    /**
174    * get title of glossary object
175    *
176    * @return	string		title
177    */
178    public function getTitle()
179    {
180        return parent::getTitle();
181    }
182
183    /**
184    * set title of glossary object
185    */
186    public function setTitle($a_title)
187    {
188        parent::setTitle($a_title);
189        //		$this->meta_data->setTitle($a_title);
190    }
191
192    /**
193     * Set presentation mode
194     *
195     * @param	string	presentation mode
196     */
197    public function setPresentationMode($a_val)
198    {
199        $this->pres_mode = $a_val;
200    }
201
202    /**
203     * Get presentation mode
204     *
205     * @return	string	presentation mode
206     */
207    public function getPresentationMode()
208    {
209        return $this->pres_mode;
210    }
211
212    /**
213     * Set snippet length
214     *
215     * @param	int	snippet length
216     */
217    public function setSnippetLength($a_val)
218    {
219        $this->snippet_length = $a_val;
220    }
221
222    /**
223     * Get snippet length
224     *
225     * @return	int	snippet length
226     */
227    public function getSnippetLength()
228    {
229        return ($this->snippet_length > 0)
230            ? $this->snippet_length
231            : null;
232    }
233
234    public function setOnline($a_online)
235    {
236        $this->online = $a_online;
237    }
238
239    public function getOnline()
240    {
241        return $this->online;
242    }
243
244    /**
245     * check wether content object is online
246     */
247    public static function _lookupOnline($a_id)
248    {
249        global $DIC;
250
251        $db = $DIC->database();
252
253        $q = "SELECT is_online FROM glossary WHERE id = " .
254            $db->quote($a_id, "integer");
255        $lm_set = $db->query($q);
256        $lm_rec = $db->fetchAssoc($lm_set);
257
258        return ilUtil::yn2tf($lm_rec["is_online"]);
259    }
260
261    /**
262     * Lookup glossary property
263     *
264     * @param	int		glossary id
265     * @param	string	property
266     */
267    protected static function lookup($a_id, $a_property)
268    {
269        global $DIC;
270
271        $db = $DIC->database();
272
273        $set = $db->query("SELECT $a_property FROM glossary WHERE id = " .
274            $db->quote($a_id, "integer"));
275        $rec = $db->fetchAssoc($set);
276
277        return $rec[$a_property];
278    }
279
280    /**
281     * Lookup snippet length
282     *
283     * @param	int		glossary id
284     * @return	int		snippet length
285     */
286    public static function lookupSnippetLength($a_id)
287    {
288        return ilObjGlossary::lookup($a_id, "snippet_length");
289    }
290
291
292    public function setActiveGlossaryMenu($a_act_glo_menu)
293    {
294        $this->glo_menu_active = $a_act_glo_menu;
295    }
296
297    public function isActiveGlossaryMenu()
298    {
299        return $this->glo_menu_active;
300    }
301
302    public function setActiveDownloads($a_down)
303    {
304        $this->downloads_active = $a_down;
305    }
306
307    public function isActiveDownloads()
308    {
309        return $this->downloads_active;
310    }
311
312    /**
313     * Get ID of assigned style sheet object
314     */
315    public function getStyleSheetId()
316    {
317        return $this->style_id;
318    }
319
320    /**
321     * Set ID of assigned style sheet object
322     */
323    public function setStyleSheetId($a_style_id)
324    {
325        $this->style_id = $a_style_id;
326    }
327
328
329    /**
330     * Set show taxonomy
331     *
332     * @param bool $a_val show taxonomy
333     */
334    public function setShowTaxonomy($a_val)
335    {
336        $this->show_tax = $a_val;
337    }
338
339    /**
340     * Get show taxonomy
341     *
342     * @return bool show taxonomy
343     */
344    public function getShowTaxonomy()
345    {
346        return $this->show_tax;
347    }
348
349    /**
350     * Set auto glossaries
351     *
352     * @param array $a_val int
353     */
354    public function setAutoGlossaries($a_val)
355    {
356        $this->auto_glossaries = array();
357        if (is_array($a_val)) {
358            foreach ($a_val as $v) {
359                $this->addAutoGlossary($v);
360            }
361        }
362    }
363
364    /**
365     * Add auto glossary
366     * @param int $glo_id
367     */
368    public function addAutoGlossary($glo_id)
369    {
370        $glo_id = (int) $glo_id;
371        if ($glo_id > 0 && ilObject::_lookupType($glo_id) == "glo" &&
372            !in_array($glo_id, $this->auto_glossaries)) {
373            $this->auto_glossaries[] = $glo_id;
374        }
375    }
376
377    /**
378     * Get auto glossaries
379     *
380     * @return array int
381     */
382    public function getAutoGlossaries()
383    {
384        return $this->auto_glossaries;
385    }
386
387    /**
388     * Remove auto glossary
389     *
390     * @param
391     * @return
392     */
393    public function removeAutoGlossary($a_glo_id)
394    {
395        $glo_ids = array();
396        foreach ($this->getAutoGlossaries() as $g) {
397            if ($g != $a_glo_id) {
398                $glo_ids[] = $g;
399            }
400        }
401        $this->setAutoGlossaries($glo_ids);
402    }
403
404    /**
405     * Update object
406     */
407    public function update()
408    {
409        $this->updateMetaData();
410
411        $this->db->update(
412            'glossary',
413            array(
414                'is_online' => array('text', ilUtil::tf2yn($this->getOnline())),
415                'virtual' => array('text', $this->getVirtualMode()),
416                'public_xml_file' => array('text', $this->getPublicExportFile("xml")),
417                'public_html_file' => array('text', $this->getPublicExportFile("html")),
418                'glo_menu_active' => array('text', ilUtil::tf2yn($this->isActiveGlossaryMenu())),
419                'downloads_active' => array('text', ilUtil::tf2yn($this->isActiveDownloads())),
420                'pres_mode' => array('text', $this->getPresentationMode()),
421                'show_tax' => array('integer', $this->getShowTaxonomy()),
422                'snippet_length' => array('integer', $this->getSnippetLength())
423            ),
424            array(
425                'id' => array('integer', $this->getId())
426            )
427        );
428        ilObjStyleSheet::writeStyleUsage($this->getId(), $this->getStyleSheetId());
429
430        $this->updateAutoGlossaries();
431        parent::update();
432    }
433
434
435    /**
436     * Update auto glossaries
437     *
438     * @param
439     * @return
440     */
441    public function updateAutoGlossaries()
442    {
443        // update auto glossaries
444        $this->db->manipulate(
445            "DELETE FROM glo_glossaries WHERE " .
446            " id = " . $this->db->quote($this->getId(), "integer")
447        );
448        foreach ($this->getAutoGlossaries() as $glo_id) {
449            $this->db->insert(
450                'glo_glossaries',
451                array(
452                    'id' => array('integer', $this->getId()),
453                    'glo_id' => array('integer', $glo_id)
454                )
455            );
456        }
457    }
458
459    /**
460     * Lookup auto glossaries
461     *
462     * @param
463     * @return
464     */
465    public static function lookupAutoGlossaries($a_id)
466    {
467        global $DIC;
468
469        $db = $DIC->database();
470
471        // read auto glossaries
472        $set = $db->query(
473            "SELECT * FROM glo_glossaries " .
474            " WHERE id = " . $db->quote($a_id, "integer")
475        );
476        $glos = array();
477        while ($rec = $db->fetchAssoc($set)) {
478            $glos[] = $rec["glo_id"];
479        }
480        return $glos;
481    }
482
483    /**
484    * Get term list
485    */
486    public function getTermList(
487        $searchterm = "",
488        $a_letter = "",
489        $a_def = "",
490        $a_tax_node = 0,
491        $a_include_offline_childs = false,
492        $a_add_amet_fields = false,
493        array $a_amet_filter = null,
494        $a_omit_virtual = false,
495        $a_include_references = false
496    ) {
497        if ($a_omit_virtual) {
498            $glo_ref_ids[] = $this->getRefId();
499        } else {
500            $glo_ref_ids = $this->getAllGlossaryIds($a_include_offline_childs, true);
501        }
502        $list = ilGlossaryTerm::getTermList(
503            $glo_ref_ids,
504            $searchterm,
505            $a_letter,
506            $a_def,
507            $a_tax_node,
508            $a_add_amet_fields,
509            $a_amet_filter,
510            $a_include_references
511        );
512        return $list;
513    }
514
515    /**
516    * Get term list
517    */
518    public function getFirstLetters($a_tax_node = 0)
519    {
520        $glo_ids = $this->getAllGlossaryIds();
521        $first_letters = ilGlossaryTerm::getFirstLetters($glo_ids, $a_tax_node);
522        return $first_letters;
523    }
524
525    /**
526     * Get all glossary ids
527     *
528     * @param
529     * @return
530     */
531    public function getAllGlossaryIds($a_include_offline_childs = false, $ids_are_ref_ids = false)
532    {
533        global $DIC;
534
535        $tree = $DIC->repositoryTree();
536
537        if ($this->isVirtual()) {
538            $glo_ids = array();
539
540            $virtual_mode = $this->getRefId() ? $this->getVirtualMode() : '';
541            switch ($virtual_mode) {
542                case "level":
543                    $glo_arr = $tree->getChildsByType($tree->getParentId($this->getRefId()), "glo");
544                    foreach ($glo_arr as $glo) {
545                        {
546                            if ($ids_are_ref_ids) {
547                                $glo_ids[] = $glo['child'];
548                            } else {
549                                $glo_ids[] = $glo['obj_id'];
550                            }
551                        }
552                    }
553                    break;
554
555                case "subtree":
556                    $subtree_nodes = $tree->getSubTree($tree->getNodeData($tree->getParentId($this->getRefId())));
557
558                    foreach ($subtree_nodes as $node) {
559                        if ($node['type'] == 'glo') {
560                            if ($ids_are_ref_ids) {
561                                $glo_ids[] = $node['child'];
562                            } else {
563                                $glo_ids[] = $node['obj_id'];
564                            }
565                        }
566                    }
567                    break;
568            }
569            if (!$a_include_offline_childs) {
570                $glo_ids = ilObjGlossary::removeOfflineGlossaries($glo_ids, $ids_are_ref_ids);
571            }
572            // always show entries of current glossary (if no permission is given, user will not come to the presentation screen)
573            // see bug #14477
574            if ($ids_are_ref_ids) {
575                if (!in_array($this->getRefId(), $glo_ids)) {
576                    $glo_ids[] = $this->getRefId();
577                }
578            } else {
579                if (!in_array($this->getId(), $glo_ids)) {
580                    $glo_ids[] = $this->getId();
581                }
582            }
583        } else {
584            if ($ids_are_ref_ids) {
585                $glo_ids = $this->getRefId();
586            } else {
587                $glo_ids = $this->getId();
588            }
589        }
590
591        return $glo_ids;
592    }
593
594    /**
595    * creates data directory for import files
596    * (data_dir/glo_data/glo_<id>/import, depending on data
597    * directory that is set in ILIAS setup/ini)
598    */
599    public function createImportDirectory()
600    {
601        $ilErr = $this->error;
602
603        $glo_data_dir = ilUtil::getDataDir() . "/glo_data";
604        ilUtil::makeDir($glo_data_dir);
605        if (!is_writable($glo_data_dir)) {
606            $ilErr->raiseError("Glossary Data Directory (" . $glo_data_dir
607                . ") not writeable.", $ilErr->error_obj->FATAL);
608        }
609
610        // create glossary directory (data_dir/glo_data/glo_<id>)
611        $glo_dir = $glo_data_dir . "/glo_" . $this->getId();
612        ilUtil::makeDir($glo_dir);
613        if (!@is_dir($glo_dir)) {
614            $ilErr->raiseError("Creation of Glossary Directory failed.", $ilErr->FATAL);
615        }
616        // create Import subdirectory (data_dir/glo_data/glo_<id>/import)
617        $import_dir = $glo_dir . "/import";
618        ilUtil::makeDir($import_dir);
619        if (!@is_dir($import_dir)) {
620            $ilErr->raiseError("Creation of Export Directory failed.", $ilErr->FATAL);
621        }
622    }
623
624    /**
625    * get import directory of glossary
626    */
627    public function getImportDirectory()
628    {
629        $export_dir = ilUtil::getDataDir() . "/glo_data" . "/glo_" . $this->getId() . "/import";
630
631        return $export_dir;
632    }
633
634    /**
635    * Creates export directory
636    */
637    public function createExportDirectory($a_type = "xml")
638    {
639        return ilExport::_createExportDirectory($this->getId(), $a_type, $this->getType());
640    }
641
642    /**
643    * Get export directory of glossary
644    */
645    public function getExportDirectory($a_type = "xml")
646    {
647        return ilExport::_getExportDirectory($this->getId(), $a_type, $this->getType());
648    }
649
650    /**
651    * Get export files
652    */
653    public function getExportFiles()
654    {
655        return ilExport::_getExportFiles($this->getId(), array("xml", "html"), $this->getType());
656    }
657
658    /**
659    * specify public export file for type
660    *
661    * @param	string		$a_type		type ("xml" / "html")
662    * @param	string		$a_file		file name
663    */
664    public function setPublicExportFile($a_type, $a_file)
665    {
666        $this->public_export_file[$a_type] = $a_file;
667    }
668
669    /**
670    * get public export file
671    *
672    * @param	string		$a_type		type ("xml" / "html")
673    *
674    * @return	string		$a_file		file name
675    */
676    public function getPublicExportFile($a_type)
677    {
678        return $this->public_export_file[$a_type];
679    }
680
681
682    /**
683    * export object to xml (see ilias_co.dtd)
684    *
685    * @param	object		$a_xml_writer	ilXmlWriter object that receives the
686    *										xml data
687    */
688    public function exportXML(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
689    {
690        // export glossary
691        $attrs = array();
692        $attrs["Type"] = "Glossary";
693        $a_xml_writer->xmlStartTag("ContentObject", $attrs);
694
695        // MetaData
696        $this->exportXMLMetaData($a_xml_writer);
697
698        // collect media objects
699        $terms = $this->getTermList();
700        $this->mob_ids = array();
701        $this->file_ids = array();
702        foreach ($terms as $term) {
703            $defs = ilGlossaryDefinition::getDefinitionList($term[id]);
704
705            foreach ($defs as $def) {
706                $this->page_object = new ilGlossaryDefPage($def["id"]);
707                $this->page_object->buildDom();
708                $this->page_object->insertInstIntoIDs(IL_INST_ID);
709                $mob_ids = $this->page_object->collectMediaObjects(false);
710                $file_ids = ilPCFileList::collectFileItems($this->page_object, $this->page_object->getDomDoc());
711                foreach ($mob_ids as $mob_id) {
712                    $this->mob_ids[$mob_id] = $mob_id;
713                }
714                foreach ($file_ids as $file_id) {
715                    $this->file_ids[$file_id] = $file_id;
716                }
717            }
718        }
719
720        // export media objects
721        $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Media Objects");
722        $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
723        $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Media Objects");
724
725        // FileItems
726        $expLog->write(date("[y-m-d H:i:s] ") . "Start Export File Items");
727        $this->exportFileItems($a_target_dir, $expLog);
728        $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export File Items");
729
730        // Glossary
731        $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Glossary Items");
732        $this->exportXMLGlossaryItems($a_xml_writer, $a_inst, $expLog);
733        $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Glossary Items");
734
735        $a_xml_writer->xmlEndTag("ContentObject");
736    }
737
738    /**
739    * export page objects to xml (see ilias_co.dtd)
740    *
741    * @param	object		$a_xml_writer	ilXmlWriter object that receives the
742    *										xml data
743    */
744    public function exportXMLGlossaryItems(&$a_xml_writer, $a_inst, &$expLog)
745    {
746        $attrs = array();
747        $a_xml_writer->xmlStartTag("Glossary", $attrs);
748
749        // MetaData
750        $this->exportXMLMetaData($a_xml_writer);
751
752        $terms = $this->getTermList();
753
754        // export glossary terms
755        reset($terms);
756        foreach ($terms as $term) {
757            $expLog->write(date("[y-m-d H:i:s] ") . "Page Object " . $page["obj_id"]);
758
759            // export xml to writer object
760            $glo_term = new ilGlossaryTerm($term["id"]);
761            $glo_term->exportXML($a_xml_writer, $a_inst);
762
763            unset($glo_term);
764        }
765
766        $a_xml_writer->xmlEndTag("Glossary");
767    }
768
769    /**
770    * export content objects meta data to xml (see ilias_co.dtd)
771    *
772    * @param	object		$a_xml_writer	ilXmlWriter object that receives the
773    *										xml data
774    */
775    public function exportXMLMetaData(&$a_xml_writer)
776    {
777        $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
778        $md2xml->setExportMode(true);
779        $md2xml->startExport();
780        $a_xml_writer->appendXML($md2xml->getXML());
781    }
782
783    /**
784    * export media objects to xml (see ilias_co.dtd)
785    *
786    * @param	object		$a_xml_writer	ilXmlWriter object that receives the
787    *										xml data
788    */
789    public function exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
790    {
791        foreach ($this->mob_ids as $mob_id) {
792            $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
793            $media_obj = new ilObjMediaObject($mob_id);
794            $media_obj->exportXML($a_xml_writer, $a_inst);
795            $media_obj->exportFiles($a_target_dir);
796            unset($media_obj);
797        }
798    }
799
800    /**
801    * export files of file itmes
802    *
803    */
804    public function exportFileItems($a_target_dir, &$expLog)
805    {
806        foreach ($this->file_ids as $file_id) {
807            $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
808            $file_obj = new ilObjFile($file_id, false);
809            $file_obj->export($a_target_dir);
810            unset($file_obj);
811        }
812    }
813
814
815
816    /**
817    *
818    */
819    public function modifyExportIdentifier($a_tag, $a_param, $a_value)
820    {
821        if ($a_tag == "Identifier" && $a_param == "Entry") {
822            $a_value = "il_" . IL_INST_ID . "_glo_" . $this->getId();
823        }
824
825        return $a_value;
826    }
827
828
829
830
831    /**
832    * delete glossary and all related data
833    *
834    * this method has been tested on may 9th 2004
835    * meta data, terms, definitions, definition meta data
836    * and definition pages have been deleted correctly as desired
837    *
838    * @access	public
839    * @return	boolean	true if all object data were removed; false if only a references were removed
840    */
841    public function delete()
842    {
843        // always call parent delete function first!!
844        if (!parent::delete()) {
845            return false;
846        }
847
848        // delete terms
849        if (!$this->isVirtual()) {
850            $terms = $this->getTermList();
851            foreach ($terms as $term) {
852                $term_obj = new ilGlossaryTerm($term["id"]);
853                $term_obj->delete();
854            }
855        }
856
857        // delete term references
858        $refs = new ilGlossaryTermReferences($this->getId());
859        $refs->delete();
860
861        // delete glossary data entry
862        $q = "DELETE FROM glossary WHERE id = " . $this->db->quote($this->getId());
863        $this->db->query($q);
864
865        // delete meta data
866        $this->deleteMetaData();
867
868        return true;
869    }
870
871    /**
872    * Get zipped xml file for glossary.
873    */
874    public function getXMLZip()
875    {
876        $glo_exp = new ilGlossaryExport($this);
877        return $glo_exp->buildExportFile();
878    }
879
880    /**
881     * Get deletion dependencies
882     *
883     */
884    public static function getDeletionDependencies($a_obj_id)
885    {
886        global $DIC;
887
888        $lng = $DIC->language();
889
890        $dep = array();
891        $sms = ilObjSAHSLearningModule::getScormModulesForGlossary($a_obj_id);
892        foreach ($sms as $sm) {
893            $lng->loadLanguageModule("content");
894            $dep[$sm] = $lng->txt("glo_used_in_scorm");
895        }
896        //echo "-".$a_obj_id."-";
897        //var_dump($dep);
898        return $dep;
899    }
900
901    /**
902     * Get taxonomy
903     *
904     * @return int taxononmy ID
905     */
906    public function getTaxonomyId()
907    {
908        $tax_ids = ilObjTaxonomy::getUsageOfObject($this->getId());
909        if (count($tax_ids) > 0) {
910            // glossaries handle max. one taxonomy
911            return $tax_ids[0];
912        }
913        return 0;
914    }
915
916
917    /**
918     * Clone glossary
919     *
920     * @param int target ref_id
921     * @param int copy id
922     */
923    public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
924    {
925        $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
926        $this->cloneMetaData($new_obj);
927
928        //copy online status if object is not the root copy object
929        $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
930
931        if (!$cp_options->isRootNode($this->getRefId())) {
932            $new_obj->setOnline($this->getOnline());
933        }
934
935        //		$new_obj->setTitle($this->getTitle());
936        $new_obj->setDescription($this->getDescription());
937        $new_obj->setVirtualMode($this->getVirtualMode());
938        $new_obj->setPresentationMode($this->getPresentationMode());
939        $new_obj->setSnippetLength($this->getSnippetLength());
940        $new_obj->setAutoGlossaries($this->getAutoGlossaries());
941        $new_obj->update();
942
943        // set/copy stylesheet
944        $style_id = $this->getStyleSheetId();
945        if ($style_id > 0 && !ilObjStyleSheet::_lookupStandard($style_id)) {
946            $style_obj = ilObjectFactory::getInstanceByObjId($style_id);
947            $new_id = $style_obj->ilClone();
948            $new_obj->setStyleSheetId($new_id);
949            $new_obj->update();
950        }
951
952        // copy taxonomy
953        if (($tax_id = $this->getTaxonomyId()) > 0) {
954            // clone it
955            $tax = new ilObjTaxonomy($tax_id);
956            $new_tax = $tax->cloneObject(0, 0, true);
957            $map = $tax->getNodeMapping();
958
959            // assign new taxonomy to new glossary
960            ilObjTaxonomy::saveUsage($new_tax->getId(), $new_obj->getId());
961        }
962
963        // assign new tax/new glossary
964        // handle mapping
965
966        // prepare tax node assignments objects
967        if ($tax_id > 0) {
968            $tax_ass = new ilTaxNodeAssignment("glo", $this->getId(), "term", $tax_id);
969            $new_tax_ass = new ilTaxNodeAssignment("glo", $new_obj->getId(), "term", $new_tax->getId());
970        }
971
972        // copy terms
973        $term_mappings = array();
974        foreach (ilGlossaryTerm::getTermList($this->getRefId()) as $term) {
975            $new_term_id = ilGlossaryTerm::_copyTerm($term["id"], $new_obj->getId());
976            $term_mappings[$term["id"]] = $new_term_id;
977
978            // copy tax node assignments
979            if ($tax_id > 0) {
980                $assignmts = $tax_ass->getAssignmentsOfItem($term["id"]);
981                foreach ($assignmts as $a) {
982                    if ($map[$a["node_id"]] > 0) {
983                        $new_tax_ass->addAssignment($map[$a["node_id"]], $new_term_id);
984                    }
985                }
986            }
987        }
988
989        // add mapping of term_ids to copy wizard options
990        if (!empty($term_mappings)) {
991            $cp_options->appendMapping($this->getRefId() . '_glo_terms', (array) $term_mappings);
992        }
993
994
995        return $new_obj;
996    }
997
998    /**
999     * Remove offline glossaries from obj id array
1000     *
1001     * @param
1002     * @return
1003     */
1004    public function removeOfflineGlossaries($a_glo_ids, $ids_are_ref_ids = false)
1005    {
1006        $glo_ids = $a_glo_ids;
1007        if ($ids_are_ref_ids) {
1008            $glo_ids = array_map(function ($id) {
1009                return ilObject::_lookupObjectId($id);
1010            }, $a_glo_ids);
1011        }
1012
1013        $set = $this->db->query(
1014            "SELECT id FROM glossary " .
1015            " WHERE " . $this->db->in("id", $glo_ids, false, "integer") .
1016            " AND is_online = " . $this->db->quote("y", "text")
1017        );
1018        $online_glo_ids = array();
1019        while ($rec = $this->db->fetchAssoc($set)) {
1020            $online_glo_ids[] = $rec["id"];
1021        }
1022
1023        if (!$ids_are_ref_ids) {
1024            return $online_glo_ids;
1025        }
1026
1027        $online_ref_ids = array_filter($a_glo_ids, function ($ref_id) use ($online_glo_ids) {
1028            return in_array(ilObject::_lookupObjectId($ref_id), $online_glo_ids);
1029        });
1030
1031
1032        return $online_ref_ids;
1033    }
1034
1035    public static function getAdvMDSubItemTitle($a_obj_id, $a_sub_type, $a_sub_id)
1036    {
1037        global $DIC;
1038
1039        $lng = $DIC->language();
1040
1041        if ($a_sub_type == "term") {
1042            $lng->loadLanguageModule("glo");
1043
1044            return $lng->txt("glo_term") . ' "' . ilGlossaryTerm::_lookGlossaryTerm($a_sub_id) . '"';
1045        }
1046    }
1047
1048    /**
1049     * Auto link glossary terms
1050     *
1051     * @param
1052     * @return
1053     */
1054    public function autoLinkGlossaryTerms($a_glo_ref_id)
1055    {
1056        // get terms of target glossary
1057        $terms = ilGlossaryTerm::getTermList($a_glo_ref_id);
1058
1059        // for each get page: get content
1060        $source_terms = ilGlossaryTerm::getTermList($this->getRefId());
1061        $found_pages = array();
1062        foreach ($source_terms as $source_term) {
1063            $source_defs = ilGlossaryDefinition::getDefinitionList($source_term["id"]);
1064
1065            for ($j = 0; $j < count($source_defs); $j++) {
1066                $def = $source_defs[$j];
1067                $pg = new ilGlossaryDefPage($def["id"]);
1068
1069                $c = $pg->getXMLContent();
1070                foreach ($terms as $t) {
1071                    if (is_int(stripos($c, $t["term"]))) {
1072                        $found_pages[$def["id"]]["terms"][] = $t;
1073                        if (!is_object($found_pages[$def["id"]]["page"])) {
1074                            $found_pages[$def["id"]]["page"] = $pg;
1075                        }
1076                    }
1077                }
1078                reset($terms);
1079            }
1080        }
1081
1082        // ilPCParagraph autoLinkGlossariesPage with page and terms
1083        foreach ($found_pages as $id => $fp) {
1084            ilPCParagraph::autoLinkGlossariesPage($fp["page"], $fp["terms"]);
1085        }
1086    }
1087
1088    /**
1089     * Is long text search supported
1090     *
1091     * @return bool
1092     */
1093    public function supportsLongTextQuery()
1094    {
1095        return true;
1096    }
1097}
1098