ILIAS  trunk Revision v12.0_alpha-1221-g4e438232683
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 array $data_records = [];
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 $a_title = ilStr::substr($a_title, 0, 200);
279
280 $query = "UPDATE lm_data SET " .
281 " title = " . $ilDB->quote($a_title, "text") .
282 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer");
283 $ilDB->manipulate($query);
284 }
285
286
287 public function setDescription(string $a_description): void
288 {
289 $this->description = $a_description;
290 }
291
292 public function getDescription(): string
293 {
294 return $this->description;
295 }
296
297 public function setType(string $a_type): void
298 {
299 $this->type = $a_type;
300 }
301
302 public function getType(): string
303 {
304 return $this->type;
305 }
306
307 public function setLMId(int $a_lm_id): void
308 {
309 $this->lm_id = $a_lm_id;
310 }
311
312 public function getLMId(): int
313 {
314 return $this->lm_id;
315 }
316
317 public function setContentObject(ilObjLearningModule $a_content_obj): void
318 {
319 $this->content_object = $a_content_obj;
320 }
321
323 {
325 }
326
327 public function setId(int $a_id): void
328 {
329 $this->id = $a_id;
330 }
331
332 public function getId(): int
333 {
334 return $this->id;
335 }
336
337 public function getImportId(): string
338 {
339 return $this->import_id;
340 }
341
342 public function setImportId(string $a_id): void
343 {
344 $this->import_id = $a_id;
345 }
346
347 public function setLayout(string $a_val): void
348 {
349 $this->layout = $a_val;
350 }
351
352 public function getLayout(): string
353 {
354 return $this->layout;
355 }
356
357 public static function _writeImportId(int $a_id, string $a_import_id): void
358 {
359 global $DIC;
360
361 $ilDB = $DIC->database();
362
363 $q = "UPDATE lm_data " .
364 "SET " .
365 "import_id = " . $ilDB->quote($a_import_id, "text") . "," .
366 "last_update = " . $ilDB->now() . " " .
367 "WHERE obj_id = " . $ilDB->quote($a_id, "integer");
368
369 $ilDB->manipulate($q);
370 }
371
372 public function create(bool $a_upload = false): void
373 {
375
376 // insert object data
377 $this->setId($ilDB->nextId("lm_data"));
378 $query = "INSERT INTO lm_data (obj_id, title, type, layout, lm_id, import_id, short_title, create_date) " .
379 "VALUES (" .
380 $ilDB->quote($this->getId(), "integer") . "," .
381 $ilDB->quote($this->getTitle(), "text") . "," .
382 $ilDB->quote($this->getType(), "text") . ", " .
383 $ilDB->quote($this->getLayout(), "text") . ", " .
384 $ilDB->quote($this->getLMId(), "integer") . "," .
385 $ilDB->quote($this->getImportId(), "text") . "," .
386 $ilDB->quote($this->getShortTitle(), "text") .
387 ", " . $ilDB->now() . ")";
388 $ilDB->manipulate($query);
389
390 if (!$a_upload) {
391 $this->createMetaData();
392 }
393 }
394
395 public function update(): void
396 {
398
399 $this->updateMetaData();
400
401 $query = "UPDATE lm_data SET " .
402 " lm_id = " . $ilDB->quote($this->getLMId(), "integer") .
403 " ,title = " . $ilDB->quote($this->getTitle(), "text") .
404 " ,short_title = " . $ilDB->quote($this->getShortTitle(), "text") .
405 " ,layout = " . $ilDB->quote($this->getLayout(), "text") .
406 " WHERE obj_id = " . $ilDB->quote($this->getId(), "integer");
407
408 $ilDB->manipulate($query);
409 }
410
411 public function delete(bool $a_delete_meta_data = true): void
412 {
414
415 $query = "DELETE FROM lm_data WHERE obj_id = " .
416 $ilDB->quote($this->getId(), "integer");
417 $ilDB->manipulate($query);
418
419 $this->deleteMetaData();
420 }
421
429 public static function _getIdForImportId(string $a_import_id): int
430 {
431 global $DIC;
432
433 $ilDB = $DIC->database();
434 $help_module = $DIC->help()->internal()->domain()->module();
435
436 $q = "SELECT obj_id FROM lm_data WHERE import_id = " .
437 $ilDB->quote($a_import_id, "text") . " " .
438 " ORDER BY create_date DESC";
439 $obj_set = $ilDB->query($q);
440 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
441 $lm_id = ilLMObject::_lookupContObjID($obj_rec["obj_id"]);
442
443 // link only in learning module, that is not trashed
444 $ref_ids = ilObject::_getAllReferences($lm_id); // will be 0 if import of lm is in progress (new import)
445 if (count($ref_ids) == 0 || ilObject::_hasUntrashedReference($lm_id) ||
446 $help_module->isHelpLM($lm_id)) {
447 return $obj_rec["obj_id"];
448 }
449 }
450
451 return 0;
452 }
453
459 public static function _getAllObjectsForImportId(
460 string $a_import_id,
461 int $a_in_lm = 0
462 ): array {
463 global $DIC;
464
465 $ilDB = $DIC->database();
466
467 $where = ($a_in_lm > 0)
468 ? " AND lm_id = " . $ilDB->quote($a_in_lm, "integer") . " "
469 : "";
470
471 $q = "SELECT * FROM lm_data WHERE import_id = " .
472 $ilDB->quote($a_import_id, "text") . " " .
473 $where .
474 " ORDER BY create_date DESC";
475 $obj_set = $ilDB->query($q);
476
477 $items = array();
478 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
479 // check, whether lm is not trashed
480 if (ilObject::_hasUntrashedReference($obj_rec["lm_id"])) {
481 $items[] = $obj_rec;
482 }
483 }
484
485 return $items;
486 }
487
491 public static function _exists(int $a_id): bool
492 {
493 global $DIC;
494
495 $ilDB = $DIC->database();
496
497 if (is_int(strpos($a_id, "_"))) {
499 }
500
501 $q = "SELECT * FROM lm_data WHERE obj_id = " .
502 $ilDB->quote($a_id, "integer");
503 $obj_set = $ilDB->query($q);
504 if ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
505 return true;
506 } else {
507 return false;
508 }
509 }
510
511 public static function getObjectList(
512 int $lm_id,
513 string $type = ""
514 ): array {
515 global $DIC;
516
517 $ilDB = $DIC->database();
518
519 $type_str = ($type != "")
520 ? "AND type = " . $ilDB->quote($type, "text") . " "
521 : "";
522
523 $query = "SELECT * FROM lm_data " .
524 "WHERE lm_id= " . $ilDB->quote($lm_id, "integer") . " " .
525 $type_str . " " .
526 "ORDER BY title";
527 $obj_set = $ilDB->query($query);
528 $obj_list = array();
529 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
530 $obj_list[] = array("obj_id" => $obj_rec["obj_id"],
531 "title" => $obj_rec["title"],
532 "import_id" => $obj_rec["import_id"],
533 "type" => $obj_rec["type"]);
534 }
535 return $obj_list;
536 }
537
538
542 public static function _deleteAllObjectData(
543 ilObjLearningModule $a_cobj
544 ): void {
545 global $DIC;
546
547 $ilDB = $DIC->database();
548
549 $query = "SELECT * FROM lm_data " .
550 "WHERE lm_id= " . $ilDB->quote($a_cobj->getId(), "integer");
551 $obj_set = $ilDB->query($query);
552
553 while ($obj_rec = $ilDB->fetchAssoc($obj_set)) {
554 $lm_obj = ilLMObjectFactory::getInstance($a_cobj, $obj_rec["obj_id"], false);
555
556 if (is_object($lm_obj)) {
557 $lm_obj->delete(true);
558 }
559 }
560 }
561
565 public static function _lookupContObjID(int $a_id): int
566 {
567 global $DIC;
568
569 $ilDB = $DIC->database();
570
571 if (isset(self::$data_records[$a_id])) {
572 return self::$data_records[$a_id]["lm_id"];
573 }
574
575 $query = "SELECT lm_id FROM lm_data WHERE obj_id = " .
576 $ilDB->quote($a_id, "integer");
577 $obj_set = $ilDB->query($query);
578 $obj_rec = $ilDB->fetchAssoc($obj_set);
579
580 return (int) ($obj_rec["lm_id"] ?? 0);
581 }
582
586 public static function putInTree(
587 ilLMObject $a_obj,
588 int $a_parent_id = 0,
589 int $a_target_node_id = 0
590 ): void {
591 global $DIC;
592
593 $ilLog = $DIC["ilLog"];
594
595 $tree = new ilLMTree($a_obj->getContentObject()->getId());
596
597 // determine parent
598 $parent_id = ($a_parent_id != 0)
599 ? $a_parent_id
600 : $tree->getRootId();
601
602 // determine target
603 if ($a_target_node_id != 0) {
604 $target = $a_target_node_id;
605 } else {
606 // determine last child that serves as predecessor
607 if ($a_obj->getType() == "st") {
608 $s_types = array("st", "pg");
609 $childs = $tree->getChildsByTypeFilter($parent_id, $s_types);
610 } else {
611 $s_types = "pg";
612 $childs = $tree->getChildsByType($parent_id, $s_types);
613 }
614
615 if (count($childs) == 0) {
616 $target = ilTree::POS_FIRST_NODE;
617 } else {
618 $target = $childs[count($childs) - 1]["obj_id"];
619 }
620 }
621
622 if ($tree->isInTree($parent_id) && !$tree->isInTree($a_obj->getId())) {
623 $ilLog->write("LMObject::putInTree: insertNode, ID: " . $a_obj->getId() .
624 "Parent ID: " . $parent_id . ", Target: " . $target);
625
626 $tree->insertNode($a_obj->getId(), $parent_id, $target);
627 }
628 }
629
633 public static function getTree(
634 int $a_cont_obj_id
635 ): ilLMTree {
636 $tree = new ilLMTree($a_cont_obj_id);
637 $tree->readRootId();
638
639 return $tree;
640 }
641
645 public static function clipboardCut(
646 int $a_cont_obj_id,
647 array $a_ids
648 ): void {
649 $tree = ilLMObject::getTree($a_cont_obj_id);
650 $cut_ids = [];
651
652 if (!is_array($a_ids)) {
653 return;
654 } else {
655 // get all "top" ids, i.e. remove ids, that have a selected parent
656 foreach ($a_ids as $id) {
657 $path = $tree->getPathId($id);
658 $take = true;
659 foreach ($path as $path_id) {
660 if ($path_id != $id && in_array($path_id, $a_ids)) {
661 $take = false;
662 }
663 }
664 if ($take) {
665 $cut_ids[] = $id;
666 }
667 }
668 }
669
670 ilLMObject::clipboardCopy($a_cont_obj_id, $cut_ids);
671
672 // remove the objects from the tree
673 // note: we are getting chapters which are *not* in the tree
674 // we do not delete any pages/chapters here
675 foreach ($cut_ids as $id) {
676 $curnode = $tree->getNodeData($id);
677 if ($tree->isInTree($id)) {
678 $tree->deleteTree($curnode);
679 }
680 }
681 }
682
686 public static function clipboardCopy(
687 int $a_cont_obj_id,
688 array $a_ids
689 ): void {
690 global $DIC;
691
692 $ilUser = $DIC->user();
693
694 $tree = ilLMObject::getTree($a_cont_obj_id);
695
696 $ilUser->clipboardDeleteObjectsOfType("pg");
697 $ilUser->clipboardDeleteObjectsOfType("st");
698
699 // put them into the clipboard
700 $time = date("Y-m-d H:i:s", time());
701 $order = 0;
702 foreach ($a_ids as $id) {
703 $curnode = array();
704 if ($tree->isInTree($id)) {
705 $curnode = $tree->getNodeData($id);
706 $subnodes = $tree->getSubTree($curnode);
707 foreach ($subnodes as $subnode) {
708 if ($subnode["child"] != $id) {
709 $ilUser->addObjectToClipboard(
710 $subnode["child"],
711 $subnode["type"],
712 ilStr::subStr($subnode["title"], 0, 70),
713 $subnode["parent"],
714 $time,
715 $subnode["lft"]
716 );
717 }
718 }
719 }
720 $order = (($curnode["lft"] ?? 0) > 0)
721 ? $curnode["lft"]
722 : (int) ($order + 1);
723 $ilUser->addObjectToClipboard(
724 $id,
725 self::_lookupType($id),
726 ilStr::subStr(self::_lookupTitle($id), 0, 70),
727 0,
728 $time,
729 $order
730 );
731 }
732 }
733
737 public static function pasteTree(
738 ilObjLearningModule $a_target_lm,
739 int $a_item_id,
740 int $a_parent_id,
741 int $a_target,
742 string $a_insert_time,
743 array &$a_copied_nodes,
744 bool $a_as_copy = false,
745 ?ilObjLearningModule $a_source_lm = null
746 ): int {
747 global $DIC;
748
749 $item = null;
750 $ilUser = $DIC->user();
751 $ilLog = $DIC["ilLog"];
752 $lom_services = $DIC->learningObjectMetadata();
753
754 $item_lm_id = ilLMObject::_lookupContObjID($a_item_id);
755 $item_type = ilLMObject::_lookupType($a_item_id);
757 $lm_obj = ilObjectFactory::getInstanceByObjId($item_lm_id);
758 if ($item_type == "st") {
759 $item = new ilStructureObject($lm_obj, $a_item_id);
760 } elseif ($item_type == "pg") {
761 $item = new ilLMPageObject($lm_obj, $a_item_id);
762 }
763
764 $ilLog->write("Getting from clipboard type " . $item_type . ", " .
765 "Item ID: " . $a_item_id . ", of original LM: " . $item_lm_id);
766
767 if ($item_lm_id != $a_target_lm->getId() && !$a_as_copy) {
768 // @todo: check whether st is NOT in tree
769
770 // "move" metadata to new lm
771 $lom_services->derive()
772 ->fromObject($item_lm_id, $item->getId(), $item->getType())
773 ->forObject($a_target_lm->getId(), $item->getId(), $item->getType());
774
775 // delete old meta data set
776 $lom_services->deleteAll($item_lm_id, $item->getId(), $item->getType());
777
778 if ($item_type == "pg") {
779 $page = $item->getPageObject();
780 $page->buildDom();
781 $page->setParentId($a_target_lm->getId());
782 $page->update();
783 }
784 }
785
786 if ($a_as_copy) {
787 $target_item = $item->copy($a_target_lm);
788 $a_copied_nodes[$item->getId()] = $target_item->getId();
789 } else {
790 $target_item = $item;
791 }
792
793 $ilLog->write("Putting into tree type " . $target_item->getType() .
794 "Item ID: " . $target_item->getId() . ", Parent: " . $a_parent_id . ", " .
795 "Target: " . $a_target . ", Item LM:" . $target_item->getContentObject()->getId());
796
797 ilLMObject::putInTree($target_item, $a_parent_id, $a_target);
798
799 if ($a_source_lm == null) {
800 $childs = $ilUser->getClipboardChilds($item->getId(), $a_insert_time);
801 } else {
802 $childs = $a_source_lm->lm_tree->getChilds($item->getId());
803 foreach ($childs as $k => $child) {
804 $childs[$k]["id"] = $child["child"];
805 }
806 }
807
808 foreach ($childs as $child) {
809 ilLMObject::pasteTree(
810 $a_target_lm,
811 $child["id"],
812 $target_item->getId(),
814 $a_insert_time,
815 $a_copied_nodes,
816 $a_as_copy,
817 $a_source_lm
818 );
819 }
820
821 return $target_item->getId();
822 // @todo: write history (see pastePage)
823 }
824
828 public static function saveTitles(
830 array $a_titles,
831 string $a_lang = "-"
832 ): void {
833 global $DIC;
834
835 $lom_services = $DIC->learningObjectMetadata();
836
837 if ($a_lang == "") {
838 $a_lang = "-";
839 }
840 if (is_array($a_titles)) {
841 foreach ($a_titles as $id => $title) {
842 self::saveTitle($id, $title, $a_lang);
843 }
844 }
845 }
846
847 public static function saveTitle(int $id, string $title, string $lang = "-"): void
848 {
849 global $DIC;
850
851 $lom_services = $DIC->learningObjectMetadata();
853 if (in_array($lang, ["-", ""])) {
854 $lm_id = self::_lookupContObjID($id);
855 $type = self::_lookupType($id);
856 if ($type !== "" && $lm_id > 0) {
857 try {
858 $lom_services->manipulate($lm_id, $id, $type)
859 ->prepareCreateOrUpdate(
860 $lom_services->paths()->title(),
861 $title
862 )->execute();
863 } catch (Exception $e) {
864 }
865 self::_writeTitle($id, $title);
866 }
867 } else {
868 $lmobjtrans = new ilLMObjTranslation($id, $lang);
869 $lmobjtrans->setTitle($title);
870 $lmobjtrans->save();
871 }
872 }
873
877 public static function updateInternalLinks(
878 array $a_copied_nodes,
879 string $a_parent_type = "lm"
880 ): void {
881 $all_fixes = array();
882 foreach ($a_copied_nodes as $original_id => $copied_id) {
883 $copied_type = ilLMObject::_lookupType($copied_id);
884 $copy_lm = ilLMObject::_lookupContObjID($copied_id);
885
886 if ($copied_type == "pg") {
887 foreach (ilPageObject::lookupTranslations($a_parent_type, $copied_id) as $l) {
888 //
889 // 1. Outgoing links from the copied page.
890 //
891 //$targets = ilInternalLink::_getTargetsOfSource($a_parent_type.":pg", $copied_id);
892 $tpg = new ilLMPage($copied_id, 0, $l);
893 $tpg->buildDom();
894 $il = $tpg->getInternalLinks();
895 $targets = array();
896 foreach ($il as $l2) {
897 $targets[] = array("type" => ilInternalLink::_extractTypeOfTarget($l2["Target"]),
898 "id" => (int) ilInternalLink::_extractObjIdOfTarget($l2["Target"]),
899 "inst" => (int) ilInternalLink::_extractInstOfTarget($l2["Target"]));
900 }
901 $fix = array();
902 foreach ($targets as $target) {
903 if (($target["inst"] == 0 || $target["inst"] = IL_INST_ID) &&
904 ($target["type"] == "pg" || $target["type"] == "st")) {
905 // first check, whether target is also within the copied set
906 if (($a_copied_nodes[$target["id"]] ?? 0) > 0) {
907 $fix[$target["id"]] = $a_copied_nodes[$target["id"]];
908 } else {
909 // now check, if a copy if the target is already in the same lm
910
911 // only if target is not already in the same lm!
912 $trg_lm = ilLMObject::_lookupContObjID($target["id"]);
913 if ($trg_lm != $copy_lm) {
914 $lm_data = ilLMObject::_getAllObjectsForImportId("il__" . $target["type"] . "_" . $target["id"]);
915 $found = false;
916
917 foreach ($lm_data as $item) {
918 if (!$found && ($item["lm_id"] == $copy_lm)) {
919 $fix[$target["id"]] = $item["obj_id"];
920 $found = true;
921 }
922 }
923 }
924 }
925 }
926 }
927
928 // outgoing links to be fixed
929 if (count($fix) > 0) {
930 //echo "<br>--".$copied_id;
931 //var_dump($fix);
932 $t = ilObject::_lookupType($copy_lm);
933 if (isset($all_fixes[$t . ":" . $copied_id])) {
934 $all_fixes[$t . ":" . $copied_id] += $fix;
935 } else {
936 $all_fixes[$t . ":" . $copied_id] = $fix;
937 }
938 }
939 }
940 }
941
942 if ($copied_type == "pg" ||
943 $copied_type == "st") {
944 //
945 // 2. Incoming links to the original pages
946 //
947 // A->B A2 (A+B currently copied)
948 // A->C B2
949 // B->A
950 // C->A C2->A (C already copied)
951 $original_lm = ilLMObject::_lookupContObjID($original_id);
952 $original_type = ilObject::_lookupType($original_lm);
953
954 if ($original_lm != $copy_lm) {
955 // This gets sources that link to A+B (so we have C here)
956 // (this also does already the trick when instance map areas are given in C)
957 // int_link, where target_type, target_id, target_inst -> ok
959 $copied_type,
960 $original_id,
961 0
962 );
963
964 // mobs linking to $original_id
965 // map_area, where link_type, target -> ok
966 $mobs = ilMapArea::_getMobsForTarget("int", "il__" . $copied_type .
967 "_" . $original_id);
968
969 // pages using these mobs
970 foreach ($mobs as $mob) {
971 // mob_usage, where id -> ok
972 // mep_item, where foreign_id, type -> ok
973 // mep_tree, where child -> already existed
974 // il_news_item, where mob_id -> ok
975 // map_area, where link_type, target -> aready existed
976 // media_item, where id -> already existed
977 // personal_clipboard, where item_id, type -> ok
978 $usages = ilObjMediaObject::lookupUsages($mob);
979 foreach ($usages as $usage) {
980 if ($usage["type"] == "lm:pg" | $usage["type"] == "lm:st") {
981 $sources[] = $usage;
982 }
983 }
984 }
985 $fix = array();
986 foreach ($sources as $source) {
987 $stype = explode(":", $source["type"]);
988 $source_type = $stype[1] ?? "";
989
990 if ($source_type == "pg" || $source_type == "st") {
991 // first of all: source must be in original lm
992 $src_lm = ilLMObject::_lookupContObjID($source["id"]);
993
994 if ($src_lm == $original_lm) {
995 // check, if a copy if the source is already in the same lm
996 // now we look for the latest copy of C in LM2
998 "il__" . $source_type . "_" . $source["id"],
999 $copy_lm
1000 );
1001 $found = false;
1002 foreach ($lm_data as $item) {
1003 if (!$found) {
1004 $fix[$item["obj_id"]][$original_id] = $copied_id;
1005 $found = true;
1006 }
1007 }
1008 }
1009 }
1010 }
1011 // outgoing links to be fixed
1012 if (count($fix) > 0) {
1013 foreach ($fix as $page_id => $fix_array) {
1014 $t = ilObject::_lookupType($copy_lm);
1015 if (isset($all_fixes[$t . ":" . $page_id])) {
1016 $all_fixes[$t . ":" . $page_id] += $fix_array;
1017 } else {
1018 $all_fixes[$t . ":" . $page_id] = $fix_array;
1019 }
1020 }
1021 }
1022 }
1023 }
1024 }
1025
1026 foreach ($all_fixes as $pg => $fixes) {
1027 $pg = explode(":", $pg);
1028 foreach (ilPageObject::lookupTranslations($pg[0], $pg[1]) as $l) {
1029 $page = ilPageObjectFactory::getInstance($pg[0], $pg[1], 0, $l);
1030 if ($page->moveIntLinks($fixes)) {
1031 $page->update(true, true);
1032 }
1033 }
1034 }
1035 }
1036
1040 public static function uniqueTypesCheck(array $a_items): bool
1041 {
1042 $types = array();
1043 if (is_array($a_items)) {
1044 foreach ($a_items as $item) {
1045 $type = ilLMObject::_lookupType($item);
1046 $types[$type] = $type;
1047 }
1048 }
1049
1050 if (count($types) > 1) {
1051 return false;
1052 }
1053 return true;
1054 }
1055
1059 public static function writeLayout(
1060 int $a_obj_id,
1061 string $a_layout,
1062 ?ilObjLearningModule $a_lm = null
1063 ): void {
1064 global $DIC;
1065
1066 $ilDB = $DIC->database();
1067
1068 $t = ilLMObject::_lookupType($a_obj_id);
1069
1070 if ($t == "pg") {
1071 $query = "UPDATE lm_data SET " .
1072 " layout = " . $ilDB->quote($a_layout, "text") .
1073 " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer");
1074 $ilDB->manipulate($query);
1075 } elseif ($t == "st" && is_object($a_lm)) {
1076 $node = $a_lm->getLMTree()->getNodeData($a_obj_id);
1077 $child_nodes = $a_lm->getLMTree()->getSubTree($node);
1078 if (is_array($child_nodes) && count($child_nodes) > 0) {
1079 foreach ($child_nodes as $c) {
1080 if ($c["type"] == "pg") {
1081 $query = "UPDATE lm_data SET " .
1082 " layout = " . $ilDB->quote($a_layout, "text") .
1083 " WHERE obj_id = " . $ilDB->quote($c["child"], "integer");
1084 $ilDB->manipulate($query);
1085 }
1086 }
1087 }
1088 }
1089 }
1090
1094 public static function lookupLayout(int $a_obj_id): string
1095 {
1096 global $DIC;
1097
1098 $ilDB = $DIC->database();
1099
1100 $query = "SELECT layout FROM lm_data WHERE obj_id = " .
1101 $ilDB->quote($a_obj_id, "integer");
1102 $obj_set = $ilDB->query($query);
1103 $obj_rec = $ilDB->fetchAssoc($obj_set);
1104
1105 return $obj_rec["layout"];
1106 }
1107
1111 public static function getPagesOfChapter(
1112 int $a_lm_id,
1113 int $a_chap_id
1114 ): array {
1115 // update structure entries: if at least one page of a chapter is public set chapter to public too
1116 $lm_tree = new ilTree($a_lm_id);
1117 $lm_tree->setTableNames('lm_tree', 'lm_data');
1118 $lm_tree->setTreeTablePK("lm_id");
1119 $lm_tree->readRootId();
1120
1121 $childs = $lm_tree->getChildsByType($a_chap_id, "pg");
1122
1123 return $childs;
1124 }
1125
1129 public static function _getAllLMObjectsOfLM(
1130 int $a_lm_id,
1131 string $a_type = ""
1132 ): array {
1133 global $DIC;
1134
1135 $ilDB = $DIC->database();
1136
1137 $and = ($a_type != "")
1138 ? " AND type = " . $ilDB->quote($a_type, "text")
1139 : "";
1140
1141 $set = $ilDB->query("SELECT obj_id FROM lm_data " .
1142 " WHERE lm_id = " . $ilDB->quote($a_lm_id, "integer") . $and);
1143 $obj_ids = array();
1144 while ($rec = $ilDB->fetchAssoc($set)) {
1145 $obj_ids[] = $rec["obj_id"];
1146 }
1147
1148 return $obj_ids;
1149 }
1150
1151
1155
1156 public static function saveExportId(
1157 int $a_lm_id,
1158 int $a_lmobj_id,
1159 string $a_exp_id,
1160 string $a_type = "pg"
1161 ): void {
1162 global $DIC;
1163
1164 $manipulator = $DIC->learningObjectMetadata()->manipulate($a_lm_id, $a_lmobj_id, $a_type);
1165 if (trim($a_exp_id) == "") {
1166 $manipulator = $manipulator->prepareDelete(self::getPathToExportIDInLOM());
1167 } else {
1168 $manipulator = $manipulator->prepareCreateOrUpdate(self::getPathToExportIDInLOM(), $a_exp_id);
1169 }
1170 $manipulator->execute();
1171 }
1172
1173 protected static function getPathToExportIDInLOM(): LOMPath
1174 {
1175 global $DIC;
1176
1177 return $DIC->learningObjectMetadata()
1178 ->paths()
1179 ->custom()
1180 ->withNextStep('general')
1181 ->withNextStep('identifier')
1182 ->withNextStep('catalog')
1183 ->withAdditionalFilterAtCurrentStep(FilterType::DATA, 'ILIAS_NID')
1184 ->withNextStepToSuperElement()
1185 ->withNextStep('entry')
1186 ->get();
1187 }
1188
1189 public static function getExportId(
1190 int $a_lm_id,
1191 int $a_lmobj_id,
1192 string $a_type = "pg"
1193 ): string {
1194 global $DIC;
1195
1196 // look for export id
1197 $export_id_path = self::getPathToExportIDInLOM();
1198 return $DIC->learningObjectMetadata()->read(
1199 $a_lm_id,
1200 $a_lmobj_id,
1201 $a_type,
1202 $export_id_path
1203 )->firstData($export_id_path)->value();
1204 }
1205
1209 public function existsExportID(
1210 int $a_lm_id,
1211 int $a_exp_id,
1212 string $a_type = "pg"
1213 ): bool {
1214 $searcher = $this->lom_services->search();
1215
1216 $search_clause = $searcher->getClauseFactory()->getBasicClause(
1217 self::getPathToExportIDInLOM(),
1218 Mode::EQUALS,
1219 $a_exp_id
1220 );
1221 $results = $searcher->execute(
1222 $search_clause,
1223 1,
1224 null,
1225 $searcher->getFilter($a_lm_id, Placeholder::ANY, $a_type)
1226 );
1227 return count(iterator_to_array($results)) > 0;
1228 }
1229
1233 public static function getDuplicateExportIDs(
1234 int $a_lm_id,
1235 string $a_type = "pg"
1236 ): array {
1237 global $DIC;
1238
1239 $lom_services = $DIC->learningObjectMetadata();
1240 $export_id_path = self::getPathToExportIDInLOM();
1241
1242 $searcher = $lom_services->search();
1243 $search_clause = $searcher->getClauseFactory()->getBasicClause(
1244 $export_id_path,
1245 Mode::EQUALS,
1246 '',
1247 true
1248 );
1249 $search_results = $searcher->execute(
1250 $search_clause,
1251 1,
1252 null,
1253 $searcher->getFilter($a_lm_id, Placeholder::ANY, $a_type)
1254 );
1255
1256 $res = [];
1257 foreach ($search_results as $search_result) {
1258 if (!ilLMObject::_exists($search_result->subID())) {
1259 continue;
1260 }
1261 $reader = $lom_services->read(
1262 $search_result->objID(),
1263 $search_result->subID(),
1264 $search_result->type(),
1265 $export_id_path
1266 );
1267 foreach ($reader->allData($export_id_path) as $export_id_datum) {
1268 $export_id = trim($export_id_datum->value());
1269 $res[$export_id] = ($res[$export_id] ?? 0) + 1;
1270 }
1271 }
1272 return $res;
1273 }
1274
1275 // Get effective title
1276 public static function _getNodePresentationTitle(
1277 array $a_node,
1278 string $a_mode = self::PAGE_TITLE,
1279 bool $a_include_numbers = false,
1280 bool $a_time_scheduled_activation = false,
1281 bool $a_force_content = false,
1282 int $a_lm_id = 0,
1283 string $a_lang = "-"
1284 ): string {
1285 if ($a_lang == "") {
1286 $a_lang = "-";
1287 }
1288
1289 if ($a_node["type"] == "st") {
1291 $a_node["child"],
1292 self::CHAPTER_TITLE,
1293 $a_include_numbers,
1294 $a_time_scheduled_activation,
1295 $a_force_content,
1296 $a_lm_id,
1297 $a_lang
1298 );
1299 } else {
1301 $a_node["child"],
1302 $a_mode,
1303 $a_include_numbers,
1304 $a_time_scheduled_activation,
1305 $a_force_content,
1306 $a_lm_id,
1307 $a_lang
1308 );
1309 }
1310 }
1311
1312 public static function getShortTitles(
1313 int $a_lm_id,
1314 string $a_lang = "-"
1315 ): array {
1316 global $DIC;
1317
1318 $db = $DIC->database();
1319
1320 $title_data = array();
1321 if ($a_lang == "-") {
1322 $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 = " .
1323 $db->quote($a_lm_id, "integer") . " ORDER BY t.lft, d.title");
1324 } else {
1325 $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 " .
1326 " LEFT JOIN lm_tree t ON (d.obj_id = t.child) " .
1327 " LEFT JOIN lm_data_transl tr ON (tr.id = d.obj_id AND tr.lang=" . $db->quote($a_lang, "text") . ") WHERE d.lm_id = " .
1328 $db->quote($a_lm_id, "integer") . " ORDER BY t.lft, d.title");
1329 }
1330 while ($rec = $db->fetchAssoc($set)) {
1331 $title_data[] = $rec;
1332 }
1333 return $title_data;
1334 }
1335
1336 public static function writeShortTitle(
1337 int $a_id,
1338 string $a_short_title,
1339 string $a_lang = "-"
1340 ): void {
1341 global $DIC;
1342
1343 $db = $DIC->database();
1344
1345 if ($a_lang != "-" && $a_lang != "") {
1346 $trans = new ilLMObjTranslation($a_id, $a_lang);
1347 $trans->setShortTitle($a_short_title);
1348 $trans->save();
1349 } else {
1350 $db->manipulate(
1351 "UPDATE lm_data SET " .
1352 " short_title = " . $db->quote($a_short_title, "text") .
1353 " WHERE obj_id = " . $db->quote($a_id, "integer")
1354 );
1355 }
1356 }
1357}
$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 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 array $data_records
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="-")
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:25