ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilObject.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
32 class ilObject
33 {
34  public const TITLE_LENGTH = 255; // title column max length in db
35  public const DESC_LENGTH = 128; // (short) description column max length in db
36  public const LONG_DESC_LENGTH = 4000; // long description column max length in db
37  public const TABLE_OBJECT_DATA = "object_data";
38 
40 
41  protected ilLogger $obj_log;
42  protected ?ILIAS $ilias;
44  protected ilDBInterface $db;
45  protected ?ilLogger $log;
46  protected ?ilErrorHandling $error;
47  protected ilTree $tree;
51  protected ilObjUser $user;
52  protected ilLanguage $lng;
55 
56  protected bool $call_by_reference;
57  protected int $max_title = self::TITLE_LENGTH;
58  protected int $max_desc = self::DESC_LENGTH;
59  protected bool $add_dots = true;
60  protected ?int $ref_id = null;
61  protected string $type = "";
62  protected string $title = "";
63  protected string $desc = "";
64  protected string $long_desc = "";
65  protected int $owner = 0;
66  protected string $create_date = "";
67  protected string $last_update = "";
68  protected string $import_id = "";
69  protected bool $register = false; // registering required for object? set to true to implement a subscription interface
70 
71  private bool $process_auto_reating = false;
72 
73 
77  public array $objectList;
78 
79 
80  // BEGIN WebDAV: WebDAV needs to access the untranslated title of an object
81  public string $untranslatedTitle;
82  // END WebDAV: WebDAV needs to access the untranslated title of an object
83 
88  public function __construct(
89  protected int $id = 0,
90  protected bool $referenced = true
91  ) {
93  global $DIC;
94 
95  $this->ilias = $DIC["ilias"];
96  $this->obj_definition = $DIC["objDefinition"];
97  $this->db = $DIC["ilDB"];
98  $this->log = $DIC["ilLog"];
99  $this->obj_log = ilLoggerFactory::getLogger("obj");
100  $this->error = $DIC["ilErr"];
101  $this->tree = $DIC["tree"];
102  $this->app_event_handler = $DIC["ilAppEventHandler"];
103  $this->lom_services = $DIC->learningObjectMetadata();
104  $this->object_dic = ilObjectDIC::dic();
105 
106  $this->call_by_reference = $this->referenced;
107 
108  if (isset($DIC["lng"])) {
109  $this->lng = $DIC["lng"];
110  }
111 
112  if (isset($DIC["ilUser"])) {
113  $this->user = $DIC["ilUser"];
114  }
115 
116  if (isset($DIC["rbacadmin"])) {
117  $this->rbac_admin = $DIC["rbacadmin"];
118  }
119 
120  if (isset($DIC["rbacreview"])) {
121  $this->rbac_review = $DIC["rbacreview"];
122  }
123 
124  if ($id == 0) {
125  $this->referenced = false; // newly created objects are never referenced
126  } // they will get referenced if createReference() is called
127 
128  if ($this->referenced) {
129  $this->ref_id = $id;
130  } else {
131  $this->id = $id;
132  }
133  // read object data
134  if ($id != 0) {
135  $this->read();
136  }
137  }
138 
140  {
141  if ($this->object_properties === null) {
142  $this->object_properties = $this->object_dic['object_properties_agregator']->getFor($this->id, $this->type);
143  }
145  }
146 
150  public function flushObjectProperties(): void
151  {
152  $this->object_properties = null;
153  }
154 
158  final public function withReferences(): bool
159  {
160  // both vars could differ. this method should always return true if one of them is true without changing their status
161  return ($this->call_by_reference) ? true : $this->referenced;
162  }
163 
168  public function processAutoRating(): void
169  {
170  $this->process_auto_reating = true;
171  }
172 
173  public function read(): void
174  {
175  global $DIC;
176  try {
177  $ilUser = $DIC["ilUser"];
178  } catch (InvalidArgumentException $e) {
179  }
180 
181  if ($this->referenced) {
182  if (!isset($this->ref_id)) {
183  $message = "ilObject::read(): No ref_id given! (" . $this->type . ")";
184  $this->error->raiseError($message, $this->error->WARNING);
185  }
186 
187  // read object data
188  $sql =
189  "SELECT od.obj_id, od.type, od.title, od.description, od.owner, od.create_date," . PHP_EOL
190  . "od.last_update, od.import_id, ore.ref_id, ore.obj_id, ore.deleted, ore.deleted_by" . PHP_EOL
191  . "FROM " . self::TABLE_OBJECT_DATA . " od" . PHP_EOL
192  . "JOIN object_reference ore ON od.obj_id = ore.obj_id" . PHP_EOL
193  . "WHERE ore.ref_id = " . $this->db->quote($this->ref_id, "integer") . PHP_EOL
194  ;
195 
196  $result = $this->db->query($sql);
197 
198  // check number of records
199  if ($this->db->numRows($result) === 0) {
200  $message = sprintf(
201  "ilObject::read(): Object with ref_id %s not found! (%s)",
202  $this->ref_id,
203  $this->type
204  );
205  $this->error->raiseError($message, $this->error->WARNING);
206  }
207  } else {
208  if (!isset($this->id)) {
209  $message = sprintf("ilObject::read(): No obj_id given! (%s)", $this->type);
210  $this->error->raiseError($message, $this->error->WARNING);
211  }
212 
213  $sql =
214  "SELECT obj_id, type, title, description, owner, create_date, last_update, import_id, offline" . PHP_EOL
215  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
216  . "WHERE obj_id = " . $this->db->quote($this->id, "integer") . PHP_EOL
217  ;
218  $result = $this->db->query($sql);
219 
220  if ($this->db->numRows($result) === 0) {
221  $message = sprintf("ilObject::read(): Object with obj_id: %s (%s) not found!", $this->id, $this->type);
222  throw new ilObjectNotFoundException($message);
223  }
224  }
225  $obj = $this->db->fetchAssoc($result);
226 
227  $this->id = (int) $obj["obj_id"];
228 
229  // check type match (the "xxx" type is used for the unit test)
230  if ($this->type != $obj["type"] && $obj["type"] != "xxx") {
231  $message = sprintf(
232  "ilObject::read(): Type mismatch. Object with obj_id: %s was instantiated by type '%s'. DB type is: %s",
233  $this->id,
234  $this->type,
235  $obj["type"]
236  );
237 
238  $this->log->write($message);
239  throw new ilObjectTypeMismatchException($message);
240  }
241 
242  $this->type = (string) $obj["type"];
243  $this->title = (string) $obj["title"];
244  // BEGIN WebDAV: WebDAV needs to access the untranslated title of an object
245  $this->untranslatedTitle = (string) $obj["title"];
246  // END WebDAV: WebDAV needs to access the untranslated title of an object
247 
248  $this->desc = (string) $obj["description"];
249  $this->owner = (int) $obj["owner"];
250  $this->create_date = (string) $obj["create_date"];
251  $this->last_update = (string) $obj["last_update"];
252  $this->import_id = (string) $obj["import_id"];
253 
254  if ($this->obj_definition->isRBACObject($this->getType())) {
255  $sql =
256  "SELECT obj_id, description" . PHP_EOL
257  . "FROM object_description" . PHP_EOL
258  . "WHERE obj_id = " . $this->db->quote($this->id, 'integer') . PHP_EOL
259  ;
260 
261  $res = $this->db->query($sql);
262 
263  $this->long_desc = '';
264  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
265  if (($row->description ?? '') !== '') {
266  $this->setDescription($row->description);
267  }
268  }
269  }
270 
271  // multilingual support system objects (sys) & categories (db)
272  $translation_type = $this->obj_definition->getTranslationType($this->type);
273 
274  if ($translation_type == "sys") {
275  $this->title = $this->lng->txt("obj_" . $this->type);
276  $this->setDescription($this->lng->txt("obj_" . $this->type . "_desc"));
277  } elseif ($translation_type == "db") {
278  $sql =
279  "SELECT title, description" . PHP_EOL
280  . "FROM object_translation" . PHP_EOL
281  . "WHERE obj_id = " . $this->db->quote($this->id, 'integer') . PHP_EOL
282  . "AND lang_code = " . $this->db->quote($ilUser->getCurrentLanguage(), 'text') . PHP_EOL
283  ;
284  $r = $this->db->query($sql);
285  $row = $r->fetchRow(ilDBConstants::FETCHMODE_OBJECT);
286  if ($row) {
287  $this->title = (string) $row->title;
288  $this->setDescription((string) $row->description);
289  }
290  }
291 
292  $this->object_properties = null;
293  }
294 
295  public function getId(): int
296  {
297  return $this->id;
298  }
299 
300  public function setId(int $id): void
301  {
302  $this->id = $id;
303  }
304 
305  final public function setRefId(int $ref_id): void
306  {
307  $this->ref_id = $ref_id;
308  $this->referenced = true;
309  }
310 
311  final public function getRefId(): int
312  {
313  return $this->ref_id ?? 0;
314  }
315 
316  public function getType(): string
317  {
318  return $this->type;
319  }
320 
321  final public function setType(string $type): void
322  {
323  $this->type = $type;
324  }
325 
331  public function getPresentationTitle(): string
332  {
333  return $this->getTitle();
334  }
335 
336  public function getTitle(): string
337  {
338  return $this->title;
339  }
340 
345  final public function getUntranslatedTitle(): string
346  {
348  }
349 
350  final public function setTitle(string $title): void
351  {
352  $property = $this->getObjectProperties()->getPropertyTitleAndDescription()->withTitle(
353  ilStr::shortenTextExtended($title, $this->max_title ?? self::TITLE_LENGTH, $this->add_dots)
354  );
355 
356  $this->object_properties = $this->getObjectProperties()->withPropertyTitleAndDescription($property);
357 
358  $this->title = $property->getTitle();
359 
360  // WebDAV needs to access the untranslated title of an object
361  $this->untranslatedTitle = $this->title;
362  }
363 
364  final public function getDescription(): string
365  {
366  return $this->desc;
367  }
368 
369  final public function setDescription(string $description): void
370  {
371  $property = $this->getObjectProperties()
372  ->getPropertyTitleAndDescription()->withDescription($description);
373 
374  $this->object_properties = $this->getObjectProperties()->withPropertyTitleAndDescription($property);
375 
376  // Shortened form is storted in object_data. Long form is stored in object_description
377  $this->desc = $property->getDescription();
378  $this->long_desc = $property->getLongDescription();
379  }
380 
384  public function getLongDescription(): string
385  {
386  if ($this->long_desc !== '') {
387  return $this->long_desc;
388  }
389 
390  if ($this->desc !== '') {
391  return $this->desc;
392  }
393  return '';
394  }
395 
396  final public function getImportId(): string
397  {
398  return $this->import_id;
399  }
400 
401  final public function setImportId(string $import_id): void
402  {
403  $this->object_properties = $this->getObjectProperties()->withImportId($import_id);
404  $this->import_id = $import_id;
405  }
406 
410  final public static function _lookupObjIdByImportId(string $import_id): int
411  {
412  global $DIC;
413  $db = $DIC->database();
414 
415  $sql =
416  "SELECT obj_id" . PHP_EOL
417  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
418  . "WHERE import_id = " . $db->quote($import_id, "text") . PHP_EOL
419  . "ORDER BY create_date DESC" . PHP_EOL
420  ;
421  $result = $db->query($sql);
422 
423  if ($db->numRows($result) == 0) {
424  return 0;
425  }
426 
427  $row = $db->fetchObject($result);
428 
429  return (int) $row->obj_id;
430  }
431 
435  public function setOfflineStatus(bool $status): void
436  {
437  $property_is_online = $this->getObjectProperties()->getPropertyIsOnline()->withOnline();
438  if ($status) {
439  $property_is_online = $property_is_online->withOffline();
440  }
441 
442  $this->object_properties = $this->getObjectProperties()->withPropertyIsOnline($property_is_online);
443  }
444 
445  public function getOfflineStatus(): bool
446  {
447  return !$this->getObjectProperties()->getPropertyIsOnline()->getIsOnline();
448  }
449 
450  public function supportsOfflineHandling(): bool
451  {
452  return $this->obj_definition->supportsOfflineHandling($this->getType());
453  }
454 
455  public static function _lookupImportId(int $obj_id): string
456  {
457  global $DIC;
458 
459  $db = $DIC->database();
460 
461  $sql =
462  "SELECT import_id" . PHP_EOL
463  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
464  . "WHERE obj_id = " . $db->quote($obj_id, "integer") . PHP_EOL
465  ;
466 
467  $res = $db->query($sql);
468  while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
469  return (string) $row->import_id;
470  }
471  return '';
472  }
473 
474  final public function getOwner(): int
475  {
476  return $this->owner;
477  }
478 
482  final public function getOwnerName(): string
483  {
484  return ilObject::_lookupOwnerName($this->getOwner());
485  }
486 
490  final public static function _lookupOwnerName(int $owner_id): string
491  {
492  global $DIC;
493  $lng = $DIC->language();
494 
495  $owner = null;
496  if ($owner_id != -1) {
497  if (ilObject::_exists($owner_id)) {
498  $owner = new ilObjUser($owner_id);
499  }
500  }
501 
502  $own_name = $lng->txt("unknown");
503  if (is_object($owner)) {
504  $own_name = $owner->getFullname();
505  }
506 
507  return $own_name;
508  }
509 
510  final public function setOwner(int $usr_id): void
511  {
512  $this->owner = $usr_id;
513  }
514 
518  final public function getCreateDate(): string
519  {
520  return $this->create_date;
521  }
522 
526  final public function getLastUpdateDate(): string
527  {
528  return $this->last_update;
529  }
530 
531 
535  public function create(): int
536  {
537  global $DIC;
538  $user = $DIC["ilUser"];
539 
540  if (!isset($this->type)) {
541  $message = sprintf("%s::create(): No object type given!", get_class($this));
542  $this->error->raiseError($message, $this->error->WARNING);
543  }
544 
545  $this->log->write("ilObject::create(), start");
546 
547  // determine owner
548  $owner = 0;
549  if ($this->getOwner() > 0) {
550  $owner = $this->getOwner();
551  } elseif (is_object($user)) {
552  $owner = $user->getId();
553  }
554 
555  $this->id = $this->db->nextId(self::TABLE_OBJECT_DATA);
556  $values = [
557  "obj_id" => ["integer", $this->getId()],
558  "type" => ["text", $this->getType()],
559  "title" => ["text", $this->getTitle()],
560  "description" => ["text", $this->getDescription()],
561  "owner" => ["integer", $owner],
562  "create_date" => ["date", $this->db->now()],
563  "last_update" => ["date", $this->db->now()],
564  "import_id" => ["text", $this->getImportId()],
565  ];
566 
567  $this->db->insert(self::TABLE_OBJECT_DATA, $values);
568  $this->object_properties = null;
569 
570  // Save long form of description if is rbac object
571  if ($this->obj_definition->isRBACObject($this->getType())) {
572  $values = [
573  'obj_id' => ['integer',$this->id],
574  'description' => ['clob', $this->getLongDescription()]
575  ];
576  $this->db->insert('object_description', $values);
577  }
578 
579  if ($this->supportsOfflineHandling()) {
580  $property_is_online = $this->getObjectProperties()->getPropertyIsOnline()->withOffline();
581  $this->getObjectProperties()->storePropertyIsOnline($property_is_online);
582  }
583 
584  if ($this->obj_definition->isOrgUnitPermissionType($this->type)) {
585  ilOrgUnitGlobalSettings::getInstance()->saveDefaultPositionActivationStatus($this->id);
586  }
587 
588  // the line ($this->read();) messes up meta data handling: meta data,
589  // that is not saved at this time, gets lost, so we query for the dates alone
590  $sql =
591  "SELECT last_update, create_date" . PHP_EOL
592  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
593  . "WHERE obj_id = " . $this->db->quote($this->id, "integer") . PHP_EOL
594  ;
595  $obj_set = $this->db->query($sql);
596  $obj_rec = $this->db->fetchAssoc($obj_set);
597  $this->last_update = $obj_rec["last_update"];
598  $this->create_date = $obj_rec["create_date"];
599 
600  // set owner for new objects
601  $this->setOwner($owner);
602 
603  // write log entry
604  $this->log->write(
605  sprintf(
606  "ilObject::create(), finished, obj_id: %s, type: %s, title: %s",
607  $this->getId(),
608  $this->getType(),
609  $this->getTitle()
610  )
611  );
612 
613  $this->app_event_handler->raise(
614  'components/ILIAS/ILIASObject',
615  'create',
616  [
617  'obj_id' => $this->id,
618  'obj_type' => $this->type
619  ]
620  );
621 
622  return $this->id;
623  }
624 
625  public function update(): bool
626  {
627  $this->getObjectProperties()->storeCoreProperties();
628 
629  $this->app_event_handler->raise(
630  'components/ILIAS/ILIASObject',
631  'update',
632  [
633  'obj_id' => $this->getId(),
634  'obj_type' => $this->getType(),
635  'ref_id' => $this->getRefId()
636  ]
637  );
638 
639  return true;
640  }
641 
651  final public function MDUpdateListener(string $element): void
652  {
653  if ($this->beforeMDUpdateListener($element)) {
654  $this->app_event_handler->raise(
655  'components/ILIAS/ILIASObject',
656  'update',
657  ['obj_id' => $this->getId(),
658  'obj_type' => $this->getType(),
659  'ref_id' => $this->getRefId()
660  ]
661  );
662 
663  // Update Title and description
664  if ($element == 'General') {
665  $paths = $this->lom_services->paths();
666  $reader = $this->lom_services->read(
667  $this->getId(),
668  0,
669  $this->getType(),
670  $paths->custom()->withNextStep('general')->get()
671  );
672 
673  $this->setTitle($reader->firstData($paths->title())->value());
674  $this->setDescription($reader->firstData($paths->descriptions())->value());
675 
676  $this->update();
677  }
678  $this->doMDUpdateListener($element);
679  }
680  }
681 
682  protected function doMDUpdateListener(string $a_element): void
683  {
684  }
685 
686  protected function beforeMDUpdateListener(string $a_element): bool
687  {
688  return true;
689  }
690 
691  final public function createMetaData(): void
692  {
693  if ($this->beforeCreateMetaData()) {
694  global $DIC;
695  $ilUser = $DIC["ilUser"];
696 
697  $this->lom_services->derive()->fromBasicProperties(
698  $this->getTitle(),
699  $this->getLongDescription(),
700  $ilUser->getPref('language')
701  )->forObject($this->getId(), 0, $this->getType());
702 
703  $this->doCreateMetaData();
704  }
705  }
706 
707  protected function doCreateMetaData(): void
708  {
709  }
710 
711  protected function beforeCreateMetaData(): bool
712  {
713  return true;
714  }
715 
716  final public function updateMetaData(): void
717  {
718  if ($this->beforeUpdateMetaData()) {
719  $paths = $this->lom_services->paths();
720 
721  $manipulator = $this->lom_services->manipulate($this->getId(), 0, $this->getType())
722  ->prepareCreateOrUpdate($paths->title(), $this->getTitle());
723 
724  if ($this->getDescription() !== '') {
725  $manipulator = $manipulator->prepareCreateOrUpdate(
726  $paths->firstDescription(),
727  $this->getLongDescription()
728  );
729  } else {
730  $manipulator = $manipulator->prepareDelete($paths->firstDescription());
731  }
732 
733  $manipulator->execute();
734  $this->doUpdateMetaData();
735  }
736  }
737 
738  protected function doUpdateMetaData(): void
739  {
740  }
741 
742  protected function beforeUpdateMetaData(): bool
743  {
744  return true;
745  }
746 
747  final public function deleteMetaData(): void
748  {
749  if ($this->beforeDeleteMetaData()) {
750  $this->lom_services->deleteAll($this->getId(), 0, $this->getType());
751  $this->doDeleteMetaData();
752  }
753  }
754 
755  protected function doDeleteMetaData(): void
756  {
757  }
758 
759  protected function beforeDeleteMetaData(): bool
760  {
761  return true;
762  }
763 
767  final public function updateOwner(): void
768  {
769  $values = [
770  "owner" => ["integer", $this->getOwner()],
771  "last_update" => ["date", $this->db->now()]
772  ];
773 
774  $where = [
775  "obj_id" => ["integer", $this->getId()]
776  ];
777 
778  $this->db->update(self::TABLE_OBJECT_DATA, $values, $where);
779 
780  // get current values from database so last_update is updated as well
781  $this->read();
782  }
783 
784  final public static function _getIdForImportId(string $import_id): int
785  {
786  global $DIC;
787  $db = $DIC->database();
788  $db->setLimit(1, 0);
789 
790  $sql =
791  "SELECT obj_id" . PHP_EOL
792  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
793  . "WHERE import_id = " . $db->quote($import_id, "text") . PHP_EOL
794  . "ORDER BY create_date DESC" . PHP_EOL
795  ;
796 
797  $result = $db->query($sql);
798 
799  if ($row = $db->fetchAssoc($result)) {
800  return (int) $row["obj_id"];
801  }
802 
803  return 0;
804  }
805 
810  final public static function _getAllReferences(int $id): array
811  {
812  global $DIC;
813  $db = $DIC->database();
814 
815  $sql =
816  "SELECT ref_id" . PHP_EOL
817  . "FROM object_reference" . PHP_EOL
818  . "WHERE obj_id = " . $db->quote($id, 'integer') . PHP_EOL
819  ;
820 
821  $result = $db->query($sql);
822 
823  $ref = [];
824  while ($row = $db->fetchAssoc($result)) {
825  $ref[(int) $row["ref_id"]] = (int) $row["ref_id"];
826  }
827 
828  return $ref;
829  }
830 
831  public static function _lookupTitle(int $obj_id): string
832  {
833  global $DIC;
834  return (string) $DIC["ilObjDataCache"]->lookupTitle($obj_id);
835  }
836 
840  public static function lookupOfflineStatus(int $obj_id): bool
841  {
842  global $DIC;
843  return $DIC['ilObjDataCache']->lookupOfflineStatus($obj_id);
844  }
845 
849  final public static function _lookupOwner(int $obj_id): int
850  {
851  global $DIC;
852  return (int) $DIC["ilObjDataCache"]->lookupOwner($obj_id);
853  }
854 
858  final public static function _getIdsForTitle(string $title, string $type = '', bool $partial_match = false): array
859  {
860  global $DIC;
861  $db = $DIC->database();
862 
863  $where = "title = " . $db->quote($title, "text");
864  if ($partial_match) {
865  $where = $db->like("title", "text", '%' . $title . '%');
866  }
867 
868  $sql =
869  "SELECT obj_id" . PHP_EOL
870  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
871  . "WHERE " . $where . PHP_EOL
872  ;
873 
874  if ($type != '') {
875  $sql .= " AND type = " . $db->quote($type, "text");
876  }
877 
878  $result = $db->query($sql);
879 
880  $object_ids = [];
881  while ($row = $db->fetchAssoc($result)) {
882  $object_ids[] = (int) $row['obj_id'];
883  }
884 
885  return $object_ids;
886  }
887 
888  final public static function _lookupDescription(int $obj_id): string
889  {
890  global $DIC;
891  return (string) $DIC["ilObjDataCache"]->lookupDescription($obj_id);
892  }
893 
894  final public static function _lookupLastUpdate(int $obj_id, bool $formatted = false): string
895  {
896  global $DIC;
897 
898  $last_update = $DIC["ilObjDataCache"]->lookupLastUpdate($obj_id);
899 
900  if ($formatted) {
901  return ilDatePresentation::formatDate(new ilDateTime($last_update, IL_CAL_DATETIME));
902  }
903 
904  return (string) $last_update;
905  }
906 
907  final public static function _getLastUpdateOfObjects(array $obj_ids): string
908  {
909  global $DIC;
910  $db = $DIC->database();
911 
912  $sql =
913  "SELECT MAX(last_update) as last_update" . PHP_EOL
914  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
915  . "WHERE " . $db->in("obj_id", $obj_ids, false, "integer") . PHP_EOL
916  ;
917 
918  $result = $db->query($sql);
919  $row = $db->fetchAssoc($result);
920 
921  return (string) $row["last_update"];
922  }
923 
924  final public static function _lookupObjId(int $ref_id): int
925  {
926  global $DIC;
927  return $DIC["ilObjDataCache"]->lookupObjId($ref_id);
928  }
929 
930  final public static function _setDeletedDate(int $ref_id, int $deleted_by): void
931  {
932  global $DIC;
933  $db = $DIC->database();
934 
935  $values = [
936  "deleted" => ["date", $db->now()],
937  "deleted_by" => ["integer", $deleted_by]
938  ];
939 
940  $where = [
941  "ref_id" => ["integer", $ref_id]
942  ];
943 
944  $db->update("object_reference", $values, $where);
945  }
946 
950  public static function setDeletedDates(array $ref_ids, int $user_id): void
951  {
952  global $DIC;
953  $db = $DIC->database();
954 
955  $sql =
956  "UPDATE object_reference" . PHP_EOL
957  . "SET deleted = " . $db->now() . ", " . PHP_EOL
958  . "deleted_by = " . $db->quote($user_id, "integer") . PHP_EOL
959  . "WHERE " . $db->in("ref_id", $ref_ids, false, "integer") . PHP_EOL;
960 
961  $db->manipulate($sql);
962  }
963 
964  final public static function _resetDeletedDate(int $ref_id): void
965  {
966  global $DIC;
967  $db = $DIC->database();
968 
969  $values = [
970  "deleted" => ["timestamp", null],
971  "deleted_by" => ["integer", 0]
972  ];
973 
974  $where = [
975  "ref_id" => ["integer", $ref_id]
976  ];
977 
978  $db->update("object_reference", $values, $where);
979  }
980 
981  final public static function _lookupDeletedDate(int $ref_id): ?string
982  {
983  global $DIC;
984  $db = $DIC->database();
985 
986  $sql =
987  "SELECT deleted" . PHP_EOL
988  . "FROM object_reference" . PHP_EOL
989  . "WHERE ref_id = " . $db->quote($ref_id, "integer") . PHP_EOL
990  ;
991  $result = $db->query($sql);
992  $row = $db->fetchAssoc($result);
993 
994  return $row["deleted"] ?? null;
995  }
996 
1000  final public static function _writeTitle(int $obj_id, string $title): void
1001  {
1002  global $DIC;
1003  $db = $DIC->database();
1004 
1005  $values = [
1006  "title" => ["text", $title],
1007  "last_update" => ["date", $db->now()]
1008  ];
1009 
1010  $where = [
1011  "obj_id" => ["integer", $obj_id]
1012  ];
1013 
1014  $db->update(self::TABLE_OBJECT_DATA, $values, $where);
1015  }
1016 
1020  final public static function _writeDescription(int $obj_id, string $desc): void
1021  {
1022  global $DIC;
1023 
1024  $db = $DIC->database();
1025  $obj_definition = $DIC["objDefinition"];
1026 
1027  $desc = ilStr::shortenTextExtended($desc, self::DESC_LENGTH, true);
1028 
1029  $values = [
1030  "description" => ["text", $desc],
1031  "last_update" => ["date", $db->now()]
1032  ];
1033 
1034  $where = [
1035  "obj_id" => ["integer", $obj_id]
1036  ];
1037 
1038  $db->update(self::TABLE_OBJECT_DATA, $values, $where);
1039 
1040 
1041  if ($obj_definition->isRBACObject(ilObject::_lookupType($obj_id))) {
1042  // Update long description
1043  $sql =
1044  "SELECT obj_id, description" . PHP_EOL
1045  . "FROM object_description" . PHP_EOL
1046  . "WHERE obj_id = " . $db->quote($obj_id, 'integer') . PHP_EOL
1047  ;
1048  $result = $db->query($sql);
1049 
1050  if ($result->numRows()) {
1051  $values = [
1052  "description" => ["clob", $desc]
1053  ];
1054  $db->update("object_description", $values, $where);
1055  } else {
1056  $values = [
1057  "description" => ["clob",$desc],
1058  "obj_id" => ["integer",$obj_id]
1059  ];
1060  $db->insert("object_description", $values);
1061  }
1062  }
1063  }
1064 
1068  final public static function _writeImportId(int $obj_id, string $import_id): void
1069  {
1070  global $DIC;
1071  $db = $DIC->database();
1072 
1073  $values = [
1074  "import_id" => ["text", $import_id],
1075  "last_update" => ["date", $db->now()]
1076  ];
1077 
1078  $where = [
1079  "obj_id" => ["integer", $obj_id]
1080  ];
1081 
1082  $db->update(self::TABLE_OBJECT_DATA, $values, $where);
1083  }
1084 
1085  final public static function _lookupType(int $id, bool $reference = false): string
1086  {
1087  global $DIC;
1088 
1089  if ($reference) {
1090  return $DIC["ilObjDataCache"]->lookupType($DIC["ilObjDataCache"]->lookupObjId($id));
1091  }
1092 
1093  return $DIC["ilObjDataCache"]->lookupType($id);
1094  }
1095 
1096  final public static function _isInTrash(int $ref_id): bool
1097  {
1098  global $DIC;
1099  return $DIC->repositoryTree()->isDeleted($ref_id);
1100  }
1101 
1105  final public static function _hasUntrashedReference(int $obj_id): bool
1106  {
1107  $ref_ids = ilObject::_getAllReferences($obj_id);
1108  foreach ($ref_ids as $ref_id) {
1109  if (!ilObject::_isInTrash($ref_id)) {
1110  return true;
1111  }
1112  }
1113 
1114  return false;
1115  }
1116 
1117  final public static function _lookupObjectId(int $ref_id): int
1118  {
1119  global $DIC;
1120  return $DIC["ilObjDataCache"]->lookupObjId($ref_id);
1121  }
1122 
1130  final public static function _getObjectsDataForType(string $type, bool $omit_trash = false): array
1131  {
1132  global $DIC;
1133  $db = $DIC->database();
1134 
1135  $sql =
1136  "SELECT obj_id, type, title, description, owner, create_date, last_update, import_id, offline" . PHP_EOL
1137  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
1138  . "WHERE type = " . $db->quote($type, "text") . PHP_EOL
1139  ;
1140  $result = $db->query($sql);
1141 
1142  $objects = [];
1143  while ($row = $db->fetchAssoc($result)) {
1144  if ((!$omit_trash) || ilObject::_hasUntrashedReference((int) $row["obj_id"])) {
1145  $objects[$row["title"] . "." . $row["obj_id"]] = [
1146  "id" => $row["obj_id"],
1147  "type" => $row["type"],
1148  "title" => $row["title"],
1149  "description" => $row["description"]
1150  ];
1151  }
1152  }
1153  ksort($objects);
1154  return $objects;
1155  }
1156 
1157 
1163  public function putInTree(int $parent_ref_id): void
1164  {
1165  $this->tree->insertNode($this->getRefId(), $parent_ref_id);
1166  $this->handleAutoRating();
1167 
1168  $log_entry = sprintf(
1169  "ilObject::putInTree(), parent_ref: %s, ref_id: %s, obj_id: %s, type: %s, title: %s",
1170  $parent_ref_id,
1171  $this->getRefId(),
1172  $this->getId(),
1173  $this->getType(),
1174  $this->getTitle()
1175  );
1176 
1177  $this->log->write($log_entry);
1178 
1179  $this->app_event_handler->raise(
1180  'components/ILIAS/ILIASObject',
1181  'putObjectInTree',
1182  [
1183  'object' => $this,
1184  'obj_type' => $this->getType(),
1185  'obj_id' => $this->getId(),
1186  'parent_ref_id' => $parent_ref_id
1187  ]
1188  );
1189  }
1190 
1191  public function setPermissions(int $parent_ref_id): void
1192  {
1193  $this->setParentRolePermissions($parent_ref_id);
1194  $this->initDefaultRoles();
1195  }
1196 
1202  public function setParentRolePermissions(int $parent_ref_id): bool
1203  {
1204  $parent_roles = $this->rbac_review->getParentRoleIds($parent_ref_id);
1205  foreach ($parent_roles as $parent_role) {
1206  if ($parent_role['obj_id'] == SYSTEM_ROLE_ID) {
1207  continue;
1208  }
1209  $operations = $this->rbac_review->getOperationsOfRole(
1210  (int) $parent_role['obj_id'],
1211  $this->getType(),
1212  (int) $parent_role['parent']
1213  );
1214  $this->rbac_admin->grantPermission(
1215  (int) $parent_role['obj_id'],
1216  $operations,
1217  $this->getRefId()
1218  );
1219  }
1220  return true;
1221  }
1222 
1226  public function createReference(): int
1227  {
1228  if (!isset($this->id)) {
1229  $message = "ilObject::createNewReference(): No obj_id given!";
1230  $this->error->raiseError($message, $this->error->WARNING);
1231  }
1232 
1233  $next_id = $this->db->nextId('object_reference');
1234 
1235  $values = [
1236  "ref_id" => ["integer", $next_id],
1237  "obj_id" => ["integer", $this->getId()]
1238  ];
1239 
1240  $this->db->insert("object_reference", $values);
1241 
1242  $this->ref_id = $next_id;
1243  $this->referenced = true;
1244 
1245  return $this->ref_id;
1246  }
1247 
1248  final public function countReferences(): int
1249  {
1250  if (!isset($this->id)) {
1251  $message = "ilObject::countReferences(): No obj_id given!";
1252  $this->error->raiseError($message, $this->error->WARNING);
1253  }
1254 
1255  $sql =
1256  "SELECT COUNT(ref_id) num" . PHP_EOL
1257  . "FROM object_reference" . PHP_EOL
1258  . "WHERE obj_id = " . $this->db->quote($this->id, 'integer') . PHP_EOL
1259  ;
1260 
1261  $res = $this->db->query($sql);
1262  $row = $this->db->fetchObject($res);
1263 
1264  return (int) $row->num;
1265  }
1266 
1275  public function delete(): bool
1276  {
1277  global $DIC;
1278  $rbac_admin = $DIC["rbacadmin"];
1279 
1280  $remove = false;
1281 
1282  // delete object_data entry
1283  if ((!$this->referenced) || ($this->countReferences() == 1)) {
1284  $type = ilObject::_lookupType($this->getId());
1285  if ($this->type != $type) {
1286  $log_entry = sprintf(
1287  "ilObject::delete(): Type mismatch. Object with obj_id: %s was instantiated by type '%s'. DB type is: %s",
1288  $this->id,
1289  $this->type,
1290  $type
1291  );
1292 
1293  $this->log->write($log_entry);
1294  $this->error->raiseError(
1295  sprintf("ilObject::delete(): Type mismatch. (%s/%s)", $this->type, $this->id),
1296  $this->error->WARNING
1297  );
1298  }
1299 
1300  $this->app_event_handler->raise('components/ILIAS/ILIASObject', 'beforeDeletion', ['object' => $this]);
1301 
1302  $sql =
1303  "DELETE FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
1304  . "WHERE obj_id = " . $this->db->quote($this->getId(), "integer") . PHP_EOL
1305  ;
1306  $this->db->manipulate($sql);
1307 
1308  $sql =
1309  "DELETE FROM object_description" . PHP_EOL
1310  . "WHERE obj_id = " . $this->db->quote($this->getId(), "integer") . PHP_EOL
1311  ;
1312  $this->db->manipulate($sql);
1313 
1314  $this->log->write(
1315  sprintf(
1316  "ilObject::delete(), deleted object, obj_id: %s, type: %s, title: %s",
1317  $this->getId(),
1318  $this->getType(),
1319  $this->getTitle()
1320  )
1321  );
1322 
1323  // keep log of core object data
1325 
1326  // remove news
1327  $news_item = new ilNewsItem();
1328  $news_item->deleteNewsOfContext($this->getId(), $this->getType());
1330 
1332 
1333  // BEGIN WebDAV: Delete WebDAV properties
1334  $sql =
1335  "DELETE FROM dav_property" . PHP_EOL
1336  . "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . PHP_EOL
1337  ;
1338  $this->db->manipulate($sql);
1339  // END WebDAV: Delete WebDAV properties
1340 
1341  ilECSImportManager::getInstance()->_deleteByObjId($this->getId());
1344 
1345  $remove = true;
1346  } else {
1347  $this->log->write(
1348  sprintf(
1349  "ilObject::delete(), object not deleted, number of references: %s, obj_id: %s, type: %s, title: %s",
1350  $this->countReferences(),
1351  $this->getId(),
1352  $this->getType(),
1353  $this->getTitle()
1354  )
1355  );
1356  }
1357 
1358  // delete object_reference entry
1359  if ($this->referenced) {
1361 
1362  $this->app_event_handler->raise('components/ILIAS/ILIASObject', 'deleteReference', ['ref_id' => $this->getRefId()]);
1363 
1364  $sql =
1365  "DELETE FROM object_reference" . PHP_EOL
1366  . "WHERE ref_id = " . $this->db->quote($this->getRefId(), 'integer') . PHP_EOL
1367  ;
1368  $this->db->manipulate($sql);
1369 
1370  $this->log->write(
1371  sprintf(
1372  "ilObject::delete(), reference deleted, ref_id: %s, obj_id: %s, type: %s, title: %s",
1373  $this->getRefId(),
1374  $this->getId(),
1375  $this->getType(),
1376  $this->getTitle()
1377  )
1378  );
1379 
1380  // DELETE PERMISSION ENTRIES IN RBAC_PA
1381  // DONE: method overwritten in ilObjRole & ilObjUser.
1382  // this call only applies for objects in rbac (not usr,role,rolt)
1383  // TODO: Do this for role templates too
1384  $rbac_admin->revokePermission($this->getRefId(), 0, false);
1385 
1386  ilRbacLog::delete($this->getRefId());
1387 
1388  // Remove applied didactic template setting
1390  }
1391 
1392  // remove conditions
1393  if ($this->referenced) {
1394  $ch = new ilConditionHandler();
1395  $ch->delete($this->getRefId());
1396  unset($ch);
1397  }
1398 
1399  return $remove;
1400  }
1401 
1409  public function initDefaultRoles(): void
1410  {
1411  }
1412 
1413  public function applyDidacticTemplate(int $tpl_id): void
1414  {
1415  ilLoggerFactory::getLogger('obj')->debug('Applying didactic template with id: ' . $tpl_id);
1416  if ($tpl_id) {
1417  foreach (ilDidacticTemplateActionFactory::getActionsByTemplateId($tpl_id) as $action) {
1418  $action->setRefId($this->getRefId());
1419  $action->apply();
1420  }
1421  }
1422 
1423  ilDidacticTemplateObjSettings::assignTemplate($this->getRefId(), $this->getId(), $tpl_id);
1424  }
1425 
1434  public static function _exists(int $id, bool $reference = false, ?string $type = null): bool
1435  {
1436  global $DIC;
1437  $db = $DIC->database();
1438 
1439  if ($reference) {
1440  $sql =
1441  "SELECT object_data.obj_id" . PHP_EOL
1442  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
1443  . "LEFT JOIN object_reference ON object_reference.obj_id = object_data.obj_id " . PHP_EOL
1444  . "WHERE object_reference.ref_id= " . $db->quote($id, "integer") . PHP_EOL
1445  ;
1446  } else {
1447  $sql =
1448  "SELECT object_data.obj_id" . PHP_EOL
1449  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
1450  . "WHERE obj_id = " . $db->quote($id, "integer") . PHP_EOL
1451  ;
1452  }
1453 
1454  if ($type) {
1455  $sql .= " AND object_data.type = " . $db->quote($type, "text") . PHP_EOL;
1456  }
1457 
1458  $result = $db->query($sql);
1459 
1460  return (bool) $db->numRows($result);
1461  }
1462 
1463  public function getXMLZip(): string
1464  {
1465  return "";
1466  }
1467  public function getHTMLDirectory(): bool
1468  {
1469  return false;
1470  }
1471 
1472  final public static function _getObjectsByType(string $obj_type = "", int $owner = null): array
1473  {
1474  global $DIC;
1475  $db = $DIC->database();
1476 
1477  $order = " ORDER BY title";
1478 
1479  $where = "";
1480  if ($obj_type) {
1481  $where = "WHERE type = " . $db->quote($obj_type, "text");
1482 
1483  if (!is_null($owner)) {
1484  $where .= " AND owner = " . $db->quote($owner, "integer");
1485  }
1486  }
1487 
1488  $sql =
1489  "SELECT obj_id, type, title, description, owner, create_date, last_update, import_id, offline" . PHP_EOL
1490  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
1491  . $where . PHP_EOL
1492  . $order . PHP_EOL
1493  ;
1494  $result = $db->query($sql);
1495 
1496  $arr = [];
1497  if ($db->numRows($result) > 0) {
1498  while ($row = $db->fetchAssoc($result)) {
1499  $row["desc"] = $row["description"];
1500  $arr[$row["obj_id"]] = $row;
1501  }
1502  }
1503 
1504  return $arr;
1505  }
1506 
1513  final public static function _prepareCloneSelection(
1514  array $ref_ids,
1515  string $new_type,
1516  bool $show_path = true
1517  ): array {
1518  global $DIC;
1519 
1520  $db = $DIC->database();
1521  $lng = $DIC->language();
1522  $obj_definition = $DIC["objDefinition"];
1523 
1524  $sql =
1525  "SELECT obj_data.title obj_title, path_data.title path_title, child" . PHP_EOL
1526  . "FROM tree " . PHP_EOL
1527  . "JOIN object_reference obj_ref ON child = obj_ref.ref_id " . PHP_EOL
1528  . "JOIN object_data obj_data ON obj_ref.obj_id = obj_data.obj_id " . PHP_EOL
1529  . "JOIN object_reference path_ref ON parent = path_ref.ref_id " . PHP_EOL
1530  . "JOIN object_data path_data ON path_ref.obj_id = path_data.obj_id " . PHP_EOL
1531  . "WHERE " . $db->in("child", $ref_ids, false, "integer") . PHP_EOL
1532  . "ORDER BY obj_data.title" . PHP_EOL
1533  ;
1534  $res = $db->query($sql);
1535 
1536  if (!$obj_definition->isPlugin($new_type)) {
1537  $options[0] = $lng->txt('obj_' . $new_type . '_select');
1538  } else {
1539  $options[0] = ilObjectPlugin::lookupTxtById($new_type, "obj_" . $new_type . "_select");
1540  }
1541 
1542  while ($row = $db->fetchObject($res)) {
1543  if (strlen($title = $row->obj_title) > 40) {
1544  $title = substr($title, 0, 40) . '...';
1545  }
1546 
1547  if ($show_path) {
1548  if (strlen($path = $row->path_title) > 40) {
1549  $path = substr($path, 0, 40) . '...';
1550  }
1551 
1552  $title .= ' (' . $lng->txt('path') . ': ' . $path . ')';
1553  }
1554 
1555  $options[$row->child] = $title;
1556  }
1557  return $options ?: [];
1558  }
1559 
1563  public function cloneObject(int $target_id, int $copy_id = 0, bool $omit_tree = false): ?ilObject
1564  {
1566  global $DIC;
1567 
1568  $ilUser = $DIC["ilUser"];
1569  $rbac_admin = $DIC["rbacadmin"];
1570 
1571  $class_name = ('ilObj' . $this->obj_definition->getClassName($this->getType()));
1572 
1573  $options = ilCopyWizardOptions::_getInstance($copy_id);
1574 
1575  $title = $this->getTitle();
1576  $this->obj_log->debug($title);
1577  $this->obj_log->debug("isTreeCopyDisabled: " . $options->isTreeCopyDisabled());
1578  $this->obj_log->debug("omit_tree: " . $omit_tree);
1579  if (!$options->isTreeCopyDisabled() && !$omit_tree) {
1580  $title_with_suffix = $this->appendCopyInfo($target_id, $copy_id);
1581  $title = mb_strlen($title_with_suffix) < self::TITLE_LENGTH ? $title_with_suffix : $title;
1582  $this->obj_log->debug("title incl. copy info: " . $title);
1583 
1584  }
1585 
1587  $new_obj = new $class_name(0, false);
1588  $new_obj->setOwner($ilUser->getId());
1589  $new_obj->title = $title;
1590  $new_obj->long_desc = $this->getLongDescription();
1591  $new_obj->desc = $this->getDescription();
1592  $new_obj->type = $this->getType();
1593 
1594  // Choose upload mode to avoid creation of additional settings, db entries ...
1595  $new_obj->create(true);
1596 
1597  if ($this->supportsOfflineHandling()) {
1598  if ($options->isRootNode($this->getRefId())) {
1599  $new_obj->getObjectProperties()->storePropertyIsOnline(
1600  $new_obj->getObjectProperties()->getPropertyIsOnline()->withOffline()
1601  );
1602  } else {
1603  $new_obj->getObjectProperties()->storePropertyIsOnline(
1604  $this->getObjectProperties()->getPropertyIsOnline()
1605  );
1606  }
1607  }
1608 
1609  if (!$options->isTreeCopyDisabled() && !$omit_tree) {
1610  ilLoggerFactory::getLogger('obj')->debug('Tree copy is enabled');
1611  $new_obj->createReference();
1612  $new_obj->putInTree($target_id);
1613  $new_obj->setPermissions($target_id);
1614 
1615  // when copying from personal workspace we have no current ref id
1616  if ($this->getRefId()) {
1617  // copy local roles
1618  $rbac_admin->copyLocalRoles($this->getRefId(), $new_obj->getRefId());
1619  }
1620  } else {
1621  ilLoggerFactory::getLogger('obj')->debug('Tree copy is disabled');
1622  }
1623 
1624  ilAdvancedMDValues::_cloneValues($copy_id, $this->getId(), $new_obj->getId());
1625 
1626  // BEGIN WebDAV: Clone WebDAV properties
1627  $sql =
1628  "INSERT INTO dav_property" . PHP_EOL
1629  . "(obj_id, node_id, ns, name, value)" . PHP_EOL
1630  . "SELECT " . $this->db->quote($new_obj->getId(), 'integer') . ", node_id, ns, name, value " . PHP_EOL
1631  . "FROM dav_property" . PHP_EOL
1632  . "WHERE obj_id = " . $this->db->quote($this->getId(), 'integer') . PHP_EOL
1633  ;
1634  $this->db->manipulate($sql);
1635  // END WebDAV: Clone WebDAV properties
1636 
1637  $customIconFactory = $DIC['object.customicons.factory'];
1638  $customIcon = $customIconFactory->getByObjId($this->getId(), $this->getType());
1639  $customIcon->copy($new_obj->getId());
1640 
1641  $new_obj->getObjectProperties()->storePropertyTileImage(
1642  $new_obj->getObjectProperties()->getPropertyTileImage()->withTileImage(
1643  $this->getObjectProperties()->getPropertyTileImage()
1644  ->getTileImage()->cloneFor($new_obj->getId())
1645  )
1646  );
1647 
1648  $this->app_event_handler->raise(
1649  'components/ILIAS/ILIASObject',
1650  'cloneObject',
1651  [
1652  'object' => $new_obj,
1653  'cloned_from_object' => $this,
1654  ]
1655  );
1656 
1657  return $new_obj;
1658  }
1659 
1663  final public function appendCopyInfo(int $target_id, int $copy_id): string
1664  {
1665  $cp_options = ilCopyWizardOptions::_getInstance($copy_id);
1666  if (!$cp_options->isRootNode($this->getRefId())) {
1667  return $this->getTitle();
1668  }
1669 
1670  $obj_translations = ilObjectTranslation::getInstance($this->getId());
1671 
1672  $other_children_of_same_type = $this->tree->getChildsByType($target_id, $this->type);
1673 
1674  if ($obj_translations->getLanguages() === []) {
1675  $existing_titles = array_map(
1676  fn(array $child): string => $child['title'],
1677  $other_children_of_same_type
1678  );
1679 
1680  return $this->appendNumberOfCopiesToTitle(
1681  $this->lng->txt('copy_of_suffix'),
1682  $this->lng->txt('copy_n_of_suffix'),
1683  $this->getTitle(),
1684  $existing_titles
1685  );
1686  }
1687 
1688  return $this->appendCopyInfoToTranslations($obj_translations, $other_children_of_same_type);
1689  }
1690 
1692  ilObjectTranslation $obj_translations,
1693  array $other_children_of_same_type
1694  ): string {
1695  $nodes_translations = array_map(
1696  fn(array $child): ilObjectTranslation =>
1697  ilObjectTranslation::getInstance($child['obj_id']),
1698  $other_children_of_same_type
1699  );
1700 
1701  $title_translations_per_lang = array_reduce(
1702  $nodes_translations,
1704  []
1705  );
1706 
1707  $new_languages = [];
1708  $installed_langs = $this->lng->getInstalledLanguages();
1709  foreach ($obj_translations->getLanguages() as $language) {
1710  $lang_code = $language->getLanguageCode();
1711  $suffix_lang = $lang_code;
1712  if (!in_array($suffix_lang, $installed_langs)) {
1713  $suffix_lang = $this->lng->getDefaultLanguage();
1714  }
1715  $language->setTitle(
1717  $this->lng->txtlng('common', 'copy_of_suffix', $suffix_lang),
1718  $this->lng->txtlng('common', 'copy_n_of_suffix', $suffix_lang),
1719  $language->getTitle(),
1720  $title_translations_per_lang[$lang_code] ?? []
1721  )
1722  );
1723  $new_languages[$lang_code] = $language;
1724  }
1725  $obj_translations->setLanguages($new_languages);
1726 
1727  return $obj_translations->getDefaultTitle();
1728  }
1729 
1731  {
1732  return function (array $npl, ?ilObjectTranslation $nt): array {
1733  $langs = $nt->getLanguages();
1734  foreach ($langs as $lang) {
1735  if (!array_key_exists($lang->getLanguageCode(), $npl)) {
1736  $npl[$lang->getLanguageCode()] = [];
1737  }
1738  $npl[$lang->getLanguageCode()][] = $lang->getTitle();
1739  }
1740  return $npl;
1741  };
1742  }
1743 
1745  string $copy_suffix,
1746  string $copy_n_suffix,
1747  string $title,
1748  array $other_titles_for_lang
1749  ): string {
1750  $title_without_suffix = $this->buildTitleWithoutCopySuffix($copy_suffix, $copy_n_suffix, $title);
1751  $title_with_suffix = "{$title_without_suffix} {$copy_suffix}";
1752  if ($other_titles_for_lang === []
1753  || $this->isTitleUnique($title_with_suffix, $other_titles_for_lang)) {
1754  return $title_with_suffix;
1755  }
1756 
1757  for ($i = 2;true;$i++) {
1758  $title_with_suffix = $title_without_suffix . ' ' . sprintf($copy_n_suffix, $i);
1759  if ($this->isTitleUnique($title_with_suffix, $other_titles_for_lang)) {
1760  return $title_with_suffix;
1761  }
1762  }
1763  }
1764 
1765  private function isTitleUnique(string $title, array $nodes): bool
1766  {
1767  foreach ($nodes as $node) {
1768  if (($title === $node)) {
1769  return false;
1770  }
1771  }
1772  return true;
1773  }
1774 
1775  private function buildTitleWithoutCopySuffix(string $copy_suffix, string $copy_n_suffix, string $title): string
1776  {
1777  /*
1778  * create a regular expression from the language text copy_n_of_suffix, so that
1779  * we can match it against $filenameWithoutExtension, and retrieve the number of the copy.
1780  * for example, if copy_n_of_suffix is 'Copy (%1s)', this creates the regular
1781  * expression '/ Copy \\([0-9]+)\\)$/'.
1782  */
1783  $regexp_for_suffix = preg_replace(
1784  '/([\^$.\[\]|()?*+{}])/',
1785  '\\\\${1}',
1786  ' '
1787  . $copy_n_suffix
1788  );
1789  $regexp_for_file_name = '/' . preg_replace('/%1\\\\\$s/', '([0-9]+)', $regexp_for_suffix) . '$/';
1790 
1791  if (preg_match($regexp_for_file_name, $title, $matches)) {
1792  return substr($title, 0, -strlen($matches[0]));
1793  }
1794 
1795  if (str_ends_with($title, " {$copy_suffix}")) {
1796  return substr(
1797  $title,
1798  0,
1799  -strlen(
1800  " {$copy_suffix}"
1801  )
1802  );
1803  }
1804 
1805  return $title;
1806  }
1807 
1815  public function cloneDependencies(int $target_id, int $copy_id): bool
1816  {
1817  ilConditionHandler::cloneDependencies($this->getRefId(), $target_id, $copy_id);
1818 
1820  if ($tpl_id) {
1821  $factory = new ilObjectFactory();
1822  $obj = $factory->getInstanceByRefId($target_id, false);
1823  if ($obj instanceof ilObject) {
1824  $obj->applyDidacticTemplate($tpl_id);
1825  }
1826  }
1827  return true;
1828  }
1829 
1833  public function cloneMetaData(ilObject $target_obj): bool
1834  {
1835  $this->lom_services->derive()
1836  ->fromObject($this->getId(), 0, $this->getType())
1837  ->forObject($target_obj->getId(), 0, $target_obj->getType());
1838  return true;
1839  }
1840 
1841  public static function getIconForReference(
1842  int $ref_id,
1843  int $obj_id,
1844  string $size,
1845  string $type = "",
1846  bool $offline = false
1847  ): string {
1849  global $DIC;
1850  $icon_factory = $DIC['ui.factory']->symbol()->icon();
1851  $irss = $DIC['resource_storage'];
1852 
1853  if ($obj_id == "" && $type == "") {
1854  return "";
1855  }
1856 
1857  if ($type === "") {
1858  $type = ilObject::_lookupType($obj_id);
1859  }
1860 
1861  if ($size === "") {
1862  $size = "big";
1863  }
1864 
1865  if ($obj_id) {
1867  $property_icon = ilObjectDIC::dic()['additional_properties_repository']->getFor($obj_id)->getPropertyIcon();
1868  $custom_icon = $property_icon->getCustomIcon();
1869  if ($custom_icon?->exists()) {
1870  return $custom_icon->getFullPath() . '?tmp=' . filemtime($custom_icon->getFullPath());
1871  }
1872 
1873  $file_type_specific_icon = $property_icon->getObjectTypeSpecificIcon($obj_id, $icon_factory, $irss);
1874  if ($file_type_specific_icon !== null) {
1875  return $file_type_specific_icon->getIconPath();
1876  }
1877 
1878  $dtpl_icon_factory = ilDidacticTemplateIconFactory::getInstance();
1879  if ($ref_id) {
1880  $path = $dtpl_icon_factory->getIconPathForReference($ref_id);
1881  } else {
1882  $path = $dtpl_icon_factory->getIconPathForObject($obj_id);
1883  }
1884  if ($path) {
1885  return $path . '?tmp=' . filemtime($path);
1886  }
1887  }
1888 
1889  if (!$offline) {
1890  return self::getIconForType($type);
1891  }
1892  return "./images/standard/icon_{$type}.svg";
1893  }
1894 
1895  public static function getIconForType(string $type): string
1896  {
1897  global $DIC;
1898  $objDefinition = $DIC['objDefinition'];
1899  if (!$objDefinition->isPluginTypeName($type)) {
1900  return ilUtil::getImagePath("standard/icon_{$type}.svg");
1901  }
1902 
1903  if ($objDefinition->getClassName($type) !== '') {
1904  $class_name = "il{$objDefinition->getClassName($type)}Plugin";
1905  $location = $objDefinition->getLocation($type);
1906  if (is_file($location . "/class.{$class_name}.php")) {
1907  return call_user_func([$class_name, '_getIcon'], $type);
1908  }
1909  }
1910  return ilUtil::getImagePath('standard/icon_cmps.svg');
1911  }
1912 
1921  final public static function _getIcon(
1922  int $obj_id = 0,
1923  string $size = "big",
1924  string $type = "",
1925  bool $offline = false
1926  ): string {
1927  return self::getIconForReference(0, $obj_id, $size, $type, $offline);
1928  }
1929 
1930  protected function handleAutoRating(): void
1931  {
1932  if ($this->process_auto_reating
1933  && $this->hasAutoRating()
1934  && method_exists($this, "setRating")
1935  ) {
1936  $this->setRating(true);
1937  $this->update();
1938  }
1939  }
1940 
1941  protected function hasAutoRating(): bool
1942  {
1943  $ref_id = $this->getRefId();
1944  $type = $this->type;
1945 
1946  if (!$ref_id || !in_array($type, ["file", "lm", "wiki"])) {
1947  return false;
1948  }
1949 
1950  return $this->selfOrParentWithRatingEnabled();
1951  }
1952 
1953  public function selfOrParentWithRatingEnabled(): bool
1954  {
1955  $tree = $this->tree;
1956  $ref_id = $this->getRefId();
1957  $parent_ref_id = $tree->checkForParentType($ref_id, "grp");
1958  if (!$parent_ref_id) {
1959  $parent_ref_id = $tree->checkForParentType($ref_id, "crs");
1960  }
1961  if ($parent_ref_id) {
1962  // get auto rate setting
1963  $parent_obj_id = ilObject::_lookupObjId($parent_ref_id);
1965  $parent_obj_id,
1967  );
1968  }
1969  return false;
1970  }
1971 
1975  public static function collectDeletionDependencies(
1976  array &$deps,
1977  int $ref_id,
1978  int $obj_id,
1979  string $type,
1980  int $depth = 0
1981  ): void {
1982  global $DIC;
1983 
1984  $objDefinition = $DIC["objDefinition"];
1985  $tree = $DIC->repositoryTree();
1986 
1987  if ($depth == 0) {
1988  $deps["dep"] = [];
1989  }
1990 
1991  $deps["del_ids"][$obj_id] = $obj_id;
1992 
1993  if (!$objDefinition->isPluginTypeName($type)) {
1994  $class_name = "ilObj" . $objDefinition->getClassName($type);
1995  $odeps = call_user_func([$class_name, "getDeletionDependencies"], $obj_id);
1996  if (is_array($odeps)) {
1997  foreach ($odeps as $id => $message) {
1998  $deps["dep"][$id][$obj_id][] = $message;
1999  }
2000  }
2001 
2002  // get deletion dependency of children
2003  foreach ($tree->getChilds($ref_id) as $c) {
2004  ilObject::collectDeletionDependencies($deps, (int) $c["child"], (int) $c["obj_id"], (string) $c["type"], $depth + 1);
2005  }
2006  }
2007 
2008  // delete all dependencies to objects that will be deleted, too
2009  if ($depth == 0) {
2010  foreach ($deps["del_ids"] as $obj_id) {
2011  unset($deps["dep"][$obj_id]);
2012  }
2013  $deps = $deps["dep"];
2014  }
2015  }
2016 
2020  public static function getDeletionDependencies(int $obj_id): array
2021  {
2022  return [];
2023  }
2024 
2025  public static function getLongDescriptions(array $obj_ids): array
2026  {
2027  global $DIC;
2028  $db = $DIC->database();
2029 
2030  $sql =
2031  "SELECT obj_id, description" . PHP_EOL
2032  . "FROM object_description" . PHP_EOL
2033  . "WHERE " . $db->in("obj_id", $obj_ids, false, "integer") . PHP_EOL
2034  ;
2035  $result = $db->query($sql);
2036 
2037  $all = [];
2038  while ($row = $db->fetchAssoc($result)) {
2039  $all[$row["obj_id"]] = $row["description"];
2040  }
2041  return $all;
2042  }
2043 
2044  public static function getAllOwnedRepositoryObjects(int $user_id): array
2045  {
2046  global $DIC;
2047 
2048  $db = $DIC->database();
2049  $obj_definition = $DIC["objDefinition"];
2050 
2051  // restrict to repository
2052  $types = array_keys($obj_definition->getSubObjectsRecursively("root"));
2053 
2054  $sql =
2055  "SELECT od.obj_id, od.type, od.title" . PHP_EOL
2056  . "FROM object_data od" . PHP_EOL
2057  . "JOIN object_reference oref ON(oref.obj_id = od.obj_id)" . PHP_EOL
2058  . "JOIN tree ON (tree.child = oref.ref_id)" . PHP_EOL
2059  ;
2060 
2061  if ($user_id) {
2062  $sql .= "WHERE od.owner = " . $db->quote($user_id, "integer") . PHP_EOL;
2063  } else {
2064  $sql .=
2065  "LEFT JOIN usr_data ud ON (ud.usr_id = od.owner)" . PHP_EOL
2066  . "WHERE (od.owner < " . $db->quote(1, "integer") . PHP_EOL
2067  . "OR od.owner IS NULL OR ud.login IS NULL)" . PHP_EOL
2068  . "AND od.owner <> " . $db->quote(-1, "integer") . PHP_EOL
2069  ;
2070  }
2071 
2072  $sql .=
2073  "AND " . $db->in("od.type", $types, false, "text") . PHP_EOL
2074  . "AND tree.tree > " . $db->quote(0, "integer") . PHP_EOL
2075  ;
2076 
2077  $res = $db->query($sql);
2078 
2079  $all = [];
2080  while ($row = $db->fetchAssoc($res)) {
2081  $all[$row["type"]][$row["obj_id"]] = $row["title"];
2082  }
2083 
2084  return $all;
2085  }
2086 
2090  public static function fixMissingTitles($type, array &$obj_title_map)
2091  {
2092  global $DIC;
2093  $db = $DIC->database();
2094 
2095  if (!in_array($type, ["catr", "crsr", "sess", "grpr", "prgr"])) {
2096  return;
2097  }
2098 
2099  // any missing titles?
2100  $missing_obj_ids = [];
2101  foreach ($obj_title_map as $obj_id => $title) {
2102  if (!trim($title)) {
2103  $missing_obj_ids[] = $obj_id;
2104  }
2105  }
2106 
2107  if (!sizeof($missing_obj_ids)) {
2108  return;
2109  }
2110 
2111  switch ($type) {
2112  case "grpr":
2113  case "catr":
2114  case "crsr":
2115  case "prgr":
2116  $sql =
2117  "SELECT oref.obj_id, od.type, od.title" . PHP_EOL
2118  . "FROM object_data od" . PHP_EOL
2119  . "JOIN container_reference oref ON (od.obj_id = oref.target_obj_id)" . PHP_EOL
2120  . "AND " . $db->in("oref.obj_id", $missing_obj_ids, false, "integer") . PHP_EOL
2121  ;
2122  $result = $db->query($sql);
2123 
2124  while ($row = $db->fetchAssoc($result)) {
2125  $obj_title_map[$row["obj_id"]] = $row["title"];
2126  }
2127  break;
2128  case "sess":
2129  foreach ($missing_obj_ids as $obj_id) {
2130  $sess = new ilObjSession($obj_id, false);
2131  $obj_title_map[$obj_id] = $sess->getFirstAppointment()->appointmentToString();
2132  }
2133  break;
2134  }
2135  }
2136 
2137  public static function _lookupCreationDate(int $obj_id): string
2138  {
2139  global $DIC;
2140  $db = $DIC->database();
2141 
2142  $sql =
2143  "SELECT create_date" . PHP_EOL
2144  . "FROM " . self::TABLE_OBJECT_DATA . PHP_EOL
2145  . "WHERE obj_id = " . $db->quote($obj_id, "integer") . PHP_EOL
2146  ;
2147  $result = $db->query($sql);
2148  $rec = $db->fetchAssoc($result);
2149  return $rec["create_date"];
2150  }
2151 
2160  public function getPossibleSubObjects(bool $filter = true): array
2161  {
2162  return $this->obj_definition->getSubObjects($this->type, $filter);
2163  }
2164 
2165  public static function _getObjectTypeIdByTitle(string $type, \ilDBInterface $ilDB = null): ?int
2166  {
2167  if (!$ilDB) {
2168  global $DIC;
2169  $ilDB = $DIC->database();
2170  }
2171 
2172  $sql =
2173  "SELECT obj_id FROM object_data" . PHP_EOL
2174  . "WHERE type = 'typ'" . PHP_EOL
2175  . "AND title = " . $ilDB->quote($type, 'text') . PHP_EOL
2176  ;
2177 
2178  $res = $ilDB->query($sql);
2179  if ($ilDB->numRows($res) == 0) {
2180  return null;
2181  }
2182 
2183  $row = $ilDB->fetchAssoc($res);
2184  return (int) $row['obj_id'] ?? null;
2185  }
2186 } // END class.ilObject
ilLogger $obj_log
string $title
beforeMDUpdateListener(string $a_element)
static deleteAllEntries(int $ref_id)
Delete all db entries for ref id.
static _lookupObjIdByImportId(string $import_id)
Get (latest) object id for an import id.
applyDidacticTemplate(int $tpl_id)
static assignTemplate(int $a_ref_id, int $a_obj_id, int $a_tpl_id)
ILIAS $ilias
$res
Definition: ltiservices.php:69
Global event handler.
string $type
static _writeTitle(int $obj_id, string $title)
write title to db (static)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ilObjUser $user=null,)
static setDeletedDates(array $ref_ids, int $user_id)
static _setDeletedDate(int $ref_id, int $deleted_by)
supportsOfflineHandling()
numRows(ilDBStatement $statement)
insert(string $table_name, array $values)
const IL_CAL_DATETIME
static _getIcon(int $obj_id=0, string $size="big", string $type="", bool $offline=false)
Get icon for repository item.
static getLogger(string $a_component_id)
Get component logger.
static _writeImportId(int $obj_id, string $import_id)
write import id to db (static)
flushObjectProperties()
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...
bool $process_auto_reating
const TITLE_LENGTH
fetchAssoc(ilDBStatement $statement)
like(string $column, string $type, string $value="?", bool $case_insensitive=true)
Generate a like subquery.
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: buildRTE.php:22
string $desc
Interface Observer Contains several chained tasks and infos about them.
static collectDeletionDependencies(array &$deps, int $ref_id, int $obj_id, string $type, int $depth=0)
Collect deletion dependencies.
const SYSTEM_ROLE_ID
Definition: constants.php:29
getChilds(int $a_node_id, string $a_order="", string $a_direction="ASC")
get child nodes of given node
const TABLE_OBJECT_DATA
static cloneDependencies(int $a_src_ref_id, int $a_target_ref_id, int $a_copy_id)
static _getAllReferences(int $id)
get all reference ids for object ID
update(string $table_name, array $values, array $where)
$where MUST contain existing columns only.
withReferences()
determines whether objects are referenced or not (got ref ids or not)
const DESC_LENGTH
ilTree $tree
static _hasUntrashedReference(int $obj_id)
checks whether an object has at least one reference that is not in trash
setImportId(string $import_id)
isRBACObject(string $obj_name)
get RBAC status by type returns true if object type is a RBAC object type
static delete(int $ref_id)
static _lookupOwner(int $obj_id)
Lookup owner user ID for object ID.
static _getObjectsDataForType(string $type, bool $omit_trash=false)
get all objects of a certain type
quote($value, string $type)
setTitle(string $title)
revokePermission(int $a_ref_id, int $a_rol_id=0, bool $a_keep_protected=true)
Revokes permissions of an object of one role.
bool $register
getCreateDate()
Get create date in YYYY-MM-DD HH-MM-SS format.
getCallbackForTitlesPerLanguageTransformation()
static _getObjectsByType(string $obj_type="", int $owner=null)
static getDeletionDependencies(int $obj_id)
Get deletion dependencies.
$c
Definition: deliver.php:9
appendNumberOfCopiesToTitle(string $copy_suffix, string $copy_n_suffix, string $title, array $other_titles_for_lang)
setPermissions(int $parent_ref_id)
isTitleUnique(string $title, array $nodes)
setRefId(int $ref_id)
setLimit(int $limit, int $offset=0)
appendCopyInfoToTranslations(ilObjectTranslation $obj_translations, array $other_children_of_same_type)
static _getIdForImportId(string $import_id)
$path
Definition: ltiservices.php:30
static _lookupContainerSetting(int $a_id, string $a_keyword, string $a_default_value=null)
setId(int $id)
static _lookupObjId(int $ref_id)
static lookupOfflineStatus(int $obj_id)
Lookup offline status using objectDataCache.
static _resetDeletedDate(int $ref_id)
const LONG_DESC_LENGTH
setType(string $type)
createReference()
creates reference for object
ilAppEventHandler $app_event_handler
static _lookupImportId(int $obj_id)
static getInstance()
Get the singleton instance of this ilECSImportManager.
static getLongDescriptions(array $obj_ids)
checkForParentType(int $a_ref_id, string $a_type, bool $a_exclude_source_check=false)
Check for parent type e.g check if a folder (ref_id 3) is in a parent course obj => checkForParentTyp...
static _exists(int $id, bool $reference=false, ?string $type=null)
checks if an object exists in object_data
cloneMetaData(ilObject $target_obj)
Copy meta data.
beforeDeleteMetaData()
create()
note: title, description and type should be set when this function is called
static _lookupTitle(int $obj_id)
string $last_update
LOMServices $lom_services
static _prepareCloneSelection(array $ref_ids, string $new_type, bool $show_path=true)
Prepare copy wizard object selection.
MDUpdateListener(string $element)
Metadata update listener.
static _lookupLastUpdate(int $obj_id, bool $formatted=false)
ilLanguage $lng
bool $call_by_reference
ilDBInterface $db
static _isInTrash(int $ref_id)
ilRbacAdmin $rbac_admin
static getInstance(int $obj_id)
global $DIC
Definition: shib_login.php:25
cloneDependencies(int $target_id, int $copy_id)
Clone object dependencies.
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static _lookupObjectId(int $ref_id)
fetchObject(ilDBStatement $query_result)
copyLocalRoles(int $a_source_id, int $a_target_id)
Copy local roles This method creates a copy of all local role.
doMDUpdateListener(string $a_element)
static _deleteSettingsOfBlock(int $a_block_id, string $a_block_type)
updateOwner()
update owner of object in db
selfOrParentWithRatingEnabled()
Class ilObjForumAdministration.
query(string $query)
Run a (read-only) Query on the database.
ilObjectDIC $object_dic
static _deleteByObjId(int $a_obj_id)
Delete by objekt id.
setOfflineStatus(bool $status)
initDefaultRoles()
init default roles settings Purpose of this function is to create a local role folder and local roles...
static _lookupDescription(int $obj_id)
getSubObjectsRecursively(string $obj_type, bool $include_source_obj=true, bool $add_admin_objects=false)
Get all sub objects by type.
static getAllOwnedRepositoryObjects(int $user_id)
ilObjectDefinition $obj_definition
static _getIdsForTitle(string $title, string $type='', bool $partial_match=false)
string $create_date
static lookupTxtById(string $plugin_id, string $lang_var)
in(string $field, array $values, bool $negate=false, string $type="")
string $long_desc
static getActionsByTemplateId(int $a_tpl_id)
Get actions of one template.
putInTree(int $parent_ref_id)
maybe this method should be in tree object!?
ilObjectProperties $object_properties
static _cloneValues(int $copy_id, int $a_source_id, int $a_target_id, ?string $a_sub_type=null, ?int $a_source_sub_id=null, ?int $a_target_sub_id=null)
Clone Advanced Meta Data.
A news item can be created by different sources.
string $untranslatedTitle
static _lookupCreationDate(int $obj_id)
setParentRolePermissions(int $parent_ref_id)
Initialize the permissions of parent roles (local roles of categories, global roles...) This method is overwritten in e.g.
appendCopyInfo(int $target_id, int $copy_id)
Prepend Copy info if object with same name exists in that container.
$id
plugin.php for ilComponentBuildPluginInfoObjectiveTest::testAddPlugins
Definition: plugin.php:24
__construct(Container $dic, ilPlugin $plugin)
ilErrorHandling $error
static shortenTextExtended(string $a_str, int $a_len, bool $a_dots=false, bool $a_next_blank=false, bool $a_keep_extension=false)
getOwnerName()
get full name of object owner
buildTitleWithoutCopySuffix(string $copy_suffix, string $copy_n_suffix, string $title)
getLongDescription()
get object long description (stored in object_description)
static fixMissingTitles($type, array &$obj_title_map)
Try to fix missing object titles.
beforeCreateMetaData()
getPossibleSubObjects(bool $filter=true)
get all possible sub objects of this type the object can decide which types of sub objects are possib...
ilLogger $log
static _getInstance(int $a_copy_id)
isPlugin(string $obj_name)
get RBAC status by type returns true if object type is an (activated) plugin type ...
static _lookupOwnerName(int $owner_id)
Lookup owner name for owner id.
Class ilRbacAdmin Core functions for role based access control.
array $objectList
string $import_id
getLastUpdateDate()
Get last update date in YYYY-MM-DD HH-MM-SS format.
ilRbacReview $rbac_review
getUntranslatedTitle()
Get untranslated object title WebDAV needs to access the untranslated title of an object...
manipulate(string $query)
Run a (write) Query on the database.
static _lookupType(int $id, bool $reference=false)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getObjectTypeIdByTitle(string $type, \ilDBInterface $ilDB=null)
static getIconForType(string $type)
bool $add_dots
setDescription(string $description)
static _lookupDeletedDate(int $ref_id)
beforeUpdateMetaData()
static _getLastUpdateOfObjects(array $obj_ids)
static _deleteByObjId(int $a_obj_id)
setOwner(int $usr_id)
getPresentationTitle()
get presentation title Normally same as title Overwritten for sessions
static _writeDescription(int $obj_id, string $desc)
write description to db (static)
ilObjUser $user
$r