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