ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilObjContentObject.php
Go to the documentation of this file.
1 <?php
2 
20 
26 {
27  protected \ILIAS\Notes\Service $notes;
28  protected array $q_ids = [];
29  protected array $mob_ids = [];
30  protected array $file_ids = [];
31  protected array $public_export_file = [];
32  protected int $header_page = 0;
33  protected int $footer_page = 0;
34  protected bool $user_comments = false;
35  protected bool $clean_frames = false;
36  protected bool $pub_notes = 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 $toc_mode = '';
44  protected bool $restrict_forw_nav = false;
45  protected bool $store_tries = false;
46  protected bool $progr_icons = false;
47  protected bool $disable_def_feedback = false;
48  protected bool $layout_per_page = false;
49  protected ilObjUser $user;
52  public string $layout = '';
53  public int $style_id = 0;
54  public string $pg_header = '';
55  public bool $online = false;
56  public bool $for_translation = false;
57  protected bool $rating = false;
58  protected bool $rating_pages = false;
59  public array $auto_glossaries = array();
60  private string $import_dir = '';
62  protected \ILIAS\Style\Content\DomainService $content_style_domain;
63  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  $this->lom_services = $DIC->learningObjectMetadata();
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  $id = parent::create();
107 
108  // meta data will be created by
109  // import parser
110  if (!$a_no_meta_data) {
111  $this->createMetaData();
112  }
113 
114  $this->createProperties();
115  $this->updateAutoGlossaries();
116  return $id;
117  }
118 
119  public function read(): void
120  {
121  $ilDB = $this->db;
122 
123  parent::read();
124 
125  $this->lm_tree = new ilLMTree($this->getId());
126 
127  $this->readProperties();
128 
129  // read auto glossaries
130  $set = $ilDB->query(
131  "SELECT * FROM lm_glossaries " .
132  " WHERE lm_id = " . $ilDB->quote($this->getId(), "integer")
133  );
134  $glos = array();
135  while ($rec = $ilDB->fetchAssoc($set)) {
136  $glos[] = $rec["glo_id"];
137  }
138  $this->setAutoGlossaries($glos);
139  }
140 
141  public function setLayoutPerPage(bool $a_val): void
142  {
143  $this->layout_per_page = $a_val;
144  }
145 
146  public function getLayoutPerPage(): bool
147  {
148  return $this->layout_per_page;
149  }
150 
154  public function setDisableDefaultFeedback(bool $a_val): void
155  {
156  $this->disable_def_feedback = $a_val;
157  }
158 
159  public function getDisableDefaultFeedback(): bool
160  {
162  }
163 
164  public function setProgressIcons(bool $a_val): void
165  {
166  $this->progr_icons = $a_val;
167  }
168 
169  public function getProgressIcons(): bool
170  {
171  return $this->progr_icons;
172  }
173 
174  public function setStoreTries(bool $a_val): void
175  {
176  $this->store_tries = $a_val;
177  }
178 
179  public function getStoreTries(): bool
180  {
181  return $this->store_tries;
182  }
183 
184  public function setRestrictForwardNavigation(bool $a_val): void
185  {
186  $this->restrict_forw_nav = $a_val;
187  }
188 
189  public function getRestrictForwardNavigation(): bool
190  {
192  }
193 
194  public function getTree(): ilLMTree
195  {
196  return $this->lm_tree;
197  }
198 
199  public function update(): bool
200  {
201  $this->updateMetaData();
202  parent::update();
203  $this->updateProperties();
204  $this->updateAutoGlossaries();
205  return true;
206  }
207 
208  public function updateAutoGlossaries(): void
209  {
210  $ilDB = $this->db;
211 
212  // update auto glossaries
213  $ilDB->manipulate(
214  "DELETE FROM lm_glossaries WHERE " .
215  " lm_id = " . $ilDB->quote($this->getId(), "integer")
216  );
217  foreach ($this->getAutoGlossaries() as $glo_id) {
218  $ilDB->manipulate("INSERT INTO lm_glossaries " .
219  "(lm_id, glo_id) VALUES (" .
220  $ilDB->quote($this->getId(), "integer") . "," .
221  $ilDB->quote($glo_id, "integer") .
222  ")");
223  }
224  }
225 
226 
230  public function import(): void
231  {
232  // nothing to do. just display the dialogue in Out
233  }
234 
235  public function createLMTree(): void
236  {
237  $this->lm_tree = new ilLMTree($this->getId(), false);
238  $this->lm_tree->addTree($this->getId(), 1);
239  }
240 
241  public function setAutoGlossaries(array $a_val): void
242  {
243  $this->auto_glossaries = array();
244  if (is_array($a_val)) {
245  foreach ($a_val as $v) {
246  $v = (int) $v;
247  if ($v > 0 && ilObject::_lookupType($v) == "glo" &&
248  !in_array($v, $this->auto_glossaries)) {
249  $this->auto_glossaries[] = $v;
250  }
251  }
252  }
253  }
254 
255  public function getAutoGlossaries(): array
256  {
257  return $this->auto_glossaries;
258  }
259 
260  public function removeAutoGlossary(int $a_glo_id): void
261  {
262  $glo_ids = array();
263  foreach ($this->getAutoGlossaries() as $g) {
264  if ($g != $a_glo_id) {
265  $glo_ids[] = $g;
266  }
267  }
268  $this->setAutoGlossaries($glo_ids);
269  }
270 
271  public function addFirstChapterAndPage(): void
272  {
273  $lng = $this->lng;
274 
275 
276  $root_id = $this->lm_tree->getRootId();
277 
278  // chapter
279  $chap = new ilStructureObject($this->lm);
280  $chap->setType("st");
281  $chap->setTitle($lng->txt("cont_new_chap"));
282  $chap->setLMId($this->getId());
283  $chap->create();
285 
286  // page
288  $lm = $this;
289  $page = new ilLMPageObject($lm);
290  $page->setType("pg");
291  $page->setTitle($lng->txt("cont_new_page"));
292  $page->setLMId($this->getId());
293  $page->create();
294  ilLMObject::putInTree($page, $chap->getId(), ilTree::POS_FIRST_NODE);
295  }
296 
300  public function setForTranslation(bool $a_val): void
301  {
302  $this->for_translation = $a_val;
303  }
304 
305  public function getForTranslation(): bool
306  {
307  return $this->for_translation;
308  }
309 
310  public function getLMTree(): ilLMTree
311  {
312  return $this->lm_tree;
313  }
314 
315 
321  public function createImportDirectory(): void
322  {
324 
325  $lm_data_dir = ilFileUtils::getDataDir() . "/lm_data";
326  if (!is_writable($lm_data_dir)) {
327  $ilErr->raiseError("Content object Data Directory (" . $lm_data_dir
328  . ") not writeable.", $ilErr->FATAL);
329  }
330 
331  // create learning module directory (data_dir/lm_data/lm_<id>)
332  $lm_dir = $lm_data_dir . "/lm_" . $this->getId();
333  ilFileUtils::makeDir($lm_dir);
334  if (!is_dir($lm_dir)) {
335  $ilErr->raiseError("Creation of Learning Module Directory failed.", $ilErr->FATAL);
336  }
337 
338  // create import subdirectory (data_dir/lm_data/lm_<id>/import)
339  $import_dir = $lm_dir . "/import";
340  ilFileUtils::makeDir($import_dir);
341  if (!is_dir($import_dir)) {
342  $ilErr->raiseError("Creation of Import Directory failed.", $ilErr->FATAL);
343  }
344  }
345 
346  public function getDataDirectory(): string
347  {
348  return ilFileUtils::getDataDir() . "/lm_data" .
349  "/lm_" . $this->getId();
350  }
351 
352  public function getImportDirectory(): string
353  {
354  if (strlen($this->import_dir)) {
355  return $this->import_dir;
356  }
357 
358  $import_dir = ilFileUtils::getDataDir() . "/lm_data" .
359  "/lm_" . $this->getId() . "/import";
360  if (is_dir($import_dir)) {
361  return $import_dir;
362  }
363  return "";
364  }
365 
366  public function setImportDirectory(string $a_import_dir): void
367  {
368  $this->import_dir = $a_import_dir;
369  }
370 
371 
377  public function createExportDirectory(
378  string $a_type = "xml"
379  ): void {
381 
382  $lm_data_dir = ilFileUtils::getDataDir() . "/lm_data";
383  // create learning module directory (data_dir/lm_data/lm_<id>)
384  $lm_dir = $lm_data_dir . "/lm_" . $this->getId();
386  if (!is_dir($lm_dir)) {
387  $ilErr->raiseError("Creation of Learning Module Directory failed.", $ilErr->FATAL);
388  }
389  // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
390  switch ($a_type) {
391  default: // = xml
392  if (substr($a_type, 0, 4) == "html") {
393  $export_dir = $lm_dir . "/export_" . $a_type;
394  } else {
395  $export_dir = $lm_dir . "/export";
396  }
397  break;
398  }
399  ilFileUtils::makeDir($export_dir);
400 
401  if (!is_dir($export_dir)) {
402  $ilErr->raiseError("Creation of Export Directory failed.", $ilErr->FATAL);
403  }
404  }
405 
406  public function getExportDirectory(
407  string $a_type = "xml"
408  ): string {
409  switch ($a_type) {
410  default: // = xml
411  if (substr($a_type, 0, 4) == "html") {
412  $export_dir = ilFileUtils::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export_" . $a_type;
413  } else {
414  $export_dir = ilFileUtils::getDataDir() . "/lm_data" . "/lm_" . $this->getId() . "/export";
415  }
416  break;
417  }
418  return $export_dir;
419  }
420 
421 
430  public function delete(): bool
431  {
432  $ilDB = $this->db;
433 
434  // always call parent delete function first!!
435  if (!parent::delete()) {
436  return false;
437  }
438 
439  // delete lm object data
441  $lm = $this;
443 
444  // delete meta data of content object
445  $this->deleteMetaData();
446 
447 
448  // delete learning module tree
449  $this->lm_tree->removeTree($this->lm_tree->getTreeId());
450 
451  // delete data directory
453 
454  // delete content object record
455  $q = "DELETE FROM content_object WHERE id = " .
456  $ilDB->quote($this->getId(), "integer");
457  $ilDB->manipulate($q);
458 
459  // delete lm menu entries
460  $q = "DELETE FROM lm_menu WHERE lm_id = " .
461  $ilDB->quote($this->getId(), "integer");
462  $ilDB->manipulate($q);
463 
464  // remove auto glossary entries
465  $ilDB->manipulate(
466  "DELETE FROM lm_glossaries WHERE " .
467  " lm_id = " . $ilDB->quote($this->getId(), "integer")
468  );
469 
470 
471  return true;
472  }
473 
474  public function getLayout(): string
475  {
476  return $this->layout;
477  }
478 
479  public function setLayout(string $a_layout): void
480  {
481  $this->layout = $a_layout;
482  }
483 
484  public static function writeHeaderPage(
485  int $a_lm_id,
486  int $a_page_id
487  ): void {
488  global $DIC;
489 
490  $ilDB = $DIC->database();
491 
492  $ilDB->manipulate(
493  "UPDATE content_object SET " .
494  " header_page = " . $ilDB->quote($a_page_id, "integer") .
495  " WHERE id = " . $ilDB->quote($a_lm_id, "integer")
496  );
497  }
498 
499  public static function writeFooterPage(
500  int $a_lm_id,
501  int $a_page_id
502  ): void {
503  global $DIC;
504 
505  $ilDB = $DIC->database();
506 
507  $ilDB->manipulate(
508  "UPDATE content_object SET " .
509  " footer_page = " . $ilDB->quote($a_page_id, "integer") .
510  " WHERE id = " . $ilDB->quote($a_lm_id, "integer")
511  );
512  }
513 
514 
518  public static function _moveLMStyles(
519  int $a_from_style,
520  int $a_to_style
521  ): void {
522  global $DIC;
523 
524  $ilDB = $DIC->database();
525 
526  if ($a_from_style < 0) { // change / delete all individual styles
527  $q = "SELECT stylesheet FROM content_object, style_data " .
528  " WHERE content_object.stylesheet = style_data.id " .
529  " AND style_data.standard = " . $ilDB->quote(0, "integer") .
530  " AND content_object.stylesheet > " . $ilDB->quote(0, "integer");
531  $style_set = $ilDB->query($q);
532  while ($style_rec = $ilDB->fetchAssoc($style_set)) {
533  // assign learning modules to new style
534  $q = "UPDATE content_object SET " .
535  " stylesheet = " . $ilDB->quote($a_to_style, "integer") .
536  " WHERE stylesheet = " . $ilDB->quote($style_rec["stylesheet"], "integer");
537  $ilDB->manipulate($q);
538 
539  // delete style
540  $style_obj = ilObjectFactory::getInstanceByObjId($style_rec["stylesheet"]);
541  $style_obj->delete();
542  }
543  } else {
544  $q = "UPDATE content_object SET " .
545  " stylesheet = " . $ilDB->quote($a_to_style, "integer") .
546  " WHERE stylesheet = " . $ilDB->quote($a_from_style, "integer");
547  $ilDB->manipulate($q);
548  }
549  }
550 
551  protected static function _lookup(
552  int $a_obj_id,
553  string $a_field
554  ): string {
555  global $DIC;
556 
557  $ilDB = $DIC->database();
558 
559  $q = "SELECT " . $a_field . " FROM content_object " .
560  " WHERE id = " . $ilDB->quote($a_obj_id, "integer");
561 
562  $res = $ilDB->query($q);
563  $rec = $ilDB->fetchAssoc($res);
564 
565  return $rec[$a_field];
566  }
567 
568  public static function _lookupRestrictForwardNavigation(
569  int $a_obj_id
570  ): string {
571  return self::_lookup($a_obj_id, "restrict_forw_nav");
572  }
573 
574  public static function _lookupStyleSheetId(int $a_cont_obj_id): int
575  {
576  global $DIC;
577 
578  $ilDB = $DIC->database();
579 
580  $q = "SELECT stylesheet FROM content_object " .
581  " WHERE id = " . $ilDB->quote($a_cont_obj_id, "integer");
582  $res = $ilDB->query($q);
583  $sheet = $ilDB->fetchAssoc($res);
584 
585  return (int) $sheet["stylesheet"];
586  }
587 
588  public static function _lookupContObjIdByStyleId(int $a_style_id): array
589  {
590  global $DIC;
591 
592  $ilDB = $DIC->database();
593 
594  $q = "SELECT id FROM content_object " .
595  " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
596  $res = $ilDB->query($q);
597  $obj_ids = array();
598  while ($cont = $ilDB->fetchAssoc($res)) {
599  $obj_ids[] = (int) $cont["id"];
600  }
601  return $obj_ids;
602  }
603 
604  public static function _lookupDisableDefaultFeedback(int $a_id): bool
605  {
606  global $DIC;
607 
608  $ilDB = $DIC->database();
609 
610  $q = "SELECT disable_def_feedback FROM content_object " .
611  " WHERE id = " . $ilDB->quote($a_id, "integer");
612  $res = $ilDB->query($q);
613  $rec = $ilDB->fetchAssoc($res);
614 
615  return (bool) ($rec["disable_def_feedback"] ?? false);
616  }
617 
618  public static function _lookupStoreTries(int $a_id): bool
619  {
620  global $DIC;
621 
622  $ilDB = $DIC->database();
623 
624  $q = "SELECT store_tries FROM content_object " .
625  " WHERE id = " . $ilDB->quote($a_id, "integer");
626  $res = $ilDB->query($q);
627  $rec = $ilDB->fetchAssoc($res);
628 
629  return (bool) ($rec["store_tries"] ?? false);
630  }
631 
632 
636  public static function _getNrOfAssignedLMs(int $a_style_id): int
637  {
638  global $DIC;
639 
640  $ilDB = $DIC->database();
641 
642  $q = "SELECT count(*) as cnt FROM content_object " .
643  " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
644  $cset = $ilDB->query($q);
645  $crow = $ilDB->fetchAssoc($cset);
646 
647  return (int) ($crow["cnt"] ?? 0);
648  }
649 
650 
654  public static function _getNrLMsIndividualStyles(): int
655  {
656  global $DIC;
657 
658  $ilDB = $DIC->database();
659 
660  // joining with style table (not perfectly nice)
661  $q = "SELECT count(*) as cnt FROM content_object, style_data " .
662  " WHERE stylesheet = style_data.id " .
663  " AND standard = " . $ilDB->quote(0, "integer");
664  $cset = $ilDB->query($q);
665  $crow = $ilDB->fetchAssoc($cset);
666 
667  return (int) $crow["cnt"];
668  }
669 
673  public static function _getNrLMsNoStyle(): int
674  {
675  global $DIC;
676 
677  $ilDB = $DIC->database();
678 
679  $q = "SELECT count(*) as cnt FROM content_object " .
680  " WHERE stylesheet = " . $ilDB->quote(0, "integer");
681  $cset = $ilDB->query($q);
682  $crow = $ilDB->fetchAssoc($cset);
683 
684  return (int) $crow["cnt"];
685  }
686 
690  public static function _deleteStyleAssignments(
691  int $a_style_id
692  ): void {
693  global $DIC;
694 
695  $ilDB = $DIC->database();
696 
697  $q = "UPDATE content_object SET " .
698  " stylesheet = " . $ilDB->quote(0, "integer") .
699  " WHERE stylesheet = " . $ilDB->quote($a_style_id, "integer");
700 
701  $ilDB->manipulate($q);
702  }
703 
707  public function getPageHeader(): string
708  {
709  return $this->pg_header;
710  }
711 
716  public function setPageHeader(
717  string $a_pg_header = ilLMObject::CHAPTER_TITLE
718  ): void {
719  $this->pg_header = $a_pg_header;
720  }
721 
725  public function getTOCMode(): string
726  {
727  return $this->toc_mode;
728  }
729 
734  public function setTOCMode(string $a_toc_mode = "chapters"): void
735  {
736  $this->toc_mode = $a_toc_mode;
737  }
738 
739  public function setActiveLMMenu(bool $a_act_lm_menu): void
740  {
741  $this->lm_menu_active = $a_act_lm_menu;
742  }
743 
744  public function isActiveLMMenu(): bool
745  {
746  return $this->lm_menu_active;
747  }
748 
749  public function setActiveTOC(bool $a_toc): void
750  {
751  $this->toc_active = $a_toc;
752  }
753 
754  public function isActiveTOC(): bool
755  {
756  return $this->toc_active;
757  }
758 
759  public function setActiveNumbering(bool $a_num): void
760  {
761  $this->numbering = $a_num;
762  }
763 
764  public function isActiveNumbering(): bool
765  {
766  return $this->numbering;
767  }
768 
769  public function setActivePrintView(bool $a_print): void
770  {
771  $this->print_view_active = $a_print;
772  }
773 
774  public function isActivePrintView(): bool
775  {
777  }
778 
779  public function setActivePreventGlossaryAppendix(bool $a_print): void
780  {
781  $this->prevent_glossary_appendix_active = $a_print;
782  }
783 
784  public function isActivePreventGlossaryAppendix(): bool
785  {
787  }
788 
792  public function setHideHeaderFooterPrint(bool $a_val): void
793  {
794  $this->hide_header_footer_print = $a_val;
795  }
796 
797  public function getHideHeaderFooterPrint(): bool
798  {
800  }
801 
802  public function setPublicNotes(bool $a_pub_notes): void
803  {
804  $this->pub_notes = $a_pub_notes;
805  }
806 
807  public function publicNotes(): bool
808  {
809  return $this->pub_notes;
810  }
811 
812  public function setCleanFrames(bool $a_clean): void
813  {
814  $this->clean_frames = $a_clean;
815  }
816 
817  public function cleanFrames(): bool
818  {
819  return $this->clean_frames;
820  }
821 
822  public function setHeaderPage(int $a_pg): void
823  {
824  $this->header_page = $a_pg;
825  }
826 
827  public function getHeaderPage(): int
828  {
829  return $this->header_page;
830  }
831 
832  public function setFooterPage(int $a_pg): void
833  {
834  $this->footer_page = $a_pg;
835  }
836 
837  public function getFooterPage(): int
838  {
839  return $this->footer_page;
840  }
841 
842  public function readProperties(): void
843  {
844  $ilDB = $this->db;
845 
846  $q = "SELECT * FROM content_object WHERE id = " .
847  $ilDB->quote($this->getId(), "integer");
848  $lm_set = $ilDB->query($q);
849  $lm_rec = $ilDB->fetchAssoc($lm_set);
850  $this->setLayout((string) $lm_rec["default_layout"]);
851  $this->setPageHeader((string) $lm_rec["page_header"]);
852  $this->setTOCMode((string) $lm_rec["toc_mode"]);
853  $this->setActiveTOC(ilUtil::yn2tf($lm_rec["toc_active"]));
854  $this->setActiveNumbering(ilUtil::yn2tf($lm_rec["numbering"]));
855  $this->setActivePrintView(ilUtil::yn2tf($lm_rec["print_view_active"]));
856  $this->setActivePreventGlossaryAppendix(ilUtil::yn2tf($lm_rec["no_glo_appendix"]));
857  $this->setHideHeaderFooterPrint((bool) $lm_rec["hide_head_foot_print"]);
858  $this->setActiveLMMenu(ilUtil::yn2tf($lm_rec["lm_menu_active"]));
859  $this->setCleanFrames(ilUtil::yn2tf($lm_rec["clean_frames"]));
860  $this->setHeaderPage((int) $lm_rec["header_page"]);
861  $this->setFooterPage((int) $lm_rec["footer_page"]);
862  $this->setLayoutPerPage((bool) $lm_rec["layout_per_page"]);
863  $this->setRating((bool) $lm_rec["rating"]);
864  $this->setRatingPages((bool) $lm_rec["rating_pages"]);
865  $this->setDisableDefaultFeedback((bool) $lm_rec["disable_def_feedback"]);
866  $this->setProgressIcons((bool) $lm_rec["progr_icons"]);
867  $this->setStoreTries((bool) $lm_rec["store_tries"]);
868  $this->setRestrictForwardNavigation((bool) $lm_rec["restrict_forw_nav"]);
869 
870  // #14661
871  $this->setPublicNotes($this->notes->domain()->commentsActive($this->getId()));
872 
873  $this->setForTranslation((bool) $lm_rec["for_translation"]);
874  }
875 
876  public function updateProperties(): void
877  {
878  $ilDB = $this->db;
879 
880  // force clean_frames to be set, if layout per page is activated
881  if ($this->getLayoutPerPage()) {
882  $this->setCleanFrames(true);
883  }
884 
885  $q = "UPDATE content_object SET " .
886  " default_layout = " . $ilDB->quote($this->getLayout(), "text") . ", " .
887  " page_header = " . $ilDB->quote($this->getPageHeader(), "text") . "," .
888  " toc_mode = " . $ilDB->quote($this->getTOCMode(), "text") . "," .
889  " toc_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveTOC()), "text") . "," .
890  " numbering = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveNumbering()), "text") . "," .
891  " print_view_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActivePrintView()), "text") . "," .
892  " no_glo_appendix = " . $ilDB->quote(ilUtil::tf2yn($this->isActivePreventGlossaryAppendix()), "text") . "," .
893  " hide_head_foot_print = " . $ilDB->quote($this->getHideHeaderFooterPrint(), "integer") . "," .
894  " clean_frames = " . $ilDB->quote(ilUtil::tf2yn($this->cleanFrames()), "text") . "," .
895  " header_page = " . $ilDB->quote($this->getHeaderPage(), "integer") . "," .
896  " footer_page = " . $ilDB->quote($this->getFooterPage(), "integer") . "," .
897  " lm_menu_active = " . $ilDB->quote(ilUtil::tf2yn($this->isActiveLMMenu()), "text") . ", " .
898  " layout_per_page = " . $ilDB->quote($this->getLayoutPerPage(), "integer") . ", " .
899  " rating = " . $ilDB->quote($this->hasRating(), "integer") . ", " .
900  " rating_pages = " . $ilDB->quote($this->hasRatingPages(), "integer") . ", " .
901  " disable_def_feedback = " . $ilDB->quote($this->getDisableDefaultFeedback(), "integer") . ", " .
902  " progr_icons = " . $ilDB->quote($this->getProgressIcons(), "integer") . ", " .
903  " store_tries = " . $ilDB->quote($this->getStoreTries(), "integer") . ", " .
904  " restrict_forw_nav = " . $ilDB->quote($this->getRestrictForwardNavigation(), "integer") . ", " .
905  " for_translation = " . $ilDB->quote((int) $this->getForTranslation(), "integer") . " " .
906  " WHERE id = " . $ilDB->quote($this->getId(), "integer");
907  $ilDB->manipulate($q);
908  // #14661
909  $this->notes->domain()->activateComments($this->getId(), $this->publicNotes());
910  }
911 
915  public function createProperties(): void
916  {
917  $ilDB = $this->db;
918 
919  $this->db->insert("content_object", [
920  "id" => ["integer", $this->getId()],
921  "page_header" => ["text", ilLMObject::PAGE_TITLE]
922  ]);
923 
924  // #14661
925  $this->notes->domain()->activateComments($this->getId());
926 
927  $this->readProperties(); // to get db default values
928  }
929 
930 
934  public static function getAvailableLayouts(): array
935  {
936  $dir = opendir("./components/ILIAS/LearningModule/layouts/lm");
937 
938  $layouts = array();
939 
940  while ($file = readdir($dir)) {
941  if ($file != "." && $file != ".." && $file != "CVS" && $file != ".svn") {
942  // directories
943  if (is_dir("./components/ILIAS/LearningModule/layouts/lm/" . $file)) {
944  $layouts[$file] = $file;
945  }
946  }
947  }
948  asort($layouts);
949 
950  // workaround: fix ordering
951  $ret = array(
952  'toc2win' => 'toc2win',
953  'toc2windyn' => 'toc2windyn',
954  '1window' => '1window',
955  '2window' => '2window',
956  '3window' => '3window',
957  'presentation' => 'presentation',
958  'fullscreen' => 'fullscreen'
959  );
960 
961  foreach ($layouts as $l) {
962  if (!in_array($l, $ret)) {
963  $ret[$l] = $l;
964  }
965  }
966 
967  return $ret;
968  }
969 
973  public static function _checkPreconditionsOfPage(
974  int $cont_ref_id,
975  int $cont_obj_id,
976  int $page_id
977  ): bool {
978  $lm_tree = new ilTree($cont_obj_id);
979  $lm_tree->setTableNames('lm_tree', 'lm_data');
980  $lm_tree->setTreeTablePK("lm_id");
981 
982  if ($lm_tree->isInTree($page_id)) {
983  $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
984  foreach ($path as $node) {
985  if ($node["type"] == "st") {
986  if (!ilConditionHandler::_checkAllConditionsOfTarget($cont_ref_id, $node["child"], "st")) {
987  return false;
988  }
989  }
990  }
991  }
992 
993  return true;
994  }
995 
999  public static function _getMissingPreconditionsOfPage(
1000  int $cont_ref_id,
1001  int $cont_obj_id,
1002  int $page_id
1003  ): array {
1004  $lm_tree = new ilTree($cont_obj_id);
1005  $lm_tree->setTableNames('lm_tree', 'lm_data');
1006  $lm_tree->setTreeTablePK("lm_id");
1007 
1008  $conds = array();
1009  if ($lm_tree->isInTree($page_id)) {
1010  // get full path of page
1011  $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1012  foreach ($path as $node) {
1013  if ($node["type"] == "st") {
1014  // get all preconditions of upper chapters
1015  $tconds = ilConditionHandler::_getPersistedConditionsOfTarget($cont_ref_id, $node["child"], "st");
1016  foreach ($tconds as $tcond) {
1017  // store all missing preconditions
1018  if (!ilConditionHandler::_checkCondition($tcond)) {
1019  $conds[] = $tcond;
1020  }
1021  }
1022  }
1023  }
1024  }
1025 
1026  return $conds;
1027  }
1028 
1032  public static function _getMissingPreconditionsTopChapter(
1033  int $cont_obj_ref_id,
1034  int $cont_obj_id,
1035  int $page_id
1036  ): int {
1037  $lm_tree = new ilTree($cont_obj_id);
1038  $lm_tree->setTableNames('lm_tree', 'lm_data');
1039  $lm_tree->setTreeTablePK("lm_id");
1040 
1041  if ($lm_tree->isInTree($page_id)) {
1042  // get full path of page
1043  $path = $lm_tree->getPathFull($page_id, $lm_tree->readRootId());
1044  foreach ($path as $node) {
1045  if ($node["type"] == "st") {
1046  // get all preconditions of upper chapters
1047  $tconds = ilConditionHandler::_getPersistedConditionsOfTarget($cont_obj_ref_id, $node["child"], "st");
1048  foreach ($tconds as $tcond) {
1049  // look for missing precondition
1050  if (!ilConditionHandler::_checkCondition($tcond)) {
1051  return (int) $node["child"];
1052  }
1053  }
1054  }
1055  }
1056  }
1057 
1058  return 0;
1059  }
1060 
1064  public static function hasSuccessorPage(
1065  int $a_cont_obj_id,
1066  int $a_page_id
1067  ): bool {
1068  $tree = new ilTree($a_cont_obj_id);
1069  $tree->setTableNames('lm_tree', 'lm_data');
1070  $tree->setTreeTablePK("lm_id");
1071  if ($tree->isInTree($a_page_id)) {
1072  $succ = $tree->fetchSuccessorNode($a_page_id, "pg");
1073  if ($succ > 0) {
1074  return true;
1075  }
1076  }
1077  return false;
1078  }
1079 
1083  public function checkTree(): void
1084  {
1085  $tree = new ilLMTree($this->getId());
1086  $tree->checkTree();
1088  }
1089 
1090  public function fixTree(): void
1091  {
1092  $ilDB = $this->db;
1093 
1094  $tree = $this->getLMTree();
1095 
1096  // check numbering, if errors, renumber
1097  // it is very important to keep this step before deleting subtrees
1098  // in the following steps
1099  $set = $ilDB->query(
1100  "SELECT DISTINCT l1.lm_id" .
1101  " FROM lm_tree l1" .
1102  " JOIN lm_tree l2 ON ( l1.child = l2.parent" .
1103  " AND l1.lm_id = l2.lm_id )" .
1104  " JOIN lm_data ON ( l1.child = lm_data.obj_id )" .
1105  " WHERE (l2.lft < l1.lft" .
1106  " OR l2.rgt > l1.rgt OR l2.lft > l1.rgt OR l2.rgt < l1.lft)" .
1107  " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer") .
1108  " ORDER BY lm_data.create_date DESC"
1109  );
1110  if ($rec = $ilDB->fetchAssoc($set)) {
1111  $tree->renumber();
1112  }
1113 
1114  // delete subtrees that have no lm_data records (changed due to #20637)
1115  $set = $ilDB->query("SELECT * FROM lm_tree WHERE lm_tree.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1116  while ($node = $ilDB->fetchAssoc($set)) {
1117  $q = "SELECT * FROM lm_data WHERE obj_id = " .
1118  $ilDB->quote($node["child"], "integer");
1119  $obj_set = $ilDB->query($q);
1120  $obj_rec = $ilDB->fetchAssoc($obj_set);
1121  if (!$obj_rec) {
1122  $node_data = $tree->getNodeData($node["child"]);
1123  $node_data["child"] = $node["child"];
1124  $tree->deleteTree($node_data);
1125  }
1126  }
1127 
1128  // delete subtrees that have pages as parent
1129  $nodes = $tree->getSubTree($tree->getNodeData($tree->getRootId()));
1130  foreach ($nodes as $node) {
1131  $q = "SELECT * FROM lm_data WHERE obj_id = " .
1132  $ilDB->quote($node["parent"], "integer");
1133  $obj_set = $ilDB->query($q);
1134  $obj_rec = $ilDB->fetchAssoc($obj_set);
1135  if (($obj_rec["type"] ?? "") == "pg") {
1136  $node_data = $tree->getNodeData($node["child"]);
1137  if ($tree->isInTree($node["child"])) {
1138  $tree->deleteTree($node_data);
1139  }
1140  }
1141  }
1142 
1143  // check for multi-references pages or chapters
1144  // if errors -> create copies of them here
1145  $set = $ilDB->query("SELECT DISTINCT l1.lm_id" .
1146  " FROM lm_tree l1" .
1147  " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1148  " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1149  " WHERE l1.child <> 1" .
1150  " AND l1.lm_id <> lm_data.lm_id" .
1151  " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1152  if ($rec = $ilDB->fetchAssoc($set)) {
1153  $set = $ilDB->query("SELECT DISTINCT l1.child " .
1154  " FROM lm_tree l1" .
1155  " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1156  " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1157  " WHERE l1.child <> 1" .
1158  " AND l1.lm_id <> lm_data.lm_id" .
1159  " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1160  while ($rec = $ilDB->fetchAssoc($set)) {
1161  $cobj = ilLMObjectFactory::getInstance($this->lm, $rec["child"]);
1162 
1163  if (is_object($cobj)) {
1164  if ($cobj->getType() == "pg") {
1165  // make a copy of it
1166  $pg_copy = $cobj->copy($this->lm);
1167 
1168  // replace the child in the tree with the copy (id)
1169  $ilDB->manipulate(
1170  "UPDATE lm_tree SET " .
1171  " child = " . $ilDB->quote($pg_copy->getId(), "integer") .
1172  " WHERE child = " . $ilDB->quote($cobj->getId(), "integer") .
1173  " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1174  );
1175  } elseif ($cobj->getType() == "st") {
1176  // make a copy of it
1177  $st_copy = $cobj->copy($this->lm);
1178 
1179  // replace the child in the tree with the copy (id)
1180  $ilDB->manipulate(
1181  "UPDATE lm_tree SET " .
1182  " child = " . $ilDB->quote($st_copy->getId(), "integer") .
1183  " WHERE child = " . $ilDB->quote($cobj->getId(), "integer") .
1184  " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1185  );
1186 
1187  // make all childs refer to the copy now
1188  $ilDB->manipulate(
1189  "UPDATE lm_tree SET " .
1190  " parent = " . $ilDB->quote($st_copy->getId(), "integer") .
1191  " WHERE parent = " . $ilDB->quote($cobj->getId(), "integer") .
1192  " AND lm_id = " . $ilDB->quote($this->getId(), "integer")
1193  );
1194  }
1195  }
1196  }
1197  }
1198 
1199  // missing copage entries
1200  $set = $ilDB->queryF(
1201  "SELECT * FROM lm_data " .
1202  " WHERE lm_id = %s AND type = %s",
1203  array("integer", "text"),
1204  array($this->getId(), "pg")
1205  );
1206  while ($rec = $ilDB->fetchAssoc($set)) {
1207  if (!ilPageObject::_exists("lm", $rec["obj_id"], "-")) {
1208  $lm_page = new ilLMPage();
1209  $lm_page->setId($rec["obj_id"]);
1210  $lm_page->setParentId($this->getId());
1211  $lm_page->create(false);
1212  }
1213  }
1214  }
1215 
1219  public function checkStructure(): array
1220  {
1221  $issues = [];
1222  $ilDB = $this->db;
1223 
1224  $tree = $this->getLMTree();
1225 
1226  // check numbering, if errors, renumber
1227  // it is very important to keep this step before deleting subtrees
1228  // in the following steps
1229  $set = $ilDB->query(
1230  "SELECT l1.child, l1.lft l1lft, l1.rgt l1rgt, l2.parent, l2.lft l2lft, l2.rgt l2rgt" .
1231  " FROM lm_tree l1" .
1232  " JOIN lm_tree l2 ON ( l1.child = l2.parent" .
1233  " AND l1.lm_id = l2.lm_id )" .
1234  " JOIN lm_data ON ( l1.child = lm_data.obj_id )" .
1235  " WHERE (l2.lft < l1.lft" .
1236  " OR l2.rgt > l1.rgt OR l2.lft > l1.rgt OR l2.rgt < l1.lft)" .
1237  " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer") .
1238  " ORDER BY lm_data.create_date DESC"
1239  );
1240  while ($rec = $ilDB->fetchAssoc($set)) {
1241  $issues[] = "Tree numbering: " . print_r($rec, true);
1242  }
1243 
1244  // delete subtrees that have no lm_data records (changed due to #20637)
1245  $set = $ilDB->query("SELECT * FROM lm_tree WHERE lm_tree.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1246  while ($node = $ilDB->fetchAssoc($set)) {
1247  $q = "SELECT * FROM lm_data WHERE obj_id = " .
1248  $ilDB->quote($node["child"], "integer");
1249  $obj_set = $ilDB->query($q);
1250  $obj_rec = $ilDB->fetchAssoc($obj_set);
1251  if (!$obj_rec) {
1252  $issues[] = "Tree entry without data entry: " . print_r($node, true);
1253  }
1254  }
1255 
1256  // delete subtrees that have pages as parent
1257  $nodes = $tree->getSubTree($tree->getNodeData($tree->getRootId()));
1258  foreach ($nodes as $node) {
1259  $q = "SELECT * FROM lm_data WHERE obj_id = " .
1260  $ilDB->quote($node["parent"], "integer");
1261  $obj_set = $ilDB->query($q);
1262  $obj_rec = $ilDB->fetchAssoc($obj_set);
1263  if (($obj_rec["type"] ?? "") == "pg") {
1264  $node_data = $tree->getNodeData($node["child"]);
1265  if ($tree->isInTree($node["child"])) {
1266  $issues[] = "Subtree with page parent: " . print_r($node_data, true);
1267  }
1268  }
1269  }
1270 
1271  // check for multi-references pages or chapters
1272  // if errors -> create copies of them here
1273  $set = $ilDB->query("SELECT DISTINCT l1.lm_id" .
1274  " FROM lm_tree l1" .
1275  " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1276  " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1277  " WHERE l1.child <> 1" .
1278  " AND l1.lm_id <> lm_data.lm_id" .
1279  " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1280  if ($rec = $ilDB->fetchAssoc($set)) {
1281  $set = $ilDB->query("SELECT DISTINCT l1.child " .
1282  " FROM lm_tree l1" .
1283  " JOIN lm_tree l2 ON ( l1.child = l2.child AND l1.lm_id <> l2.lm_id )" .
1284  " JOIN lm_data ON (l1.child = lm_data.obj_id)" .
1285  " WHERE l1.child <> 1" .
1286  " AND l1.lm_id <> lm_data.lm_id" .
1287  " AND l1.lm_id = " . $ilDB->quote($this->getId(), "integer"));
1288  while ($rec = $ilDB->fetchAssoc($set)) {
1289  $set3 = $ilDB->queryF(
1290  "SELECT * FROM lm_tree " .
1291  " WHERE child = %s ",
1292  array("integer"),
1293  array($rec["child"])
1294  );
1295  while ($rec3 = $ilDB->fetchAssoc($set3)) {
1296  $issues[] = "Multi-reference item: " . print_r($rec3, true);
1297  }
1298  }
1299  }
1300 
1301  // missing copage entries
1302  $set = $ilDB->queryF(
1303  "SELECT * FROM lm_data " .
1304  " WHERE lm_id = %s AND type = %s",
1305  array("integer", "text"),
1306  array($this->getId(), "pg")
1307  );
1308  while ($rec = $ilDB->fetchAssoc($set)) {
1309  if (!ilPageObject::_exists("lm", $rec["obj_id"], "-")) {
1310  $issues[] = "Missing COPage: " . print_r($rec, true);
1311  }
1312  }
1313 
1314 
1315  return $issues;
1316  }
1317 
1318  public function exportXML(
1319  ilXmlWriter $a_xml_writer,
1320  int $a_inst,
1321  string $a_target_dir,
1322  ilLog $expLog
1323  ): void {
1324  $attrs = array();
1325  switch ($this->getType()) {
1326  case "lm":
1327  $attrs["Type"] = "LearningModule";
1328  break;
1329  }
1330  $a_xml_writer->xmlStartTag("ContentObject", $attrs);
1331 
1332  // MetaData
1333  $this->exportXMLMetaData($a_xml_writer);
1334 
1335  // StructureObjects
1336  //echo "ContObj:".$a_inst.":<br>";
1337  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Structure Objects");
1338  $this->exportXMLStructureObjects($a_xml_writer, $a_inst, $expLog);
1339  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Structure Objects");
1340 
1341  // PageObjects
1342  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Page Objects");
1343  $this->exportXMLPageObjects($a_xml_writer, $a_inst, $expLog);
1344  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Page Objects");
1345 
1346  // MediaObjects
1347  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Media Objects");
1348  $this->exportXMLMediaObjects($a_xml_writer, $a_inst, $a_target_dir, $expLog);
1349  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Media Objects");
1350 
1351  // FileItems
1352  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export File Items");
1353  $this->exportFileItems($a_target_dir, $expLog);
1354  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export File Items");
1355 
1356  // Questions
1357  if (count($this->q_ids) > 0) {
1358  $qti_file = fopen($a_target_dir . "/qti.xml", "w");
1359  $pool = new ilObjQuestionPool();
1360  fwrite($qti_file, $pool->questionsToXML($this->q_ids));
1361  fclose($qti_file);
1362  }
1363 
1364  // To do: implement version selection/detection
1365  // Properties
1366  $expLog->write(date("[y-m-d H:i:s] ") . "Start Export Properties");
1367  $this->exportXMLProperties($a_xml_writer, $expLog);
1368  $expLog->write(date("[y-m-d H:i:s] ") . "Finished Export Properties");
1369 
1370  $a_xml_writer->xmlEndTag("ContentObject");
1371  }
1372 
1373  public function exportXMLMetaData(
1374  ilXmlWriter $a_xml_writer
1375  ): void {
1376  /*
1377  * As far as I can tell, this is unused.
1378  *
1379  * I traced usages of this method up to ilObjContentObjectGUI::export and
1380  * ilObjMediaPoolGUI::export (both via ilObjContentObject::exportXML), which have
1381  * both been made redundant by the usual export mechanisms.
1382  */
1383  /*$md2xml = new ilMD2XML($this->getId(), 0, $this->getType());
1384  $md2xml->setExportMode(true);
1385  $md2xml->startExport();
1386  $a_xml_writer->appendXML($md2xml->getXML());*/
1387  }
1388 
1389  public function exportXMLStructureObjects(
1390  ilXmlWriter $a_xml_writer,
1391  int $a_inst,
1392  ilLog $expLog
1393  ): void {
1394  $childs = $this->lm_tree->getChilds($this->lm_tree->getRootId());
1395  foreach ($childs as $child) {
1396  if ($child["type"] != "st") {
1397  continue;
1398  }
1399 
1400  $structure_obj = new ilStructureObject($this->lm, $child["obj_id"]);
1401  $structure_obj->exportXML($a_xml_writer, $a_inst, $expLog);
1402  unset($structure_obj);
1403  }
1404  }
1405 
1406  public function exportXMLPageObjects(
1407  ilXmlWriter $a_xml_writer,
1408  int $a_inst,
1409  ilLog $expLog
1410  ): void {
1411  $pages = ilLMPageObject::getPageList($this->getId());
1412  foreach ($pages as $page) {
1413  if (ilLMPage::_exists($this->getType(), $page["obj_id"])) {
1414  $expLog->write(date("[y-m-d H:i:s] ") . "Page Object " . $page["obj_id"]);
1415 
1416  // export xml to writer object
1417  $page_obj = new ilLMPageObject($this->lm, $page["obj_id"]);
1418  $page_obj->exportXML($a_xml_writer, "normal", $a_inst);
1419 
1420  // collect media objects
1421  $mob_ids = $page_obj->getMediaObjectIds();
1422  foreach ($mob_ids as $mob_id) {
1423  $this->mob_ids[$mob_id] = $mob_id;
1424  }
1425 
1426  // collect all file items
1427  $file_ids = $page_obj->getFileItemIds();
1428  foreach ($file_ids as $file_id) {
1429  $this->file_ids[$file_id] = $file_id;
1430  }
1431 
1432  // collect all questions
1433  $q_ids = $page_obj->getQuestionIds();
1434  foreach ($q_ids as $q_id) {
1435  $this->q_ids[$q_id] = $q_id;
1436  }
1437 
1438  unset($page_obj);
1439  }
1440  }
1441  }
1442 
1443  public function exportXMLMediaObjects(
1444  ilXmlWriter $a_xml_writer,
1445  int $a_inst,
1446  string $a_target_dir,
1447  ilLog $expLog
1448  ): void {
1449  $linked_mobs = array();
1450 
1451  // mobs directly embedded into pages
1452  foreach ($this->mob_ids as $mob_id) {
1453  if ($mob_id > 0 && ilObject::_lookupType($mob_id) == "mob") {
1454  $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
1455  $media_obj = new ilObjMediaObject($mob_id);
1456  $media_obj->exportXML($a_xml_writer, $a_inst);
1457  $media_obj->exportFiles($a_target_dir);
1458 
1459  $lmobs = $media_obj->getLinkedMediaObjects($this->mob_ids);
1460  $linked_mobs = array_merge($linked_mobs, $lmobs);
1461 
1462  unset($media_obj);
1463  }
1464  }
1465 
1466  // linked mobs (in map areas)
1467  foreach ($linked_mobs as $mob_id) {
1468  if ($mob_id > 0) {
1469  $expLog->write(date("[y-m-d H:i:s] ") . "Media Object " . $mob_id);
1470  $media_obj = new ilObjMediaObject($mob_id);
1471  $media_obj->exportXML($a_xml_writer, $a_inst);
1472  $media_obj->exportFiles($a_target_dir);
1473  unset($media_obj);
1474  }
1475  }
1476  }
1477 
1478  public function exportFileItems(
1479  string $a_target_dir,
1480  ilLog $expLog
1481  ): void {
1482  foreach ($this->file_ids as $file_id) {
1483  $expLog->write(date("[y-m-d H:i:s] ") . "File Item " . $file_id);
1484  $file_obj = new ilObjFile($file_id, false);
1485  $file_obj->export($a_target_dir);
1486  unset($file_obj);
1487  }
1488  }
1489 
1490  public function exportXMLProperties(
1491  ilXmlWriter $a_xml_writer,
1492  ilLog $expLog
1493  ): void {
1494  $attrs = array();
1495  $a_xml_writer->xmlStartTag("Properties", $attrs);
1496 
1497  // Layout
1498  $attrs = array("Name" => "Layout", "Value" => $this->getLayout());
1499  $a_xml_writer->xmlElement("Property", $attrs);
1500 
1501  // Page Header
1502  $attrs = array("Name" => "PageHeader", "Value" => $this->getPageHeader());
1503  $a_xml_writer->xmlElement("Property", $attrs);
1504 
1505  // TOC Mode
1506  $attrs = array("Name" => "TOCMode", "Value" => $this->getTOCMode());
1507  $a_xml_writer->xmlElement("Property", $attrs);
1508 
1509  // LM Menu Activation
1510  $attrs = array("Name" => "ActiveLMMenu", "Value" =>
1511  ilUtil::tf2yn($this->isActiveLMMenu()));
1512  $a_xml_writer->xmlElement("Property", $attrs);
1513 
1514  // Numbering Activation
1515  $attrs = array("Name" => "ActiveNumbering", "Value" =>
1516  ilUtil::tf2yn($this->isActiveNumbering()));
1517  $a_xml_writer->xmlElement("Property", $attrs);
1518 
1519  // Table of contents button activation
1520  $attrs = array("Name" => "ActiveTOC", "Value" =>
1521  ilUtil::tf2yn($this->isActiveTOC()));
1522  $a_xml_writer->xmlElement("Property", $attrs);
1523 
1524  // Print view button activation
1525  $attrs = array("Name" => "ActivePrintView", "Value" =>
1526  ilUtil::tf2yn($this->isActivePrintView()));
1527  $a_xml_writer->xmlElement("Property", $attrs);
1528 
1529  // Note that download button is not saved, because
1530  // download files do not exist after import
1531 
1532  // Clean frames
1533  $attrs = array("Name" => "CleanFrames", "Value" =>
1534  ilUtil::tf2yn($this->cleanFrames()));
1535  $a_xml_writer->xmlElement("Property", $attrs);
1536 
1537  // Public notes activation
1538  $attrs = array("Name" => "PublicNotes", "Value" =>
1539  ilUtil::tf2yn($this->publicNotes()));
1540  $a_xml_writer->xmlElement("Property", $attrs);
1541 
1542  // Rating
1543  $attrs = array("Name" => "Rating", "Value" =>
1544  ilUtil::tf2yn($this->hasRating()));
1545  $a_xml_writer->xmlElement("Property", $attrs);
1546  $attrs = array("Name" => "RatingPages", "Value" =>
1547  ilUtil::tf2yn($this->hasRatingPages()));
1548  $a_xml_writer->xmlElement("Property", $attrs);
1549 
1550  // Header Page
1551  if ($this->getHeaderPage() > 0) {
1552  $attrs = array("Name" => "HeaderPage", "Value" =>
1553  "il_" . IL_INST_ID . "_pg_" . $this->getHeaderPage());
1554  $a_xml_writer->xmlElement("Property", $attrs);
1555  }
1556 
1557  // Footer Page
1558  if ($this->getFooterPage() > 0) {
1559  $attrs = array("Name" => "FooterPage", "Value" =>
1560  "il_" . IL_INST_ID . "_pg_" . $this->getFooterPage());
1561  $a_xml_writer->xmlElement("Property", $attrs);
1562  }
1563 
1564  // layout per page
1565  $attrs = array("Name" => "LayoutPerPage", "Value" =>
1566  $this->getLayoutPerPage());
1567  $a_xml_writer->xmlElement("Property", $attrs);
1568 
1569  // progress icons
1570  $attrs = array("Name" => "ProgressIcons", "Value" =>
1571  $this->getProgressIcons());
1572  $a_xml_writer->xmlElement("Property", $attrs);
1573 
1574  // store tries
1575  $attrs = array("Name" => "StoreTries", "Value" =>
1576  $this->getStoreTries());
1577  $a_xml_writer->xmlElement("Property", $attrs);
1578 
1579  // restrict forward navigation
1580  $attrs = array("Name" => "RestrictForwardNavigation", "Value" =>
1581  $this->getRestrictForwardNavigation());
1582  $a_xml_writer->xmlElement("Property", $attrs);
1583 
1584  // disable default feedback
1585  $attrs = array("Name" => "DisableDefaultFeedback", "Value" =>
1586  $this->getDisableDefaultFeedback());
1587  $a_xml_writer->xmlElement("Property", $attrs);
1588 
1589  $a_xml_writer->xmlEndTag("Properties");
1590  }
1591 
1592  public function getExportFiles(): array
1593  {
1594  $file = array();
1595 
1596  $types = array("xml", "html");
1597 
1598  foreach ($types as $type) {
1599  $dir = $this->getExportDirectory($type);
1600  // quit if import dir not available
1601  if (!is_dir($dir) or
1602  !is_writeable($dir)) {
1603  continue;
1604  }
1605 
1606  // open directory
1607  $cdir = dir($dir);
1608 
1609  // initialize array
1610 
1611  // get files and save the in the array
1612  while ($entry = $cdir->read()) {
1613  if ($entry != "." and
1614  $entry != ".." and
1615  substr($entry, -4) == ".zip" and
1616  preg_match("~^[0-9]{10}_{2}[0-9]+_{2}(lm_)*[0-9]+\.zip\$~", $entry)) {
1617  $file[$entry . $type] = array("type" => $type, "file" => $entry,
1618  "size" => filesize($dir . "/" . $entry));
1619  }
1620  }
1621 
1622  // close import directory
1623  $cdir->close();
1624  }
1625 
1626  // sort files
1627  ksort($file);
1628  return $file;
1629  }
1630 
1631  public function executeDragDrop(
1632  int $source_id,
1633  int $target_id,
1634  bool $first_child,
1635  bool $as_subitem = false,
1636  string $movecopy = "move"
1637  ): void {
1638  if ($source_id === $target_id) {
1639  return;
1640  }
1641  $lmtree = new ilTree($this->getId());
1642  $lmtree->setTableNames('lm_tree', 'lm_data');
1643  $lmtree->setTreeTablePK("lm_id");
1644  //echo "-".$source_id."-".$target_id."-".$first_child."-".$as_subitem."-";
1645  $source_obj = ilLMObjectFactory::getInstance($this->lm, $source_id, true);
1646  $source_obj->setLMId($this->getId());
1647 
1648  if (!$first_child) {
1649  $target_obj = ilLMObjectFactory::getInstance($this->lm, $target_id, true);
1650  $target_obj->setLMId($this->getId());
1651  $target_parent = $lmtree->getParentId($target_id);
1652  }
1653 
1654  // handle pages
1655  if ($source_obj->getType() == "pg") {
1656  //echo "1";
1657  if ($lmtree->isInTree($source_obj->getId())) {
1658  $node_data = $lmtree->getNodeData($source_obj->getId());
1659 
1660  // cut on move
1661  if ($movecopy == "move") {
1662  $parent_id = $lmtree->getParentId($source_obj->getId());
1663  $lmtree->deleteTree($node_data);
1664 
1665  } else {
1666  // copy page
1667  $new_page = $source_obj->copy($this->lm);
1668  $source_id = $new_page->getId();
1669  $source_obj = $new_page;
1670  }
1671 
1672  // paste page
1673  if (!$lmtree->isInTree($source_obj->getId())) {
1674  if ($first_child) { // as first child
1675  $target_pos = ilTree::POS_FIRST_NODE;
1676  $parent = $target_id;
1677  } elseif ($as_subitem) { // as last child
1678  $parent = $target_id;
1679  $target_pos = ilTree::POS_FIRST_NODE;
1680  $pg_childs = $lmtree->getChildsByType($parent, "pg");
1681  if (count($pg_childs) != 0) {
1682  $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
1683  }
1684  } else { // at position
1685  $target_pos = $target_id;
1686  $parent = $target_parent;
1687  }
1688 
1689  // insert page into tree
1690  $lmtree->insertNode(
1691  $source_obj->getId(),
1692  $parent,
1693  $target_pos
1694  );
1695 
1696  }
1697  }
1698  }
1699 
1700  // handle chapters
1701  if ($source_obj->getType() == "st") {
1702  //echo "2";
1703  $source_node = $lmtree->getNodeData($source_id);
1704  $subnodes = $lmtree->getSubTree($source_node);
1705 
1706  // check, if target is within subtree
1707  foreach ($subnodes as $subnode) {
1708  if ($subnode["obj_id"] == $target_id) {
1709  return;
1710  }
1711  }
1712 
1713  $target_pos = $target_id;
1714 
1715  if ($first_child) { // as first subchapter
1716  $target_pos = ilTree::POS_FIRST_NODE;
1717  $target_parent = $target_id;
1718 
1719  $pg_childs = $lmtree->getChildsByType($target_parent, "pg");
1720  if (count($pg_childs) != 0) {
1721  $target_pos = $pg_childs[count($pg_childs) - 1]["obj_id"];
1722  }
1723  } elseif ($as_subitem) { // as last subchapter
1724  $target_parent = $target_id;
1725  $target_pos = ilTree::POS_FIRST_NODE;
1726  $childs = $lmtree->getChilds($target_parent);
1727  if (count($childs) != 0) {
1728  $target_pos = $childs[count($childs) - 1]["obj_id"];
1729  }
1730  }
1731 
1732  // delete source tree
1733  if ($movecopy == "move") {
1734  $lmtree->deleteTree($source_node);
1735  } else {
1736  // copy chapter (incl. subcontents)
1737  throw new ilException("ilObjContentObject: Not implemented");
1738  //$new_chapter = $source_obj->copy($lmtree, $target_parent, $target_pos);
1739  }
1740 
1741  if (!$lmtree->isInTree($source_id)) {
1742  $lmtree->insertNode($source_id, $target_parent, $target_pos);
1743 
1744  // insert moved tree
1745  foreach ($subnodes as $node) {
1746  if ($node["obj_id"] != $source_id) {
1747  $lmtree->insertNode($node["obj_id"], $node["parent"]);
1748  }
1749  }
1750  }
1751 
1752  // check the tree
1753  $this->checkTree();
1754  }
1755 
1756  $this->checkTree();
1757  }
1758 
1762  public function validatePages(): string
1763  {
1764  $mess = "";
1765 
1766  $pages = ilLMPageObject::getPageList($this->getId());
1767  foreach ($pages as $page) {
1768  if (ilLMPage::_exists($this->getType(), $page["obj_id"])) {
1769  $cpage = new ilLMPage($page["obj_id"]);
1770  $cpage->buildDom();
1771  $error = $cpage->validateDom();
1772 
1773  if ($error != "") {
1774  $this->lng->loadLanguageModule("content");
1775  $this->main_tpl->setOnScreenMessage('info', $this->lng->txt("cont_import_validation_errors"));
1776  $title = ilLMObject::_lookupTitle($page["obj_id"]);
1777  $page_obj = new ilLMPageObject($this->lm, $page["obj_id"]);
1778  $mess .= $this->lng->txt("obj_pg") . ": " . $title;
1779  $mess .= '<div class="small">';
1780  foreach ($error as $e) {
1781  $err_mess = implode(" - ", $e);
1782  if (!is_int(strpos($err_mess, ":0:"))) {
1783  $mess .= htmlentities($err_mess) . "<br />";
1784  }
1785  }
1786  $mess .= '</div>';
1787  $mess .= "<br />";
1788  }
1789  }
1790  }
1791 
1792  return $mess;
1793  }
1794 
1795  public function cloneObject(int $target_id, int $copy_id = 0, bool $omit_tree = false): ?ilObject
1796  {
1798  $new_obj = parent::cloneObject($target_id, $copy_id, $omit_tree);
1799  $this->cloneMetaData($new_obj);
1800  //$new_obj->createProperties();
1801 
1802  //copy online status if object is not the root copy object
1803  $cp_options = ilCopyWizardOptions::_getInstance($copy_id);
1804 
1805  if (!$cp_options->isRootNode($this->getRefId())) {
1806  $new_obj->setOfflineStatus($this->getOfflineStatus());
1807  }
1808 
1809  // $new_obj->setTitle($this->getTitle());
1810  $new_obj->setDescription($this->getDescription());
1811  $new_obj->setLayoutPerPage($this->getLayoutPerPage());
1812  $new_obj->setLayout($this->getLayout());
1813  $new_obj->setTOCMode($this->getTOCMode());
1814  $new_obj->setActiveLMMenu($this->isActiveLMMenu());
1815  $new_obj->setActiveTOC($this->isActiveTOC());
1816  $new_obj->setActiveNumbering($this->isActiveNumbering());
1817  $new_obj->setActivePrintView($this->isActivePrintView());
1818  $new_obj->setActivePreventGlossaryAppendix($this->isActivePreventGlossaryAppendix());
1819  $new_obj->setPublicNotes($this->publicNotes());
1820  $new_obj->setCleanFrames($this->cleanFrames());
1821  $new_obj->setPageHeader($this->getPageHeader());
1822  $new_obj->setRating($this->hasRating());
1823  $new_obj->setRatingPages($this->hasRatingPages());
1824  $new_obj->setDisableDefaultFeedback($this->getDisableDefaultFeedback());
1825  $new_obj->setProgressIcons($this->getProgressIcons());
1826  $new_obj->setStoreTries($this->getStoreTries());
1827  $new_obj->setRestrictForwardNavigation($this->getRestrictForwardNavigation());
1828  $new_obj->setAutoGlossaries($this->getAutoGlossaries());
1829 
1830  $new_obj->update();
1831 
1832  $new_obj->createLMTree();
1833 
1834  // copy style
1835  $style = $this->content_style_domain->styleForObjId($this->getId());
1836  $style->cloneTo($new_obj->getId());
1837 
1838  $new_obj->update();
1839 
1840  // copy content
1841  $copied_nodes = $this->copyAllPagesAndChapters($new_obj, $copy_id);
1842 
1843  // page header and footer
1844  if ($this->getHeaderPage() > 0 && ($new_page_header = ($copied_nodes[$this->getHeaderPage()] ?? null)) > 0) {
1845  $new_obj->setHeaderPage($new_page_header);
1846  }
1847  if ($this->getFooterPage() > 0 && ($new_page_footer = ($copied_nodes[$this->getFooterPage()] ?? null)) > 0) {
1848  $new_obj->setFooterPage($new_page_footer);
1849  }
1850  $new_obj->update();
1851 
1852  // Copy learning progress settings
1853  $obj_settings = new ilLPObjSettings($this->getId());
1854  $obj_settings->cloneSettings($new_obj->getId());
1855  unset($obj_settings);
1856 
1857  // copy (page) multilang settings
1858  $this->getObjectProperties()->clonePropertyTranslations($new_obj->getId());
1859 
1860  // copy lm menu
1861  $menu = new ilLMMenuEditor();
1862  $menu->setObjId($this->getId());
1863  $new_menu = new ilLMMenuEditor();
1864  $new_menu->setObjId($new_obj->getId());
1865  foreach ($menu->getMenuEntries() as $entry) {
1866  /*'id' => $row->id,
1867  'title' => $row->title,
1868  'link' => $row->target,
1869  'type' => $row->link_type,
1870  'ref_id' => $row->link_ref_id,
1871  'active'*/
1872 
1873  $new_menu->setTarget($entry["link"] ?? "");
1874  $new_menu->setTitle($entry["title"] ?? "");
1875  $new_menu->setLinkType($entry["type"] ?? "");
1876  $new_menu->setLinkRefId($entry["ref_id"] ?? 0);
1877  $new_menu->create();
1878  ilLMMenuEditor::writeActive($new_menu->getEntryId(), $entry["active"] == "y");
1879  }
1880 
1881 
1882  return $new_obj;
1883  }
1884 
1885  public function copyAllPagesAndChapters(
1886  ilObjLearningModule $a_target_obj,
1887  int $a_copy_id = 0
1888  ): array {
1889  $parent_id = $a_target_obj->lm_tree->readRootId();
1890  $time = null;
1891 
1892  // get all chapters of root lm
1893  $chapters = $this->lm_tree->getChildsByType($this->lm_tree->readRootId(), "st");
1894  $copied_nodes = array();
1895  //$time = time();
1896  foreach ($chapters as $chap) {
1897  $cid = ilLMObject::pasteTree(
1898  $a_target_obj,
1899  $chap["child"],
1900  $parent_id,
1902  (string) $time,
1903  $copied_nodes,
1904  true,
1905  $this->lm
1906  );
1907  $target = $cid;
1908  }
1909 
1910  // copy free pages
1911  $pages = ilLMPageObject::getPageList($this->getId());
1912  foreach ($pages as $p) {
1913  if (!$this->lm_tree->isInTree($p["obj_id"])) {
1914  $item = new ilLMPageObject($this->lm, $p["obj_id"]);
1915  $target_item = $item->copy($a_target_obj);
1916  $copied_nodes[$item->getId()] = $target_item->getId();
1917  }
1918  }
1919 
1920  // Add mapping for pages and chapters
1921  $options = ilCopyWizardOptions::_getInstance($a_copy_id);
1922  foreach ($copied_nodes as $old_id => $new_id) {
1923  $options->appendMapping(
1924  $this->getRefId() . '_' . $old_id,
1925  $a_target_obj->getRefId() . '_' . $new_id
1926  );
1927  }
1928 
1929  ilLMObject::updateInternalLinks($copied_nodes);
1930 
1931  $a_target_obj->checkTree();
1932 
1933  return $copied_nodes;
1934  }
1935 
1936  public static function lookupAutoGlossaries(
1937  int $a_lm_id
1938  ): array {
1939  global $DIC;
1940 
1941  $ilDB = $DIC->database();
1942 
1943  // read auto glossaries
1944  $set = $ilDB->query(
1945  "SELECT * FROM lm_glossaries " .
1946  " WHERE lm_id = " . $ilDB->quote($a_lm_id, "integer")
1947  );
1948  $glos = array();
1949  while ($rec = $ilDB->fetchAssoc($set)) {
1950  $glos[] = $rec["glo_id"];
1951  }
1952  return $glos;
1953  }
1954 
1955  public function autoLinkGlossaryTerms(
1956  int $a_glo_ref_id
1957  ): void {
1958  // get terms
1959  $terms = ilGlossaryTerm::getTermList([$a_glo_ref_id]);
1960 
1961  // each get page: get content
1962  $pages = ilLMPage::getAllPages($this->getType(), $this->getId());
1963 
1964  // determine terms that occur in the page
1965  $found_pages = array();
1966  foreach ($pages as $p) {
1967  $pg = new ilLMPage($p["id"]);
1968  $c = $pg->getXMLContent();
1969  foreach ($terms as $t) {
1970  if (is_int(stripos($c, $t["term"]))) {
1971  $found_pages[$p["id"]]["terms"][] = $t;
1972  if (!is_object($found_pages[$p["id"]]["page"] ?? null)) {
1973  $found_pages[$p["id"]]["page"] = $pg;
1974  }
1975  }
1976  }
1977  reset($terms);
1978  }
1979 
1980  // ilPCParagraph autoLinkGlossariesPage with page and terms
1981  foreach ($found_pages as $id => $fp) {
1982  ilPCParagraph::autoLinkGlossariesPage($fp["page"], $fp["terms"]);
1983  }
1984  }
1985 
1986 
1990 
1995  public static function isOnlineHelpModule(
1996  int $a_id,
1997  bool $a_as_obj_id = false
1998  ): bool {
1999  if (!$a_as_obj_id && $a_id > 0 && $a_id === (int) OH_REF_ID) {
2000  return true;
2001  }
2002  if ($a_as_obj_id && $a_id > 0 && $a_id === ilObject::_lookupObjId((int) OH_REF_ID)) {
2003  return true;
2004  }
2005  return false;
2006  }
2007 
2008  public function setRating(bool $a_value): void
2009  {
2010  $this->rating = $a_value;
2011  }
2012 
2013  public function hasRating(): bool
2014  {
2015  return $this->rating;
2016  }
2017 
2018  public function setRatingPages(bool $a_value): void
2019  {
2020  $this->rating_pages = $a_value;
2021  }
2022 
2023  public function hasRatingPages(): bool
2024  {
2025  return $this->rating_pages;
2026  }
2027 
2028 
2029  protected function doMDUpdateListener(
2030  string $a_element
2031  ): void {
2032  switch ($a_element) {
2033  case 'Educational':
2034  $obj_lp = ilObjectLP::getInstance($this->getId());
2035  if (in_array(
2036  $obj_lp->getCurrentMode(),
2038  )) {
2040  }
2041  break;
2042 
2043  case 'General':
2044  // Update Title and description
2045  $ot = $this->getObjectProperties()->getPropertyTranslations();
2046  if (!$ot->getContentTranslationActivated()) {
2047  return;
2048  }
2049 
2050  $paths = $this->lom_services->paths();
2051  $reader = $this->lom_services->read(
2052  $this->getId(),
2053  0,
2054  $this->getType(),
2055  $paths->custom()->withNextStep('general')->get()
2056  );
2057 
2058  $this->getObjectProperties()->storePropertyTranslations(
2059  $ot->withDefaultTitle($reader->firstData($paths->title())->value())
2060  ->withDefaultDescription($reader->firstData($paths->firstDescription())->value())
2061  );
2062  break;
2063  }
2064  }
2065 
2066  public function isInfoEnabled(): bool
2067  {
2069  }
2070 }
static updateInternalLinks(array $a_copied_nodes, string $a_parent_type="lm")
Update internal links, after multiple pages have been copied.
string $title
setActiveLMMenu(bool $a_act_lm_menu)
static _getNrOfAssignedLMs(int $a_style_id)
gets the number of learning modules assigned to a content style
executeDragDrop(int $source_id, int $target_id, bool $first_child, bool $as_subitem=false, string $movecopy="move")
static _getMissingPreconditionsOfPage(int $cont_ref_id, int $cont_obj_id, int $page_id)
gets all missing preconditions of page
$res
Definition: ltiservices.php:66
string $type
fetchSuccessorNode(int $a_node_id, string $a_type="")
get node data of successor node
static _getNrLMsNoStyle()
get number of learning modules assigned no style
getNodeData(int $a_node_id, ?int $a_tree_pk=null)
get all information of a node.
static _lookupDisableDefaultFeedback(int $a_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
insert(string $table_name, array $values)
const IL_INST_ID
Definition: constants.php:40
static getLogger(string $a_component_id)
Get component logger.
static writeFooterPage(int $a_lm_id, int $a_page_id)
checkStructure()
Check tree (this has been copied from fixTree due to a bug fixing, should be reorganised) ...
txt(string $a_topic, string $a_default_lang_fallback_mod="")
gets the text for a given topic if the topic is not in the list, the topic itself with "-" will be re...
exportXMLMediaObjects(ilXmlWriter $a_xml_writer, int $a_inst, string $a_target_dir, ilLog $expLog)
validatePages()
Validate all pages.
static writeActive(int $entry_id, bool $active)
static autoLinkGlossariesPage(ilPageObject $a_page, array $a_terms)
Auto link glossary of whole page.
checkTreeChilds(bool $a_no_zero_child=true)
check, if all childs of tree nodes exist in object table
static _lookupRestrictForwardNavigation(int $a_obj_id)
static _deleteAllObjectData(ilObjLearningModule $a_cobj)
delete all objects of content object (digi book / learning module)
static getInstance(ilObjLearningModule $a_content_obj, int $a_id=0, bool $a_halt=true)
ilTree $tree
isInTree(?int $a_node_id)
get all information of a node.
static getAvailableLayouts()
get all available lm layouts
static _lookupContObjIdByStyleId(int $a_style_id)
static _lookupStoreTries(int $a_id)
createExportDirectory(string $a_type="xml")
creates data directory for export files (data_dir/lm_data/lm_<id>/export, depending on data directory...
setTreeTablePK(string $a_column_name)
set column containing primary key in tree table
static writeHeaderPage(int $a_lm_id, int $a_page_id)
deleteTree(array $a_node)
delete node and the whole subtree under this node
setImportDirectory(string $a_import_dir)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: class.ilLog.php:30
static tf2yn(bool $a_tf)
exportXMLMetaData(ilXmlWriter $a_xml_writer)
$c
Definition: deliver.php:25
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static hasSuccessorPage(int $a_cont_obj_id, int $a_page_id)
checks if page has a successor page
setPageHeader(string $a_pg_header=ilLMObject::CHAPTER_TITLE)
set page header mode
setForTranslation(bool $a_val)
Set for translation (lm has been imported for translation purposes)
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...
static putInTree(ilLMObject $a_obj, int $a_parent_id=0, int $a_target_node_id=0)
put this object into content object tree
$ilErr
Definition: raiseError.php:33
$path
Definition: ltiservices.php:29
static getTermList(array $a_glo_ref_id, string $searchterm="", string $a_first_letter="", string $a_def="", int $a_tax_node=0, bool $a_add_amet_fields=false, ?array $a_amet_filter=null, bool $a_include_references=false)
Get all terms for given set of glossary ids.
ilGlobalTemplateInterface $main_tpl
static _lookupObjId(int $ref_id)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
xmlEndTag(string $tag)
Writes an endtag.
setRestrictForwardNavigation(bool $a_val)
static _lookupTitle(int $a_obj_id)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
create(bool $a_no_meta_data=false)
create content object
const POS_FIRST_NODE
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 &#39;obj_id&#39; You may use...
cloneMetaData(ilObject $target_obj)
Copy meta data.
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...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getPageHeader()
get page header mode (ilLMOBject::CHAPTER_TITLE | ilLMOBject::PAGE_TITLE | ilLMOBject::NO_HEADER) ...
doMDUpdateListener(string $a_element)
static _checkPreconditionsOfPage(int $cont_ref_id, int $cont_obj_id, int $page_id)
checks whether the preconditions of a page are fulfilled or not
getExportDirectory(string $a_type="xml")
static _exists(string $a_parent_type, int $a_id, string $a_lang="", bool $a_no_cache=false)
Checks whether page exists.
setTOCMode(string $a_toc_mode="chapters")
set toc mode
checkTree()
check consistence of tree all left & right values are checked if they are exists only once ...
static _lookupStyleSheetId(int $a_cont_obj_id)
ilLanguage $lng
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
ilDBInterface $db
getTOCMode()
get toc mode ("chapters" | "pages")
renumber(int $node_id=1, int $i=1)
Wrapper for renumber.
Class ilObjFile.
static _moveLMStyles(int $a_from_style, int $a_to_style)
move learning modules from one style to another
global $DIC
Definition: shib_login.php:26
static _refreshStatus(int $a_obj_id, ?array $a_users=null)
exportFileItems(string $a_target_dir, ilLog $expLog)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getDataDir()
get data directory (outside webspace)
static _deleteStyleAssignments(int $a_style_id)
delete all style references to style
setPublicNotes(bool $a_pub_notes)
setActivePreventGlossaryAppendix(bool $a_print)
createImportDirectory()
creates data directory for import files (data_dir/lm_data/lm_<id>/import, depending on data directory...
static lookupAutoGlossaries(int $a_lm_id)
static getInstanceByObjId(?int $obj_id, bool $stop_on_error=true)
get an instance of an Ilias object by object id
const POS_LAST_NODE
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$lm_set
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
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ILIAS Style Content DomainService $content_style_domain
static getPageList(int $lm_id)
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
__construct(Container $dic, ilPlugin $plugin)
ilErrorHandling $error
autoLinkGlossaryTerms(int $a_glo_ref_id)
static _getNrLMsIndividualStyles()
get number of learning modules with individual styles
exportXMLStructureObjects(ilXmlWriter $a_xml_writer, int $a_inst, ilLog $expLog)
$q
Definition: shib_logout.php:23
setDisableDefaultFeedback(bool $a_val)
Set disable default feedback for questions.
xmlStartTag(string $tag, ?array $attrs=null, bool $empty=false, bool $encode=true, bool $escape=true)
Writes a starttag.
copyAllPagesAndChapters(ilObjLearningModule $a_target_obj, int $a_copy_id=0)
static yn2tf(string $a_yn)
static _getInstance(int $a_copy_id)
xmlElement(string $tag, $attrs=null, $data=null, $encode=true, $escape=true)
Writes a basic element (no children, just textual content)
write(string $a_msg, $a_log_level=null)
logging
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
exportXML(ilXmlWriter $a_xml_writer, int $a_inst, string $a_target_dir, ilLog $expLog)
getSubTree(array $a_node, bool $a_with_data=true, array $a_type=[])
get all nodes in the subtree under specified node
static _lookupType(int $id, bool $reference=false)
setHideHeaderFooterPrint(bool $a_val)
Set hide header footer in print mode.
exportXMLProperties(ilXmlWriter $a_xml_writer, ilLog $expLog)
static getInstance(int $obj_id)
createProperties()
create new properties record
static _lookup(int $a_obj_id, string $a_field)
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
ILIAS Notes Service $notes
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
exportXMLPageObjects(ilXmlWriter $a_xml_writer, int $a_inst, ilLog $expLog)
static _getPersistedConditionsOfTarget(int $a_target_ref_id, int $a_target_obj_id, string $a_target_type="")
get all persisted conditions of target object
static isOnlineHelpModule(int $a_id, bool $a_as_obj_id=false)
Is module an online module.
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static getAllPages(string $a_parent_type, int $a_parent_id, string $a_lang="-")
Get all pages for parent object.