ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilObjContentObject.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
18{
22 protected $user;
23
24
28 protected $locator;
29
33 public $lm_tree;
34
35 public $meta_data;
36 public $layout;
37 public $style_id;
38 public $pg_header;
39 public $online;
40 public $for_translation = 0;
41 protected $rating;
42 protected $rating_pages;
43 public $auto_glossaries = array();
44
45 private $import_dir = '';
49 protected $log;
50
57 public function __construct($a_id = 0, $a_call_by_reference = true)
58 {
59 global $DIC;
60
61 $this->user = $DIC->user();
62 $this->db = $DIC->database();
63 $this->tree = $DIC->repositoryTree();
64 $this->lng = $DIC->language();
65 $this->error = $DIC["ilErr"];
66 if (isset($DIC["ilLocator"])) {
67 $this->locator = $DIC["ilLocator"];
68 }
69
70 // this also calls read() method! (if $a_id is set)
71 parent::__construct($a_id, $a_call_by_reference);
72
73 $this->log = ilLoggerFactory::getLogger('lm');
74
75 $this->mob_ids = array();
76 $this->file_ids = array();
77 $this->q_ids = array();
78 }
79
83 public function create($a_no_meta_data = false)
84 {
85 $this->setOfflineStatus(true);
86 parent::create();
87
88 // meta data will be created by
89 // import parser
90 if (!$a_no_meta_data) {
91 $this->createMetaData();
92 }
93
94 $this->createProperties();
95 $this->updateAutoGlossaries();
96 }
97
98
99
103 public function read()
104 {
106
107 parent::read();
108 # echo "Content<br>\n";
109
110 $this->lm_tree = new ilTree($this->getId());
111 $this->lm_tree->setTableNames('lm_tree', 'lm_data');
112 $this->lm_tree->setTreeTablePK("lm_id");
113
114 $this->readProperties();
115
116 // read auto glossaries
117 $set = $ilDB->query(
118 "SELECT * FROM lm_glossaries " .
119 " WHERE lm_id = " . $ilDB->quote($this->getId(), "integer")
120 );
121 $glos = array();
122 while ($rec = $ilDB->fetchAssoc($set)) {
123 $glos[] = $rec["glo_id"];
124 }
125 $this->setAutoGlossaries($glos);
126
127 //parent::read();
128 }
129
135 public function getTitle()
136 {
137 return parent::getTitle();
138 }
139
143 public function setTitle($a_title)
144 {
145 parent::setTitle($a_title);
146 // $this->meta_data->setTitle($a_title);
147 }
148
154 public function getDescription()
155 {
156 return parent::getDescription();
157 }
158
162 public function setDescription($a_description)
163 {
164 parent::setDescription($a_description);
165 // $this->meta_data->setDescription($a_description);
166 }
167
168
169 public function getImportId()
170 {
171 return $this->import_id;
172 }
173
174 public function setImportId($a_id)
175 {
176 $this->import_id = $a_id;
177 }
178
184 public function setLayoutPerPage($a_val)
185 {
186 $this->layout_per_page = $a_val;
187 }
188
194 public function getLayoutPerPage()
195 {
196 return $this->layout_per_page;
197 }
198
204 public function setDisableDefaultFeedback($a_val)
205 {
206 $this->disable_def_feedback = $a_val;
207 }
208
215 {
216 return $this->disable_def_feedback;
217 }
218
224 public function setProgressIcons($a_val)
225 {
226 $this->progr_icons = $a_val;
227 }
228
234 public function getProgressIcons()
235 {
236 return $this->progr_icons;
237 }
238
244 public function setStoreTries($a_val)
245 {
246 $this->store_tries = $a_val;
247 }
248
254 public function getStoreTries()
255 {
256 return $this->store_tries;
257 }
258
264 public function setRestrictForwardNavigation($a_val)
265 {
266 $this->restrict_forw_nav = $a_val;
267 }
268
275 {
276 return $this->restrict_forw_nav;
277 }
278
279
280 public function &getTree()
281 {
282 return $this->lm_tree;
283 }
284
288 public function update()
289 {
290 $this->updateMetaData();
291 parent::update();
292 $this->updateProperties();
293 $this->updateAutoGlossaries();
294 }
295
302 public function updateAutoGlossaries()
303 {
305
306 // update auto glossaries
307 $ilDB->manipulate(
308 "DELETE FROM lm_glossaries WHERE " .
309 " lm_id = " . $ilDB->quote($this->getId(), "integer")
310 );
311 foreach ($this->getAutoGlossaries() as $glo_id) {
312 $ilDB->manipulate("INSERT INTO lm_glossaries " .
313 "(lm_id, glo_id) VALUES (" .
314 $ilDB->quote($this->getId(), "integer") . "," .
315 $ilDB->quote($glo_id, "integer") .
316 ")");
317 }
318 }
319
320
324 public function import()
325 {
326 // nothing to do. just display the dialogue in Out
327 return;
328 }
329
330
335 public function putInTree($a_parent)
336 {
338
339 // put this object in tree under $a_parent
340 parent::putInTree($a_parent);
341
342 // make new tree for this object
343 //$tree->addTree($this->getId());
344 }
345
346
352 public function createLMTree()
353 {
354 $this->lm_tree = new ilTree($this->getId());
355 $this->lm_tree->setTreeTablePK("lm_id");
356 $this->lm_tree->setTableNames('lm_tree', 'lm_data');
357 $this->lm_tree->addTree($this->getId(), 1);
358 }
359
365 public function setAutoGlossaries($a_val)
366 {
367 $this->auto_glossaries = array();
368 if (is_array($a_val)) {
369 foreach ($a_val as $v) {
370 $v = (int) $v;
371 if ($v > 0 && ilObject::_lookupType($v) == "glo" &&
372 !in_array($v, $this->auto_glossaries)) {
373 $this->auto_glossaries[] = $v;
374 }
375 }
376 }
377 }
378
384 public function getAutoGlossaries()
385 {
387 }
388
395 public function removeAutoGlossary($a_glo_id)
396 {
397 $glo_ids = array();
398 foreach ($this->getAutoGlossaries() as $g) {
399 if ($g != $a_glo_id) {
400 $glo_ids[] = $g;
401 }
402 }
403 $this->setAutoGlossaries($glo_ids);
404 }
405
406
410 public function addFirstChapterAndPage()
411 {
413
414
415 $root_id = $this->lm_tree->getRootId();
416
417 // chapter
418 $chap = new ilStructureObject($this);
419 $chap->setType("st");
420 $chap->setTitle($lng->txt("cont_new_chap"));
421 $chap->setLMId($this->getId());
422 $chap->create();
423 ilLMObject::putInTree($chap, $root_id, IL_FIRST_NODE);
424
425 // page
426 $page = new ilLMPageObject($this);
427 $page->setType("pg");
428 $page->setTitle($lng->txt("cont_new_page"));
429 $page->setLMId($this->getId());
430 $page->create();
431 ilLMObject::putInTree($page, $chap->getId(), IL_FIRST_NODE);
432 }
433
439 public function setForTranslation($a_val)
440 {
441 $this->for_translation = $a_val;
442 }
443
449 public function getForTranslation()
450 {
452 }
453
457 public function getLMTree()
458 {
459 return $this->lm_tree;
460 }
461
462
468 public function createImportDirectory()
469 {
471
472 $lm_data_dir = ilUtil::getDataDir() . "/lm_data";
473 if (!is_writable($lm_data_dir)) {
474 $ilErr->raiseError("Content object Data Directory (" . $lm_data_dir
475 . ") not writeable.", $ilErr->FATAL);
476 }
477
478 // create learning module directory (data_dir/lm_data/lm_<id>)
479 $lm_dir = $lm_data_dir . "/lm_" . $this->getId();
480 ilUtil::makeDir($lm_dir);
481 if (!@is_dir($lm_dir)) {
482 $ilErr->raiseError("Creation of Learning Module Directory failed.", $ilErr->FATAL);
483 }
484
485 // create import subdirectory (data_dir/lm_data/lm_<id>/import)
486 $import_dir = $lm_dir . "/import";
488 if (!@is_dir($import_dir)) {
489 $ilErr->raiseError("Creation of Import Directory failed.", $ilErr->FATAL);
490 }
491 }
492
496 public function getDataDirectory()
497 {
498 return ilUtil::getDataDir() . "/lm_data" .
499 "/lm_" . $this->getId();
500 }
501
505 public function getImportDirectory()
506 {
507 if (strlen($this->import_dir)) {
508 return $this->import_dir;
509 }
510
511 $import_dir = ilUtil::getDataDir() . "/lm_data" .
512 "/lm_" . $this->getId() . "/import";
513 if (@is_dir($import_dir)) {
514 return $import_dir;
515 } else {
516 return false;
517 }
518 }
519
526 public function setImportDirectory($a_import_dir)
527 {
528 $this->import_dir = $a_import_dir;
529 }
530
531
537 public function createExportDirectory($a_type = "xml")
538 {
540
541 $lm_data_dir = ilUtil::getDataDir() . "/lm_data";
542 // create learning module directory (data_dir/lm_data/lm_<id>)
543 $lm_dir = $lm_data_dir . "/lm_" . $this->getId();
544 ilUtil::makeDirParents($lm_dir);
545 if (!@is_dir($lm_dir)) {
546 $ilErr->raiseError("Creation of Learning Module Directory failed.", $ilErr->FATAL);
547 }
548 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
549 switch ($a_type) {
550 // scorm
551 case "scorm":
552 $export_dir = $lm_dir . "/export_scorm";
553 break;
554
555 default: // = xml
556 if (substr($a_type, 0, 4) == "html") {
557 $export_dir = $lm_dir . "/export_" . $a_type;
558 } else {
559 $export_dir = $lm_dir . "/export";
560 }
561 break;
562 }
563 ilUtil::makeDir($export_dir);
564
565 if (!@is_dir($export_dir)) {
566 $ilErr->raiseError("Creation of Export Directory failed.", $ilErr->FATAL);
567 }
568 }
569
573 public function getExportDirectory($a_type = "xml")
574 {
575 switch ($a_type) {
576 case "scorm":
577 $export_dir = ilUtil::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export_scorm";
578 break;
579
580 default: // = xml
581 if (substr($a_type, 0, 4) == "html") {
582 $export_dir = ilUtil::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export_" . $a_type;
583 } else {
584 $export_dir = ilUtil::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export";
585 }
586 break;
587 }
588 return $export_dir;
589 }
590
591
602 public function delete()
603 {
605
606 // always call parent delete function first!!
607 if (!parent::delete()) {
608 return false;
609 }
610
611 // delete lm object data
613
614 // delete meta data of content object
615 $this->deleteMetaData();
616
617
618 // delete learning module tree
619 $this->lm_tree->removeTree($this->lm_tree->getTreeId());
620
621 // delete data directory
623
624 // delete content object record
625 $q = "DELETE FROM content_object WHERE id = " .
626 $ilDB->quote($this->getId(), "integer");
627 $ilDB->manipulate($q);
628
629 // delete lm menu entries
630 $q = "DELETE FROM lm_menu WHERE lm_id = " .
631 $ilDB->quote($this->getId(), "integer");
632 $ilDB->manipulate($q);
633
634 // remove auto glossary entries
635 $ilDB->manipulate(
636 "DELETE FROM lm_glossaries WHERE " .
637 " lm_id = " . $ilDB->quote($this->getId(), "integer")
638 );
639
640
641 return true;
642 }
643
644
650 public function getLayout()
651 {
652 return $this->layout;
653 }
654
660 public function setLayout($a_layout)
661 {
662 $this->layout = $a_layout;
663 }
664
668 public function getStyleSheetId()
669 {
670 return $this->style_id;
671 }
672
676 public function setStyleSheetId($a_style_id)
677 {
678 $this->style_id = $a_style_id;
679 }
680
684 public function writeStyleSheetId($a_style_id)
685 {
687
688 $q = "UPDATE content_object SET " .
689 " stylesheet = " . $ilDB->quote((int) $a_style_id, "integer") .
690 " WHERE id = " . $ilDB->quote($this->getId(), "integer");
691 $ilDB->manipulate($q);
692
693 $this->style_id = $a_style_id;
694 }
695
702 public static function writeHeaderPage($a_lm_id, $a_page_id)
703 {
704 global $DIC;
705
706 $ilDB = $DIC->database();
707
708 $ilDB->manipulate(
709 "UPDATE content_object SET " .
710 " header_page = " . $ilDB->quote($a_page_id, "integer") .
711 " WHERE id = " . $ilDB->quote($a_lm_id, "integer")
712 );
713 }
714
721 public static function writeFooterPage($a_lm_id, $a_page_id)
722 {
723 global $DIC;
724
725 $ilDB = $DIC->database();
726
727 $ilDB->manipulate(
728 "UPDATE content_object SET " .
729 " footer_page = " . $ilDB->quote($a_page_id, "integer") .
730 " WHERE id = " . $ilDB->quote($a_lm_id, "integer")
731 );
732 }
733
734
738 public static function _moveLMStyles($a_from_style, $a_to_style)
739 {
740 global $DIC;
741
742 $ilDB = $DIC->database();
743
744 if ($a_from_style < 0) { // change / delete all individual styles
745 $q = "SELECT stylesheet FROM content_object, style_data " .
746 " WHERE content_object.stylesheet = style_data.id " .
747 " AND style_data.standard = " . $ilDB->quote(0, "integer") .
748 " AND content_object.stylesheet > " . $ilDB->quote(0, "integer");
749 $style_set = $ilDB->query($q);
750 while ($style_rec = $ilDB->fetchAssoc($style_set)) {
751 // assign learning modules to new style
752 $q = "UPDATE content_object SET " .
753 " stylesheet = " . $ilDB->quote((int) $a_to_style, "integer") .
754 " WHERE stylesheet = " . $ilDB->quote($style_rec["stylesheet"], "integer");
755 $ilDB->manipulate($q);
756
757 // delete style
758 $style_obj = ilObjectFactory::getInstanceByObjId($style_rec["stylesheet"]);
759 $style_obj->delete();
760 }
761 } else {
762 $q = "UPDATE content_object SET " .
763 " stylesheet = " . $ilDB->quote((int) $a_to_style, "integer") .
764 " WHERE stylesheet = " . $ilDB->quote($a_from_style, "integer");
765 $ilDB->manipulate($q);
766 }
767 }
768
776 protected static function _lookup($a_obj_id, $a_field)
777 {
778 global $DIC;
779
780 $ilDB = $DIC->database();
781 $ilLog = $DIC["ilLog"];
782
783 $q = "SELECT " . $a_field . " FROM content_object " .
784 " WHERE id = " . $ilDB->quote($a_obj_id, "integer");
785
786 $res = $ilDB->query($q);
787 $rec = $ilDB->fetchAssoc($res);
788
789 return $rec[$a_field];
790 }
791
798 public static function _lookupRestrictForwardNavigation($a_obj_id)
799 {
800 return self::_lookup($a_obj_id, "restrict_forw_nav");
801 }
802
806 public static function _lookupStyleSheetId($a_cont_obj_id)
807 {
808 global $DIC;
809
810 $ilDB = $DIC->database();
811
812 $q = "SELECT stylesheet FROM content_object " .
813 " WHERE id = " . $ilDB->quote($a_cont_obj_id, "integer");
814 $res = $ilDB->query($q);
815 $sheet = $ilDB->fetchAssoc($res);
816
817 return $sheet["stylesheet"];
818 }
819
823 public static function _lookupContObjIdByStyleId($a_style_id)
824 {
825 global $DIC;
826
827 $ilDB = $DIC->database();
828
829 $q = "SELECT id FROM content_object " .
830 " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
831 $res = $ilDB->query($q);
832 $obj_ids = array();
833 while ($cont = $ilDB->fetchAssoc($res)) {
834 $obj_ids[] = $cont["id"];
835 }
836 return $obj_ids;
837 }
838
842 public static function _lookupDisableDefaultFeedback($a_id)
843 {
844 global $DIC;
845
846 $ilDB = $DIC->database();
847
848 $q = "SELECT disable_def_feedback FROM content_object " .
849 " WHERE id = " . $ilDB->quote($a_id, "integer");
850 $res = $ilDB->query($q);
851 $rec = $ilDB->fetchAssoc($res);
852
853 return $rec["disable_def_feedback"];
854 }
855
859 public static function _lookupStoreTries($a_id)
860 {
861 global $DIC;
862
863 $ilDB = $DIC->database();
864
865 $q = "SELECT store_tries FROM content_object " .
866 " WHERE id = " . $ilDB->quote($a_id, "integer");
867 $res = $ilDB->query($q);
868 $rec = $ilDB->fetchAssoc($res);
869
870 return $rec["store_tries"];
871 }
872
873
879 public static function _getNrOfAssignedLMs($a_style_id)
880 {
881 global $DIC;
882
883 $ilDB = $DIC->database();
884
885 $q = "SELECT count(*) as cnt FROM content_object " .
886 " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
887 $cset = $ilDB->query($q);
888 $crow = $ilDB->fetchAssoc($cset);
889
890 return (int) $crow["cnt"];
891 }
892
893
897 public static function _getNrLMsIndividualStyles()
898 {
899 global $DIC;
900
901 $ilDB = $DIC->database();
902
903 // joining with style table (not perfectly nice)
904 $q = "SELECT count(*) as cnt FROM content_object, style_data " .
905 " WHERE stylesheet = style_data.id " .
906 " AND standard = " . $ilDB->quote(0, "integer");
907 $cset = $ilDB->query($q);
908 $crow = $ilDB->fetchAssoc($cset);
909
910 return (int) $crow["cnt"];
911 }
912
916 public static function _getNrLMsNoStyle()
917 {
918 global $DIC;
919
920 $ilDB = $DIC->database();
921
922 $q = "SELECT count(*) as cnt FROM content_object " .
923 " WHERE stylesheet = " . $ilDB->quote(0, "integer");
924 $cset = $ilDB->query($q);
925 $crow = $ilDB->fetchAssoc($cset);
926
927 return (int) $crow["cnt"];
928 }
929
935 public static function _deleteStyleAssignments($a_style_id)
936 {
937 global $DIC;
938
939 $ilDB = $DIC->database();
940
941 $q = "UPDATE content_object SET " .
942 " stylesheet = " . $ilDB->quote(0, "integer") .
943 " WHERE stylesheet = " . $ilDB->quote((int) $a_style_id, "integer");
944
945 $ilDB->manipulate($q);
946 }
947
951 public function getPageHeader()
952 {
953 return $this->pg_header;
954 }
955
961 public function setPageHeader($a_pg_header = ilLMObject::CHAPTER_TITLE)
962 {
963 $this->pg_header = $a_pg_header;
964 }
965
969 public function getTOCMode()
970 {
971 return $this->toc_mode;
972 }
973
977 public function getPublicAccessMode()
978 {
979 return $this->public_access_mode;
980 }
981
987 public function setTOCMode($a_toc_mode = "chapters")
988 {
989 $this->toc_mode = $a_toc_mode;
990 }
991
992 public function setActiveLMMenu($a_act_lm_menu)
993 {
994 $this->lm_menu_active = $a_act_lm_menu;
995 }
996
997 public function isActiveLMMenu()
998 {
999 return $this->lm_menu_active;
1000 }
1001
1002 public function setActiveTOC($a_toc)
1003 {
1004 $this->toc_active = $a_toc;
1005 }
1006
1007 public function isActiveTOC()
1008 {
1009 return $this->toc_active;
1010 }
1011
1012 public function setActiveNumbering($a_num)
1013 {
1014 $this->numbering = $a_num;
1015 }
1016
1017 public function isActiveNumbering()
1018 {
1019 return $this->numbering;
1020 }
1021
1022 public function setActivePrintView($a_print)
1023 {
1024 $this->print_view_active = $a_print;
1025 }
1026
1027 public function isActivePrintView()
1028 {
1029 return $this->print_view_active;
1030 }
1031
1032 public function setActivePreventGlossaryAppendix($a_print)
1033 {
1034 $this->prevent_glossary_appendix_active = $a_print;
1035 }
1036
1038 {
1039 return $this->prevent_glossary_appendix_active;
1040 }
1041
1047 public function setHideHeaderFooterPrint($a_val)
1048 {
1049 $this->hide_header_footer_print = $a_val;
1050 }
1051
1058 {
1059 return $this->hide_header_footer_print;
1060 }
1061
1062 public function setActiveDownloads($a_down)
1063 {
1064 $this->downloads_active = $a_down;
1065 }
1066
1067 public function isActiveDownloads()
1068 {
1069 return $this->downloads_active;
1070 }
1071
1072 public function setActiveDownloadsPublic($a_down)
1073 {
1074 $this->downloads_public_active = $a_down;
1075 }
1076
1077 public function isActiveDownloadsPublic()
1078 {
1079 return $this->downloads_public_active;
1080 }
1081
1082 public function setPublicNotes($a_pub_notes)
1083 {
1084 $this->pub_notes = $a_pub_notes;
1085 }
1086
1087 public function publicNotes()
1088 {
1089 return $this->pub_notes;
1090 }
1091
1092 public function setCleanFrames($a_clean)
1093 {
1094 $this->clean_frames = $a_clean;
1095 }
1096
1097 public function cleanFrames()
1098 {
1099 return $this->clean_frames;
1100 }
1101
1102 public function setHistoryUserComments($a_comm)
1103 {
1104 $this->user_comments = $a_comm;
1105 }
1106
1107 public function setPublicAccessMode($a_mode)
1108 {
1109 $this->public_access_mode = $a_mode;
1110 }
1111
1113 {
1114 return $this->user_comments;
1115 }
1116
1117 public function setHeaderPage($a_pg)
1118 {
1119 $this->header_page = $a_pg;
1120 }
1121
1122 public function getHeaderPage()
1123 {
1124 return $this->header_page;
1125 }
1126
1127 public function setFooterPage($a_pg)
1128 {
1129 $this->footer_page = $a_pg;
1130 }
1131
1132 public function getFooterPage()
1133 {
1134 return $this->footer_page;
1135 }
1136
1140 public function readProperties()
1141 {
1142 $ilDB = $this->db;
1143
1144 $q = "SELECT * FROM content_object WHERE id = " .
1145 $ilDB->quote($this->getId(), "integer");
1146 $lm_set = $ilDB->query($q);
1147 $lm_rec = $ilDB->fetchAssoc($lm_set);
1148 $this->setLayout($lm_rec["default_layout"]);
1149 $this->setStyleSheetId((int) $lm_rec["stylesheet"]);
1150 $this->setPageHeader($lm_rec["page_header"]);
1151 $this->setTOCMode($lm_rec["toc_mode"]);
1152 $this->setActiveTOC(ilUtil::yn2tf($lm_rec["toc_active"]));
1153 $this->setActiveNumbering(ilUtil::yn2tf($lm_rec["numbering"]));
1154 $this->setActivePrintView(ilUtil::yn2tf($lm_rec["print_view_active"]));
1155 $this->setActivePreventGlossaryAppendix(ilUtil::yn2tf($lm_rec["no_glo_appendix"]));
1156 $this->setHideHeaderFooterPrint($lm_rec["hide_head_foot_print"]);
1157 $this->setActiveDownloads(ilUtil::yn2tf($lm_rec["downloads_active"]));
1158 $this->setActiveDownloadsPublic(ilUtil::yn2tf($lm_rec["downloads_public_active"]));
1159 $this->setActiveLMMenu(ilUtil::yn2tf($lm_rec["lm_menu_active"]));
1160 $this->setCleanFrames(ilUtil::yn2tf($lm_rec["clean_frames"]));
1161 $this->setHeaderPage((int) $lm_rec["header_page"]);
1162 $this->setFooterPage((int) $lm_rec["footer_page"]);
1163 $this->setHistoryUserComments(ilUtil::yn2tf($lm_rec["hist_user_comments"]));
1164 $this->setPublicAccessMode($lm_rec["public_access_mode"]);
1165 $this->setPublicExportFile("xml", $lm_rec["public_xml_file"]);
1166 $this->setPublicExportFile("html", $lm_rec["public_html_file"]);
1167 $this->setPublicExportFile("scorm", $lm_rec["public_scorm_file"]);
1168 $this->setLayoutPerPage($lm_rec["layout_per_page"]);
1169 $this->setRating($lm_rec["rating"]);
1170 $this->setRatingPages($lm_rec["rating_pages"]);
1171 $this->setDisableDefaultFeedback($lm_rec["disable_def_feedback"]);
1172 $this->setProgressIcons($lm_rec["progr_icons"]);
1173 $this->setStoreTries($lm_rec["store_tries"]);
1174 $this->setRestrictForwardNavigation($lm_rec["restrict_forw_nav"]);
1175
1176 // #14661
1177 $this->setPublicNotes(ilNote::commentsActivated($this->getId(), 0, $this->getType()));
1178
1179 $this->setForTranslation($lm_rec["for_translation"]);
1180 }
1181
1185 public function updateProperties()
1186 {
1187 $ilDB = $this->db;
1188
1189 // force clean_frames to be set, if layout per page is activated
1190 if ($this->getLayoutPerPage()) {
1191 $this->setCleanFrames(true);
1192 }
1193
1194 $q = "UPDATE content_object SET " .
1195 " default_layout = " . $ilDB->quote($this->getLayout(), "text") . ", " .
1196 " stylesheet = " . $ilDB->quote($this->getStyleSheetId(), "integer") . "," .
1197 " page_header = " . $ilDB->quote($this->getPageHeader(), "text") . "," .
1198 " toc_mode = " . $ilDB->quote($this->getTOCMode(), "text") . "," .
1199 " toc_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveTOC()), "text") . "," .
1200 " numbering = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveNumbering()), "text") . "," .
1201 " print_view_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActivePrintView()), "text") . "," .
1202 " no_glo_appendix = " . $ilDB->quote(ilUtil::tf2yn($this->isActivePreventGlossaryAppendix()), "text") . "," .
1203 " hide_head_foot_print = " . $ilDB->quote($this->getHideHeaderFooterPrint(), "integer") . "," .
1204 " downloads_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveDownloads()), "text") . "," .
1205 " downloads_public_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveDownloadsPublic()), "text") . "," .
1206 " clean_frames = " . $ilDB->quote(ilUtil::tf2yn($this->cleanFrames()), "text") . "," .
1207 " hist_user_comments = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveHistoryUserComments()), "text") . "," .
1208 " public_access_mode = " . $ilDB->quote($this->getPublicAccessMode(), "text") . "," .
1209 " public_xml_file = " . $ilDB->quote($this->getPublicExportFile("xml"), "text") . "," .
1210 " public_html_file = " . $ilDB->quote($this->getPublicExportFile("html"), "text") . "," .
1211 " public_scorm_file = " . $ilDB->quote($this->getPublicExportFile("scorm"), "text") . "," .
1212 " header_page = " . $ilDB->quote($this->getHeaderPage(), "integer") . "," .
1213 " footer_page = " . $ilDB->quote($this->getFooterPage(), "integer") . "," .
1214 " lm_menu_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveLMMenu()), "text") . ", " .
1215 " layout_per_page = " . $ilDB->quote($this->getLayoutPerPage(), "integer") . ", " .
1216 " rating = " . $ilDB->quote($this->hasRating(), "integer") . ", " .
1217 " rating_pages = " . $ilDB->quote($this->hasRatingPages(), "integer") . ", " .
1218 " disable_def_feedback = " . $ilDB->quote($this->getDisableDefaultFeedback(), "integer") . ", " .
1219 " progr_icons = " . $ilDB->quote($this->getProgressIcons(), "integer") . ", " .
1220 " store_tries = " . $ilDB->quote($this->getStoreTries(), "integer") . ", " .
1221 " restrict_forw_nav = " . $ilDB->quote($this->getRestrictForwardNavigation(), "integer") . ", " .
1222 " for_translation = " . $ilDB->quote((int) $this->getForTranslation(), "integer") . " " .
1223 " WHERE id = " . $ilDB->quote($this->getId(), "integer");
1224 $ilDB->manipulate($q);
1225 // #14661
1226 ilNote::activateComments($this->getId(), 0, $this->getType(), $this->publicNotes());
1227 }
1228
1232 public function createProperties()
1233 {
1234 $ilDB = $this->db;
1235
1236 $q = "INSERT INTO content_object (id) VALUES (" . $ilDB->quote($this->getId(), "integer") . ")";
1237 $ilDB->manipulate($q);
1238
1239 // #14661
1240 ilNote::activateComments($this->getId(), 0, $this->getType(), true);
1241
1242 $this->readProperties(); // to get db default values
1243 }
1244
1245
1249 public static function getAvailableLayouts()
1250 {
1251 $dir = opendir("./Modules/LearningModule/layouts/lm");
1252
1253 $layouts = array();
1254
1255 while ($file = readdir($dir)) {
1256 if ($file != "." && $file != ".." && $file != "CVS" && $file != ".svn") {
1257 // directories
1258 if (@is_dir("./Modules/LearningModule/layouts/lm/" . $file)) {
1259 $layouts[$file] = $file;
1260 }
1261 }
1262 }
1263 asort($layouts);
1264
1265 // workaround: fix ordering
1266 $ret = array(
1267 'toc2win' => 'toc2win',
1268 'toc2windyn' => 'toc2windyn',
1269 '1window' => '1window',
1270 '2window' => '2window',
1271 '3window' => '3window',
1272 'presentation' => 'presentation',
1273 'fullscreen' => 'fullscreen'
1274 );
1275
1276 foreach ($layouts as $l) {
1277 if (!in_array($l, $ret)) {
1278 $ret[$l] = $l;
1279 }
1280 }
1281
1282 return $ret;
1283 }
1284
1288 public static function _checkPreconditionsOfPage($cont_ref_id, $cont_obj_id, $page_id)
1289 {
1290 global $DIC;
1291
1292 $ilUser = $DIC->user();
1293 $ilErr = $DIC["ilErr"];
1294
1295 $lm_tree = new ilTree($cont_obj_id);
1296 $lm_tree->setTableNames('lm_tree', 'lm_data');
1297 $lm_tree->setTreeTablePK("lm_id");
1298
1299 if ($lm_tree->isInTree($page_id)) {
1300 $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1301 foreach ($path as $node) {
1302 if ($node["type"] == "st") {
1303 if (!ilConditionHandler::_checkAllConditionsOfTarget($cont_ref_id, $node["child"], "st")) {
1304 return false;
1305 }
1306 }
1307 }
1308 }
1309
1310 return true;
1311 }
1312
1316 public static function _getMissingPreconditionsOfPage($cont_ref_id, $cont_obj_id, $page_id)
1317 {
1318 $lm_tree = new ilTree($cont_obj_id);
1319 $lm_tree->setTableNames('lm_tree', 'lm_data');
1320 $lm_tree->setTreeTablePK("lm_id");
1321
1322 $conds = array();
1323 if ($lm_tree->isInTree($page_id)) {
1324 // get full path of page
1325 $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1326 foreach ($path as $node) {
1327 if ($node["type"] == "st") {
1328 // get all preconditions of upper chapters
1329 $tconds = ilConditionHandler::_getPersistedConditionsOfTarget($cont_ref_id, $node["child"], "st");
1330 foreach ($tconds as $tcond) {
1331 // store all missing preconditions
1333 $conds[] = $tcond;
1334 }
1335 }
1336 }
1337 }
1338 }
1339
1340 return $conds;
1341 }
1342
1346 public static function _getMissingPreconditionsTopChapter($cont_obj_ref_id, $cont_obj_id, $page_id)
1347 {
1348 $lm_tree = new ilTree($cont_obj_id);
1349 $lm_tree->setTableNames('lm_tree', 'lm_data');
1350 $lm_tree->setTreeTablePK("lm_id");
1351
1352 $conds = array();
1353 if ($lm_tree->isInTree($page_id)) {
1354 // get full path of page
1355 $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1356 foreach ($path as $node) {
1357 if ($node["type"] == "st") {
1358 // get all preconditions of upper chapters
1359 $tconds = ilConditionHandler::_getPersistedConditionsOfTarget($cont_obj_ref_id, $node["child"], "st");
1360 foreach ($tconds as $tcond) {
1361 // look for missing precondition
1363 return $node["child"];
1364 }
1365 }
1366 }
1367 }
1368 }
1369
1370 return "";
1371 }
1372
1376 public static function hasSuccessorPage($a_cont_obj_id, $a_page_id)
1377 {
1378 $tree = new ilTree($a_cont_obj_id);
1379 $tree->setTableNames('lm_tree', 'lm_data');
1380 $tree->setTreeTablePK("lm_id");
1381 if ($tree->isInTree($a_page_id)) {
1382 $succ = $tree->fetchSuccessorNode($a_page_id, "pg");
1383 if ($succ > 0) {
1384 return true;
1385 }
1386 }
1387 return false;
1388 }
1389
1390
1391 public function checkTree()
1392 {
1393 $tree = new ilTree($this->getId());
1394 $tree->setTableNames('lm_tree', 'lm_data');
1395 $tree->setTreeTablePK("lm_id");
1396 $tree->checkTree();
1397 $tree->checkTreeChilds();
1398 //echo "checked";
1399 }
1400
1404 public function fixTree()
1405 {
1406 $ilDB = $this->db;
1407
1408 $tree = $this->getLMTree();
1409
1410 // check numbering, if errors, renumber
1411 // it is very important to keep this step before deleting subtrees
1412 // in the following steps
1413 $set = $ilDB->query(
1414 "SELECT DISTINCT l1.lm_id" .
1415 " FROM lm_tree l1" .
1416 " JOIN lm_tree l2 ON ( l1.child = l2.parent" .
1417 " AND l1.lm_id = l2.lm_id )" .
1418 " JOIN lm_data ON ( l1.child = lm_data.obj_id )" .
1419 " WHERE (l2.lft < l1.lft" .
1420 " OR l2.rgt > l1.rgt OR l2.lft > l1.rgt OR l2.rgt < l1.lft)" .
1421 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer") .
1422 " ORDER BY lm_data.create_date DESC"
1423 );
1424 if ($rec = $ilDB->fetchAssoc($set)) {
1425 $tree->renumber();
1426 }
1427
1428 // delete subtrees that have no lm_data records (changed due to #20637)
1429 $set = $ilDB->query("SELECT * FROM lm_tree WHERE lm_tree.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1430 while ($node = $ilDB->fetchAssoc($set)) {
1431 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1432 $ilDB->quote($node["child"], "integer");
1433 $obj_set = $ilDB->query($q);
1434 $obj_rec = $ilDB->fetchAssoc($obj_set);
1435 if (!$obj_rec) {
1436 $node_data = $tree->getNodeData($node["child"]);
1437 $node_data["child"] = $node["child"];
1438 $tree->deleteTree($node_data);
1439 }
1440 }
1441
1442 // delete subtrees that have pages as parent
1443 $nodes = $tree->getSubtree($tree->getNodeData($tree->getRootId()));
1444 foreach ($nodes as $node) {
1445 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1446 $ilDB->quote($node["parent"], "integer");
1447 $obj_set = $ilDB->query($q);
1448 $obj_rec = $ilDB->fetchAssoc($obj_set);
1449 if ($obj_rec["type"] == "pg") {
1450 $node_data = $tree->getNodeData($node["child"]);
1451 if ($tree->isInTree($node["child"])) {
1452 $tree->deleteTree($node_data);
1453 }
1454 }
1455 }
1456
1457 // check for multi-references pages or chapters
1458 // if errors -> create copies of them here
1459 $set = $ilDB->query("SELECT DISTINCT l1.lm_id" .
1460 " FROM lm_tree l1" .
1461 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1462 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1463 " WHERE l1.child <> 1" .
1464 " AND l1.lm_id <> lm_data.lm_id" .
1465 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1466 if ($rec = $ilDB->fetchAssoc($set)) {
1467 $set = $ilDB->query("SELECT DISTINCT l1.child " .
1468 " FROM lm_tree l1" .
1469 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1470 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1471 " WHERE l1.child <> 1" .
1472 " AND l1.lm_id <> lm_data.lm_id" .
1473 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1474 while ($rec = $ilDB->fetchAssoc($set)) {
1475 $cobj = ilLMObjectFactory::getInstance($this, $rec["child"]);
1476
1477 if (is_object($cobj)) {
1478 if ($cobj->getType() == "pg") {
1479 // make a copy of it
1480 $pg_copy = $cobj->copy($this);
1481
1482 // replace the child in the tree with the copy (id)
1483 $ilDB->manipulate(
1484 "UPDATE lm_tree SET " .
1485 " child = " . $ilDB->quote($pg_copy->getId(), "integer") .
1486 " WHERE child = " . $ilDB->quote($cobj->getId(), "integer") .
1487 " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1488 );
1489 } elseif ($cobj->getType() == "st") {
1490 // make a copy of it
1491 $st_copy = $cobj->copy($this);
1492
1493 // replace the child in the tree with the copy (id)
1494 $ilDB->manipulate(
1495 "UPDATE lm_tree SET " .
1496 " child = " . $ilDB->quote($st_copy->getId(), "integer") .
1497 " WHERE child = " . $ilDB->quote($cobj->getId(), "integer") .
1498 " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1499 );
1500
1501 // make all childs refer to the copy now
1502 $ilDB->manipulate(
1503 "UPDATE lm_tree SET " .
1504 " parent = " . $ilDB->quote($st_copy->getId(), "integer") .
1505 " WHERE parent = " . $ilDB->quote($cobj->getId(), "integer") .
1506 " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1507 );
1508 }
1509 }
1510 }
1511 }
1512
1513 // missing copage entries
1514 $set = $ilDB->queryF(
1515 "SELECT * FROM lm_data " .
1516 " WHERE lm_id = %s AND type = %s",
1517 array("integer", "text"),
1518 array($this->getId(), "pg")
1519 );
1520 while ($rec = $ilDB->fetchAssoc($set)) {
1521 if (!ilPageObject::_exists("lm", $rec["obj_id"], "-")) {
1522 $lm_page = new ilLMPage();
1523 $lm_page->setId($rec["obj_id"]);
1524 $lm_page->setParentId($this->getId());
1525 $lm_page->create();
1526 }
1527 }
1528 }
1529
1533 public function checkStructure()
1534 {
1535 $issues = [];
1536 $ilDB = $this->db;
1537
1538 $tree = $this->getLMTree();
1539
1540 // check numbering, if errors, renumber
1541 // it is very important to keep this step before deleting subtrees
1542 // in the following steps
1543 $set = $ilDB->query(
1544 "SELECT l1.child, l1.lft l1lft, l1.rgt l1rgt, l2.parent, l2.lft l2lft, l2.rgt l2rgt" .
1545 " FROM lm_tree l1" .
1546 " JOIN lm_tree l2 ON ( l1.child = l2.parent" .
1547 " AND l1.lm_id = l2.lm_id )" .
1548 " JOIN lm_data ON ( l1.child = lm_data.obj_id )" .
1549 " WHERE (l2.lft < l1.lft" .
1550 " OR l2.rgt > l1.rgt OR l2.lft > l1.rgt OR l2.rgt < l1.lft)" .
1551 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer") .
1552 " ORDER BY lm_data.create_date DESC"
1553 );
1554 while ($rec = $ilDB->fetchAssoc($set)) {
1555 $issues[] = "Tree numbering: " . print_r($rec, true);
1556 }
1557
1558 // delete subtrees that have no lm_data records (changed due to #20637)
1559 $set = $ilDB->query("SELECT * FROM lm_tree WHERE lm_tree.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1560 while ($node = $ilDB->fetchAssoc($set)) {
1561 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1562 $ilDB->quote($node["child"], "integer");
1563 $obj_set = $ilDB->query($q);
1564 $obj_rec = $ilDB->fetchAssoc($obj_set);
1565 if (!$obj_rec) {
1566 $issues[] = "Tree entry without data entry: " . print_r($node, true);
1567 }
1568 }
1569
1570 // delete subtrees that have pages as parent
1571 $nodes = $tree->getSubtree($tree->getNodeData($tree->getRootId()));
1572 foreach ($nodes as $node) {
1573 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1574 $ilDB->quote($node["parent"], "integer");
1575 $obj_set = $ilDB->query($q);
1576 $obj_rec = $ilDB->fetchAssoc($obj_set);
1577 if ($obj_rec["type"] == "pg") {
1578 $node_data = $tree->getNodeData($node["child"]);
1579 if ($tree->isInTree($node["child"])) {
1580 $issues[] = "Subtree with page parent: " . print_r($node_data, true);
1581 }
1582 }
1583 }
1584
1585 // check for multi-references pages or chapters
1586 // if errors -> create copies of them here
1587 $set = $ilDB->query("SELECT DISTINCT l1.lm_id" .
1588 " FROM lm_tree l1" .
1589 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1590 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1591 " WHERE l1.child <> 1" .
1592 " AND l1.lm_id <> lm_data.lm_id" .
1593 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1594 if ($rec = $ilDB->fetchAssoc($set)) {
1595 $set = $ilDB->query("SELECT DISTINCT l1.child " .
1596 " FROM lm_tree l1" .
1597 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1598 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1599 " WHERE l1.child <> 1" .
1600 " AND l1.lm_id <> lm_data.lm_id" .
1601 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1602 while ($rec = $ilDB->fetchAssoc($set)) {
1603 $set3 = $ilDB->queryF(
1604 "SELECT * FROM lm_tree " .
1605 " WHERE child = %s ",
1606 array("integer"),
1607 array($rec["child"])
1608 );
1609 while ($rec3 = $ilDB->fetchAssoc($set3)) {
1610 $issues[] = "Multi-reference item: " . print_r($rec3, true);
1611 }
1612 }
1613 }
1614
1615 // missing copage entries
1616 $set = $ilDB->queryF(
1617 "SELECT * FROM lm_data " .
1618 " WHERE lm_id = %s AND type = %s",
1619 array("integer", "text"),
1620 array($this->getId(), "pg")
1621 );
1622 while ($rec = $ilDB->fetchAssoc($set)) {
1623 if (!ilPageObject::_exists("lm", $rec["obj_id"], "-")) {
1624 $issues[] = "Missing COPage: " . print_r($rec, true);
1625 }
1626 }
1627
1628
1629 return $issues;
1630 }
1631
1638 public function exportXML(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
1639 {
1640 $attrs = array();
1641 switch ($this->getType()) {
1642 case "lm":
1643 $attrs["Type"] = "LearningModule";
1644 break;
1645 }
1646 $a_xml_writer->xmlStartTag("ContentObject", $attrs);
1647
1648 // MetaData
1649 $this->exportXMLMetaData($a_xml_writer);
1650
1651 // StructureObjects
1652 //echo "ContObj:".$a_inst.":<br>";
1653 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Structure Objects");
1654 $this->exportXMLStructureObjects($a_xml_writer, $a_inst, $expLog);
1655 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Structure Objects");
1656
1657 // PageObjects
1658 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Page Objects");
1659 $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog);
1660 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Page Objects");
1661
1662 // MediaObjects
1663 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Media Objects");
1664 $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
1665 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Media Objects");
1666
1667 // FileItems
1668 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export File Items");
1669 $this->exportFileItems($a_target_dir, $expLog);
1670 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export File Items");
1671
1672 // Questions
1673 if (count($this->q_ids) > 0) {
1674 $qti_file = fopen($a_target_dir . "/qti.xml", "w");
1675 $pool = new ilObjQuestionPool();
1676 fwrite($qti_file, $pool->questionsToXML($this->q_ids));
1677 fclose($qti_file);
1678 }
1679
1680 // To do: implement version selection/detection
1681 // Properties
1682 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Properties");
1683 $this->exportXMLProperties($a_xml_writer, $expLog);
1684 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Properties");
1685
1686 $a_xml_writer->xmlEndTag("ContentObject");
1687 }
1688
1695 public function exportXMLMetaData(&$a_xml_writer)
1696 {
1697 $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
1698 $md2xml->setExportMode(true);
1699 $md2xml->startExport();
1700 $a_xml_writer->appendXML($md2xml->getXML());
1701 }
1702
1709 public function exportXMLStructureObjects(&$a_xml_writer, $a_inst, &$expLog)
1710 {
1711 $childs = $this->lm_tree->getChilds($this->lm_tree->getRootId());
1712 foreach ($childs as $child) {
1713 if ($child["type"] != "st") {
1714 continue;
1715 }
1716
1717 $structure_obj = new ilStructureObject($this, $child["obj_id"]);
1718 $structure_obj->exportXML($a_xml_writer, $a_inst, $expLog);
1719 unset($structure_obj);
1720 }
1721 }
1722
1723
1730 public function exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog)
1731 {
1732 $pages = ilLMPageObject::getPageList($this->getId());
1733 foreach ($pages as $page) {
1734 if (ilLMPage::_exists($this->getType(), $page["obj_id"])) {
1735 $expLog->write(date("[y-m-d H:i:s] ") . "Page Object " . $page["obj_id"]);
1736
1737 // export xml to writer object
1738 $page_obj = new ilLMPageObject($this, $page["obj_id"]);
1739 $page_obj->exportXML($a_xml_writer, "normal", $a_inst);
1740
1741 // collect media objects
1742 $mob_ids = $page_obj->getMediaObjectIDs();
1743 foreach ($mob_ids as $mob_id) {
1744 $this->mob_ids[$mob_id] = $mob_id;
1745 }
1746
1747 // collect all file items
1748 $file_ids = $page_obj->getFileItemIds();
1749 foreach ($file_ids as $file_id) {
1750 $this->file_ids[$file_id] = $file_id;
1751 }
1752
1753 // collect all questions
1754 $q_ids = $page_obj->getQuestionIds();
1755 foreach ($q_ids as $q_id) {
1756 $this->q_ids[$q_id] = $q_id;
1757 }
1758
1759 unset($page_obj);
1760 }
1761 }
1762 }
1763
1770 public function exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
1771 {
1772 $linked_mobs = array();
1773
1774 // mobs directly embedded into pages
1775 foreach ($this->mob_ids as $mob_id) {
1776 if ($mob_id > 0 && ilObject::_lookupType($mob_id) == "mob") {
1777 $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
1778 $media_obj = new ilObjMediaObject($mob_id);
1779 $media_obj->exportXML($a_xml_writer, $a_inst);
1780 $media_obj->exportFiles($a_target_dir);
1781
1782 $lmobs = $media_obj->getLinkedMediaObjects($this->mob_ids);
1783 $linked_mobs = array_merge($linked_mobs, $lmobs);
1784
1785 unset($media_obj);
1786 }
1787 }
1788
1789 // linked mobs (in map areas)
1790 foreach ($linked_mobs as $mob_id) {
1791 if ($mob_id > 0) {
1792 $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
1793 $media_obj = new ilObjMediaObject($mob_id);
1794 $media_obj->exportXML($a_xml_writer, $a_inst);
1795 $media_obj->exportFiles($a_target_dir);
1796 unset($media_obj);
1797 }
1798 }
1799 }
1800
1805 public function exportFileItems($a_target_dir, &$expLog)
1806 {
1807 foreach ($this->file_ids as $file_id) {
1808 $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
1809 $file_obj = new ilObjFile($file_id, false);
1810 $file_obj->export($a_target_dir);
1811 unset($file_obj);
1812 }
1813 }
1814
1819 public function exportXMLProperties($a_xml_writer, &$expLog)
1820 {
1821 $attrs = array();
1822 $a_xml_writer->xmlStartTag("Properties", $attrs);
1823
1824 // Layout
1825 $attrs = array("Name" => "Layout", "Value" => $this->getLayout());
1826 $a_xml_writer->xmlElement("Property", $attrs);
1827
1828 // Page Header
1829 $attrs = array("Name" => "PageHeader", "Value" => $this->getPageHeader());
1830 $a_xml_writer->xmlElement("Property", $attrs);
1831
1832 // TOC Mode
1833 $attrs = array("Name" => "TOCMode", "Value" => $this->getTOCMode());
1834 $a_xml_writer->xmlElement("Property", $attrs);
1835
1836 // LM Menu Activation
1837 $attrs = array("Name" => "ActiveLMMenu", "Value" =>
1838 ilUtil::tf2yn($this->isActiveLMMenu()));
1839 $a_xml_writer->xmlElement("Property", $attrs);
1840
1841 // Numbering Activation
1842 $attrs = array("Name" => "ActiveNumbering", "Value" =>
1844 $a_xml_writer->xmlElement("Property", $attrs);
1845
1846 // Table of contents button activation
1847 $attrs = array("Name" => "ActiveTOC", "Value" =>
1848 ilUtil::tf2yn($this->isActiveTOC()));
1849 $a_xml_writer->xmlElement("Property", $attrs);
1850
1851 // Print view button activation
1852 $attrs = array("Name" => "ActivePrintView", "Value" =>
1854 $a_xml_writer->xmlElement("Property", $attrs);
1855
1856 // Note that download button is not saved, because
1857 // download files do not exist after import
1858
1859 // Clean frames
1860 $attrs = array("Name" => "CleanFrames", "Value" =>
1861 ilUtil::tf2yn($this->cleanFrames()));
1862 $a_xml_writer->xmlElement("Property", $attrs);
1863
1864 // Public notes activation
1865 $attrs = array("Name" => "PublicNotes", "Value" =>
1866 ilUtil::tf2yn($this->publicNotes()));
1867 $a_xml_writer->xmlElement("Property", $attrs);
1868
1869 // History comments for authors activation
1870 $attrs = array("Name" => "HistoryUserComments", "Value" =>
1872 $a_xml_writer->xmlElement("Property", $attrs);
1873
1874 // Rating
1875 $attrs = array("Name" => "Rating", "Value" =>
1876 ilUtil::tf2yn($this->hasRating()));
1877 $a_xml_writer->xmlElement("Property", $attrs);
1878 $attrs = array("Name" => "RatingPages", "Value" =>
1879 ilUtil::tf2yn($this->hasRatingPages()));
1880 $a_xml_writer->xmlElement("Property", $attrs);
1881
1882 // Header Page
1883 if ($this->getHeaderPage() > 0) {
1884 $attrs = array("Name" => "HeaderPage", "Value" =>
1885 "il_" . IL_INST_ID . "_pg_" . $this->getHeaderPage());
1886 $a_xml_writer->xmlElement("Property", $attrs);
1887 }
1888
1889 // Footer Page
1890 if ($this->getFooterPage() > 0) {
1891 $attrs = array("Name" => "FooterPage", "Value" =>
1892 "il_" . IL_INST_ID . "_pg_" . $this->getFooterPage());
1893 $a_xml_writer->xmlElement("Property", $attrs);
1894 }
1895
1896 // layout per page
1897 $attrs = array("Name" => "LayoutPerPage", "Value" =>
1898 $this->getLayoutPerPage());
1899 $a_xml_writer->xmlElement("Property", $attrs);
1900
1901 // progress icons
1902 $attrs = array("Name" => "ProgressIcons", "Value" =>
1903 $this->getProgressIcons());
1904 $a_xml_writer->xmlElement("Property", $attrs);
1905
1906 // store tries
1907 $attrs = array("Name" => "StoreTries", "Value" =>
1908 $this->getStoreTries());
1909 $a_xml_writer->xmlElement("Property", $attrs);
1910
1911 // restrict forward navigation
1912 $attrs = array("Name" => "RestrictForwardNavigation", "Value" =>
1914 $a_xml_writer->xmlElement("Property", $attrs);
1915
1916 // disable default feedback
1917 $attrs = array("Name" => "DisableDefaultFeedback", "Value" =>
1918 $this->getDisableDefaultFeedback());
1919 $a_xml_writer->xmlElement("Property", $attrs);
1920
1921 $a_xml_writer->xmlEndTag("Properties");
1922 }
1923
1927 public function getExportFiles()
1928 {
1929 $file = array();
1930
1931 $types = array("xml", "html", "scorm");
1932
1933 foreach ($types as $type) {
1934 $dir = $this->getExportDirectory($type);
1935 // quit if import dir not available
1936 if (!@is_dir($dir) or
1937 !is_writeable($dir)) {
1938 continue;
1939 }
1940
1941 // open directory
1942 $cdir = dir($dir);
1943
1944 // initialize array
1945
1946 // get files and save the in the array
1947 while ($entry = $cdir->read()) {
1948 if ($entry != "." and
1949 $entry != ".." and
1950 substr($entry, -4) == ".zip" and
1951 preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(lm_)*[0-9]+\.zip\$~", $entry)) {
1952 $file[$entry . $type] = array("type" => $type, "file" => $entry,
1953 "size" => filesize($dir . "/" . $entry));
1954 }
1955 }
1956
1957 // close import directory
1958 $cdir->close();
1959 }
1960
1961 // sort files
1962 ksort($file);
1963 reset($file);
1964 return $file;
1965 }
1966
1973 public function setPublicExportFile($a_type, $a_file)
1974 {
1975 $this->public_export_file[$a_type] = $a_file;
1976 }
1977
1986 {
1987 return $this->public_export_file[$a_type];
1988 }
1989
1993 public function getOfflineFiles($dir)
1994 {
1995 // quit if offline dir not available
1996 if (!@is_dir($dir) or
1997 !is_writeable($dir)) {
1998 return array();
1999 }
2000
2001 // open directory
2002 $dir = dir($dir);
2003
2004 // initialize array
2005 $file = array();
2006
2007 // get files and save the in the array
2008 while ($entry = $dir->read()) {
2009 if ($entry != "." and
2010 $entry != ".." and
2011 substr($entry, -4) == ".pdf" and
2012 preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(lm_)*[0-9]+\.pdf\$~", $entry)) {
2013 $file[] = $entry;
2014 }
2015 }
2016
2017 // close import directory
2018 $dir->close();
2019
2020 // sort files
2021 sort($file);
2022 reset($file);
2023
2024 return $file;
2025 }
2026
2030 /*
2031 public function exportSCORM($a_target_dir, $log)
2032 {
2033 ilUtil::delDir($a_target_dir);
2034 ilUtil::makeDir($a_target_dir);
2035 //ilUtil::makeDir($a_target_dir."/res");
2036
2037 // export everything to html
2038 $this->exportHTML($a_target_dir . "/res", $log, false, "scorm");
2039
2040 // build manifest file
2041 include("./Modules/LearningModule/classes/class.ilLMContObjectManifestBuilder.php");
2042 $man_builder = new ilLMContObjectManifestBuilder($this);
2043 $man_builder->buildManifest();
2044 $man_builder->dump($a_target_dir);
2045
2046 // copy scorm 1.2 schema definitions
2047 copy("Modules/LearningModule/scorm_xsd/adlcp_rootv1p2.xsd", $a_target_dir . "/adlcp_rootv1p2.xsd");
2048 copy("Modules/LearningModule/scorm_xsd/imscp_rootv1p1p2.xsd", $a_target_dir . "/imscp_rootv1p1p2.xsd");
2049 copy("Modules/LearningModule/scorm_xsd/imsmd_rootv1p2p1.xsd", $a_target_dir . "/imsmd_rootv1p2p1.xsd");
2050 copy("Modules/LearningModule/scorm_xsd/ims_xml.xsd", $a_target_dir . "/ims_xml.xsd");
2051
2052 // zip it all
2053 $date = time();
2054 $zip_file = $a_target_dir . "/" . $date . "__" . IL_INST_ID . "__" .
2055 $this->getType() . "_" . $this->getId() . ".zip";
2056 //echo "zip-".$a_target_dir."-to-".$zip_file;
2057 ilUtil::zip(array($a_target_dir . "/res",
2058 $a_target_dir . "/imsmanifest.xml",
2059 $a_target_dir . "/adlcp_rootv1p2.xsd",
2060 $a_target_dir . "/imscp_rootv1p1p2.xsd",
2061 $a_target_dir . "/ims_xml.xsd",
2062 $a_target_dir . "/imsmd_rootv1p2p1.xsd"), $zip_file);
2063
2064 $dest_file = $this->getExportDirectory("scorm") . "/" . $date . "__" . IL_INST_ID . "__" .
2065 $this->getType() . "_" . $this->getId() . ".zip";
2066
2067 rename($zip_file, $dest_file);
2068 ilUtil::delDir($a_target_dir);
2069 }*/
2070
2071
2072
2079 public function exportFO(&$a_xml_writer, $a_target_dir)
2080 {
2081 // fo:root (start)
2082 $attrs = array();
2083 $attrs["xmlns:fo"] = "http://www.w3.org/1999/XSL/Format";
2084 $a_xml_writer->xmlStartTag("fo:root", $attrs);
2085
2086 // fo:layout-master-set (start)
2087 $attrs = array();
2088 $a_xml_writer->xmlStartTag("fo:layout-master-set", $attrs);
2089
2090 // fo:simple-page-master (start)
2091 $attrs = array();
2092 $attrs["master-name"] = "DinA4";
2093 $attrs["page-height"] = "29.7cm";
2094 $attrs["page-width"] = "21cm";
2095 $attrs["margin-top"] = "4cm";
2096 $attrs["margin-bottom"] = "1cm";
2097 $attrs["margin-left"] = "2.8cm";
2098 $attrs["margin-right"] = "7.3cm";
2099 $a_xml_writer->xmlStartTag("fo:simple-page-master", $attrs);
2100
2101 // fo:region-body (complete)
2102 $attrs = array();
2103 $attrs["margin-top"] = "0cm";
2104 $attrs["margin-bottom"] = "1.25cm";
2105 $a_xml_writer->xmlElement("fo:region-body", $attrs);
2106
2107 // fo:region-before (complete)
2108 $attrs = array();
2109 $attrs["extent"] = "1cm";
2110 $a_xml_writer->xmlElement("fo:region-before", $attrs);
2111
2112 // fo:region-after (complete)
2113 $attrs = array();
2114 $attrs["extent"] = "1cm";
2115 $a_xml_writer->xmlElement("fo:region-after", $attrs);
2116
2117 // fo:simple-page-master (end)
2118 $a_xml_writer->xmlEndTag("fo:simple-page-master");
2119
2120 // fo:layout-master-set (end)
2121 $a_xml_writer->xmlEndTag("fo:layout-master-set");
2122
2123 // fo:page-sequence (start)
2124 $attrs = array();
2125 $attrs["master-reference"] = "DinA4";
2126 $a_xml_writer->xmlStartTag("fo:page-sequence", $attrs);
2127
2128 // fo:flow (start)
2129 $attrs = array();
2130 $attrs["flow-name"] = "xsl-region-body";
2131 $a_xml_writer->xmlStartTag("fo:flow", $attrs);
2132
2133
2134 // StructureObjects
2135 $this->exportFOStructureObjects($a_xml_writer, $expLog);
2136
2137 // fo:flow (end)
2138 $a_xml_writer->xmlEndTag("fo:flow");
2139
2140 // fo:page-sequence (end)
2141 $a_xml_writer->xmlEndTag("fo:page-sequence");
2142
2143 // fo:root (end)
2144 $a_xml_writer->xmlEndTag("fo:root");
2145 }
2146
2153 public function exportFOStructureObjects(&$a_xml_writer)
2154 {
2155 $childs = $this->lm_tree->getChilds($this->lm_tree->getRootId());
2156 foreach ($childs as $child) {
2157 if ($child["type"] != "st") {
2158 continue;
2159 }
2160
2161 $structure_obj = new ilStructureObject($this, $child["obj_id"]);
2162 $structure_obj->exportFO($a_xml_writer, $expLog);
2163 unset($structure_obj);
2164 }
2165 }
2166
2167 public function getXMLZip()
2168 {
2169 $cont_exp = new ilContObjectExport($this, 'xml');
2170
2171 $export_file = $cont_exp->buildExportFile();
2172 return $export_file;
2173 }
2174
2183 public function executeDragDrop($source_id, $target_id, $first_child, $as_subitem = false, $movecopy = "move")
2184 {
2185 $lmtree = new ilTree($this->getId());
2186 $lmtree->setTableNames('lm_tree', 'lm_data');
2187 $lmtree->setTreeTablePK("lm_id");
2188 //echo "-".$source_id."-".$target_id."-".$first_child."-".$as_subitem."-";
2189 $source_obj = ilLMObjectFactory::getInstance($this, $source_id, true);
2190 $source_obj->setLMId($this->getId());
2191
2192 if (!$first_child) {
2193 $target_obj = ilLMObjectFactory::getInstance($this, $target_id, true);
2194 $target_obj->setLMId($this->getId());
2195 $target_parent = $lmtree->getParentId($target_id);
2196 }
2197
2198 // handle pages
2199 if ($source_obj->getType() == "pg") {
2200 //echo "1";
2201 if ($lmtree->isInTree($source_obj->getId())) {
2202 $node_data = $lmtree->getNodeData($source_obj->getId());
2203
2204 // cut on move
2205 if ($movecopy == "move") {
2206 $parent_id = $lmtree->getParentId($source_obj->getId());
2207 $lmtree->deleteTree($node_data);
2208
2209 // write history entry
2211 $source_obj->getId(),
2212 "cut",
2213 array(ilLMObject::_lookupTitle($parent_id), $parent_id),
2214 $this->getType() . ":pg"
2215 );
2217 $parent_id,
2218 "cut_page",
2219 array(ilLMObject::_lookupTitle($source_obj->getId()), $source_obj->getId()),
2220 $this->getType() . ":st"
2221 );
2222 } else {
2223 // copy page
2224 $new_page = $source_obj->copy();
2225 $source_id = $new_page->getId();
2226 $source_obj = $new_page;
2227 }
2228
2229 // paste page
2230 if (!$lmtree->isInTree($source_obj->getId())) {
2231 if ($first_child) { // as first child
2232 $target_pos = IL_FIRST_NODE;
2233 $parent = $target_id;
2234 } elseif ($as_subitem) { // as last child
2235 $parent = $target_id;
2236 $target_pos = IL_FIRST_NODE;
2237 $pg_childs = $lmtree->getChildsByType($parent, "pg");
2238 if (count($pg_childs) != 0) {
2239 $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
2240 }
2241 } else { // at position
2242 $target_pos = $target_id;
2243 $parent = $target_parent;
2244 }
2245
2246 // insert page into tree
2247 $lmtree->insertNode(
2248 $source_obj->getId(),
2249 $parent,
2250 $target_pos
2251 );
2252
2253 // write history entry
2254 if ($movecopy == "move") {
2255 // write history comments
2257 $source_obj->getId(),
2258 "paste",
2259 array(ilLMObject::_lookupTitle($parent), $parent),
2260 $this->getType() . ":pg"
2261 );
2263 $parent,
2264 "paste_page",
2265 array(ilLMObject::_lookupTitle($source_obj->getId()), $source_obj->getId()),
2266 $this->getType() . ":st"
2267 );
2268 }
2269 }
2270 }
2271 }
2272
2273 // handle chapters
2274 if ($source_obj->getType() == "st") {
2275 //echo "2";
2276 $source_node = $lmtree->getNodeData($source_id);
2277 $subnodes = $lmtree->getSubtree($source_node);
2278
2279 // check, if target is within subtree
2280 foreach ($subnodes as $subnode) {
2281 if ($subnode["obj_id"] == $target_id) {
2282 return;
2283 }
2284 }
2285
2286 $target_pos = $target_id;
2287
2288 if ($first_child) { // as first subchapter
2289 $target_pos = IL_FIRST_NODE;
2290 $target_parent = $target_id;
2291
2292 $pg_childs = $lmtree->getChildsByType($target_parent, "pg");
2293 if (count($pg_childs) != 0) {
2294 $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
2295 }
2296 } elseif ($as_subitem) { // as last subchapter
2297 $target_parent = $target_id;
2298 $target_pos = IL_FIRST_NODE;
2299 $childs = $lmtree->getChilds($target_parent);
2300 if (count($childs) != 0) {
2301 $target_pos = $childs[count($childs) - 1]["obj_id"];
2302 }
2303 }
2304
2305 // insert into
2306 /*
2307 if ($position == "into")
2308 {
2309 $target_parent = $target_id;
2310 $target_pos = IL_FIRST_NODE;
2311
2312 // if target_pos is still first node we must skip all pages
2313 if ($target_pos == IL_FIRST_NODE)
2314 {
2315 $pg_childs =& $lmtree->getChildsByType($target_parent, "pg");
2316 if (count($pg_childs) != 0)
2317 {
2318 $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
2319 }
2320 }
2321 }
2322 */
2323
2324
2325 // delete source tree
2326 if ($movecopy == "move") {
2327 $lmtree->deleteTree($source_node);
2328 } else {
2329 // copy chapter (incl. subcontents)
2330 $new_chapter = $source_obj->copy($lmtree, $target_parent, $target_pos);
2331 }
2332
2333 if (!$lmtree->isInTree($source_id)) {
2334 $lmtree->insertNode($source_id, $target_parent, $target_pos);
2335
2336 // insert moved tree
2337 if ($movecopy == "move") {
2338 foreach ($subnodes as $node) {
2339 if ($node["obj_id"] != $source_id) {
2340 $lmtree->insertNode($node["obj_id"], $node["parent"]);
2341 }
2342 }
2343 }
2344 }
2345
2346 // check the tree
2347 $this->checkTree();
2348 }
2349
2350 $this->checkTree();
2351 }
2352
2356 public function validatePages()
2357 {
2358 $mess = "";
2359
2360 $pages = ilLMPageObject::getPageList($this->getId());
2361 foreach ($pages as $page) {
2362 if (ilLMPage::_exists($this->getType(), $page["obj_id"])) {
2363 $cpage = new ilLMPage($page["obj_id"]);
2364 $cpage->buildDom();
2365 $error = @$cpage->validateDom();
2366
2367 if ($error != "") {
2368 $this->lng->loadLanguageModule("content");
2369 ilUtil::sendInfo($this->lng->txt("cont_import_validation_errors"));
2370 $title = ilLMObject::_lookupTitle($page["obj_id"]);
2371 $page_obj = new ilLMPageObject($this, $page["obj_id"]);
2372 $mess .= $this->lng->txt("obj_pg") . ": " . $title;
2373 $mess .= '<div class="small">';
2374 foreach ($error as $e) {
2375 $err_mess = implode(" - ", $e);
2376 if (!is_int(strpos($err_mess, ":0:"))) {
2377 $mess .= htmlentities($err_mess) . "<br />";
2378 }
2379 }
2380 $mess .= '</div>';
2381 $mess .= "<br />";
2382 }
2383 }
2384 }
2385
2386 return $mess;
2387 }
2388
2395 public function importFromZipFile(
2396 $a_tmp_file,
2397 $a_filename,
2398 $a_validate = true,
2399 $a_import_into_help_module = 0
2400 ) {
2401 $lng = $this->lng;
2402
2403 // create import directory
2404 $this->createImportDirectory();
2405
2406 // copy uploaded file to import directory
2407 $file = pathinfo($a_filename);
2408 $full_path = $this->getImportDirectory() . "/" . $a_filename;
2409
2411 $a_tmp_file,
2412 $a_filename,
2413 $full_path
2414 );
2415
2416 // unzip file
2417 ilUtil::unzip($full_path);
2418
2419 $subdir = basename($file["basename"], "." . $file["extension"]);
2420
2421 $mess = $this->importFromDirectory(
2422 $this->getImportDirectory() . "/" . $subdir,
2423 $a_validate
2424 );
2425
2426
2427 // delete import directory
2429
2430 return $mess;
2431 }
2432
2433
2440 // begin-patch optes_lok_export
2441 public function importFromDirectory($a_directory, $a_validate = true, $a_mapping = null)
2442 // end-patch optes_lok_export
2443 {
2444 $lng = $this->lng;
2445
2446 $this->log->debug("import from directory " . $a_directory);
2447
2448 // determine filename of xml file
2449 $subdir = basename($a_directory);
2450 $xml_file = $a_directory . "/" . $subdir . ".xml";
2451
2452 // check directory exists within zip file
2453 if (!is_dir($a_directory)) {
2454 $this->log->error(sprintf($lng->txt("cont_no_subdir_in_zip"), $subdir));
2455 return sprintf($lng->txt("cont_no_subdir_in_zip"), $subdir);
2456 }
2457
2458 // check whether xml file exists within zip file
2459 if (!is_file($xml_file)) {
2460 $this->log->error(sprintf($lng->txt("cont_zip_file_invalid"), $subdir . "/" . $subdir . ".xml"));
2461 return sprintf($lng->txt("cont_zip_file_invalid"), $subdir . "/" . $subdir . ".xml");
2462 }
2463
2464 // import questions
2465 $this->log->debug("import qti");
2466 $qti_file = $a_directory . "/qti.xml";
2467 $qtis = array();
2468 if (is_file($qti_file)) {
2469 $qtiParser = new ilQTIParser(
2470 $qti_file,
2472 0,
2473 ""
2474 );
2475 $result = $qtiParser->startParsing();
2476 $founditems = &$qtiParser->getFoundItems();
2477 $testObj = new ilObjTest(0, true);
2478 if (count($founditems) > 0) {
2479 $qtiParser = new ilQTIParser($qti_file, IL_MO_PARSE_QTI, 0, "");
2480 $qtiParser->setTestObject($testObj);
2481 $result = $qtiParser->startParsing();
2482 $qtis = array_merge($qtis, $qtiParser->getImportMapping());
2483 }
2484 }
2485
2486 $this->log->debug("get ilContObjParser");
2487 $subdir = ".";
2488 $contParser = new ilContObjParser($this, $xml_file, $subdir, $a_directory);
2489 // smeyer: added \ilImportMapping lok im/export
2490 $contParser->setImportMapping($a_mapping);
2491 $contParser->setQuestionMapping($qtis);
2492 $contParser->startParsing();
2493 ilObject::_writeImportId($this->getId(), $this->getImportId());
2494 $this->MDUpdateListener('General');
2495
2496 // import style
2497 $style_file = $a_directory . "/style.xml";
2498 $style_zip_file = $a_directory . "/style.zip";
2499 if (is_file($style_zip_file)) { // try to import style.zip first
2500 $style = new ilObjStyleSheet();
2501 $style->import($style_zip_file);
2502 $this->writeStyleSheetId($style->getId());
2503 } elseif (is_file($style_file)) { // try to import style.xml
2504 $style = new ilObjStyleSheet();
2505 $style->import($style_file);
2506 $this->writeStyleSheetId($style->getId());
2507 }
2508
2509 // // validate
2510 if ($a_validate) {
2511 $mess = $this->validatePages();
2512 }
2513
2514 if ($mess == "") {
2515 // handle internal links to this learning module
2517 $this->getImportId(),
2518 $this->getType(),
2519 $this->getRefId()
2520 );
2521 }
2522
2523 return $mess;
2524 }
2525
2534 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
2535 {
2536 $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
2537 $this->cloneMetaData($new_obj);
2538 //$new_obj->createProperties();
2539
2540 //copy online status if object is not the root copy object
2541 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
2542
2543 if (!$cp_options->isRootNode($this->getRefId())) {
2544 $new_obj->setOfflineStatus($this->getOfflineStatus());
2545 }
2546
2547 // $new_obj->setTitle($this->getTitle());
2548 $new_obj->setDescription($this->getDescription());
2549 $new_obj->setLayoutPerPage($this->getLayoutPerPage());
2550 $new_obj->setLayout($this->getLayout());
2551 $new_obj->setTOCMode($this->getTOCMode());
2552 $new_obj->setActiveLMMenu($this->isActiveLMMenu());
2553 $new_obj->setActiveTOC($this->isActiveTOC());
2554 $new_obj->setActiveNumbering($this->isActiveNumbering());
2555 $new_obj->setActivePrintView($this->isActivePrintView());
2556 $new_obj->setActivePreventGlossaryAppendix($this->isActivePreventGlossaryAppendix());
2557 $new_obj->setActiveDownloads($this->isActiveDownloads());
2558 $new_obj->setActiveDownloadsPublic($this->isActiveDownloadsPublic());
2559 $new_obj->setPublicNotes($this->publicNotes());
2560 $new_obj->setCleanFrames($this->cleanFrames());
2561 $new_obj->setHistoryUserComments($this->isActiveHistoryUserComments());
2562 $new_obj->setPublicAccessMode($this->getPublicAccessMode());
2563 $new_obj->setPageHeader($this->getPageHeader());
2564 $new_obj->setRating($this->hasRating());
2565 $new_obj->setRatingPages($this->hasRatingPages());
2566 $new_obj->setDisableDefaultFeedback($this->getDisableDefaultFeedback());
2567 $new_obj->setProgressIcons($this->getProgressIcons());
2568 $new_obj->setStoreTries($this->getStoreTries());
2569 $new_obj->setRestrictForwardNavigation($this->getRestrictForwardNavigation());
2570 $new_obj->setAutoGlossaries($this->getAutoGlossaries());
2571
2572 $new_obj->update();
2573
2574 $new_obj->createLMTree();
2575
2576 // copy style
2577 $style_id = $this->getStyleSheetId();
2578 if ($style_id > 0 &&
2581 $new_id = $style_obj->ilClone();
2582 $new_obj->setStyleSheetId($new_id);
2583 } else { // or just set the same standard style
2584 $new_obj->setStyleSheetId($style_id);
2585 }
2586 $new_obj->update();
2587
2588 // copy content
2589 $copied_nodes = $this->copyAllPagesAndChapters($new_obj, $a_copy_id);
2590
2591 // page header and footer
2592 if ($this->getHeaderPage() > 0 && ($new_page_header = $copied_nodes[$this->getHeaderPage()]) > 0) {
2593 $new_obj->setHeaderPage($new_page_header);
2594 }
2595 if ($this->getFooterPage() > 0 && ($new_page_footer = $copied_nodes[$this->getFooterPage()]) > 0) {
2596 $new_obj->setFooterPage($new_page_footer);
2597 }
2598 $new_obj->update();
2599
2600 // Copy learning progress settings
2601 $obj_settings = new ilLPObjSettings($this->getId());
2602 $obj_settings->cloneSettings($new_obj->getId());
2603 unset($obj_settings);
2604
2605 // copy (page) multilang settings
2607 $ot->copy($new_obj->getId());
2608
2609 // copy lm menu
2610 $menu = new ilLMMenuEditor();
2611 $menu->setObjId($this->getId());
2612 $new_menu = new ilLMMenuEditor();
2613 $new_menu->setObjId($new_obj->getId());
2614 foreach ($menu->getMenuEntries() as $entry) {
2615 /*'id' => $row->id,
2616 'title' => $row->title,
2617 'link' => $row->target,
2618 'type' => $row->link_type,
2619 'ref_id' => $row->link_ref_id,
2620 'active'*/
2621
2622 $new_menu->setTarget($entry["link"]);
2623 $new_menu->setTitle($entry["title"]);
2624 $new_menu->setLinkType($entry["type"]);
2625 $new_menu->setLinkRefId($entry["ref_id"]);
2626 $new_menu->create();
2627 ilLMMenuEditor::writeActive($new_menu->getEntryId(), $entry["active"] == "y" ? true : false);
2628 }
2629
2630
2631 return $new_obj;
2632 }
2633
2639 public function copyAllPagesAndChapters($a_target_obj, $a_copy_id = 0)
2640 {
2641 $parent_id = $a_target_obj->lm_tree->readRootId();
2642
2643 // get all chapters of root lm
2644 $chapters = $this->lm_tree->getChildsByType($this->lm_tree->readRootId(), "st");
2645 $copied_nodes = array();
2646 //$time = time();
2647 foreach ($chapters as $chap) {
2648 $cid = ilLMObject::pasteTree(
2649 $a_target_obj,
2650 $chap["child"],
2651 $parent_id,
2653 $time,
2654 $copied_nodes,
2655 true,
2656 $this
2657 );
2658 $target = $cid;
2659 }
2660
2661 // copy free pages
2662 $pages = ilLMPageObject::getPageList($this->getId());
2663 foreach ($pages as $p) {
2664 if (!$this->lm_tree->isInTree($p["obj_id"])) {
2665 $item = new ilLMPageObject($this, $p["obj_id"]);
2666 $target_item = $item->copy($a_target_obj);
2667 $copied_nodes[$item->getId()] = $target_item->getId();
2668 }
2669 }
2670
2671 // Add mapping for pages and chapters
2672 $options = ilCopyWizardOptions::_getInstance($a_copy_id);
2673 foreach ($copied_nodes as $old_id => $new_id) {
2674 $options->appendMapping(
2675 $this->getRefId() . '_' . $old_id,
2676 $a_target_obj->getRefId() . '_' . $new_id
2677 );
2678 }
2679
2680 ilLMObject::updateInternalLinks($copied_nodes);
2681
2682 $a_target_obj->checkTree();
2683
2684 return $copied_nodes;
2685 }
2686
2687
2694 public static function lookupAutoGlossaries($a_lm_id)
2695 {
2696 global $DIC;
2697
2698 $ilDB = $DIC->database();
2699
2700 // read auto glossaries
2701 $set = $ilDB->query(
2702 "SELECT * FROM lm_glossaries " .
2703 " WHERE lm_id = " . $ilDB->quote($a_lm_id, "integer")
2704 );
2705 $glos = array();
2706 while ($rec = $ilDB->fetchAssoc($set)) {
2707 $glos[] = $rec["glo_id"];
2708 }
2709 return $glos;
2710 }
2711
2718 public function autoLinkGlossaryTerms($a_glo_ref_id)
2719 {
2720 // get terms
2721 $terms = ilGlossaryTerm::getTermList($a_glo_ref_id);
2722
2723 // each get page: get content
2724 $pages = ilLMPage::getAllPages($this->getType(), $this->getId());
2725
2726 // determine terms that occur in the page
2727 $found_pages = array();
2728 foreach ($pages as $p) {
2729 $pg = new ilLMPage($p["id"]);
2730 $c = $pg->getXMLContent();
2731 foreach ($terms as $t) {
2732 if (is_int(stripos($c, $t["term"]))) {
2733 $found_pages[$p["id"]]["terms"][] = $t;
2734 if (!is_object($found_pages[$p["id"]]["page"])) {
2735 $found_pages[$p["id"]]["page"] = $pg;
2736 }
2737 }
2738 }
2739 reset($terms);
2740 }
2741
2742 // ilPCParagraph autoLinkGlossariesPage with page and terms
2743 foreach ($found_pages as $id => $fp) {
2744 ilPCParagraph::autoLinkGlossariesPage($fp["page"], $fp["terms"]);
2745 }
2746 }
2747
2748
2752
2758 public static function isOnlineHelpModule($a_id, $a_as_obj_id = false)
2759 {
2760 if (!$a_as_obj_id && $a_id > 0 && $a_id == OH_REF_ID) {
2761 return true;
2762 }
2763 if ($a_as_obj_id && $a_id > 0 && $a_id == ilObject::_lookupObjId(OH_REF_ID)) {
2764 return true;
2765 }
2766 return false;
2767 }
2768
2769 public function setRating($a_value)
2770 {
2771 $this->rating = (bool) $a_value;
2772 }
2773
2774 public function hasRating()
2775 {
2776 return $this->rating;
2777 }
2778
2779 public function setRatingPages($a_value)
2780 {
2781 $this->rating_pages = (bool) $a_value;
2782 }
2783
2784 public function hasRatingPages()
2785 {
2786 return $this->rating_pages;
2787 }
2788
2789
2790 public function MDUpdateListener($a_element)
2791 {
2792 parent::MDUpdateListener($a_element);
2793
2794 switch ($a_element) {
2795 case 'Educational':
2796 $obj_lp = ilObjectLP::getInstance($this->getId());
2797 if (in_array(
2798 $obj_lp->getCurrentMode(),
2800 )) {
2802 }
2803 break;
2804
2805 case 'General':
2806
2807 // Update Title and description
2808 $md = new ilMD($this->getId(), 0, $this->getType());
2809 if (!is_object($md_gen = $md->getGeneral())) {
2810 return false;
2811 }
2812
2814 if ($ot->getContentActivated()) {
2815 $ot->setDefaultTitle($md_gen->getTitle());
2816
2817 foreach ($md_gen->getDescriptionIds() as $id) {
2818 $md_des = $md_gen->getDescription($id);
2819 $ot->setDefaultDescription($md_des->getDescription());
2820 break;
2821 }
2822 $ot->save();
2823 }
2824 break;
2825
2826 }
2827 return true;
2828 }
2829
2835 public function getPublicExportFiles()
2836 {
2837 $dirs = array("xml", "scorm");
2838 $export_files = array();
2839
2841 if ($ot->getContentActivated()) {
2842 $langs = $ot->getLanguages();
2843 foreach ($langs as $l => $ldata) {
2844 $dirs[] = "html_" . $l;
2845 }
2846 $dirs[] = "html_all";
2847 } else {
2848 $dirs[] = "html";
2849 }
2850
2851 foreach ($dirs as $dir) {
2852 $type = explode("_", $dir);
2853 $type = $type[0];
2854 if ($this->getPublicExportFile($type) != "") {
2855 if (is_file($this->getExportDirectory($dir) . "/" .
2856 $this->getPublicExportFile($type))) {
2857 $size = filesize($this->getExportDirectory($dir) . "/" .
2858 $this->getPublicExportFile($type));
2859 $export_files[] = array("type" => $type,
2860 "dir_type" => $dir,
2861 "file" => $this->getPublicExportFile($type),
2862 "size" => $size);
2863 }
2864 }
2865 }
2866
2867 return $export_files;
2868 }
2869}
$result
user()
Definition: user.php:4
$size
Definition: RandomTest.php:84
An exception for terminatinating execution or to throw for unit testing.
error($a_errmsg)
set error message @access public
const IL_MO_VERIFY_QTI
const IL_MO_PARSE_QTI
const IL_LAST_NODE
Definition: class.ilTree.php:4
const IL_FIRST_NODE
Definition: class.ilTree.php:5
static _checkCondition($condition, $a_usr_id=0)
checks wether a single condition is fulfilled every trigger object type must implement a static metho...
static _checkAllConditionsOfTarget($a_target_ref_id, $a_target_id, $a_target_type="", $a_usr_id=0)
checks wether all conditions of a target object are fulfilled
static _getPersistedConditionsOfTarget($a_target_ref_id, $a_target_obj_id, $a_target_type="")
get all persisted conditions of target object
Content Object Parser.
Export class for content objects.
static _getInstance($a_copy_id)
Get instance of copy wizard options.
static getTermList( $a_glo_ref_id, $searchterm="", $a_first_letter="", $a_def="", $a_tax_node=0, $a_add_amet_fields=false, array $a_amet_filter=null, $a_include_references=false)
Get all terms for given set of glossary ids.
static _createEntry( $a_obj_id, $a_action, $a_info_params="", $a_obj_type="", $a_user_comment="", $a_update_last=false)
Creates a new history entry for an object.
class for editing lm menu
static writeActive($entry_id, $active)
Write status for entry id.
static getInstance(&$a_content_obj, $a_id=0, $a_halt=true)
static updateInternalLinks($a_copied_nodes, $a_parent_type="lm")
Update internal links, after multiple pages have been copied.
static _lookupTitle($a_obj_id)
Lookup title.
static putInTree($a_obj, $a_parent_id="", $a_target_node_id="")
put this object into content object tree
static _deleteAllObjectData(&$a_cobj)
delete all objects of content object (digi book / learning module)
static pasteTree( $a_target_lm, $a_item_id, $a_parent_id, $a_target, $a_insert_time, &$a_copied_nodes, $a_as_copy=false, $a_source_lm=null)
Paste item (tree) from clipboard to current lm.
Class ilLMPageObject.
static getPageList($lm_id)
static
Extension of ilPageObject for learning modules.
static _refreshStatus($a_obj_id, $a_users=null)
Set dirty.
static getLogger($a_component_id)
Get component logger.
static commentsActivated($a_rep_obj_id, $a_obj_id, $a_obj_type, $a_news_id=0)
Are comments activated for object?
static activateComments($a_rep_obj_id, $a_obj_id, $a_obj_type, $a_activate=true)
Activate notes feature.
Class ilObjContentObject.
exportXMLMediaObjects(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
export media objects to xml (see ilias_co.dtd)
exportFO(&$a_xml_writer, $a_target_dir)
export scorm package
static lookupAutoGlossaries($a_lm_id)
Lookup auto glossaries.
putInTree($a_parent)
put content object in main tree
__construct($a_id=0, $a_call_by_reference=true)
Constructor @access public.
updateProperties()
Update content object properties.
setAutoGlossaries($a_val)
Set auto glossaries.
setTitle($a_title)
set title of content object
exportFileItems($a_target_dir, &$expLog)
export files of file itmes
getLayoutPerPage()
Get layout per page.
createProperties()
create new properties record
static _getNrLMsIndividualStyles()
get number of learning modules with individual styles
setForTranslation($a_val)
Set for translation.
static getAvailableLayouts()
get all available lm layouts
getRestrictForwardNavigation()
Get restrict forward navigation.
getDataDirectory()
get data directory
getHideHeaderFooterPrint()
Get hide header footer in print mode.
copyAllPagesAndChapters($a_target_obj, $a_copy_id=0)
Copy all pages and chapters.
update()
update complete object (meta data and properties)
getTOCMode()
get toc mode ("chapters" | "pages")
setPageHeader($a_pg_header=ilLMObject::CHAPTER_TITLE)
set page header mode
exportXMLPageObjects(&$a_xml_writer, $a_inst, &$expLog)
export page objects to xml (see ilias_co.dtd)
getExportDirectory($a_type="xml")
get export directory of lm
exportXMLMetaData(&$a_xml_writer)
export content objects meta data to xml (see ilias_co.dtd)
static _lookupRestrictForwardNavigation($a_obj_id)
Lookup forward restriction navigation.
static writeHeaderPage($a_lm_id, $a_page_id)
Write header page.
setImportDirectory($a_import_dir)
Set import directory for further use in ilContObjParser.
getForTranslation()
Get for translation.
importFromDirectory($a_directory, $a_validate=true, $a_mapping=null)
Import lm from directory.
getTitle()
get title of content object
static _lookupStoreTries($a_id)
Lookup disable default feedback.
createImportDirectory()
creates data directory for import files (data_dir/lm_data/lm_<id>/import, depending on data directory...
create($a_no_meta_data=false)
create content object
getAutoGlossaries()
Get auto glossaries.
static _lookupStyleSheetId($a_cont_obj_id)
lookup style sheet ID
static _getNrLMsNoStyle()
get number of learning modules assigned no style
static writeFooterPage($a_lm_id, $a_page_id)
Write footer page.
static _getMissingPreconditionsTopChapter($cont_obj_ref_id, $cont_obj_id, $page_id)
get top chapter of page for that any precondition is missing
writeStyleSheetId($a_style_id)
write ID of assigned style sheet object to db
removeAutoGlossary($a_glo_id)
Remove auto glossary.
setProgressIcons($a_val)
Set progress icons.
setLayoutPerPage($a_val)
Set layout per page.
autoLinkGlossaryTerms($a_glo_ref_id)
Auto link glossary terms.
createLMTree()
create content object tree (that stores structure object hierarchie)
importFromZipFile( $a_tmp_file, $a_filename, $a_validate=true, $a_import_into_help_module=0)
Import lm from zip file.
getExportFiles()
get export files
getLayout()
get default page layout of content object (see directory layouts/)
getDescription()
get description of content object
getPageHeader()
get page header mode (ilLMOBject::CHAPTER_TITLE | ilLMOBject::PAGE_TITLE | ilLMOBject::NO_HEADER)
exportXMLProperties($a_xml_writer, &$expLog)
export properties of content object
static _lookup($a_obj_id, $a_field)
Lookup property.
getPublicAccessMode()
get public access mode ("complete" | "selected")
setRestrictForwardNavigation($a_val)
Set restrict forward navigation.
getImportDirectory()
get import directory of lm
setDisableDefaultFeedback($a_val)
Set disable default feedback for questions.
checkStructure()
Check tree (this has been copied from fixTree due to a bug fixing, should be reorganised)
addFirstChapterAndPage()
Add first chapter and page.
setImportId($a_id)
set import id
readProperties()
read content object properties
getStyleSheetId()
get ID of assigned style sheet object
setHideHeaderFooterPrint($a_val)
Set hide header footer in print mode.
exportXMLStructureObjects(&$a_xml_writer, $a_inst, &$expLog)
export structure objects to xml (see ilias_co.dtd)
MDUpdateListener($a_element)
Meta data update listener.
static hasSuccessorPage($a_cont_obj_id, $a_page_id)
checks if page has a successor page
static _checkPreconditionsOfPage($cont_ref_id, $cont_obj_id, $page_id)
checks wether the preconditions of a page are fulfilled or not
setDescription($a_description)
set description of content object
executeDragDrop($source_id, $target_id, $first_child, $as_subitem=false, $movecopy="move")
Execute Drag Drop Action.
setPublicExportFile($a_type, $a_file)
specify public export file for type
validatePages()
Validate all pages.
static _lookupContObjIdByStyleId($a_style_id)
lookup style sheet ID
getStoreTries()
Get store tries.
read()
read data of content object
exportFOStructureObjects(&$a_xml_writer)
export structure objects to fo
updateAutoGlossaries()
Update auto glossaries.
createExportDirectory($a_type="xml")
creates data directory for export files (data_dir/lm_data/lm_<id>/export, depending on data directory...
setStoreTries($a_val)
Set store tries.
setTOCMode($a_toc_mode="chapters")
set toc mode
getProgressIcons()
Get progress icons.
static _getMissingPreconditionsOfPage($cont_ref_id, $cont_obj_id, $page_id)
gets all missing preconditions of page
setStyleSheetId($a_style_id)
set ID of assigned style sheet object
static isOnlineHelpModule($a_id, $a_as_obj_id=false)
Is module an online module.
static _getNrOfAssignedLMs($a_style_id)
gets the number of learning modules assigned to a content style
static _lookupDisableDefaultFeedback($a_id)
Lookup disable default feedback.
getLMTree()
get content object tree
static _deleteStyleAssignments($a_style_id)
delete all style references to style
exportXML(&$a_xml_writer, $a_inst, $a_target_dir, &$expLog)
export object to xml (see ilias_co.dtd)
getPublicExportFiles()
Get public export files.
setLayout($a_layout)
set default page layout
cloneObject($a_target_id, $a_copy_id=0, $a_omit_tree=false)
Clone learning module.
static _moveLMStyles($a_from_style, $a_to_style)
move learning modules from one style to another
getOfflineFiles($dir)
get offline files
getDisableDefaultFeedback()
Get disable default feedback for questions.
getPublicExportFile($a_type)
get public export file
Class ilObjFile.
Class ilObjMediaObject.
Class ilObjStyleSheet.
static _lookupStandard($a_id)
Lookup standard flag.
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
static getInstance($a_obj_id)
static getInstance($a_obj_id)
Get instance.
Class ilObject Basic functions for all objects.
static _writeImportId($a_obj_id, $a_import_id)
write import id to db (static)
getType()
get object type @access public
static _lookupObjId($a_id)
setOfflineStatus($a_status)
Set offline status.
deleteMetaData()
delete meta data entry
updateMetaData()
update meta data entry
getOfflineStatus()
Get offline status.
createMetaData()
create meta data entry
getRefId()
get reference id @access public
cloneMetaData($target_obj)
Copy meta data.
getId()
get object id @access public
static _lookupType($a_id, $a_reference=false)
lookup object type
static autoLinkGlossariesPage($a_page, $a_terms)
Auto link glossary of whole page.
static _handleImportRepositoryLinks($a_rep_import_id, $a_rep_type, $a_rep_ref_id)
Change targest of repository links.
static _exists($a_parent_type, $a_id, $a_lang="", $a_no_cache=false)
Checks whether page exists.
static getAllPages($a_parent_type, $a_parent_id, $a_lang="-")
Get all pages for parent object.
Class ilStructreObject.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
static getDataDir()
get data directory (outside webspace)
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static tf2yn($a_tf)
convert true/false to "y"/"n"
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static yn2tf($a_yn)
convert "y"/"n" to true/false
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
$target_id
Definition: goto.php:49
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$ret
Definition: parser.php:6
$ilErr
Definition: raiseError.php:18
foreach($_POST as $key=> $value) $res
global $ilDB
$lm_set
$ilUser
Definition: imgupload.php:18
$a_type
Definition: workflow.php:92
$DIC
Definition: xapitoken.php:46