ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilLMObject.php
Go to the documentation of this file.
1<?php
2
24
33{
34 public const CHAPTER_TITLE = "st_title";
35 public const PAGE_TITLE = "pg_title";
36 public const NO_HEADER = "none";
37 protected string $layout = "";
38 protected string $import_id = "";
39
40 protected ilObjUser $user;
41 public int $lm_id = 0;
42 public string $type = "";
43 public int $id = 0;
44 public ?array $data_record; // assoc array of lm_data record
46 public string $title = "";
47 public string $short_title = "";
48 public string $description = "";
49 public bool $active = true;
50 protected static $data_records = array();
51 protected ilDBInterface $db;
52 protected LOMServices $lom_services;
53
54 public function __construct(
55 ilObjLearningModule $a_content_obj,
56 int $a_id = 0
57 ) {
58 global $DIC;
59 $this->user = $DIC->user();
60
61 $this->db = $DIC->database();
62 $this->lom_services = $DIC->learningObjectMetadata();
63
64 $this->id = $a_id;
65 $this->setContentObject($a_content_obj);
66 $this->setLMId($a_content_obj->getId());
67 if ($a_id != 0) {
68 $this->read();
69 }
70 }
71
81 public function MDUpdateListener(string $a_element): void
82 {
83 switch ($a_element) {
84 case 'General':
85
86 // Update Title and description
87 $paths = $this->lom_services->paths();
88 $reader = $this->lom_services->read(
89 $this->getLMId(),
90 $this->getId(),
91 $this->getType(),
92 $paths->custom()->withNextStep('general')->get()
93 );
94 $title = $reader->firstData($paths->title())->value();
95
96 ilLMObject::_writeTitle($this->getId(), $title);
97 break;
98
99 case 'Educational':
100 $obj_lp = ilObjectLP::getInstance($this->getLMId());
101 if (in_array(
102 $obj_lp->getCurrentMode(),
104 )) {
106 }
107 break;
108
109 default:
110 }
111 }
112
113
117 public function createMetaData(): void
118 {
119 $ilUser = $this->user;
120
121 $this->lom_services->derive()
122 ->fromBasicProperties(
123 $this->getTitle(),
124 $this->getDescription(),
125 $ilUser->getPref('language')
126 )->forObject($this->getLMId(), $this->getId(), $this->getType());
127 }
128
132 public function updateMetaData(): void
133 {
134 $this->lom_services->manipulate($this->getLMId(), $this->getId(), $this->getType())
135 ->prepareCreateOrUpdate(
136 $this->lom_services->paths()->title(),
137 $this->getTitle()
138 )->execute();
139 }
140
141
145 public function deleteMetaData(): void
146 {
147 $this->lom_services->deleteAll($this->getLMId(), $this->getId(), $this->getType());
148 }
149
150
151
155 public function setDataRecord(array $a_record): void
156 {
157 $this->data_record = $a_record;
158 }
159
160 public function read(): void
161 {
163
164 if (!isset($this->data_record)) {
165 $query = "SELECT * FROM lm_data WHERE obj_id = " .
166 $ilDB->quote($this->id, "integer");
167 $obj_set = $ilDB->query($query);
168 $this->data_record = $ilDB->fetchAssoc($obj_set);
169 }
170
171 $this->type = $this->data_record["type"];
172 $this->setImportId((string) $this->data_record["import_id"]);
173 $this->setTitle((string) $this->data_record["title"]);
174 $this->setShortTitle((string) $this->data_record["short_title"]);
175 $this->setLayout((string) $this->data_record["layout"]);
176 }
177
178
183 public static function preloadDataByLM(int $a_lm_id): int
184 {
185 global $DIC;
186
187 $ilDB = $DIC->database();
188
189 $set = $ilDB->query(
190 "SELECT * FROM lm_data " .
191 " WHERE lm_id = " . $ilDB->quote($a_lm_id, "integer")
192 );
193 while ($rec = $ilDB->fetchAssoc($set)) {
194 self::$data_records[$rec["obj_id"]] = $rec;
195 }
196 return count(self::$data_records);
197 }
198
199 public function setTitle(string $a_title): void
200 {
201 $this->title = $a_title;
202 }
203
204 public function getTitle(): string
205 {
206 return $this->title;
207 }
208
209 public function setShortTitle(string $a_title): void
210 {
211 $this->short_title = $a_title;
212 }
213
214 public function getShortTitle(): string
215 {
216 return $this->short_title;
217 }
218
219 protected static function _lookup(int $a_obj_id, string $a_field): string
220 {
221 global $DIC;
222
223 $ilDB = $DIC->database();
224
225 if (isset(self::$data_records[$a_obj_id])) {
226 return self::$data_records[$a_obj_id][$a_field] ?? "";
227 }
228
229 $query = "SELECT " . $a_field . " FROM lm_data WHERE obj_id = " .
230 $ilDB->quote($a_obj_id, "integer");
231 $obj_set = $ilDB->query($query);
232 $obj_rec = $ilDB->fetchAssoc($obj_set);
233
234 return $obj_rec[$a_field] ?? "";
235 }
236
237 public static function _lookupTitle(int $a_obj_id): string
238 {
239 return self::_lookup($a_obj_id, "title");
240 }
241
242 public static function _lookupShortTitle(int $a_obj_id): string
243 {
244 return self::_lookup($a_obj_id, "short_title");
245 }
246
247 public static function _lookupType(int $a_obj_id, int $a_lm_id = 0): string
248 {
249 global $DIC;
250
251 $ilDB = $DIC->database();
252
253 if (isset(self::$data_records[$a_obj_id])) {
254 if ($a_lm_id == 0 || self::$data_records[$a_obj_id]["lm_id"] == $a_lm_id) {
255 return self::$data_records[$a_obj_id]["type"];
256 }
257 }
258
259 $and = "";
260 if ($a_lm_id) {
261 $and = ' AND lm_id = ' . $ilDB->quote($a_lm_id, 'integer');
262 }
263
264 $query = "SELECT type FROM lm_data WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer") . $and;
265 $obj_set = $ilDB->query($query);
266 $obj_rec = $ilDB->fetchAssoc($obj_set);
267
268 return $obj_rec["type"] ?? "";
269 }
270
271
272 public static function _writeTitle(int $a_obj_id, string $a_title): void
273 {
274 global $DIC;
275
276 $ilDB = $DIC->database();
277
278 $query = "UPDATE lm_data SET " .
279 " title = " . $ilDB->quote($a_title, "text") .
280 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer");
281 $ilDB->manipulate($query);
282 }
283
284
285 public function setDescription(string $a_description): void
286 {
287 $this->description = $a_description;
288 }
289
290 public function getDescription(): string
291 {
292 return $this->description;
293 }
294
295 public function setType(string $a_type): void
296 {
297 $this->type = $a_type;
298 }
299
300 public function getType(): string
301 {
302 return $this->type;
303 }
304
305 public function setLMId(int $a_lm_id): void
306 {
307 $this->lm_id = $a_lm_id;
308 }
309
310 public function getLMId(): int
311 {
312 return $this->lm_id;
313 }
314
315 public function setContentObject(ilObjLearningModule $a_content_obj): void
316 {
317 $this->content_object = $a_content_obj;
318 }
319
321 {
323 }
324
325 public function setId(int $a_id): void
326 {
327 $this->id = $a_id;
328 }
329
330 public function getId(): int
331 {
332 return $this->id;
333 }
334
335 public function getImportId(): string
336 {
337 return $this->import_id;
338 }
339
340 public function setImportId(string $a_id): void
341 {
342 $this->import_id = $a_id;
343 }
344
345 public function setLayout(string $a_val): void
346 {
347 $this->layout = $a_val;
348 }
349
350 public function getLayout(): string
351 {
352 return $this->layout;
353 }
354
355 public static function _writeImportId(int $a_id, string $a_import_id): void
356 {
357 global $DIC;
358
359 $ilDB = $DIC->database();
360
361 $q = "UPDATE lm_data " .
362 "SET " .
363 "import_id = " . $ilDB->quote($a_import_id, "text") . "," .
364 "last_update = " . $ilDB->now() . " " .
365 "WHERE obj_id = " . $ilDB->quote($a_id, "integer");
366
367 $ilDB->manipulate($q);
368 }
369
370 public function create(bool $a_upload = false): void
371 {
373
374 // insert object data
375 $this->setId($ilDB->nextId("lm_data"));
376 $query = "INSERT INTO lm_data (obj_id, title, type, layout, lm_id, import_id, short_title, create_date) " .
377 "VALUES (" .
378 $ilDB->quote($this->getId(), "integer") . "," .
379 $ilDB->quote($this->getTitle(), "text") . "," .
380 $ilDB->quote($this->getType(), "text") . ", " .
381 $ilDB->quote($this->getLayout(), "text") . ", " .
382 $ilDB->quote($this->getLMId(), "integer") . "," .
383 $ilDB->quote($this->getImportId(), "text") . "," .
384 $ilDB->quote($this->getShortTitle(), "text") .
385 ", " . $ilDB->now() . ")";
386 $ilDB->manipulate($query);
387
388 if (!$a_upload) {
389 $this->createMetaData();
390 }
391 }
392
393 public function update(): void
394 {
396
397 $this->updateMetaData();
398
399 $query = "UPDATE lm_data SET " .
400 " lm_id = " . $ilDB->quote($this->getLMId(), "integer") .
401 " ,title = " . $ilDB->quote($this->getTitle(), "text") .
402 " ,short_title = " . $ilDB->quote($this->getShortTitle(), "text") .
403 " ,layout = " . $ilDB->quote($this->getLayout(), "text") .
404 " WHERE obj_id = " . $ilDB->quote($this->getId(), "integer");
405
406 $ilDB->manipulate($query);
407 }
408
409 public function delete(bool $a_delete_meta_data = true): void
410 {
412
413 $query = "DELETE FROM lm_data WHERE obj_id = " .
414 $ilDB->quote($this->getId(), "integer");
415 $ilDB->manipulate($query);
416
417 $this->deleteMetaData();
418 }
419
427 public static function _getIdForImportId(string $a_import_id): int
428 {
429 global $DIC;
430
431 $ilDB = $DIC->database();
432 $help_module = $DIC->help()->internal()->domain()->module();
433
434 $q = "SELECT obj_id FROM lm_data WHERE import_id = " .
435 $ilDB->quote($a_import_id, "text") . " " .
436 " ORDER BY create_date DESC";
437 $obj_set = $ilDB->query($q);
438 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
439 $lm_id = ilLMObject::_lookupContObjID($obj_rec["obj_id"]);
440
441 // link only in learning module, that is not trashed
442 $ref_ids = ilObject::_getAllReferences($lm_id); // will be 0 if import of lm is in progress (new import)
443 if (count($ref_ids) == 0 || ilObject::_hasUntrashedReference($lm_id) ||
444 $help_module->isHelpLM($lm_id)) {
445 return $obj_rec["obj_id"];
446 }
447 }
448
449 return 0;
450 }
451
457 public static function _getAllObjectsForImportId(
458 string $a_import_id,
459 int $a_in_lm = 0
460 ): array {
461 global $DIC;
462
463 $ilDB = $DIC->database();
464
465 $where = ($a_in_lm > 0)
466 ? " AND lm_id = " . $ilDB->quote($a_in_lm, "integer") . " "
467 : "";
468
469 $q = "SELECT * FROM lm_data WHERE import_id = " .
470 $ilDB->quote($a_import_id, "text") . " " .
471 $where .
472 " ORDER BY create_date DESC";
473 $obj_set = $ilDB->query($q);
474
475 $items = array();
476 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
477 // check, whether lm is not trashed
478 if (ilObject::_hasUntrashedReference($obj_rec["lm_id"])) {
479 $items[] = $obj_rec;
480 }
481 }
482
483 return $items;
484 }
485
489 public static function _exists(int $a_id): bool
490 {
491 global $DIC;
492
493 $ilDB = $DIC->database();
494
495 if (is_int(strpos($a_id, "_"))) {
497 }
498
499 $q = "SELECT * FROM lm_data WHERE obj_id = " .
500 $ilDB->quote($a_id, "integer");
501 $obj_set = $ilDB->query($q);
502 if ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
503 return true;
504 } else {
505 return false;
506 }
507 }
508
509 public static function getObjectList(
510 int $lm_id,
511 string $type = ""
512 ): array {
513 global $DIC;
514
515 $ilDB = $DIC->database();
516
517 $type_str = ($type != "")
518 ? "AND type = " . $ilDB->quote($type, "text") . " "
519 : "";
520
521 $query = "SELECT * FROM lm_data " .
522 "WHERE lm_id= " . $ilDB->quote($lm_id, "integer") . " " .
523 $type_str . " " .
524 "ORDER BY title";
525 $obj_set = $ilDB->query($query);
526 $obj_list = array();
527 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
528 $obj_list[] = array("obj_id" => $obj_rec["obj_id"],
529 "title" => $obj_rec["title"],
530 "import_id" => $obj_rec["import_id"],
531 "type" => $obj_rec["type"]);
532 }
533 return $obj_list;
534 }
535
536
540 public static function _deleteAllObjectData(
541 ilObjLearningModule $a_cobj
542 ): void {
543 global $DIC;
544
545 $ilDB = $DIC->database();
546
547 $query = "SELECT * FROM lm_data " .
548 "WHERE lm_id= " . $ilDB->quote($a_cobj->getId(), "integer");
549 $obj_set = $ilDB->query($query);
550
551 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
552 $lm_obj = ilLMObjectFactory::getInstance($a_cobj, $obj_rec["obj_id"], false);
553
554 if (is_object($lm_obj)) {
555 $lm_obj->delete(true);
556 }
557 }
558 }
559
563 public static function _lookupContObjID(int $a_id): int
564 {
565 global $DIC;
566
567 $ilDB = $DIC->database();
568
569 if (isset(self::$data_records[$a_id])) {
570 return self::$data_records[$a_id]["lm_id"];
571 }
572
573 $query = "SELECT lm_id FROM lm_data WHERE obj_id = " .
574 $ilDB->quote($a_id, "integer");
575 $obj_set = $ilDB->query($query);
576 $obj_rec = $ilDB->fetchAssoc($obj_set);
577
578 return (int) ($obj_rec["lm_id"] ?? 0);
579 }
580
584 public static function putInTree(
585 ilLMObject $a_obj,
586 int $a_parent_id = 0,
587 int $a_target_node_id = 0
588 ): void {
589 global $DIC;
590
591 $ilLog = $DIC["ilLog"];
592
593 $tree = new ilLMTree($a_obj->getContentObject()->getId());
594
595 // determine parent
596 $parent_id = ($a_parent_id != 0)
597 ? $a_parent_id
598 : $tree->getRootId();
599
600 // determine target
601 if ($a_target_node_id != 0) {
602 $target = $a_target_node_id;
603 } else {
604 // determine last child that serves as predecessor
605 if ($a_obj->getType() == "st") {
606 $s_types = array("st", "pg");
607 $childs = $tree->getChildsByTypeFilter($parent_id, $s_types);
608 } else {
609 $s_types = "pg";
610 $childs = $tree->getChildsByType($parent_id, $s_types);
611 }
612
613 if (count($childs) == 0) {
614 $target = ilTree::POS_FIRST_NODE;
615 } else {
616 $target = $childs[count($childs) - 1]["obj_id"];
617 }
618 }
619
620 if ($tree->isInTree($parent_id) && !$tree->isInTree($a_obj->getId())) {
621 $ilLog->write("LMObject::putInTree: insertNode, ID: " . $a_obj->getId() .
622 "Parent ID: " . $parent_id . ", Target: " . $target);
623
624 $tree->insertNode($a_obj->getId(), $parent_id, $target);
625 }
626 }
627
631 public static function getTree(
632 int $a_cont_obj_id
633 ): ilLMTree {
634 $tree = new ilLMTree($a_cont_obj_id);
635 $tree->readRootId();
636
637 return $tree;
638 }
639
643 public static function clipboardCut(
644 int $a_cont_obj_id,
645 array $a_ids
646 ): void {
647 $tree = ilLMObject::getTree($a_cont_obj_id);
648 $cut_ids = [];
649
650 if (!is_array($a_ids)) {
651 return;
652 } else {
653 // get all "top" ids, i.e. remove ids, that have a selected parent
654 foreach ($a_ids as $id) {
655 $path = $tree->getPathId($id);
656 $take = true;
657 foreach ($path as $path_id) {
658 if ($path_id != $id && in_array($path_id, $a_ids)) {
659 $take = false;
660 }
661 }
662 if ($take) {
663 $cut_ids[] = $id;
664 }
665 }
666 }
667
668 ilLMObject::clipboardCopy($a_cont_obj_id, $cut_ids);
669
670 // remove the objects from the tree
671 // note: we are getting chapters which are *not* in the tree
672 // we do not delete any pages/chapters here
673 foreach ($cut_ids as $id) {
674 $curnode = $tree->getNodeData($id);
675 if ($tree->isInTree($id)) {
676 $tree->deleteTree($curnode);
677 }
678 }
679 }
680
684 public static function clipboardCopy(
685 int $a_cont_obj_id,
686 array $a_ids
687 ): void {
688 global $DIC;
689
690 $ilUser = $DIC->user();
691
692 $tree = ilLMObject::getTree($a_cont_obj_id);
693
694 $ilUser->clipboardDeleteObjectsOfType("pg");
695 $ilUser->clipboardDeleteObjectsOfType("st");
696
697 // put them into the clipboard
698 $time = date("Y-m-d H:i:s", time());
699 $order = 0;
700 foreach ($a_ids as $id) {
701 $curnode = array();
702 if ($tree->isInTree($id)) {
703 $curnode = $tree->getNodeData($id);
704 $subnodes = $tree->getSubTree($curnode);
705 foreach ($subnodes as $subnode) {
706 if ($subnode["child"] != $id) {
707 $ilUser->addObjectToClipboard(
708 $subnode["child"],
709 $subnode["type"],
710 ilStr::subStr($subnode["title"], 0, 70),
711 $subnode["parent"],
712 $time,
713 $subnode["lft"]
714 );
715 }
716 }
717 }
718 $order = (($curnode["lft"] ?? 0) > 0)
719 ? $curnode["lft"]
720 : (int) ($order + 1);
721 $ilUser->addObjectToClipboard(
722 $id,
723 self::_lookupType($id),
724 ilStr::subStr(self::_lookupTitle($id), 0, 70),
725 0,
726 $time,
727 $order
728 );
729 }
730 }
731
735 public static function pasteTree(
736 ilObjLearningModule $a_target_lm,
737 int $a_item_id,
738 int $a_parent_id,
739 int $a_target,
740 string $a_insert_time,
741 array &$a_copied_nodes,
742 bool $a_as_copy = false,
743 ?ilObjLearningModule $a_source_lm = null
744 ): int {
745 global $DIC;
746
747 $item = null;
748 $ilUser = $DIC->user();
749 $ilLog = $DIC["ilLog"];
750 $lom_services = $DIC->learningObjectMetadata();
751
752 $item_lm_id = ilLMObject::_lookupContObjID($a_item_id);
753 $item_type = ilLMObject::_lookupType($a_item_id);
755 $lm_obj = ilObjectFactory::getInstanceByObjId($item_lm_id);
756 if ($item_type == "st") {
757 $item = new ilStructureObject($lm_obj, $a_item_id);
758 } elseif ($item_type == "pg") {
759 $item = new ilLMPageObject($lm_obj, $a_item_id);
760 }
761
762 $ilLog->write("Getting from clipboard type " . $item_type . ", " .
763 "Item ID: " . $a_item_id . ", of original LM: " . $item_lm_id);
764
765 if ($item_lm_id != $a_target_lm->getId() && !$a_as_copy) {
766 // @todo: check whether st is NOT in tree
767
768 // "move" metadata to new lm
769 $lom_services->derive()
770 ->fromObject($item_lm_id, $item->getId(), $item->getType())
771 ->forObject($a_target_lm->getId(), $item->getId(), $item->getType());
772
773 // delete old meta data set
774 $lom_services->deleteAll($item_lm_id, $item->getId(), $item->getType());
775
776 if ($item_type == "pg") {
777 $page = $item->getPageObject();
778 $page->buildDom();
779 $page->setParentId($a_target_lm->getId());
780 $page->update();
781 }
782 }
783
784 if ($a_as_copy) {
785 $target_item = $item->copy($a_target_lm);
786 $a_copied_nodes[$item->getId()] = $target_item->getId();
787 } else {
788 $target_item = $item;
789 }
790
791 $ilLog->write("Putting into tree type " . $target_item->getType() .
792 "Item ID: " . $target_item->getId() . ", Parent: " . $a_parent_id . ", " .
793 "Target: " . $a_target . ", Item LM:" . $target_item->getContentObject()->getId());
794
795 ilLMObject::putInTree($target_item, $a_parent_id, $a_target);
796
797 if ($a_source_lm == null) {
798 $childs = $ilUser->getClipboardChilds($item->getId(), $a_insert_time);
799 } else {
800 $childs = $a_source_lm->lm_tree->getChilds($item->getId());
801 foreach ($childs as $k => $child) {
802 $childs[$k]["id"] = $child["child"];
803 }
804 }
805
806 foreach ($childs as $child) {
807 ilLMObject::pasteTree(
808 $a_target_lm,
809 $child["id"],
810 $target_item->getId(),
812 $a_insert_time,
813 $a_copied_nodes,
814 $a_as_copy,
815 $a_source_lm
816 );
817 }
818
819 return $target_item->getId();
820 // @todo: write history (see pastePage)
821 }
822
826 public static function saveTitles(
828 array $a_titles,
829 string $a_lang = "-"
830 ): void {
831 global $DIC;
832
833 $lom_services = $DIC->learningObjectMetadata();
834
835 if ($a_lang == "") {
836 $a_lang = "-";
837 }
838 if (is_array($a_titles)) {
839 foreach ($a_titles as $id => $title) {
840 self::saveTitle($id, $title, $a_lang);
841 }
842 }
843 }
844
845 public static function saveTitle(int $id, string $title, string $lang = "-"): void
846 {
847 global $DIC;
848
849 $lom_services = $DIC->learningObjectMetadata();
851 if (in_array($lang, ["-", ""])) {
852 $lm_id = self::_lookupContObjID($id);
853 $type = self::_lookupType($id);
854 if ($type !== "" && $lm_id > 0) {
855 $lom_services->manipulate($lm_id, $id, $type)
856 ->prepareCreateOrUpdate(
857 $lom_services->paths()->title(),
858 $title
859 )->execute();
860 self::_writeTitle($id, $title);
861 }
862 } else {
863 $lmobjtrans = new ilLMObjTranslation($id, $lang);
864 $lmobjtrans->setTitle($title);
865 $lmobjtrans->save();
866 }
867 }
868
872 public static function updateInternalLinks(
873 array $a_copied_nodes,
874 string $a_parent_type = "lm"
875 ): void {
876 $all_fixes = array();
877 foreach ($a_copied_nodes as $original_id => $copied_id) {
878 $copied_type = ilLMObject::_lookupType($copied_id);
879 $copy_lm = ilLMObject::_lookupContObjID($copied_id);
880
881 if ($copied_type == "pg") {
882 foreach (ilPageObject::lookupTranslations($a_parent_type, $copied_id) as $l) {
883 //
884 // 1. Outgoing links from the copied page.
885 //
886 //$targets = ilInternalLink::_getTargetsOfSource($a_parent_type.":pg", $copied_id);
887 $tpg = new ilLMPage($copied_id, 0, $l);
888 $tpg->buildDom();
889 $il = $tpg->getInternalLinks();
890 $targets = array();
891 foreach ($il as $l2) {
892 $targets[] = array("type" => ilInternalLink::_extractTypeOfTarget($l2["Target"]),
893 "id" => (int) ilInternalLink::_extractObjIdOfTarget($l2["Target"]),
894 "inst" => (int) ilInternalLink::_extractInstOfTarget($l2["Target"]));
895 }
896 $fix = array();
897 foreach ($targets as $target) {
898 if (($target["inst"] == 0 || $target["inst"] = IL_INST_ID) &&
899 ($target["type"] == "pg" || $target["type"] == "st")) {
900 // first check, whether target is also within the copied set
901 if (($a_copied_nodes[$target["id"]] ?? 0) > 0) {
902 $fix[$target["id"]] = $a_copied_nodes[$target["id"]];
903 } else {
904 // now check, if a copy if the target is already in the same lm
905
906 // only if target is not already in the same lm!
907 $trg_lm = ilLMObject::_lookupContObjID($target["id"]);
908 if ($trg_lm != $copy_lm) {
909 $lm_data = ilLMObject::_getAllObjectsForImportId("il__" . $target["type"] . "_" . $target["id"]);
910 $found = false;
911
912 foreach ($lm_data as $item) {
913 if (!$found && ($item["lm_id"] == $copy_lm)) {
914 $fix[$target["id"]] = $item["obj_id"];
915 $found = true;
916 }
917 }
918 }
919 }
920 }
921 }
922
923 // outgoing links to be fixed
924 if (count($fix) > 0) {
925 //echo "<br>--".$copied_id;
926 //var_dump($fix);
927 $t = ilObject::_lookupType($copy_lm);
928 if (isset($all_fixes[$t . ":" . $copied_id])) {
929 $all_fixes[$t . ":" . $copied_id] += $fix;
930 } else {
931 $all_fixes[$t . ":" . $copied_id] = $fix;
932 }
933 }
934 }
935 }
936
937 if ($copied_type == "pg" ||
938 $copied_type == "st") {
939 //
940 // 2. Incoming links to the original pages
941 //
942 // A->B A2 (A+B currently copied)
943 // A->C B2
944 // B->A
945 // C->A C2->A (C already copied)
946 $original_lm = ilLMObject::_lookupContObjID($original_id);
947 $original_type = ilObject::_lookupType($original_lm);
948
949 if ($original_lm != $copy_lm) {
950 // This gets sources that link to A+B (so we have C here)
951 // (this also does already the trick when instance map areas are given in C)
952 // int_link, where target_type, target_id, target_inst -> ok
954 $copied_type,
955 $original_id,
956 0
957 );
958
959 // mobs linking to $original_id
960 // map_area, where link_type, target -> ok
961 $mobs = ilMapArea::_getMobsForTarget("int", "il__" . $copied_type .
962 "_" . $original_id);
963
964 // pages using these mobs
965 foreach ($mobs as $mob) {
966 // mob_usage, where id -> ok
967 // mep_item, where foreign_id, type -> ok
968 // mep_tree, where child -> already existed
969 // il_news_item, where mob_id -> ok
970 // map_area, where link_type, target -> aready existed
971 // media_item, where id -> already existed
972 // personal_clipboard, where item_id, type -> ok
973 $usages = ilObjMediaObject::lookupUsages($mob);
974 foreach ($usages as $usage) {
975 if ($usage["type"] == "lm:pg" | $usage["type"] == "lm:st") {
976 $sources[] = $usage;
977 }
978 }
979 }
980 $fix = array();
981 foreach ($sources as $source) {
982 $stype = explode(":", $source["type"]);
983 $source_type = $stype[1] ?? "";
984
985 if ($source_type == "pg" || $source_type == "st") {
986 // first of all: source must be in original lm
987 $src_lm = ilLMObject::_lookupContObjID($source["id"]);
988
989 if ($src_lm == $original_lm) {
990 // check, if a copy if the source is already in the same lm
991 // now we look for the latest copy of C in LM2
993 "il__" . $source_type . "_" . $source["id"],
994 $copy_lm
995 );
996 $found = false;
997 foreach ($lm_data as $item) {
998 if (!$found) {
999 $fix[$item["obj_id"]][$original_id] = $copied_id;
1000 $found = true;
1001 }
1002 }
1003 }
1004 }
1005 }
1006 // outgoing links to be fixed
1007 if (count($fix) > 0) {
1008 foreach ($fix as $page_id => $fix_array) {
1009 $t = ilObject::_lookupType($copy_lm);
1010 if (isset($all_fixes[$t . ":" . $page_id])) {
1011 $all_fixes[$t . ":" . $page_id] += $fix_array;
1012 } else {
1013 $all_fixes[$t . ":" . $page_id] = $fix_array;
1014 }
1015 }
1016 }
1017 }
1018 }
1019 }
1020
1021 foreach ($all_fixes as $pg => $fixes) {
1022 $pg = explode(":", $pg);
1023 foreach (ilPageObject::lookupTranslations($pg[0], $pg[1]) as $l) {
1024 $page = ilPageObjectFactory::getInstance($pg[0], $pg[1], 0, $l);
1025 if ($page->moveIntLinks($fixes)) {
1026 $page->update(true, true);
1027 }
1028 }
1029 }
1030 }
1031
1035 public static function uniqueTypesCheck(array $a_items): bool
1036 {
1037 $types = array();
1038 if (is_array($a_items)) {
1039 foreach ($a_items as $item) {
1040 $type = ilLMObject::_lookupType($item);
1041 $types[$type] = $type;
1042 }
1043 }
1044
1045 if (count($types) > 1) {
1046 return false;
1047 }
1048 return true;
1049 }
1050
1054 public static function writeLayout(
1055 int $a_obj_id,
1056 string $a_layout,
1057 ?ilObjLearningModule $a_lm = null
1058 ): void {
1059 global $DIC;
1060
1061 $ilDB = $DIC->database();
1062
1063 $t = ilLMObject::_lookupType($a_obj_id);
1064
1065 if ($t == "pg") {
1066 $query = "UPDATE lm_data SET " .
1067 " layout = " . $ilDB->quote($a_layout, "text") .
1068 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer");
1069 $ilDB->manipulate($query);
1070 } elseif ($t == "st" && is_object($a_lm)) {
1071 $node = $a_lm->getLMTree()->getNodeData($a_obj_id);
1072 $child_nodes = $a_lm->getLMTree()->getSubTree($node);
1073 if (is_array($child_nodes) && count($child_nodes) > 0) {
1074 foreach ($child_nodes as $c) {
1075 if ($c["type"] == "pg") {
1076 $query = "UPDATE lm_data SET " .
1077 " layout = " . $ilDB->quote($a_layout, "text") .
1078 " WHERE obj_id = " . $ilDB->quote($c["child"], "integer");
1079 $ilDB->manipulate($query);
1080 }
1081 }
1082 }
1083 }
1084 }
1085
1089 public static function lookupLayout(int $a_obj_id): string
1090 {
1091 global $DIC;
1092
1093 $ilDB = $DIC->database();
1094
1095 $query = "SELECT layout FROM lm_data WHERE obj_id = " .
1096 $ilDB->quote($a_obj_id, "integer");
1097 $obj_set = $ilDB->query($query);
1098 $obj_rec = $ilDB->fetchAssoc($obj_set);
1099
1100 return $obj_rec["layout"];
1101 }
1102
1106 public static function getPagesOfChapter(
1107 int $a_lm_id,
1108 int $a_chap_id
1109 ): array {
1110 // update structure entries: if at least one page of a chapter is public set chapter to public too
1111 $lm_tree = new ilTree($a_lm_id);
1112 $lm_tree->setTableNames('lm_tree', 'lm_data');
1113 $lm_tree->setTreeTablePK("lm_id");
1114 $lm_tree->readRootId();
1115
1116 $childs = $lm_tree->getChildsByType($a_chap_id, "pg");
1117
1118 return $childs;
1119 }
1120
1124 public static function _getAllLMObjectsOfLM(
1125 int $a_lm_id,
1126 string $a_type = ""
1127 ): array {
1128 global $DIC;
1129
1130 $ilDB = $DIC->database();
1131
1132 $and = ($a_type != "")
1133 ? " AND type = " . $ilDB->quote($a_type, "text")
1134 : "";
1135
1136 $set = $ilDB->query("SELECT obj_id FROM lm_data " .
1137 " WHERE lm_id = " . $ilDB->quote($a_lm_id, "integer") . $and);
1138 $obj_ids = array();
1139 while ($rec = $ilDB->fetchAssoc($set)) {
1140 $obj_ids[] = $rec["obj_id"];
1141 }
1142
1143 return $obj_ids;
1144 }
1145
1146
1150
1151 public static function saveExportId(
1152 int $a_lm_id,
1153 int $a_lmobj_id,
1154 string $a_exp_id,
1155 string $a_type = "pg"
1156 ): void {
1157 global $DIC;
1158
1159 $manipulator = $DIC->learningObjectMetadata()->manipulate($a_lm_id, $a_lmobj_id, $a_type);
1160 if (trim($a_exp_id) == "") {
1161 $manipulator = $manipulator->prepareDelete(self::getPathToExportIDInLOM());
1162 } else {
1163 $manipulator = $manipulator->prepareCreateOrUpdate(self::getPathToExportIDInLOM(), $a_exp_id);
1164 }
1165 $manipulator->execute();
1166 }
1167
1168 protected static function getPathToExportIDInLOM(): LOMPath
1169 {
1170 global $DIC;
1171
1172 return $DIC->learningObjectMetadata()
1173 ->paths()
1174 ->custom()
1175 ->withNextStep('general')
1176 ->withNextStep('identifier')
1177 ->withNextStep('catalog')
1178 ->withAdditionalFilterAtCurrentStep(FilterType::DATA, 'ILIAS_NID')
1179 ->withNextStepToSuperElement()
1180 ->withNextStep('entry')
1181 ->get();
1182 }
1183
1184 public static function getExportId(
1185 int $a_lm_id,
1186 int $a_lmobj_id,
1187 string $a_type = "pg"
1188 ): string {
1189 global $DIC;
1190
1191 // look for export id
1192 $export_id_path = self::getPathToExportIDInLOM();
1193 return $DIC->learningObjectMetadata()->read(
1194 $a_lm_id,
1195 $a_lmobj_id,
1196 $a_type,
1197 $export_id_path
1198 )->firstData($export_id_path)->value();
1199 }
1200
1204 public function existsExportID(
1205 int $a_lm_id,
1206 int $a_exp_id,
1207 string $a_type = "pg"
1208 ): bool {
1209 $searcher = $this->lom_services->search();
1210
1211 $search_clause = $searcher->getClauseFactory()->getBasicClause(
1212 self::getPathToExportIDInLOM(),
1213 Mode::EQUALS,
1214 $a_exp_id
1215 );
1216 $results = $searcher->execute(
1217 $search_clause,
1218 1,
1219 null,
1220 $searcher->getFilter($a_lm_id, Placeholder::ANY, $a_type)
1221 );
1222 return count(iterator_to_array($results)) > 0;
1223 }
1224
1228 public static function getDuplicateExportIDs(
1229 int $a_lm_id,
1230 string $a_type = "pg"
1231 ): array {
1232 global $DIC;
1233
1234 $lom_services = $DIC->learningObjectMetadata();
1235 $export_id_path = self::getPathToExportIDInLOM();
1236
1237 $searcher = $lom_services->search();
1238 $search_clause = $searcher->getClauseFactory()->getBasicClause(
1239 $export_id_path,
1240 Mode::EQUALS,
1241 '',
1242 true
1243 );
1244 $search_results = $searcher->execute(
1245 $search_clause,
1246 1,
1247 null,
1248 $searcher->getFilter($a_lm_id, Placeholder::ANY, $a_type)
1249 );
1250
1251 $res = [];
1252 foreach ($search_results as $search_result) {
1253 if (!ilLMObject::_exists($search_result->subID())) {
1254 continue;
1255 }
1256 $reader = $lom_services->read(
1257 $search_result->objID(),
1258 $search_result->subID(),
1259 $search_result->type(),
1260 $export_id_path
1261 );
1262 foreach ($reader->allData($export_id_path) as $export_id_datum) {
1263 $export_id = trim($export_id_datum->value());
1264 $res[$export_id] = ($res[$export_id] ?? 0) + 1;
1265 }
1266 }
1267 return $res;
1268 }
1269
1270 // Get effective title
1271 public static function _getNodePresentationTitle(
1272 array $a_node,
1273 string $a_mode = self::PAGE_TITLE,
1274 bool $a_include_numbers = false,
1275 bool $a_time_scheduled_activation = false,
1276 bool $a_force_content = false,
1277 int $a_lm_id = 0,
1278 string $a_lang = "-"
1279 ): string {
1280 if ($a_lang == "") {
1281 $a_lang = "-";
1282 }
1283
1284 if ($a_node["type"] == "st") {
1286 $a_node["child"],
1287 self::CHAPTER_TITLE,
1288 $a_include_numbers,
1289 $a_time_scheduled_activation,
1290 $a_force_content,
1291 $a_lm_id,
1292 $a_lang
1293 );
1294 } else {
1296 $a_node["child"],
1297 $a_mode,
1298 $a_include_numbers,
1299 $a_time_scheduled_activation,
1300 $a_force_content,
1301 $a_lm_id,
1302 $a_lang
1303 );
1304 }
1305 }
1306
1307 public static function getShortTitles(
1308 int $a_lm_id,
1309 string $a_lang = "-"
1310 ): array {
1311 global $DIC;
1312
1313 $db = $DIC->database();
1314
1315 $title_data = array();
1316 if ($a_lang == "-") {
1317 $set = $db->query("SELECT t.child, d.obj_id, d.title, d.short_title FROM lm_data d LEFT JOIN lm_tree t ON (d.obj_id = t.child) WHERE d.lm_id = " .
1318 $db->quote($a_lm_id, "integer") . " ORDER BY t.lft, d.title");
1319 } else {
1320 $set = $db->query("SELECT t.child, d.obj_id, tr.title, tr.short_title, d.title default_title, d.short_title default_short_title FROM lm_data d " .
1321 " LEFT JOIN lm_tree t ON (d.obj_id = t.child) " .
1322 " LEFT JOIN lm_data_transl tr ON (tr.id = d.obj_id AND tr.lang=" . $db->quote($a_lang, "text") . ") WHERE d.lm_id = " .
1323 $db->quote($a_lm_id, "integer") . " ORDER BY t.lft, d.title");
1324 }
1325 while ($rec = $db->fetchAssoc($set)) {
1326 $title_data[] = $rec;
1327 }
1328 return $title_data;
1329 }
1330
1331 public static function writeShortTitle(
1332 int $a_id,
1333 string $a_short_title,
1334 string $a_lang = "-"
1335 ): void {
1336 global $DIC;
1337
1338 $db = $DIC->database();
1339
1340 if ($a_lang != "-" && $a_lang != "") {
1341 $trans = new ilLMObjTranslation($a_id, $a_lang);
1342 $trans->setShortTitle($a_short_title);
1343 $trans->save();
1344 } else {
1345 $db->manipulate(
1346 "UPDATE lm_data SET " .
1347 " short_title = " . $db->quote($a_short_title, "text") .
1348 " WHERE obj_id = " . $db->quote($a_id, "integer")
1349 );
1350 }
1351 }
1352}
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:23
static removeProhibitedCharacters(string $a_text)
Remove prohibited characters see #19159.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstance(ilObjLearningModule $a_content_obj, int $a_id=0, bool $a_halt=true)
Class ilLMObject.
static saveTitle(int $id, string $title, string $lang="-")
setContentObject(ilObjLearningModule $a_content_obj)
existsExportID(int $a_lm_id, int $a_exp_id, string $a_type="pg")
Does export ID exist in lm?
static writeLayout(int $a_obj_id, string $a_layout, ?ilObjLearningModule $a_lm=null)
Write layout setting.
setShortTitle(string $a_title)
static _getAllObjectsForImportId(string $a_import_id, int $a_in_lm=0)
Get all items for an import ID.
ilObjLearningModule $content_object
static writeShortTitle(int $a_id, string $a_short_title, string $a_lang="-")
setId(int $a_id)
static getPathToExportIDInLOM()
LOMServices $lom_services
static getPagesOfChapter(int $a_lm_id, int $a_chap_id)
Get pages of chapter.
static _exists(int $a_id)
checks wether a lm content object with specified id exists or not
ilObjUser $user
setImportId(string $a_id)
ilDBInterface $db
static clipboardCut(int $a_cont_obj_id, array $a_ids)
Copy a set of chapters/pages into the clipboard.
setDataRecord(array $a_record)
this method should only be called by class ilLMObjectFactory
static saveExportId(int $a_lm_id, int $a_lmobj_id, string $a_exp_id, string $a_type="pg")
string $description
static _getAllLMObjectsOfLM(int $a_lm_id, string $a_type="")
Get all objects of learning module.
static _lookupShortTitle(int $a_obj_id)
MDUpdateListener(string $a_element)
Meta data update listener Important note: Do never call create() or update() method of ilObject here.
static saveTitles(ilObjLearningModule $a_lm, array $a_titles, string $a_lang="-")
Save titles for lm objects.
static preloadDataByLM(int $a_lm_id)
Preload data records by lm.
static getShortTitles(int $a_lm_id, string $a_lang="-")
static _writeImportId(int $a_id, string $a_import_id)
__construct(ilObjLearningModule $a_content_obj, int $a_id=0)
static _writeTitle(int $a_obj_id, string $a_title)
static _lookupContObjID(int $a_id)
get learning module id for lm object
static _lookupTitle(int $a_obj_id)
setDescription(string $a_description)
static getObjectList(int $lm_id, string $type="")
static getTree(int $a_cont_obj_id)
Get learning module tree.
static $data_records
static clipboardCopy(int $a_cont_obj_id, array $a_ids)
Copy a set of chapters/pages into the clipboard.
deleteMetaData()
delete meta data entry
static updateInternalLinks(array $a_copied_nodes, string $a_parent_type="lm")
Update internal links, after multiple pages have been copied.
static lookupLayout(int $a_obj_id)
Lookup type.
string $short_title
createMetaData()
create meta data entry
static _getNodePresentationTitle(array $a_node, string $a_mode=self::PAGE_TITLE, bool $a_include_numbers=false, bool $a_time_scheduled_activation=false, bool $a_force_content=false, int $a_lm_id=0, string $a_lang="-")
static putInTree(ilLMObject $a_obj, int $a_parent_id=0, int $a_target_node_id=0)
put this object into content object tree
setLayout(string $a_val)
static _getIdForImportId(string $a_import_id)
get current object id for import id (static)
static _lookup(int $a_obj_id, string $a_field)
static uniqueTypesCheck(array $a_items)
Check for unique types (all pages or all chapters)
static getExportId(int $a_lm_id, int $a_lmobj_id, string $a_type="pg")
setType(string $a_type)
setTitle(string $a_title)
static _lookupType(int $a_obj_id, int $a_lm_id=0)
updateMetaData()
update meta data entry
static _deleteAllObjectData(ilObjLearningModule $a_cobj)
delete all objects of content object (digi book / learning module)
setLMId(int $a_lm_id)
static getDuplicateExportIDs(int $a_lm_id, string $a_type="pg")
Get duplicate export IDs (count export ID usages)
create(bool $a_upload=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getPresentationTitle(int $a_pg_id, string $a_mode=self::CHAPTER_TITLE, bool $a_include_numbers=false, bool $a_time_scheduled_activation=false, bool $a_force_content=false, int $a_lm_id=0, string $a_lang="-", bool $a_include_short=false)
presentation title doesn't have to be page title, it may be chapter title + page title or chapter tit...
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)
static _getMobsForTarget(string $a_type, string $a_target)
Get areas for a certain target.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static lookupUsages(int $a_id, bool $a_include_history=true)
Lookup usages of media object.
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 _lookupType(int $id, bool $reference=false)
static _hasUntrashedReference(int $obj_id)
checks whether an object has at least one reference that is not in trash
static _getAllReferences(int $id)
get all reference ids for object ID
static getInstance(string $a_parent_type, int $a_id=0, int $a_old_nr=0, string $a_lang="-")
Get page object instance.
static lookupTranslations(string $a_parent_type, int $a_id)
Lookup translations.
static subStr(string $a_str, int $a_start, ?int $a_length=null)
Definition: class.ilStr.php:21
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getPresentationTitle(int $a_st_id, string $a_mode=self::CHAPTER_TITLE, bool $a_include_numbers=false, bool $a_time_scheduled_activation=false, bool $a_force_content=false, int $a_lm_id=0, string $a_lang="-", bool $a_include_short=false)
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
const POS_LAST_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 'obj_id' You may use...
const POS_FIRST_NODE
const IL_INST_ID
Definition: constants.php:40
$c
Definition: deliver.php:25
Interface ilDBInterface.
quote($value, string $type)
manipulate(string $query)
Run a (write) Query on the database.
query(string $query)
Run a (read-only) Query on the database.
fetchAssoc(ilDBStatement $statement)
$path
Definition: ltiservices.php:30
$res
Definition: ltiservices.php:69
FilterType
Values should always be all lowercase.
Definition: FilterType.php:27
$results
if(!file_exists('../ilias.ini.php'))
global $DIC
Definition: shib_login.php:26
$q
Definition: shib_logout.php:23
$lang
Definition: xapiexit.php:25