ILIAS  release_8 Revision v8.24
class.ilObjContentObject.php
Go to the documentation of this file.
1<?php
2
24{
25 protected \ILIAS\Notes\Service $notes;
26 protected array $q_ids = [];
27 protected array $mob_ids = [];
28 protected array $file_ids = [];
29 protected array $public_export_file = [];
30 protected int $header_page = 0;
31 protected int $footer_page = 0;
32 protected bool $user_comments = false;
33 protected bool $clean_frames = false;
34 protected bool $pub_notes = false;
35 protected bool $downloads_public_active = false;
36 protected bool $downloads_active = false;
37 protected bool $hide_header_footer_print = false;
38 protected bool $prevent_glossary_appendix_active = false;
39 protected bool $print_view_active = false;
40 protected bool $numbering = false;
41 protected bool $toc_active = false;
42 protected bool $lm_menu_active = false;
43 protected string $public_access_mode = '';
44 protected string $toc_mode = '';
45 protected bool $restrict_forw_nav = false;
46 protected bool $store_tries = false;
47 protected bool $progr_icons = false;
48 protected bool $disable_def_feedback = false;
49 protected bool $layout_per_page = false;
50 protected ilObjUser $user;
53 public string $layout = '';
54 public int $style_id = 0;
55 public string $pg_header = '';
56 public bool $online = false;
57 public bool $for_translation = false;
58 protected bool $rating = false;
59 protected bool $rating_pages = false;
60 public array $auto_glossaries = array();
61 private string $import_dir = '';
63 protected \ILIAS\Style\Content\DomainService $content_style_domain;
64 private \ilGlobalTemplateInterface $main_tpl;
65
66 public function __construct(
67 int $a_id = 0,
68 bool $a_call_by_reference = true
69 ) {
70 global $DIC;
71 $this->main_tpl = $DIC->ui()->mainTemplate();
72
73 $this->user = $DIC->user();
74 $this->db = $DIC->database();
75 $this->tree = $DIC->repositoryTree();
76 $this->lng = $DIC->language();
77 $this->error = $DIC["ilErr"];
78 if (isset($DIC["ilLocator"])) {
79 $this->locator = $DIC["ilLocator"];
80 }
81
82 $this->notes = $DIC->notes();
83
84 // this also calls read() method! (if $a_id is set)
85 parent::__construct($a_id, $a_call_by_reference);
86
87 $this->log = ilLoggerFactory::getLogger('lm');
88
90 $lm = $this;
91 $this->lm = $lm;
92
93 $this->mob_ids = array();
94 $this->file_ids = array();
95 $this->q_ids = array();
96 $cs = $DIC->contentStyle();
97 $this->content_style_domain = $cs->domain();
98 }
99
103 public function create(
104 bool $a_no_meta_data = false
105 ): int {
106 $this->setOfflineStatus(true);
107 $id = parent::create();
108
109 // meta data will be created by
110 // import parser
111 if (!$a_no_meta_data) {
112 $this->createMetaData();
113 }
114
115 $this->createProperties();
116 $this->updateAutoGlossaries();
117 return $id;
118 }
119
120 public function read(): void
121 {
122 $ilDB = $this->db;
123
124 parent::read();
125
126 $this->lm_tree = new ilLMTree($this->getId());
127
128 $this->readProperties();
129
130 // read auto glossaries
131 $set = $ilDB->query(
132 "SELECT * FROM lm_glossaries " .
133 " WHERE lm_id = " . $ilDB->quote($this->getId(), "integer")
134 );
135 $glos = array();
136 while ($rec = $ilDB->fetchAssoc($set)) {
137 $glos[] = $rec["glo_id"];
138 }
139 $this->setAutoGlossaries($glos);
140 }
141
142 public function setLayoutPerPage(bool $a_val): void
143 {
144 $this->layout_per_page = $a_val;
145 }
146
147 public function getLayoutPerPage(): bool
148 {
149 return $this->layout_per_page;
150 }
151
155 public function setDisableDefaultFeedback(bool $a_val): void
156 {
157 $this->disable_def_feedback = $a_val;
158 }
159
160 public function getDisableDefaultFeedback(): bool
161 {
162 return $this->disable_def_feedback;
163 }
164
165 public function setProgressIcons(bool $a_val): void
166 {
167 $this->progr_icons = $a_val;
168 }
169
170 public function getProgressIcons(): bool
171 {
172 return $this->progr_icons;
173 }
174
175 public function setStoreTries(bool $a_val): void
176 {
177 $this->store_tries = $a_val;
178 }
179
180 public function getStoreTries(): bool
181 {
182 return $this->store_tries;
183 }
184
185 public function setRestrictForwardNavigation(bool $a_val): void
186 {
187 $this->restrict_forw_nav = $a_val;
188 }
189
190 public function getRestrictForwardNavigation(): bool
191 {
192 return $this->restrict_forw_nav;
193 }
194
195 public function getTree(): ilLMTree
196 {
197 return $this->lm_tree;
198 }
199
200 public function update(): bool
201 {
202 $this->updateMetaData();
203 parent::update();
204 $this->updateProperties();
205 $this->updateAutoGlossaries();
206 return true;
207 }
208
209 public function updateAutoGlossaries(): void
210 {
211 $ilDB = $this->db;
212
213 // update auto glossaries
214 $ilDB->manipulate(
215 "DELETE FROM lm_glossaries WHERE " .
216 " lm_id = " . $ilDB->quote($this->getId(), "integer")
217 );
218 foreach ($this->getAutoGlossaries() as $glo_id) {
219 $ilDB->manipulate("INSERT INTO lm_glossaries " .
220 "(lm_id, glo_id) VALUES (" .
221 $ilDB->quote($this->getId(), "integer") . "," .
222 $ilDB->quote($glo_id, "integer") .
223 ")");
224 }
225 }
226
227
231 public function import(): void
232 {
233 // nothing to do. just display the dialogue in Out
234 }
235
236 public function createLMTree(): void
237 {
238 $this->lm_tree = new ilLMTree($this->getId(), false);
239 $this->lm_tree->addTree($this->getId(), 1);
240 }
241
242 public function setAutoGlossaries(array $a_val): void
243 {
244 $this->auto_glossaries = array();
245 if (is_array($a_val)) {
246 foreach ($a_val as $v) {
247 $v = (int) $v;
248 if ($v > 0 && ilObject::_lookupType($v) == "glo" &&
249 !in_array($v, $this->auto_glossaries)) {
250 $this->auto_glossaries[] = $v;
251 }
252 }
253 }
254 }
255
256 public function getAutoGlossaries(): array
257 {
258 return $this->auto_glossaries;
259 }
260
261 public function removeAutoGlossary(int $a_glo_id): void
262 {
263 $glo_ids = array();
264 foreach ($this->getAutoGlossaries() as $g) {
265 if ($g != $a_glo_id) {
266 $glo_ids[] = $g;
267 }
268 }
269 $this->setAutoGlossaries($glo_ids);
270 }
271
272 public function addFirstChapterAndPage(): void
273 {
275
276
277 $root_id = $this->lm_tree->getRootId();
278
279 // chapter
280 $chap = new ilStructureObject($this->lm);
281 $chap->setType("st");
282 $chap->setTitle($lng->txt("cont_new_chap"));
283 $chap->setLMId($this->getId());
284 $chap->create();
286
287 // page
289 $lm = $this;
290 $page = new ilLMPageObject($lm);
291 $page->setType("pg");
292 $page->setTitle($lng->txt("cont_new_page"));
293 $page->setLMId($this->getId());
294 $page->create();
295 ilLMObject::putInTree($page, $chap->getId(), ilTree::POS_FIRST_NODE);
296 }
297
301 public function setForTranslation(bool $a_val): void
302 {
303 $this->for_translation = $a_val;
304 }
305
306 public function getForTranslation(): bool
307 {
308 return $this->for_translation;
309 }
310
311 public function getLMTree(): ilLMTree
312 {
313 return $this->lm_tree;
314 }
315
316
322 public function createImportDirectory(): void
323 {
324 $ilErr = $this->error;
325
326 $lm_data_dir = ilFileUtils::getDataDir() . "/lm_data";
327 if (!is_writable($lm_data_dir)) {
328 $ilErr->raiseError("Content object Data Directory (" . $lm_data_dir
329 . ") not writeable.", $ilErr->FATAL);
330 }
331
332 // create learning module directory (data_dir/lm_data/lm_<id>)
333 $lm_dir = $lm_data_dir . "/lm_" . $this->getId();
334 ilFileUtils::makeDir($lm_dir);
335 if (!is_dir($lm_dir)) {
336 $ilErr->raiseError("Creation of Learning Module Directory failed.", $ilErr->FATAL);
337 }
338
339 // create import subdirectory (data_dir/lm_data/lm_<id>/import)
340 $import_dir = $lm_dir . "/import";
341 ilFileUtils::makeDir($import_dir);
342 if (!is_dir($import_dir)) {
343 $ilErr->raiseError("Creation of Import Directory failed.", $ilErr->FATAL);
344 }
345 }
346
347 public function getDataDirectory(): string
348 {
349 return ilFileUtils::getDataDir() . "/lm_data" .
350 "/lm_" . $this->getId();
351 }
352
353 public function getImportDirectory(): string
354 {
355 if (strlen($this->import_dir)) {
356 return $this->import_dir;
357 }
358
359 $import_dir = ilFileUtils::getDataDir() . "/lm_data" .
360 "/lm_" . $this->getId() . "/import";
361 if (is_dir($import_dir)) {
362 return $import_dir;
363 }
364 return "";
365 }
366
367 public function setImportDirectory(string $a_import_dir): void
368 {
369 $this->import_dir = $a_import_dir;
370 }
371
372
378 public function createExportDirectory(
379 string $a_type = "xml"
380 ): void {
381 $ilErr = $this->error;
382
383 $lm_data_dir = ilFileUtils::getDataDir() . "/lm_data";
384 // create learning module directory (data_dir/lm_data/lm_<id>)
385 $lm_dir = $lm_data_dir . "/lm_" . $this->getId();
387 if (!is_dir($lm_dir)) {
388 $ilErr->raiseError("Creation of Learning Module Directory failed.", $ilErr->FATAL);
389 }
390 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
391 switch ($a_type) {
392 default: // = xml
393 if (substr($a_type, 0, 4) == "html") {
394 $export_dir = $lm_dir . "/export_" . $a_type;
395 } else {
396 $export_dir = $lm_dir . "/export";
397 }
398 break;
399 }
400 ilFileUtils::makeDir($export_dir);
401
402 if (!is_dir($export_dir)) {
403 $ilErr->raiseError("Creation of Export Directory failed.", $ilErr->FATAL);
404 }
405 }
406
407 public function getExportDirectory(
408 string $a_type = "xml"
409 ): string {
410 switch ($a_type) {
411 default: // = xml
412 if (substr($a_type, 0, 4) == "html") {
413 $export_dir = ilFileUtils::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export_" . $a_type;
414 } else {
415 $export_dir = ilFileUtils::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export";
416 }
417 break;
418 }
419 return $export_dir;
420 }
421
422
431 public function delete(): bool
432 {
433 $ilDB = $this->db;
434
435 // always call parent delete function first!!
436 if (!parent::delete()) {
437 return false;
438 }
439
440 // delete lm object data
442 $lm = $this;
444
445 // delete meta data of content object
446 $this->deleteMetaData();
447
448
449 // delete learning module tree
450 $this->lm_tree->removeTree($this->lm_tree->getTreeId());
451
452 // delete data directory
453 ilFileUtils::delDir($this->getDataDirectory());
454
455 // delete content object record
456 $q = "DELETE FROM content_object WHERE id = " .
457 $ilDB->quote($this->getId(), "integer");
458 $ilDB->manipulate($q);
459
460 // delete lm menu entries
461 $q = "DELETE FROM lm_menu WHERE lm_id = " .
462 $ilDB->quote($this->getId(), "integer");
463 $ilDB->manipulate($q);
464
465 // remove auto glossary entries
466 $ilDB->manipulate(
467 "DELETE FROM lm_glossaries WHERE " .
468 " lm_id = " . $ilDB->quote($this->getId(), "integer")
469 );
470
471
472 return true;
473 }
474
475 public function getLayout(): string
476 {
477 return $this->layout;
478 }
479
480 public function setLayout(string $a_layout): void
481 {
482 $this->layout = $a_layout;
483 }
484
485 public static function writeHeaderPage(
486 int $a_lm_id,
487 int $a_page_id
488 ): void {
489 global $DIC;
490
491 $ilDB = $DIC->database();
492
493 $ilDB->manipulate(
494 "UPDATE content_object SET " .
495 " header_page = " . $ilDB->quote($a_page_id, "integer") .
496 " WHERE id = " . $ilDB->quote($a_lm_id, "integer")
497 );
498 }
499
500 public static function writeFooterPage(
501 int $a_lm_id,
502 int $a_page_id
503 ): void {
504 global $DIC;
505
506 $ilDB = $DIC->database();
507
508 $ilDB->manipulate(
509 "UPDATE content_object SET " .
510 " footer_page = " . $ilDB->quote($a_page_id, "integer") .
511 " WHERE id = " . $ilDB->quote($a_lm_id, "integer")
512 );
513 }
514
515
519 public static function _moveLMStyles(
520 int $a_from_style,
521 int $a_to_style
522 ): void {
523 global $DIC;
524
525 $ilDB = $DIC->database();
526
527 if ($a_from_style < 0) { // change / delete all individual styles
528 $q = "SELECT stylesheet FROM content_object, style_data " .
529 " WHERE content_object.stylesheet = style_data.id " .
530 " AND style_data.standard = " . $ilDB->quote(0, "integer") .
531 " AND content_object.stylesheet > " . $ilDB->quote(0, "integer");
532 $style_set = $ilDB->query($q);
533 while ($style_rec = $ilDB->fetchAssoc($style_set)) {
534 // assign learning modules to new style
535 $q = "UPDATE content_object SET " .
536 " stylesheet = " . $ilDB->quote($a_to_style, "integer") .
537 " WHERE stylesheet = " . $ilDB->quote($style_rec["stylesheet"], "integer");
538 $ilDB->manipulate($q);
539
540 // delete style
541 $style_obj = ilObjectFactory::getInstanceByObjId($style_rec["stylesheet"]);
542 $style_obj->delete();
543 }
544 } else {
545 $q = "UPDATE content_object SET " .
546 " stylesheet = " . $ilDB->quote($a_to_style, "integer") .
547 " WHERE stylesheet = " . $ilDB->quote($a_from_style, "integer");
548 $ilDB->manipulate($q);
549 }
550 }
551
552 protected static function _lookup(
553 int $a_obj_id,
554 string $a_field
555 ): string {
556 global $DIC;
557
558 $ilDB = $DIC->database();
559
560 $q = "SELECT " . $a_field . " FROM content_object " .
561 " WHERE id = " . $ilDB->quote($a_obj_id, "integer");
562
563 $res = $ilDB->query($q);
564 $rec = $ilDB->fetchAssoc($res);
565
566 return $rec[$a_field];
567 }
568
569 public static function _lookupRestrictForwardNavigation(
570 int $a_obj_id
571 ): string {
572 return self::_lookup($a_obj_id, "restrict_forw_nav");
573 }
574
575 public static function _lookupStyleSheetId(int $a_cont_obj_id): int
576 {
577 global $DIC;
578
579 $ilDB = $DIC->database();
580
581 $q = "SELECT stylesheet FROM content_object " .
582 " WHERE id = " . $ilDB->quote($a_cont_obj_id, "integer");
583 $res = $ilDB->query($q);
584 $sheet = $ilDB->fetchAssoc($res);
585
586 return (int) $sheet["stylesheet"];
587 }
588
589 public static function _lookupContObjIdByStyleId(int $a_style_id): array
590 {
591 global $DIC;
592
593 $ilDB = $DIC->database();
594
595 $q = "SELECT id FROM content_object " .
596 " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
597 $res = $ilDB->query($q);
598 $obj_ids = array();
599 while ($cont = $ilDB->fetchAssoc($res)) {
600 $obj_ids[] = (int) $cont["id"];
601 }
602 return $obj_ids;
603 }
604
605 public static function _lookupDisableDefaultFeedback(int $a_id): bool
606 {
607 global $DIC;
608
609 $ilDB = $DIC->database();
610
611 $q = "SELECT disable_def_feedback FROM content_object " .
612 " WHERE id = " . $ilDB->quote($a_id, "integer");
613 $res = $ilDB->query($q);
614 $rec = $ilDB->fetchAssoc($res);
615
616 return (bool) ($rec["disable_def_feedback"] ?? false);
617 }
618
619 public static function _lookupStoreTries(int $a_id): bool
620 {
621 global $DIC;
622
623 $ilDB = $DIC->database();
624
625 $q = "SELECT store_tries FROM content_object " .
626 " WHERE id = " . $ilDB->quote($a_id, "integer");
627 $res = $ilDB->query($q);
628 $rec = $ilDB->fetchAssoc($res);
629
630 return (bool) ($rec["store_tries"] ?? false);
631 }
632
633
637 public static function _getNrOfAssignedLMs(int $a_style_id): int
638 {
639 global $DIC;
640
641 $ilDB = $DIC->database();
642
643 $q = "SELECT count(*) as cnt FROM content_object " .
644 " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
645 $cset = $ilDB->query($q);
646 $crow = $ilDB->fetchAssoc($cset);
647
648 return (int) ($crow["cnt"] ?? 0);
649 }
650
651
655 public static function _getNrLMsIndividualStyles(): int
656 {
657 global $DIC;
658
659 $ilDB = $DIC->database();
660
661 // joining with style table (not perfectly nice)
662 $q = "SELECT count(*) as cnt FROM content_object, style_data " .
663 " WHERE stylesheet = style_data.id " .
664 " AND standard = " . $ilDB->quote(0, "integer");
665 $cset = $ilDB->query($q);
666 $crow = $ilDB->fetchAssoc($cset);
667
668 return (int) $crow["cnt"];
669 }
670
674 public static function _getNrLMsNoStyle(): int
675 {
676 global $DIC;
677
678 $ilDB = $DIC->database();
679
680 $q = "SELECT count(*) as cnt FROM content_object " .
681 " WHERE stylesheet = " . $ilDB->quote(0, "integer");
682 $cset = $ilDB->query($q);
683 $crow = $ilDB->fetchAssoc($cset);
684
685 return (int) $crow["cnt"];
686 }
687
691 public static function _deleteStyleAssignments(
692 int $a_style_id
693 ): void {
694 global $DIC;
695
696 $ilDB = $DIC->database();
697
698 $q = "UPDATE content_object SET " .
699 " stylesheet = " . $ilDB->quote(0, "integer") .
700 " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
701
702 $ilDB->manipulate($q);
703 }
704
708 public function getPageHeader(): string
709 {
710 return $this->pg_header;
711 }
712
717 public function setPageHeader(
718 string $a_pg_header = ilLMObject::CHAPTER_TITLE
719 ): void {
720 $this->pg_header = $a_pg_header;
721 }
722
726 public function getTOCMode(): string
727 {
728 return $this->toc_mode;
729 }
730
734 public function getPublicAccessMode(): string
735 {
736 return $this->public_access_mode;
737 }
738
743 public function setTOCMode(string $a_toc_mode = "chapters"): void
744 {
745 $this->toc_mode = $a_toc_mode;
746 }
747
748 public function setActiveLMMenu(bool $a_act_lm_menu): void
749 {
750 $this->lm_menu_active = $a_act_lm_menu;
751 }
752
753 public function isActiveLMMenu(): bool
754 {
755 return $this->lm_menu_active;
756 }
757
758 public function setActiveTOC(bool $a_toc): void
759 {
760 $this->toc_active = $a_toc;
761 }
762
763 public function isActiveTOC(): bool
764 {
765 return $this->toc_active;
766 }
767
768 public function setActiveNumbering(bool $a_num): void
769 {
770 $this->numbering = $a_num;
771 }
772
773 public function isActiveNumbering(): bool
774 {
775 return $this->numbering;
776 }
777
778 public function setActivePrintView(bool $a_print): void
779 {
780 $this->print_view_active = $a_print;
781 }
782
783 public function isActivePrintView(): bool
784 {
785 return $this->print_view_active;
786 }
787
788 public function setActivePreventGlossaryAppendix(bool $a_print): void
789 {
790 $this->prevent_glossary_appendix_active = $a_print;
791 }
792
793 public function isActivePreventGlossaryAppendix(): bool
794 {
795 return $this->prevent_glossary_appendix_active;
796 }
797
801 public function setHideHeaderFooterPrint(bool $a_val): void
802 {
803 $this->hide_header_footer_print = $a_val;
804 }
805
806 public function getHideHeaderFooterPrint(): bool
807 {
808 return $this->hide_header_footer_print;
809 }
810
811 public function setActiveDownloads(bool $a_down): void
812 {
813 $this->downloads_active = $a_down;
814 }
815
816 public function isActiveDownloads(): bool
817 {
818 return $this->downloads_active;
819 }
820
821 public function setActiveDownloadsPublic(bool $a_down): void
822 {
823 $this->downloads_public_active = $a_down;
824 }
825
826 public function isActiveDownloadsPublic(): bool
827 {
828 return $this->downloads_public_active;
829 }
830
831 public function setPublicNotes(bool $a_pub_notes): void
832 {
833 $this->pub_notes = $a_pub_notes;
834 }
835
836 public function publicNotes(): bool
837 {
838 return $this->pub_notes;
839 }
840
841 public function setCleanFrames(bool $a_clean): void
842 {
843 $this->clean_frames = $a_clean;
844 }
845
846 public function cleanFrames(): bool
847 {
848 return $this->clean_frames;
849 }
850
851 public function setHistoryUserComments(bool $a_comm): void
852 {
853 $this->user_comments = $a_comm;
854 }
855
856 public function setPublicAccessMode(string $a_mode): void
857 {
858 $this->public_access_mode = $a_mode;
859 }
860
861 public function isActiveHistoryUserComments(): bool
862 {
863 return $this->user_comments;
864 }
865
866 public function setHeaderPage(int $a_pg): void
867 {
868 $this->header_page = $a_pg;
869 }
870
871 public function getHeaderPage(): int
872 {
873 return $this->header_page;
874 }
875
876 public function setFooterPage(int $a_pg): void
877 {
878 $this->footer_page = $a_pg;
879 }
880
881 public function getFooterPage(): int
882 {
883 return $this->footer_page;
884 }
885
886 public function readProperties(): void
887 {
888 $ilDB = $this->db;
889
890 $q = "SELECT * FROM content_object WHERE id = " .
891 $ilDB->quote($this->getId(), "integer");
892 $lm_set = $ilDB->query($q);
893 $lm_rec = $ilDB->fetchAssoc($lm_set);
894 $this->setLayout((string) $lm_rec["default_layout"]);
895 $this->setPageHeader((string) $lm_rec["page_header"]);
896 $this->setTOCMode((string) $lm_rec["toc_mode"]);
897 $this->setActiveTOC(ilUtil::yn2tf($lm_rec["toc_active"]));
898 $this->setActiveNumbering(ilUtil::yn2tf($lm_rec["numbering"]));
899 $this->setActivePrintView(ilUtil::yn2tf($lm_rec["print_view_active"]));
900 $this->setActivePreventGlossaryAppendix(ilUtil::yn2tf($lm_rec["no_glo_appendix"]));
901 $this->setHideHeaderFooterPrint((bool) $lm_rec["hide_head_foot_print"]);
902 $this->setActiveDownloads(ilUtil::yn2tf($lm_rec["downloads_active"]));
903 $this->setActiveDownloadsPublic(ilUtil::yn2tf($lm_rec["downloads_public_active"]));
904 $this->setActiveLMMenu(ilUtil::yn2tf($lm_rec["lm_menu_active"]));
905 $this->setCleanFrames(ilUtil::yn2tf($lm_rec["clean_frames"]));
906 $this->setHeaderPage((int) $lm_rec["header_page"]);
907 $this->setFooterPage((int) $lm_rec["footer_page"]);
908 $this->setHistoryUserComments(ilUtil::yn2tf($lm_rec["hist_user_comments"]));
909 $this->setPublicAccessMode((string) $lm_rec["public_access_mode"]);
910 $this->setPublicExportFile("xml", (string) $lm_rec["public_xml_file"]);
911 $this->setPublicExportFile("html", (string) $lm_rec["public_html_file"]);
912 $this->setLayoutPerPage((bool) $lm_rec["layout_per_page"]);
913 $this->setRating((bool) $lm_rec["rating"]);
914 $this->setRatingPages((bool) $lm_rec["rating_pages"]);
915 $this->setDisableDefaultFeedback((bool) $lm_rec["disable_def_feedback"]);
916 $this->setProgressIcons((bool) $lm_rec["progr_icons"]);
917 $this->setStoreTries((bool) $lm_rec["store_tries"]);
918 $this->setRestrictForwardNavigation((bool) $lm_rec["restrict_forw_nav"]);
919
920 // #14661
921 $this->setPublicNotes($this->notes->domain()->commentsActive($this->getId()));
922
923 $this->setForTranslation((bool) $lm_rec["for_translation"]);
924 }
925
926 public function updateProperties(): void
927 {
928 $ilDB = $this->db;
929
930 // force clean_frames to be set, if layout per page is activated
931 if ($this->getLayoutPerPage()) {
932 $this->setCleanFrames(true);
933 }
934
935 $q = "UPDATE content_object SET " .
936 " default_layout = " . $ilDB->quote($this->getLayout(), "text") . ", " .
937 " page_header = " . $ilDB->quote($this->getPageHeader(), "text") . "," .
938 " toc_mode = " . $ilDB->quote($this->getTOCMode(), "text") . "," .
939 " toc_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveTOC()), "text") . "," .
940 " numbering = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveNumbering()), "text") . "," .
941 " print_view_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActivePrintView()), "text") . "," .
942 " no_glo_appendix = " . $ilDB->quote(ilUtil::tf2yn($this->isActivePreventGlossaryAppendix()), "text") . "," .
943 " hide_head_foot_print = " . $ilDB->quote($this->getHideHeaderFooterPrint(), "integer") . "," .
944 " downloads_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveDownloads()), "text") . "," .
945 " downloads_public_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveDownloadsPublic()), "text") . "," .
946 " clean_frames = " . $ilDB->quote(ilUtil::tf2yn($this->cleanFrames()), "text") . "," .
947 " hist_user_comments = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveHistoryUserComments()), "text") . "," .
948 " public_access_mode = " . $ilDB->quote($this->getPublicAccessMode(), "text") . "," .
949 " public_xml_file = " . $ilDB->quote($this->getPublicExportFile("xml"), "text") . "," .
950 " public_html_file = " . $ilDB->quote($this->getPublicExportFile("html"), "text") . "," .
951 " header_page = " . $ilDB->quote($this->getHeaderPage(), "integer") . "," .
952 " footer_page = " . $ilDB->quote($this->getFooterPage(), "integer") . "," .
953 " lm_menu_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveLMMenu()), "text") . ", " .
954 " layout_per_page = " . $ilDB->quote($this->getLayoutPerPage(), "integer") . ", " .
955 " rating = " . $ilDB->quote($this->hasRating(), "integer") . ", " .
956 " rating_pages = " . $ilDB->quote($this->hasRatingPages(), "integer") . ", " .
957 " disable_def_feedback = " . $ilDB->quote($this->getDisableDefaultFeedback(), "integer") . ", " .
958 " progr_icons = " . $ilDB->quote($this->getProgressIcons(), "integer") . ", " .
959 " store_tries = " . $ilDB->quote($this->getStoreTries(), "integer") . ", " .
960 " restrict_forw_nav = " . $ilDB->quote($this->getRestrictForwardNavigation(), "integer") . ", " .
961 " for_translation = " . $ilDB->quote((int) $this->getForTranslation(), "integer") . " " .
962 " WHERE id = " . $ilDB->quote($this->getId(), "integer");
963 $ilDB->manipulate($q);
964 // #14661
965 $this->notes->domain()->activateComments($this->getId(), $this->publicNotes());
966 }
967
971 public function createProperties(): void
972 {
973 $ilDB = $this->db;
974
975 $this->db->insert("content_object", [
976 "id" => ["integer", $this->getId()],
977 "page_header" => ["text", ilLMObject::PAGE_TITLE]
978 ]);
979
980 // #14661
981 $this->notes->domain()->activateComments($this->getId());
982
983 $this->readProperties(); // to get db default values
984 }
985
986
990 public static function getAvailableLayouts(): array
991 {
992 $dir = opendir("./Modules/LearningModule/layouts/lm");
993
994 $layouts = array();
995
996 while ($file = readdir($dir)) {
997 if ($file != "." && $file != ".." && $file != "CVS" && $file != ".svn") {
998 // directories
999 if (is_dir("./Modules/LearningModule/layouts/lm/" . $file)) {
1000 $layouts[$file] = $file;
1001 }
1002 }
1003 }
1004 asort($layouts);
1005
1006 // workaround: fix ordering
1007 $ret = array(
1008 'toc2win' => 'toc2win',
1009 'toc2windyn' => 'toc2windyn',
1010 '1window' => '1window',
1011 '2window' => '2window',
1012 '3window' => '3window',
1013 'presentation' => 'presentation',
1014 'fullscreen' => 'fullscreen'
1015 );
1016
1017 foreach ($layouts as $l) {
1018 if (!in_array($l, $ret)) {
1019 $ret[$l] = $l;
1020 }
1021 }
1022
1023 return $ret;
1024 }
1025
1029 public static function _checkPreconditionsOfPage(
1030 int $cont_ref_id,
1031 int $cont_obj_id,
1032 int $page_id
1033 ): bool {
1034 $lm_tree = new ilTree($cont_obj_id);
1035 $lm_tree->setTableNames('lm_tree', 'lm_data');
1036 $lm_tree->setTreeTablePK("lm_id");
1037
1038 if ($lm_tree->isInTree($page_id)) {
1039 $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1040 foreach ($path as $node) {
1041 if ($node["type"] == "st") {
1042 if (!ilConditionHandler::_checkAllConditionsOfTarget($cont_ref_id, $node["child"], "st")) {
1043 return false;
1044 }
1045 }
1046 }
1047 }
1048
1049 return true;
1050 }
1051
1055 public static function _getMissingPreconditionsOfPage(
1056 int $cont_ref_id,
1057 int $cont_obj_id,
1058 int $page_id
1059 ): array {
1060 $lm_tree = new ilTree($cont_obj_id);
1061 $lm_tree->setTableNames('lm_tree', 'lm_data');
1062 $lm_tree->setTreeTablePK("lm_id");
1063
1064 $conds = array();
1065 if ($lm_tree->isInTree($page_id)) {
1066 // get full path of page
1067 $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1068 foreach ($path as $node) {
1069 if ($node["type"] == "st") {
1070 // get all preconditions of upper chapters
1071 $tconds = ilConditionHandler::_getPersistedConditionsOfTarget($cont_ref_id, $node["child"], "st");
1072 foreach ($tconds as $tcond) {
1073 // store all missing preconditions
1075 $conds[] = $tcond;
1076 }
1077 }
1078 }
1079 }
1080 }
1081
1082 return $conds;
1083 }
1084
1089 int $cont_obj_ref_id,
1090 int $cont_obj_id,
1091 int $page_id
1092 ): int {
1093 $lm_tree = new ilTree($cont_obj_id);
1094 $lm_tree->setTableNames('lm_tree', 'lm_data');
1095 $lm_tree->setTreeTablePK("lm_id");
1096
1097 if ($lm_tree->isInTree($page_id)) {
1098 // get full path of page
1099 $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1100 foreach ($path as $node) {
1101 if ($node["type"] == "st") {
1102 // get all preconditions of upper chapters
1103 $tconds = ilConditionHandler::_getPersistedConditionsOfTarget($cont_obj_ref_id, $node["child"], "st");
1104 foreach ($tconds as $tcond) {
1105 // look for missing precondition
1107 return (int) $node["child"];
1108 }
1109 }
1110 }
1111 }
1112 }
1113
1114 return 0;
1115 }
1116
1120 public static function hasSuccessorPage(
1121 int $a_cont_obj_id,
1122 int $a_page_id
1123 ): bool {
1124 $tree = new ilTree($a_cont_obj_id);
1125 $tree->setTableNames('lm_tree', 'lm_data');
1126 $tree->setTreeTablePK("lm_id");
1127 if ($tree->isInTree($a_page_id)) {
1128 $succ = $tree->fetchSuccessorNode($a_page_id, "pg");
1129 if ($succ > 0) {
1130 return true;
1131 }
1132 }
1133 return false;
1134 }
1135
1139 public function checkTree(): void
1140 {
1141 $tree = new ilLMTree($this->getId());
1142 $tree->checkTree();
1143 $tree->checkTreeChilds();
1144 }
1145
1146 public function fixTree(): void
1147 {
1148 $ilDB = $this->db;
1149
1150 $tree = $this->getLMTree();
1151
1152 // check numbering, if errors, renumber
1153 // it is very important to keep this step before deleting subtrees
1154 // in the following steps
1155 $set = $ilDB->query(
1156 "SELECT DISTINCT l1.lm_id" .
1157 " FROM lm_tree l1" .
1158 " JOIN lm_tree l2 ON ( l1.child = l2.parent" .
1159 " AND l1.lm_id = l2.lm_id )" .
1160 " JOIN lm_data ON ( l1.child = lm_data.obj_id )" .
1161 " WHERE (l2.lft < l1.lft" .
1162 " OR l2.rgt > l1.rgt OR l2.lft > l1.rgt OR l2.rgt < l1.lft)" .
1163 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer") .
1164 " ORDER BY lm_data.create_date DESC"
1165 );
1166 if ($rec = $ilDB->fetchAssoc($set)) {
1167 $tree->renumber();
1168 }
1169
1170 // delete subtrees that have no lm_data records (changed due to #20637)
1171 $set = $ilDB->query("SELECT * FROM lm_tree WHERE lm_tree.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1172 while ($node = $ilDB->fetchAssoc($set)) {
1173 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1174 $ilDB->quote($node["child"], "integer");
1175 $obj_set = $ilDB->query($q);
1176 $obj_rec = $ilDB->fetchAssoc($obj_set);
1177 if (!$obj_rec) {
1178 $node_data = $tree->getNodeData($node["child"]);
1179 $node_data["child"] = $node["child"];
1180 $tree->deleteTree($node_data);
1181 }
1182 }
1183
1184 // delete subtrees that have pages as parent
1185 $nodes = $tree->getSubTree($tree->getNodeData($tree->getRootId()));
1186 foreach ($nodes as $node) {
1187 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1188 $ilDB->quote($node["parent"], "integer");
1189 $obj_set = $ilDB->query($q);
1190 $obj_rec = $ilDB->fetchAssoc($obj_set);
1191 if (($obj_rec["type"] ?? "") == "pg") {
1192 $node_data = $tree->getNodeData($node["child"]);
1193 if ($tree->isInTree($node["child"])) {
1194 $tree->deleteTree($node_data);
1195 }
1196 }
1197 }
1198
1199 // check for multi-references pages or chapters
1200 // if errors -> create copies of them here
1201 $set = $ilDB->query("SELECT DISTINCT l1.lm_id" .
1202 " FROM lm_tree l1" .
1203 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1204 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1205 " WHERE l1.child <> 1" .
1206 " AND l1.lm_id <> lm_data.lm_id" .
1207 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1208 if ($rec = $ilDB->fetchAssoc($set)) {
1209 $set = $ilDB->query("SELECT DISTINCT l1.child " .
1210 " FROM lm_tree l1" .
1211 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1212 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1213 " WHERE l1.child <> 1" .
1214 " AND l1.lm_id <> lm_data.lm_id" .
1215 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1216 while ($rec = $ilDB->fetchAssoc($set)) {
1217 $cobj = ilLMObjectFactory::getInstance($this->lm, $rec["child"]);
1218
1219 if (is_object($cobj)) {
1220 if ($cobj->getType() == "pg") {
1221 // make a copy of it
1222 $pg_copy = $cobj->copy($this->lm);
1223
1224 // replace the child in the tree with the copy (id)
1225 $ilDB->manipulate(
1226 "UPDATE lm_tree SET " .
1227 " child = " . $ilDB->quote($pg_copy->getId(), "integer") .
1228 " WHERE child = " . $ilDB->quote($cobj->getId(), "integer") .
1229 " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1230 );
1231 } elseif ($cobj->getType() == "st") {
1232 // make a copy of it
1233 $st_copy = $cobj->copy($this->lm);
1234
1235 // replace the child in the tree with the copy (id)
1236 $ilDB->manipulate(
1237 "UPDATE lm_tree SET " .
1238 " child = " . $ilDB->quote($st_copy->getId(), "integer") .
1239 " WHERE child = " . $ilDB->quote($cobj->getId(), "integer") .
1240 " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1241 );
1242
1243 // make all childs refer to the copy now
1244 $ilDB->manipulate(
1245 "UPDATE lm_tree SET " .
1246 " parent = " . $ilDB->quote($st_copy->getId(), "integer") .
1247 " WHERE parent = " . $ilDB->quote($cobj->getId(), "integer") .
1248 " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1249 );
1250 }
1251 }
1252 }
1253 }
1254
1255 // missing copage entries
1256 $set = $ilDB->queryF(
1257 "SELECT * FROM lm_data " .
1258 " WHERE lm_id = %s AND type = %s",
1259 array("integer", "text"),
1260 array($this->getId(), "pg")
1261 );
1262 while ($rec = $ilDB->fetchAssoc($set)) {
1263 if (!ilPageObject::_exists("lm", $rec["obj_id"], "-")) {
1264 $lm_page = new ilLMPage();
1265 $lm_page->setId($rec["obj_id"]);
1266 $lm_page->setParentId($this->getId());
1267 $lm_page->create(false);
1268 }
1269 }
1270 }
1271
1275 public function checkStructure(): array
1276 {
1277 $issues = [];
1278 $ilDB = $this->db;
1279
1280 $tree = $this->getLMTree();
1281
1282 // check numbering, if errors, renumber
1283 // it is very important to keep this step before deleting subtrees
1284 // in the following steps
1285 $set = $ilDB->query(
1286 "SELECT l1.child, l1.lft l1lft, l1.rgt l1rgt, l2.parent, l2.lft l2lft, l2.rgt l2rgt" .
1287 " FROM lm_tree l1" .
1288 " JOIN lm_tree l2 ON ( l1.child = l2.parent" .
1289 " AND l1.lm_id = l2.lm_id )" .
1290 " JOIN lm_data ON ( l1.child = lm_data.obj_id )" .
1291 " WHERE (l2.lft < l1.lft" .
1292 " OR l2.rgt > l1.rgt OR l2.lft > l1.rgt OR l2.rgt < l1.lft)" .
1293 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer") .
1294 " ORDER BY lm_data.create_date DESC"
1295 );
1296 while ($rec = $ilDB->fetchAssoc($set)) {
1297 $issues[] = "Tree numbering: " . print_r($rec, true);
1298 }
1299
1300 // delete subtrees that have no lm_data records (changed due to #20637)
1301 $set = $ilDB->query("SELECT * FROM lm_tree WHERE lm_tree.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1302 while ($node = $ilDB->fetchAssoc($set)) {
1303 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1304 $ilDB->quote($node["child"], "integer");
1305 $obj_set = $ilDB->query($q);
1306 $obj_rec = $ilDB->fetchAssoc($obj_set);
1307 if (!$obj_rec) {
1308 $issues[] = "Tree entry without data entry: " . print_r($node, true);
1309 }
1310 }
1311
1312 // delete subtrees that have pages as parent
1313 $nodes = $tree->getSubTree($tree->getNodeData($tree->getRootId()));
1314 foreach ($nodes as $node) {
1315 $q = "SELECT * FROM lm_data WHERE obj_id = " .
1316 $ilDB->quote($node["parent"], "integer");
1317 $obj_set = $ilDB->query($q);
1318 $obj_rec = $ilDB->fetchAssoc($obj_set);
1319 if (($obj_rec["type"] ?? "") == "pg") {
1320 $node_data = $tree->getNodeData($node["child"]);
1321 if ($tree->isInTree($node["child"])) {
1322 $issues[] = "Subtree with page parent: " . print_r($node_data, true);
1323 }
1324 }
1325 }
1326
1327 // check for multi-references pages or chapters
1328 // if errors -> create copies of them here
1329 $set = $ilDB->query("SELECT DISTINCT l1.lm_id" .
1330 " FROM lm_tree l1" .
1331 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1332 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1333 " WHERE l1.child <> 1" .
1334 " AND l1.lm_id <> lm_data.lm_id" .
1335 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1336 if ($rec = $ilDB->fetchAssoc($set)) {
1337 $set = $ilDB->query("SELECT DISTINCT l1.child " .
1338 " FROM lm_tree l1" .
1339 " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1340 " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1341 " WHERE l1.child <> 1" .
1342 " AND l1.lm_id <> lm_data.lm_id" .
1343 " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1344 while ($rec = $ilDB->fetchAssoc($set)) {
1345 $set3 = $ilDB->queryF(
1346 "SELECT * FROM lm_tree " .
1347 " WHERE child = %s ",
1348 array("integer"),
1349 array($rec["child"])
1350 );
1351 while ($rec3 = $ilDB->fetchAssoc($set3)) {
1352 $issues[] = "Multi-reference item: " . print_r($rec3, true);
1353 }
1354 }
1355 }
1356
1357 // missing copage entries
1358 $set = $ilDB->queryF(
1359 "SELECT * FROM lm_data " .
1360 " WHERE lm_id = %s AND type = %s",
1361 array("integer", "text"),
1362 array($this->getId(), "pg")
1363 );
1364 while ($rec = $ilDB->fetchAssoc($set)) {
1365 if (!ilPageObject::_exists("lm", $rec["obj_id"], "-")) {
1366 $issues[] = "Missing COPage: " . print_r($rec, true);
1367 }
1368 }
1369
1370
1371 return $issues;
1372 }
1373
1374 public function exportXML(
1375 ilXmlWriter $a_xml_writer,
1376 int $a_inst,
1377 string $a_target_dir,
1378 ilLog $expLog
1379 ): void {
1380 $attrs = array();
1381 switch ($this->getType()) {
1382 case "lm":
1383 $attrs["Type"] = "LearningModule";
1384 break;
1385 }
1386 $a_xml_writer->xmlStartTag("ContentObject", $attrs);
1387
1388 // MetaData
1389 $this->exportXMLMetaData($a_xml_writer);
1390
1391 // StructureObjects
1392 //echo "ContObj:".$a_inst.":<br>";
1393 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Structure Objects");
1394 $this->exportXMLStructureObjects($a_xml_writer, $a_inst, $expLog);
1395 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Structure Objects");
1396
1397 // PageObjects
1398 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Page Objects");
1399 $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog);
1400 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Page Objects");
1401
1402 // MediaObjects
1403 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Media Objects");
1404 $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
1405 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Media Objects");
1406
1407 // FileItems
1408 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export File Items");
1409 $this->exportFileItems($a_target_dir, $expLog);
1410 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export File Items");
1411
1412 // Questions
1413 if (count($this->q_ids) > 0) {
1414 $qti_file = fopen($a_target_dir . "/qti.xml", "w");
1415 $pool = new ilObjQuestionPool();
1416 fwrite($qti_file, $pool->questionsToXML($this->q_ids));
1417 fclose($qti_file);
1418 }
1419
1420 // To do: implement version selection/detection
1421 // Properties
1422 $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Properties");
1423 $this->exportXMLProperties($a_xml_writer, $expLog);
1424 $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Properties");
1425
1426 $a_xml_writer->xmlEndTag("ContentObject");
1427 }
1428
1429 public function exportXMLMetaData(
1430 ilXmlWriter $a_xml_writer
1431 ): void {
1432 $md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
1433 $md2xml->setExportMode(true);
1434 $md2xml->startExport();
1435 $a_xml_writer->appendXML($md2xml->getXML());
1436 }
1437
1439 ilXmlWriter $a_xml_writer,
1440 int $a_inst,
1441 ilLog $expLog
1442 ): void {
1443 $childs = $this->lm_tree->getChilds($this->lm_tree->getRootId());
1444 foreach ($childs as $child) {
1445 if ($child["type"] != "st") {
1446 continue;
1447 }
1448
1449 $structure_obj = new ilStructureObject($this->lm, $child["obj_id"]);
1450 $structure_obj->exportXML($a_xml_writer, $a_inst, $expLog);
1451 unset($structure_obj);
1452 }
1453 }
1454
1455 public function exportXMLPageObjects(
1456 ilXmlWriter $a_xml_writer,
1457 int $a_inst,
1458 ilLog $expLog
1459 ): void {
1460 $pages = ilLMPageObject::getPageList($this->getId());
1461 foreach ($pages as $page) {
1462 if (ilLMPage::_exists($this->getType(), $page["obj_id"])) {
1463 $expLog->write(date("[y-m-d H:i:s] ") . "Page Object " . $page["obj_id"]);
1464
1465 // export xml to writer object
1466 $page_obj = new ilLMPageObject($this->lm, $page["obj_id"]);
1467 $page_obj->exportXML($a_xml_writer, "normal", $a_inst);
1468
1469 // collect media objects
1470 $mob_ids = $page_obj->getMediaObjectIds();
1471 foreach ($mob_ids as $mob_id) {
1472 $this->mob_ids[$mob_id] = $mob_id;
1473 }
1474
1475 // collect all file items
1476 $file_ids = $page_obj->getFileItemIds();
1477 foreach ($file_ids as $file_id) {
1478 $this->file_ids[$file_id] = $file_id;
1479 }
1480
1481 // collect all questions
1482 $q_ids = $page_obj->getQuestionIds();
1483 foreach ($q_ids as $q_id) {
1484 $this->q_ids[$q_id] = $q_id;
1485 }
1486
1487 unset($page_obj);
1488 }
1489 }
1490 }
1491
1492 public function exportXMLMediaObjects(
1493 ilXmlWriter $a_xml_writer,
1494 int $a_inst,
1495 string $a_target_dir,
1496 ilLog $expLog
1497 ): void {
1498 $linked_mobs = array();
1499
1500 // mobs directly embedded into pages
1501 foreach ($this->mob_ids as $mob_id) {
1502 if ($mob_id > 0 && ilObject::_lookupType($mob_id) == "mob") {
1503 $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
1504 $media_obj = new ilObjMediaObject($mob_id);
1505 $media_obj->exportXML($a_xml_writer, $a_inst);
1506 $media_obj->exportFiles($a_target_dir);
1507
1508 $lmobs = $media_obj->getLinkedMediaObjects($this->mob_ids);
1509 $linked_mobs = array_merge($linked_mobs, $lmobs);
1510
1511 unset($media_obj);
1512 }
1513 }
1514
1515 // linked mobs (in map areas)
1516 foreach ($linked_mobs as $mob_id) {
1517 if ($mob_id > 0) {
1518 $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
1519 $media_obj = new ilObjMediaObject($mob_id);
1520 $media_obj->exportXML($a_xml_writer, $a_inst);
1521 $media_obj->exportFiles($a_target_dir);
1522 unset($media_obj);
1523 }
1524 }
1525 }
1526
1527 public function exportFileItems(
1528 string $a_target_dir,
1529 ilLog $expLog
1530 ): void {
1531 foreach ($this->file_ids as $file_id) {
1532 $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
1533 $file_obj = new ilObjFile($file_id, false);
1534 $file_obj->export($a_target_dir);
1535 unset($file_obj);
1536 }
1537 }
1538
1539 public function exportXMLProperties(
1540 ilXmlWriter $a_xml_writer,
1541 ilLog $expLog
1542 ): void {
1543 $attrs = array();
1544 $a_xml_writer->xmlStartTag("Properties", $attrs);
1545
1546 // Layout
1547 $attrs = array("Name" => "Layout", "Value" => $this->getLayout());
1548 $a_xml_writer->xmlElement("Property", $attrs);
1549
1550 // Page Header
1551 $attrs = array("Name" => "PageHeader", "Value" => $this->getPageHeader());
1552 $a_xml_writer->xmlElement("Property", $attrs);
1553
1554 // TOC Mode
1555 $attrs = array("Name" => "TOCMode", "Value" => $this->getTOCMode());
1556 $a_xml_writer->xmlElement("Property", $attrs);
1557
1558 // LM Menu Activation
1559 $attrs = array("Name" => "ActiveLMMenu", "Value" =>
1560 ilUtil::tf2yn($this->isActiveLMMenu()));
1561 $a_xml_writer->xmlElement("Property", $attrs);
1562
1563 // Numbering Activation
1564 $attrs = array("Name" => "ActiveNumbering", "Value" =>
1565 ilUtil::tf2yn($this->isActiveNumbering()));
1566 $a_xml_writer->xmlElement("Property", $attrs);
1567
1568 // Table of contents button activation
1569 $attrs = array("Name" => "ActiveTOC", "Value" =>
1570 ilUtil::tf2yn($this->isActiveTOC()));
1571 $a_xml_writer->xmlElement("Property", $attrs);
1572
1573 // Print view button activation
1574 $attrs = array("Name" => "ActivePrintView", "Value" =>
1575 ilUtil::tf2yn($this->isActivePrintView()));
1576 $a_xml_writer->xmlElement("Property", $attrs);
1577
1578 // Note that download button is not saved, because
1579 // download files do not exist after import
1580
1581 // Clean frames
1582 $attrs = array("Name" => "CleanFrames", "Value" =>
1583 ilUtil::tf2yn($this->cleanFrames()));
1584 $a_xml_writer->xmlElement("Property", $attrs);
1585
1586 // Public notes activation
1587 $attrs = array("Name" => "PublicNotes", "Value" =>
1588 ilUtil::tf2yn($this->publicNotes()));
1589 $a_xml_writer->xmlElement("Property", $attrs);
1590
1591 // History comments for authors activation
1592 $attrs = array("Name" => "HistoryUserComments", "Value" =>
1593 ilUtil::tf2yn($this->isActiveHistoryUserComments()));
1594 $a_xml_writer->xmlElement("Property", $attrs);
1595
1596 // Rating
1597 $attrs = array("Name" => "Rating", "Value" =>
1598 ilUtil::tf2yn($this->hasRating()));
1599 $a_xml_writer->xmlElement("Property", $attrs);
1600 $attrs = array("Name" => "RatingPages", "Value" =>
1601 ilUtil::tf2yn($this->hasRatingPages()));
1602 $a_xml_writer->xmlElement("Property", $attrs);
1603
1604 // Header Page
1605 if ($this->getHeaderPage() > 0) {
1606 $attrs = array("Name" => "HeaderPage", "Value" =>
1607 "il_" . IL_INST_ID . "_pg_" . $this->getHeaderPage());
1608 $a_xml_writer->xmlElement("Property", $attrs);
1609 }
1610
1611 // Footer Page
1612 if ($this->getFooterPage() > 0) {
1613 $attrs = array("Name" => "FooterPage", "Value" =>
1614 "il_" . IL_INST_ID . "_pg_" . $this->getFooterPage());
1615 $a_xml_writer->xmlElement("Property", $attrs);
1616 }
1617
1618 // layout per page
1619 $attrs = array("Name" => "LayoutPerPage", "Value" =>
1620 $this->getLayoutPerPage());
1621 $a_xml_writer->xmlElement("Property", $attrs);
1622
1623 // progress icons
1624 $attrs = array("Name" => "ProgressIcons", "Value" =>
1625 $this->getProgressIcons());
1626 $a_xml_writer->xmlElement("Property", $attrs);
1627
1628 // store tries
1629 $attrs = array("Name" => "StoreTries", "Value" =>
1630 $this->getStoreTries());
1631 $a_xml_writer->xmlElement("Property", $attrs);
1632
1633 // restrict forward navigation
1634 $attrs = array("Name" => "RestrictForwardNavigation", "Value" =>
1635 $this->getRestrictForwardNavigation());
1636 $a_xml_writer->xmlElement("Property", $attrs);
1637
1638 // disable default feedback
1639 $attrs = array("Name" => "DisableDefaultFeedback", "Value" =>
1640 $this->getDisableDefaultFeedback());
1641 $a_xml_writer->xmlElement("Property", $attrs);
1642
1643 $a_xml_writer->xmlEndTag("Properties");
1644 }
1645
1646 public function getExportFiles(): array
1647 {
1648 $file = array();
1649
1650 $types = array("xml", "html");
1651
1652 foreach ($types as $type) {
1653 $dir = $this->getExportDirectory($type);
1654 // quit if import dir not available
1655 if (!is_dir($dir) or
1656 !is_writeable($dir)) {
1657 continue;
1658 }
1659
1660 // open directory
1661 $cdir = dir($dir);
1662
1663 // initialize array
1664
1665 // get files and save the in the array
1666 while ($entry = $cdir->read()) {
1667 if ($entry != "." and
1668 $entry != ".." and
1669 substr($entry, -4) == ".zip" and
1670 preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(lm_)*[0-9]+\.zip\$~", $entry)) {
1671 $file[$entry . $type] = array("type" => $type, "file" => $entry,
1672 "size" => filesize($dir . "/" . $entry));
1673 }
1674 }
1675
1676 // close import directory
1677 $cdir->close();
1678 }
1679
1680 // sort files
1681 ksort($file);
1682 return $file;
1683 }
1684
1688 public function setPublicExportFile(
1689 string $a_type,
1690 string $a_file
1691 ): void {
1692 $this->public_export_file[$a_type] = $a_file;
1693 }
1694
1695 public function getPublicExportFile(string $a_type): string
1696 {
1697 return $this->public_export_file[$a_type] ?? "";
1698 }
1699
1700 public function getOfflineFiles(
1701 string $dir
1702 ): array {
1703 // quit if offline dir not available
1704 if (!is_dir($dir) or
1705 !is_writeable($dir)) {
1706 return array();
1707 }
1708
1709 // open directory
1710 $dir = dir($dir);
1711
1712 // initialize array
1713 $file = array();
1714
1715 // get files and save the in the array
1716 while ($entry = $dir->read()) {
1717 if ($entry != "." and
1718 $entry != ".." and
1719 substr($entry, -4) == ".pdf" and
1720 preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(lm_)*[0-9]+\.pdf\$~", $entry)) {
1721 $file[] = $entry;
1722 }
1723 }
1724
1725 // close import directory
1726 $dir->close();
1727
1728 // sort files
1729 sort($file);
1730 return $file;
1731 }
1732
1733 public function exportFO(
1734 ilXmlWriter $a_xml_writer,
1735 string $a_target_dir
1736 ): void {
1737 throw new ilException("Export FO is deprecated.");
1738 /*
1739 // fo:root (start)
1740 $attrs = array();
1741 $attrs["xmlns:fo"] = "http://www.w3.org/1999/XSL/Format";
1742 $a_xml_writer->xmlStartTag("fo:root", $attrs);
1743
1744 // fo:layout-master-set (start)
1745 $attrs = array();
1746 $a_xml_writer->xmlStartTag("fo:layout-master-set", $attrs);
1747
1748 // fo:simple-page-master (start)
1749 $attrs = array();
1750 $attrs["master-name"] = "DinA4";
1751 $attrs["page-height"] = "29.7cm";
1752 $attrs["page-width"] = "21cm";
1753 $attrs["margin-top"] = "4cm";
1754 $attrs["margin-bottom"] = "1cm";
1755 $attrs["margin-left"] = "2.8cm";
1756 $attrs["margin-right"] = "7.3cm";
1757 $a_xml_writer->xmlStartTag("fo:simple-page-master", $attrs);
1758
1759 // fo:region-body (complete)
1760 $attrs = array();
1761 $attrs["margin-top"] = "0cm";
1762 $attrs["margin-bottom"] = "1.25cm";
1763 $a_xml_writer->xmlElement("fo:region-body", $attrs);
1764
1765 // fo:region-before (complete)
1766 $attrs = array();
1767 $attrs["extent"] = "1cm";
1768 $a_xml_writer->xmlElement("fo:region-before", $attrs);
1769
1770 // fo:region-after (complete)
1771 $attrs = array();
1772 $attrs["extent"] = "1cm";
1773 $a_xml_writer->xmlElement("fo:region-after", $attrs);
1774
1775 // fo:simple-page-master (end)
1776 $a_xml_writer->xmlEndTag("fo:simple-page-master");
1777
1778 // fo:layout-master-set (end)
1779 $a_xml_writer->xmlEndTag("fo:layout-master-set");
1780
1781 // fo:page-sequence (start)
1782 $attrs = array();
1783 $attrs["master-reference"] = "DinA4";
1784 $a_xml_writer->xmlStartTag("fo:page-sequence", $attrs);
1785
1786 // fo:flow (start)
1787 $attrs = array();
1788 $attrs["flow-name"] = "xsl-region-body";
1789 $a_xml_writer->xmlStartTag("fo:flow", $attrs);
1790
1791
1792 // StructureObjects
1793 $this->exportFOStructureObjects($a_xml_writer);
1794
1795 // fo:flow (end)
1796 $a_xml_writer->xmlEndTag("fo:flow");
1797
1798 // fo:page-sequence (end)
1799 $a_xml_writer->xmlEndTag("fo:page-sequence");
1800
1801 // fo:root (end)
1802 $a_xml_writer->xmlEndTag("fo:root");
1803 */
1804 }
1805
1807 ilXmlWriter $a_xml_writer
1808 ): void {
1809 $childs = $this->lm_tree->getChilds($this->lm_tree->getRootId());
1810 foreach ($childs as $child) {
1811 if ($child["type"] != "st") {
1812 continue;
1813 }
1814
1815 $structure_obj = new ilStructureObject($this->lm, $child["obj_id"]);
1816 $structure_obj->exportFO($a_xml_writer);
1817 unset($structure_obj);
1818 }
1819 }
1820
1821 public function executeDragDrop(
1822 int $source_id,
1823 int $target_id,
1824 bool $first_child,
1825 bool $as_subitem = false,
1826 string $movecopy = "move"
1827 ): void {
1828 if ($source_id === $target_id) {
1829 return;
1830 }
1831 $lmtree = new ilTree($this->getId());
1832 $lmtree->setTableNames('lm_tree', 'lm_data');
1833 $lmtree->setTreeTablePK("lm_id");
1834 //echo "-".$source_id."-".$target_id."-".$first_child."-".$as_subitem."-";
1835 $source_obj = ilLMObjectFactory::getInstance($this->lm, $source_id, true);
1836 $source_obj->setLMId($this->getId());
1837
1838 if (!$first_child) {
1839 $target_obj = ilLMObjectFactory::getInstance($this->lm, $target_id, true);
1840 $target_obj->setLMId($this->getId());
1841 $target_parent = $lmtree->getParentId($target_id);
1842 }
1843
1844 // handle pages
1845 if ($source_obj->getType() == "pg") {
1846 //echo "1";
1847 if ($lmtree->isInTree($source_obj->getId())) {
1848 $node_data = $lmtree->getNodeData($source_obj->getId());
1849
1850 // cut on move
1851 if ($movecopy == "move") {
1852 $parent_id = $lmtree->getParentId($source_obj->getId());
1853 $lmtree->deleteTree($node_data);
1854
1855 // write history entry
1857 $source_obj->getId(),
1858 "cut",
1859 array(ilLMObject::_lookupTitle($parent_id), $parent_id),
1860 $this->getType() . ":pg"
1861 );
1863 $parent_id,
1864 "cut_page",
1865 array(ilLMObject::_lookupTitle($source_obj->getId()), $source_obj->getId()),
1866 $this->getType() . ":st"
1867 );
1868 } else {
1869 // copy page
1870 $new_page = $source_obj->copy($this->lm);
1871 $source_id = $new_page->getId();
1872 $source_obj = $new_page;
1873 }
1874
1875 // paste page
1876 if (!$lmtree->isInTree($source_obj->getId())) {
1877 if ($first_child) { // as first child
1878 $target_pos = ilTree::POS_FIRST_NODE;
1879 $parent = $target_id;
1880 } elseif ($as_subitem) { // as last child
1881 $parent = $target_id;
1882 $target_pos = ilTree::POS_FIRST_NODE;
1883 $pg_childs = $lmtree->getChildsByType($parent, "pg");
1884 if (count($pg_childs) != 0) {
1885 $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
1886 }
1887 } else { // at position
1888 $target_pos = $target_id;
1889 $parent = $target_parent;
1890 }
1891
1892 // insert page into tree
1893 $lmtree->insertNode(
1894 $source_obj->getId(),
1895 $parent,
1896 $target_pos
1897 );
1898
1899 // write history entry
1900 if ($movecopy == "move") {
1901 // write history comments
1903 $source_obj->getId(),
1904 "paste",
1905 array(ilLMObject::_lookupTitle($parent), $parent),
1906 $this->getType() . ":pg"
1907 );
1909 $parent,
1910 "paste_page",
1911 array(ilLMObject::_lookupTitle($source_obj->getId()), $source_obj->getId()),
1912 $this->getType() . ":st"
1913 );
1914 }
1915 }
1916 }
1917 }
1918
1919 // handle chapters
1920 if ($source_obj->getType() == "st") {
1921 //echo "2";
1922 $source_node = $lmtree->getNodeData($source_id);
1923 $subnodes = $lmtree->getSubTree($source_node);
1924
1925 // check, if target is within subtree
1926 foreach ($subnodes as $subnode) {
1927 if ($subnode["obj_id"] == $target_id) {
1928 return;
1929 }
1930 }
1931
1932 $target_pos = $target_id;
1933
1934 if ($first_child) { // as first subchapter
1935 $target_pos = ilTree::POS_FIRST_NODE;
1936 $target_parent = $target_id;
1937
1938 $pg_childs = $lmtree->getChildsByType($target_parent, "pg");
1939 if (count($pg_childs) != 0) {
1940 $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
1941 }
1942 } elseif ($as_subitem) { // as last subchapter
1943 $target_parent = $target_id;
1944 $target_pos = ilTree::POS_FIRST_NODE;
1945 $childs = $lmtree->getChilds($target_parent);
1946 if (count($childs) != 0) {
1947 $target_pos = $childs[count($childs) - 1]["obj_id"];
1948 }
1949 }
1950
1951 // delete source tree
1952 if ($movecopy == "move") {
1953 $lmtree->deleteTree($source_node);
1954 } else {
1955 // copy chapter (incl. subcontents)
1956 throw new ilException("ilObjContentObject: Not implemented");
1957 //$new_chapter = $source_obj->copy($lmtree, $target_parent, $target_pos);
1958 }
1959
1960 if (!$lmtree->isInTree($source_id)) {
1961 $lmtree->insertNode($source_id, $target_parent, $target_pos);
1962
1963 // insert moved tree
1964 foreach ($subnodes as $node) {
1965 if ($node["obj_id"] != $source_id) {
1966 $lmtree->insertNode($node["obj_id"], $node["parent"]);
1967 }
1968 }
1969 }
1970
1971 // check the tree
1972 $this->checkTree();
1973 }
1974
1975 $this->checkTree();
1976 }
1977
1981 public function validatePages(): string
1982 {
1983 $mess = "";
1984
1985 $pages = ilLMPageObject::getPageList($this->getId());
1986 foreach ($pages as $page) {
1987 if (ilLMPage::_exists($this->getType(), $page["obj_id"])) {
1988 $cpage = new ilLMPage($page["obj_id"]);
1989 $cpage->buildDom();
1990 $error = $cpage->validateDom();
1991
1992 if ($error != "") {
1993 $this->lng->loadLanguageModule("content");
1994 $this->main_tpl->setOnScreenMessage('info', $this->lng->txt("cont_import_validation_errors"));
1995 $title = ilLMObject::_lookupTitle($page["obj_id"]);
1996 $page_obj = new ilLMPageObject($this->lm, $page["obj_id"]);
1997 $mess .= $this->lng->txt("obj_pg") . ": " . $title;
1998 $mess .= '<div class="small">';
1999 foreach ($error as $e) {
2000 $err_mess = implode(" - ", $e);
2001 if (!is_int(strpos($err_mess, ":0:"))) {
2002 $mess .= htmlentities($err_mess) . "<br />";
2003 }
2004 }
2005 $mess .= '</div>';
2006 $mess .= "<br />";
2007 }
2008 }
2009 }
2010
2011 return $mess;
2012 }
2013
2014 public function cloneObject(int $target_id, int $copy_id = 0, bool $omit_tree = false): ?ilObject
2015 {
2017 $new_obj = parent::cloneObject($target_id, $copy_id, $omit_tree);
2018 $this->cloneMetaData($new_obj);
2019 //$new_obj->createProperties();
2020
2021 //copy online status if object is not the root copy object
2022 $cp_options = ilCopyWizardOptions::_getInstance($copy_id);
2023
2024 if (!$cp_options->isRootNode($this->getRefId())) {
2025 $new_obj->setOfflineStatus($this->getOfflineStatus());
2026 }
2027
2028 // $new_obj->setTitle($this->getTitle());
2029 $new_obj->setDescription($this->getDescription());
2030 $new_obj->setLayoutPerPage($this->getLayoutPerPage());
2031 $new_obj->setLayout($this->getLayout());
2032 $new_obj->setTOCMode($this->getTOCMode());
2033 $new_obj->setActiveLMMenu($this->isActiveLMMenu());
2034 $new_obj->setActiveTOC($this->isActiveTOC());
2035 $new_obj->setActiveNumbering($this->isActiveNumbering());
2036 $new_obj->setActivePrintView($this->isActivePrintView());
2037 $new_obj->setActivePreventGlossaryAppendix($this->isActivePreventGlossaryAppendix());
2038 $new_obj->setActiveDownloads($this->isActiveDownloads());
2039 $new_obj->setActiveDownloadsPublic($this->isActiveDownloadsPublic());
2040 $new_obj->setPublicNotes($this->publicNotes());
2041 $new_obj->setCleanFrames($this->cleanFrames());
2042 $new_obj->setHistoryUserComments($this->isActiveHistoryUserComments());
2043 $new_obj->setPublicAccessMode($this->getPublicAccessMode());
2044 $new_obj->setPageHeader($this->getPageHeader());
2045 $new_obj->setRating($this->hasRating());
2046 $new_obj->setRatingPages($this->hasRatingPages());
2047 $new_obj->setDisableDefaultFeedback($this->getDisableDefaultFeedback());
2048 $new_obj->setProgressIcons($this->getProgressIcons());
2049 $new_obj->setStoreTries($this->getStoreTries());
2050 $new_obj->setRestrictForwardNavigation($this->getRestrictForwardNavigation());
2051 $new_obj->setAutoGlossaries($this->getAutoGlossaries());
2052
2053 $new_obj->update();
2054
2055 $new_obj->createLMTree();
2056
2057 // copy style
2058 $style = $this->content_style_domain->styleForObjId($this->getId());
2059 $style->cloneTo($new_obj->getId());
2060
2061 $new_obj->update();
2062
2063 // copy content
2064 $copied_nodes = $this->copyAllPagesAndChapters($new_obj, $copy_id);
2065
2066 // page header and footer
2067 if ($this->getHeaderPage() > 0 && ($new_page_header = $copied_nodes[$this->getHeaderPage()]) > 0) {
2068 $new_obj->setHeaderPage($new_page_header);
2069 }
2070 if ($this->getFooterPage() > 0 && ($new_page_footer = $copied_nodes[$this->getFooterPage()]) > 0) {
2071 $new_obj->setFooterPage($new_page_footer);
2072 }
2073 $new_obj->update();
2074
2075 // Copy learning progress settings
2076 $obj_settings = new ilLPObjSettings($this->getId());
2077 $obj_settings->cloneSettings($new_obj->getId());
2078 unset($obj_settings);
2079
2080 // copy (page) multilang settings
2082 $ot->copy($new_obj->getId());
2083
2084 // copy lm menu
2085 $menu = new ilLMMenuEditor();
2086 $menu->setObjId($this->getId());
2087 $new_menu = new ilLMMenuEditor();
2088 $new_menu->setObjId($new_obj->getId());
2089 foreach ($menu->getMenuEntries() as $entry) {
2090 /*'id' => $row->id,
2091 'title' => $row->title,
2092 'link' => $row->target,
2093 'type' => $row->link_type,
2094 'ref_id' => $row->link_ref_id,
2095 'active'*/
2096
2097 $new_menu->setTarget($entry["link"]);
2098 $new_menu->setTitle($entry["title"]);
2099 $new_menu->setLinkType($entry["type"]);
2100 $new_menu->setLinkRefId($entry["ref_id"]);
2101 $new_menu->create();
2102 ilLMMenuEditor::writeActive($new_menu->getEntryId(), $entry["active"] == "y");
2103 }
2104
2105
2106 return $new_obj;
2107 }
2108
2110 ilObjLearningModule $a_target_obj,
2111 int $a_copy_id = 0
2112 ): array {
2113 $parent_id = $a_target_obj->lm_tree->readRootId();
2114 $time = null;
2115
2116 // get all chapters of root lm
2117 $chapters = $this->lm_tree->getChildsByType($this->lm_tree->readRootId(), "st");
2118 $copied_nodes = array();
2119 //$time = time();
2120 foreach ($chapters as $chap) {
2121 $cid = ilLMObject::pasteTree(
2122 $a_target_obj,
2123 $chap["child"],
2124 $parent_id,
2126 (string) $time,
2127 $copied_nodes,
2128 true,
2129 $this->lm
2130 );
2131 $target = $cid;
2132 }
2133
2134 // copy free pages
2135 $pages = ilLMPageObject::getPageList($this->getId());
2136 foreach ($pages as $p) {
2137 if (!$this->lm_tree->isInTree($p["obj_id"])) {
2138 $item = new ilLMPageObject($this->lm, $p["obj_id"]);
2139 $target_item = $item->copy($a_target_obj);
2140 $copied_nodes[$item->getId()] = $target_item->getId();
2141 }
2142 }
2143
2144 // Add mapping for pages and chapters
2145 $options = ilCopyWizardOptions::_getInstance($a_copy_id);
2146 foreach ($copied_nodes as $old_id => $new_id) {
2147 $options->appendMapping(
2148 $this->getRefId() . '_' . $old_id,
2149 $a_target_obj->getRefId() . '_' . $new_id
2150 );
2151 }
2152
2153 ilLMObject::updateInternalLinks($copied_nodes);
2154
2155 $a_target_obj->checkTree();
2156
2157 return $copied_nodes;
2158 }
2159
2160 public static function lookupAutoGlossaries(
2161 int $a_lm_id
2162 ): array {
2163 global $DIC;
2164
2165 $ilDB = $DIC->database();
2166
2167 // read auto glossaries
2168 $set = $ilDB->query(
2169 "SELECT * FROM lm_glossaries " .
2170 " WHERE lm_id = " . $ilDB->quote($a_lm_id, "integer")
2171 );
2172 $glos = array();
2173 while ($rec = $ilDB->fetchAssoc($set)) {
2174 $glos[] = $rec["glo_id"];
2175 }
2176 return $glos;
2177 }
2178
2179 public function autoLinkGlossaryTerms(
2180 int $a_glo_ref_id
2181 ): void {
2182 // get terms
2183 $terms = ilGlossaryTerm::getTermList([$a_glo_ref_id]);
2184
2185 // each get page: get content
2186 $pages = ilLMPage::getAllPages($this->getType(), $this->getId());
2187
2188 // determine terms that occur in the page
2189 $found_pages = array();
2190 foreach ($pages as $p) {
2191 $pg = new ilLMPage($p["id"]);
2192 $c = $pg->getXMLContent();
2193 foreach ($terms as $t) {
2194 if (is_int(stripos($c, $t["term"]))) {
2195 $found_pages[$p["id"]]["terms"][] = $t;
2196 if (!is_object($found_pages[$p["id"]]["page"] ?? null)) {
2197 $found_pages[$p["id"]]["page"] = $pg;
2198 }
2199 }
2200 }
2201 reset($terms);
2202 }
2203
2204 // ilPCParagraph autoLinkGlossariesPage with page and terms
2205 foreach ($found_pages as $id => $fp) {
2206 ilPCParagraph::autoLinkGlossariesPage($fp["page"], $fp["terms"]);
2207 }
2208 }
2209
2210
2214
2219 public static function isOnlineHelpModule(
2220 int $a_id,
2221 bool $a_as_obj_id = false
2222 ): bool {
2223 if (!$a_as_obj_id && $a_id > 0 && $a_id === (int) OH_REF_ID) {
2224 return true;
2225 }
2226 if ($a_as_obj_id && $a_id > 0 && $a_id === ilObject::_lookupObjId((int) OH_REF_ID)) {
2227 return true;
2228 }
2229 return false;
2230 }
2231
2232 public function setRating(bool $a_value): void
2233 {
2234 $this->rating = $a_value;
2235 }
2236
2237 public function hasRating(): bool
2238 {
2239 return $this->rating;
2240 }
2241
2242 public function setRatingPages(bool $a_value): void
2243 {
2244 $this->rating_pages = $a_value;
2245 }
2246
2247 public function hasRatingPages(): bool
2248 {
2249 return $this->rating_pages;
2250 }
2251
2252
2253 protected function doMDUpdateListener(
2254 string $a_element
2255 ): void {
2256 switch ($a_element) {
2257 case 'Educational':
2258 $obj_lp = ilObjectLP::getInstance($this->getId());
2259 if (in_array(
2260 $obj_lp->getCurrentMode(),
2262 )) {
2264 }
2265 break;
2266
2267 case 'General':
2268
2269 // Update Title and description
2270 $md = new ilMD($this->getId(), 0, $this->getType());
2271 if (!is_object($md_gen = $md->getGeneral())) {
2272 return;
2273 }
2274
2276 if ($ot->getContentActivated()) {
2277 $ot->setDefaultTitle($md_gen->getTitle());
2278
2279 foreach ($md_gen->getDescriptionIds() as $id) {
2280 $md_des = $md_gen->getDescription($id);
2281 $ot->setDefaultDescription($md_des->getDescription());
2282 break;
2283 }
2284 $ot->save();
2285 }
2286 break;
2287
2288 }
2289 }
2290
2296 public function getPublicExportFiles(): array
2297 {
2298 $dirs = array("xml");
2299 $export_files = array();
2300
2302 if ($ot->getContentActivated()) {
2303 $langs = $ot->getLanguages();
2304 foreach ($langs as $l => $ldata) {
2305 $dirs[] = "html_" . $l;
2306 }
2307 $dirs[] = "html_all";
2308 } else {
2309 $dirs[] = "html";
2310 }
2311
2312 foreach ($dirs as $dir) {
2313 $type = explode("_", $dir);
2314 $type = $type[0];
2315 if ($this->getPublicExportFile($type) != "") {
2316 if (is_file($this->getExportDirectory($dir) . "/" .
2317 $this->getPublicExportFile($type))) {
2318 $size = filesize($this->getExportDirectory($dir) . "/" .
2319 $this->getPublicExportFile($type));
2320 $export_files[] = array("type" => $type,
2321 "dir_type" => $dir,
2322 "file" => $this->getPublicExportFile($type),
2323 "size" => $size);
2324 }
2325 }
2326 }
2327
2328 return $export_files;
2329 }
2330
2331 public function isInfoEnabled(): bool
2332 {
2334 }
2335}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
error(string $a_errmsg)
return true
static _getPersistedConditionsOfTarget(int $a_target_ref_id, int $a_target_obj_id, string $a_target_type="")
get all persisted conditions of target object
static _checkCondition(array $condition, int $a_usr_id=0)
checks wether a single condition is fulfilled every trigger object type must implement a static metho...
static _checkAllConditionsOfTarget(int $a_target_ref_id, int $a_target_id, string $a_target_type="", int $a_usr_id=0)
checks wether all conditions of a target object are fulfilled
static _getInstance(int $a_copy_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getDataDir()
get data directory (outside webspace)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _createEntry(int $a_obj_id, string $a_action, array $a_info_params=[], string $a_obj_type="", string $a_user_comment="", bool $a_update_last=false)
Creates a new history entry for an object.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static writeActive(int $entry_id, bool $active)
static getInstance(ilObjLearningModule $a_content_obj, int $a_id=0, bool $a_halt=true)
static _lookupTitle(int $a_obj_id)
static updateInternalLinks(array $a_copied_nodes, string $a_parent_type="lm")
Update internal links, after multiple pages have been copied.
static putInTree(ilLMObject $a_obj, int $a_parent_id=0, int $a_target_node_id=0)
put this object into content object tree
static _deleteAllObjectData(ilObjLearningModule $a_cobj)
delete all objects of content object (digi book / learning module)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getPageList(int $lm_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _refreshStatus(int $a_obj_id, ?array $a_users=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: class.ilLog.php:31
write(string $a_msg, $a_log_level=null)
logging
static getLogger(string $a_component_id)
Get component logger.
setExportMode(bool $a_export_mode=true)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getMissingPreconditionsTopChapter(int $cont_obj_ref_id, int $cont_obj_id, int $page_id)
get top chapter of page for that any precondition is missing
static writeFooterPage(int $a_lm_id, int $a_page_id)
setPublicAccessMode(string $a_mode)
ILIAS Notes Service $notes
exportFileItems(string $a_target_dir, ilLog $expLog)
setRestrictForwardNavigation(bool $a_val)
setPublicExportFile(string $a_type, string $a_file)
specify public export file for type
doMDUpdateListener(string $a_element)
createProperties()
create new properties record
static _lookupStoreTries(int $a_id)
static _getNrOfAssignedLMs(int $a_style_id)
gets the number of learning modules assigned to a content style
static _getNrLMsIndividualStyles()
get number of learning modules with individual styles
exportXMLStructureObjects(ilXmlWriter $a_xml_writer, int $a_inst, ilLog $expLog)
static getAvailableLayouts()
get all available lm layouts
static writeHeaderPage(int $a_lm_id, int $a_page_id)
copyAllPagesAndChapters(ilObjLearningModule $a_target_obj, int $a_copy_id=0)
setForTranslation(bool $a_val)
Set for translation (lm has been imported for translation purposes)
setHideHeaderFooterPrint(bool $a_val)
Set hide header footer in print mode.
getTOCMode()
get toc mode ("chapters" | "pages")
setDisableDefaultFeedback(bool $a_val)
Set disable default feedback for questions.
setActiveLMMenu(bool $a_act_lm_menu)
createImportDirectory()
creates data directory for import files (data_dir/lm_data/lm_<id>/import, depending on data directory...
static _getNrLMsNoStyle()
get number of learning modules assigned no style
static _checkPreconditionsOfPage(int $cont_ref_id, int $cont_obj_id, int $page_id)
checks whether the preconditions of a page are fulfilled or not
executeDragDrop(int $source_id, int $target_id, bool $first_child, bool $as_subitem=false, string $movecopy="move")
exportFO(ilXmlWriter $a_xml_writer, string $a_target_dir)
static _moveLMStyles(int $a_from_style, int $a_to_style)
move learning modules from one style to another
getExportDirectory(string $a_type="xml")
setPublicNotes(bool $a_pub_notes)
exportXML(ilXmlWriter $a_xml_writer, int $a_inst, string $a_target_dir, ilLog $expLog)
static _deleteStyleAssignments(int $a_style_id)
delete all style references to style
getPageHeader()
get page header mode (ilLMOBject::CHAPTER_TITLE | ilLMOBject::PAGE_TITLE | ilLMOBject::NO_HEADER)
getPublicAccessMode()
get public access mode ("complete" | "selected")
create(bool $a_no_meta_data=false)
create content object
static _lookup(int $a_obj_id, string $a_field)
checkStructure()
Check tree (this has been copied from fixTree due to a bug fixing, should be reorganised)
exportFOStructureObjects(ilXmlWriter $a_xml_writer)
exportXMLProperties(ilXmlWriter $a_xml_writer, ilLog $expLog)
validatePages()
Validate all pages.
static _lookupStyleSheetId(int $a_cont_obj_id)
exportXMLPageObjects(ilXmlWriter $a_xml_writer, int $a_inst, ilLog $expLog)
static lookupAutoGlossaries(int $a_lm_id)
setTOCMode(string $a_toc_mode="chapters")
set toc mode
setActivePreventGlossaryAppendix(bool $a_print)
static hasSuccessorPage(int $a_cont_obj_id, int $a_page_id)
checks if page has a successor page
exportXMLMediaObjects(ilXmlWriter $a_xml_writer, int $a_inst, string $a_target_dir, ilLog $expLog)
ILIAS Style Content DomainService $content_style_domain
setPageHeader(string $a_pg_header=ilLMObject::CHAPTER_TITLE)
set page header mode
createExportDirectory(string $a_type="xml")
creates data directory for export files (data_dir/lm_data/lm_<id>/export, depending on data directory...
static _lookupContObjIdByStyleId(int $a_style_id)
ilGlobalTemplateInterface $main_tpl
setActiveDownloadsPublic(bool $a_down)
autoLinkGlossaryTerms(int $a_glo_ref_id)
static _lookupDisableDefaultFeedback(int $a_id)
setImportDirectory(string $a_import_dir)
getPublicExportFiles()
Get public export files.
static isOnlineHelpModule(int $a_id, bool $a_as_obj_id=false)
Is module an online module.
static _lookupRestrictForwardNavigation(int $a_obj_id)
exportXMLMetaData(ilXmlWriter $a_xml_writer)
static _getMissingPreconditionsOfPage(int $cont_ref_id, int $cont_obj_id, int $page_id)
gets all missing preconditions of page
Class ilObjFile.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
User class.
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
static getInstance(int $obj_id)
static getInstance(int $obj_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $id, bool $reference=false)
__construct(int $id=0, bool $reference=true)
setOfflineStatus(bool $status)
static _lookupObjId(int $ref_id)
static autoLinkGlossariesPage(ilPageObject $a_page, array $a_terms)
Auto link glossary of whole page.
static getAllPages(string $a_parent_type, int $a_parent_id, string $a_lang="-")
Get all pages for parent object.
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
isInTree(?int $a_node_id)
get all information of a node.
getPathFull(int $a_endnode_id, int $a_startnode_id=0)
get path from a given startnode to a given endnode if startnode is not given the rootnode is startnod...
const POS_LAST_NODE
setTreeTablePK(string $a_column_name)
set column containing primary key in tree table
setTableNames(string $a_table_tree, string $a_table_obj_data, string $a_table_obj_reference="")
set table names The primary key of the table containing your object_data must be 'obj_id' You may use...
const POS_FIRST_NODE
static tf2yn(bool $a_tf)
static yn2tf(string $a_yn)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
xmlElement(string $tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
xmlEndTag(string $tag)
Writes an endtag.
appendXML(string $a_str)
append xml string to document
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
$c
Definition: cli.php:38
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
const IL_INST_ID
Definition: constants.php:40
return['3gp', '7z', 'ai', 'aif', 'aifc', 'aiff', 'au', 'arw', 'avi', 'backup', 'bak', 'bas', 'bpmn', 'bpmn2', 'bmp', 'bib', 'bibtex', 'bz', 'bz2', 'c', 'c++', 'cc', 'cct', 'cdf', 'cer', 'class', 'cls', 'conf', 'cpp', 'crt', 'crs', 'crw', 'cr2', 'css', 'cst', 'csv', 'cur', 'db', 'dcr', 'des', 'dng', 'doc', 'docx', 'dot', 'dotx', 'dtd', 'dvi', 'el', 'eps', 'epub', 'f', 'f77', 'f90', 'flv', 'for', 'g3', 'gif', 'gl', 'gan', 'ggb', 'gsd', 'gsm', 'gtar', 'gz', 'gzip', 'h', 'hpp', 'htm', 'html', 'htmls', 'ibooks', 'ico', 'ics', 'ini', 'ipynb', 'java', 'jbf', 'jpeg', 'jpg', 'js', 'jsf', 'jso', 'json', 'latex', 'lang', 'less', 'log', 'lsp', 'ltx', 'm1v', 'm2a', 'm2v', 'm3u', 'm4a', 'm4v', 'markdown', 'm', 'mat', 'md', 'mdl', 'mdown', 'mid', 'min', 'midi', 'mobi', 'mod', 'mov', 'movie', 'mp2', 'mp3', 'mp4', 'mpa', 'mpeg', 'mpg', 'mph', 'mpga', 'mpp', 'mpt', 'mpv', 'mpx', 'mv', 'mw', 'mv4', 'nb', 'nbp', 'nef', 'nif', 'niff', 'obj', 'obm', 'odt', 'ods', 'odp', 'odg', 'odf', 'oga', 'ogg', 'ogv', 'old', 'p', 'pas', 'pbm', 'pcl', 'pct', 'pcx', 'pdf', 'pgm', 'pic', 'pict', 'png', 'por', 'pov', 'project', 'properties', 'ppa', 'ppm', 'pps', 'ppsx', 'ppt', 'pptx', 'ppz', 'ps', 'psd', 'pwz', 'qt', 'qtc', 'qti', 'qtif', 'r', 'ra', 'ram', 'rar', 'rast', 'rda', 'rev', 'rexx', 'ris', 'rf', 'rgb', 'rm', 'rmd', 'rmi', 'rmm', 'rmp', 'rt', 'rtf', 'rtx', 'rv', 's', 's3m', 'sav', 'sbs', 'sec', 'sdml', 'sgm', 'sgml', 'smi', 'smil', 'srt', 'sps', 'spv', 'stl', 'svg', 'swa', 'swf', 'swz', 'tar', 'tex', 'texi', 'texinfo', 'text', 'tgz', 'tif', 'tiff', 'ttf', 'txt', 'tmp', 'uvproj', 'vdf', 'vimeo', 'viv', 'vivo', 'vrml', 'vsdx', 'wav', 'webm', 'wmv', 'wmx', 'wmz', 'woff', 'wwd', 'xhtml', 'xif', 'xls', 'xlsx', 'xmind', 'xml', 'xsl', 'xsd', 'zip']
global $DIC
Definition: feed.php:28
$target_id
Definition: goto.php:52
$path
Definition: ltiservices.php:32
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$type
$ilErr
Definition: raiseError.php:17
$lng
$lm_set