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