ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilDclTable.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
25 {
26  protected int $id = 0;
27  protected ?int $objId = null;
29  protected string $title = "";
33  protected array $fields = [];
37  protected array $stdFields = [];
41  protected array $records = [];
42  protected bool $is_visible = false;
43  protected bool $add_perm = false;
44  protected bool $edit_perm = false;
45  protected bool $delete_perm = false;
46  protected bool $edit_by_owner = false;
47  protected bool $delete_by_owner = false;
48  protected bool $save_confirmation = false;
49  protected bool $limited = false;
50  protected string $limit_start = "";
51  protected string $limit_end = "";
52  protected bool $export_enabled = false;
53  protected int $table_order = 0;
54  protected bool $import_enabled = false;
55 
56  protected string $default_sort_field = "0";
60  protected string $default_sort_field_order = 'asc';
64  protected string $description = '';
68  protected bool $public_comments = false;
72  protected int $view_own_records_perm = 0;
76  protected ?array $all_fields = null;
79  protected ilObjUser $user;
80  protected ilDBInterface $db;
81  protected bool $show_invalid = false;
82 
83  public function __construct(int $a_id = 0)
84  {
85  global $DIC;
86 
87  $this->http = $DIC->http();
88  $this->refinery = $DIC->refinery();
89  $this->db = $DIC->database();
90  $this->user = $DIC->user();
91 
92  if ($a_id != 0) {
93  $this->id = $a_id;
94  $this->doRead();
95  }
96  }
97 
101  public function doRead(): void
102  {
103  $query = "SELECT * FROM il_dcl_table WHERE id = " . $this->db->quote($this->getId(), "integer");
104  $set = $this->db->query($query);
105  $rec = $this->db->fetchAssoc($set);
106 
107  $this->setObjId($rec["obj_id"]);
108  if (null !== $rec["title"]) {
109  $this->setTitle($rec["title"]);
110  }
111  $this->setAddPerm((bool) $rec["add_perm"]);
112  $this->setEditPerm((bool) $rec["edit_perm"]);
113  $this->setDeletePerm((bool) $rec["delete_perm"]);
114  $this->setEditByOwner((bool) $rec["edit_by_owner"]);
115  if (null !== $rec["export_enabled"]) {
116  $this->setExportEnabled((bool) $rec["export_enabled"]);
117  }
118  $this->setImportEnabled((bool) $rec["import_enabled"]);
119  $this->setLimited((bool) $rec["limited"]);
120  $this->setLimitStart((string) $rec["limit_start"]);
121  $this->setLimitEnd((string) $rec["limit_end"]);
122  $this->setIsVisible((bool) $rec["is_visible"]);
123  if (null !== $rec['description']) {
124  $this->setDescription($rec['description']);
125  }
126  $this->setDefaultSortField((string) $rec['default_sort_field_id']);
127  $this->setDefaultSortFieldOrder($rec['default_sort_field_order']);
128  $this->setPublicCommentsEnabled((bool) $rec['public_comments']);
129  $this->setViewOwnRecordsPerm((bool) $rec['view_own_records_perm']);
130  $this->setDeleteByOwner((bool) $rec['delete_by_owner']);
131  $this->setSaveConfirmation((bool) $rec['save_confirmation']);
132  if (null !== $rec['table_order']) {
133  $this->setOrder($rec['table_order']);
134  }
135  }
136 
142  public function doDelete(bool $delete_only_content = false, bool $omit_notification = false): void
143  {
144  foreach ($this->getRecords() as $record) {
145  $record->doDelete($omit_notification);
146  }
147 
148  foreach ($this->getRecordFields() as $field) {
149  $field->doDelete();
150  }
151 
152  if (!$delete_only_content) {
153  $query = "DELETE FROM il_dcl_table WHERE id = " . $this->db->quote($this->getId(), "integer");
154  $this->db->manipulate($query);
155  }
156  }
157 
158  public function doCreate(bool $create_tablefield_setting = true, bool $create_standardview = true): void
159  {
160  $id = $this->db->nextId("il_dcl_table");
161  $this->setId($id);
162  $query = "INSERT INTO il_dcl_table (" . "id" . ", obj_id" . ", title" . ", add_perm" . ", edit_perm" . ", delete_perm" . ", edit_by_owner"
163  . ", limited" . ", limit_start" . ", limit_end" . ", is_visible" . ", export_enabled" . ", import_enabled" . ", default_sort_field_id"
164  . ", default_sort_field_order" . ", description" . ", public_comments" . ", view_own_records_perm"
165  . ", delete_by_owner, save_confirmation , table_order ) VALUES (" . $this->db->quote(
166  $this->getId(),
167  "integer"
168  ) . ","
169  . $this->db->quote($this->getObjId(), "integer") . "," . $this->db->quote($this->getTitle(), "text") . ","
170  . $this->db->quote($this->getAddPerm() ? 1 : 0, "integer") . "," . $this->db->quote(
171  $this->getEditPerm() ? 1 : 0,
172  "integer"
173  ) . ","
174  . $this->db->quote(
175  $this->getDeletePerm() ? 1 : 0,
176  "integer"
177  ) . "," . $this->db->quote($this->getEditByOwner() ? 1 : 0, "integer") . ","
178  . $this->db->quote($this->getLimited() ? 1 : 0, "integer") . "," . $this->db->quote(
179  $this->getLimitStart(),
180  "timestamp"
181  ) . ","
182  . $this->db->quote($this->getLimitEnd(), "timestamp") . "," . $this->db->quote(
183  $this->getIsVisible() ? 1 : 0,
184  "integer"
185  ) . ","
186  . $this->db->quote(
187  $this->getExportEnabled() ? 1 : 0,
188  "integer"
189  ) . "," . $this->db->quote($this->getImportEnabled() ? 1 : 0, "integer") . ","
190  . $this->db->quote($this->getDefaultSortField(), "text") . "," . $this->db->quote(
191  $this->getDefaultSortFieldOrder(),
192  "text"
193  ) . ","
194  . $this->db->quote($this->getDescription(), "text") . "," . $this->db->quote(
195  $this->getPublicCommentsEnabled(),
196  "integer"
197  ) . ","
198  . $this->db->quote(
199  $this->getViewOwnRecordsPerm(),
200  "integer"
201  ) . "," . $this->db->quote($this->getDeleteByOwner() ? 1 : 0, 'integer') . ","
202  . $this->db->quote($this->getSaveConfirmation() ? 1 : 0, 'integer') . "," . $this->db->quote(
203  $this->getOrder(),
204  'integer'
205  ) . ")";
206 
207  $this->db->manipulate($query);
208 
209  if ($create_standardview) {
210  //standard tableview
212  }
213 
214  if ($create_tablefield_setting) {
215  $this->buildOrderFields();
216  }
217  }
218 
219  public function doUpdate(): void
220  {
221  $this->db->update(
222  "il_dcl_table",
223  [
224  "obj_id" => ["integer", $this->getObjId()],
225  "title" => ["text", $this->getTitle()],
226  "add_perm" => ["integer", (int) $this->getAddPerm()],
227  "edit_perm" => ["integer", (int) $this->getEditPerm()],
228  "delete_perm" => ["integer", (int) $this->getDeletePerm()],
229  "edit_by_owner" => ["integer", (int) $this->getEditByOwner()],
230  "limited" => ["integer", $this->getLimited()],
231  "limit_start" => ["timestamp", $this->getLimitStart()],
232  "limit_end" => ["timestamp", $this->getLimitEnd()],
233  "is_visible" => ["integer", $this->getIsVisible() ? 1 : 0],
234  "export_enabled" => ["integer", $this->getExportEnabled() ? 1 : 0],
235  "import_enabled" => ["integer", $this->getImportEnabled() ? 1 : 0],
236  "description" => ["text", $this->getDescription()],
237  "default_sort_field_id" => ["text", $this->getDefaultSortField()],
238  "default_sort_field_order" => ["text", $this->getDefaultSortFieldOrder()],
239  "public_comments" => ["integer", $this->getPublicCommentsEnabled() ? 1 : 0],
240  "view_own_records_perm" => ["integer", $this->getViewOwnRecordsPerm()],
241  'delete_by_owner' => ['integer', $this->getDeleteByOwner() ? 1 : 0],
242  'save_confirmation' => ['integer', $this->getSaveConfirmation() ? 1 : 0],
243  'table_order' => ['integer', $this->getOrder()],
244  ],
245  [
246  "id" => ["integer", $this->getId()],
247  ]
248  );
249  }
250 
254  public function setId(int $a_id): void
255  {
256  $this->id = $a_id;
257  }
258 
262  public function getId(): int
263  {
264  return $this->id;
265  }
266 
267  public function setObjId(int $a_id): void
268  {
269  $this->objId = $a_id;
270  }
271 
272  public function getObjId(): ?int
273  {
274  return $this->objId;
275  }
276 
277  public function setTitle(string $a_title): void
278  {
279  $this->title = $a_title;
280  }
281 
282  public function getTitle(): string
283  {
284  return $this->title;
285  }
286 
288  {
289  $this->loadObj();
290 
291  return $this->obj;
292  }
293 
294  protected function loadObj(): void
295  {
296  if ($this->obj == null) {
297  $this->obj = new ilObjDataCollection($this->objId, false);
298  }
299  }
300 
304  public function getRecords(): array
305  {
306  if ($this->records == null) {
307  $this->loadRecords();
308  }
309 
310  return $this->records;
311  }
312 
313  public function loadRecords(): void
314  {
315  $records = [];
316  $query = "SELECT id FROM il_dcl_record WHERE table_id = " . $this->db->quote($this->id, "integer");
317  $set = $this->db->query($query);
318 
319  while ($rec = $this->db->fetchAssoc($set)) {
320  $records[$rec['id']] = ilDclCache::getRecordCache($rec['id']);
321  }
322 
323  $this->records = $records;
324  }
325 
326  public function deleteField(int $field_id): void
327  {
328  $field = ilDclCache::getFieldCache($field_id);
329  $records = $this->getRecords();
330 
331  foreach ($records as $record) {
332  $record->deleteField($field_id);
333  }
334 
335  $field->doDelete();
336  }
337 
338  public function getField(string $field_id): ?ilDclBaseFieldModel
339  {
340  $fields = $this->getFields();
341  $field = null;
342  foreach ($fields as $field_1) {
343  if ($field_1->getId() == $field_id) {
344  $field = $field_1;
345  }
346  }
347 
348  return $field;
349  }
350 
351  public function getFieldIds(): array
352  {
353  $field_ids = [];
354  foreach ($this->getFields() as $field) {
355  if ($field->getId()) {
356  $field_ids[] = $field->getId();
357  }
358  }
359 
360  return $field_ids;
361  }
362 
363  protected function loadCustomFields(): void
364  {
365  if (!$this->fields) {
366  $query
367  = "SELECT DISTINCT il_dcl_field.*, il_dcl_tfield_set.field_order
368  FROM il_dcl_field
369  INNER JOIN il_dcl_tfield_set
370  ON ( il_dcl_tfield_set.field NOT IN ('owner',
371  'last_update',
372  'last_edit_by',
373  'id',
374  'create_date')
375  AND il_dcl_tfield_set.table_id = il_dcl_field.table_id
376  AND il_dcl_tfield_set.field = " . $this->db->cast("il_dcl_field.id", "text") . ")
377  WHERE il_dcl_field.table_id = %s
378  ORDER BY il_dcl_tfield_set.field_order ASC";
379 
380  $set = $this->db->queryF($query, ['integer'], [$this->getId()]);
381  $fields = [];
382  while ($rec = $this->db->fetchAssoc($set)) {
383  $field = ilDclCache::buildFieldFromRecord($rec);
384  if ($this->show_invalid || in_array($field->getDatatypeId(), array_keys(ilDclDatatype::getAllDatatype()))) {
385  $fields[] = $field;
386  }
387  }
388  $this->fields = $fields;
389 
391  }
392  }
393 
397  public function getCustomFields(): array
398  {
399  if (!$this->fields) {
400  $this->loadCustomFields();
401  }
402 
403  return $this->fields;
404  }
405 
410  public function getNewFieldOrder(): int
411  {
412  $fields = $this->getFields();
413  $place = 0;
414  foreach ($fields as $field) {
415  if (!$field->isStandardField()) {
416  $place = $field->getOrder() + 1;
417  }
418  }
419 
420  return $place;
421  }
422 
426  public function getNewTableviewOrder(): int
427  {
428  return (ilDclTableView::getCountForTableId($this->getId()) + 1) * 10;
429  }
430 
434  public function sortTableViews(?array $tableviews = null): void
435  {
436  if ($tableviews == null) {
437  $tableviews = $this->getTableViews();
438  }
439 
440  $order = 10;
441  foreach ($tableviews as $tableview) {
442  $tableview->setTableviewOrder($order);
443  $tableview->update();
444  $order += 10;
445  }
446  }
447 
453  public function getFields(): array
454  {
455  if ($this->all_fields == null) {
456  $this->reloadFields();
457  }
458 
459  return $this->all_fields;
460  }
461 
462  public function reloadFields(): void
463  {
464  $this->loadCustomFields();
465  $this->stdFields = $this->getStandardFields();
466  $fields = array_merge($this->fields, $this->stdFields);
467 
468  $this->sortByOrder($fields);
469 
470  $this->all_fields = $fields;
471  }
472 
476  public function getTableViews(): array
477  {
478  return ilDclTableView::getAllForTableId($this->getId());
479  }
480 
484  public function getVisibleTableViews(int $user_id = 0, bool $with_active_detailedview = false): array
485  {
486  if (ilObjDataCollectionAccess::hasWriteAccess($this->getCollectionObject()->getRefId(), $user_id) && !$with_active_detailedview) {
487  return $this->getTableViews();
488  }
489 
490  $visible_views = [];
491  foreach ($this->getTableViews() as $tableView) {
493  $page = new ilDclDetailedViewDefinitionGUI($tableView->getId());
494  if (!$with_active_detailedview || $page->getPageObject()->isActive()) {
495  $visible_views[] = $tableView;
496  }
497  }
498  }
499 
500  return $visible_views;
501  }
502 
503  public function getFirstTableViewId(int $user_id = 0, bool $with_detailed_view = false): ?int
504  {
505  $array = $this->getVisibleTableViews($user_id, $with_detailed_view);
506  $tableview = array_shift($array);
507 
508  return $tableview?->getId();
509  }
510 
515  public function getFieldsForFormula(): array
516  {
517  $syntax_chars = array_merge(
518  array_map(static fn(Operators $function): string => $function->value, Operators::cases()),
519  array_map(static fn(Functions $function): string => $function->value, Functions::cases()),
520  ['(', ')', ',']
521  );
522  foreach ($this->getFields() as $field) {
523  if (in_array($field->getDatatypeId(), ilDclFormulaFieldModel::SUPPORTED_FIELDS)) {
524  foreach ($syntax_chars as $element) {
525  if (str_contains($field->getTitle(), $element)) {
526  continue 2;
527  }
528  }
529  $return[] = $field;
530  }
531  }
532 
533  return $return;
534  }
535 
541  public function getStandardFields(): array
542  {
543  if ($this->stdFields == null) {
544  $this->stdFields = ilDclStandardField::_getStandardFields($this->id);
545  // Don't return comments as field if this feature is not activated in the settings
546  if (!$this->getPublicCommentsEnabled()) {
548  foreach ($this->stdFields as $k => $field) {
549  if ($field->getId() == 'comments') {
550  unset($this->stdFields[$k]);
551  break;
552  }
553  }
554  }
555  }
556 
557  return $this->stdFields;
558  }
559 
564  public function getRecordFields(): array
565  {
566  $this->loadCustomFields();
567 
568  return $this->fields;
569  }
570 
575  public function getEditableFields(bool $creation_mode): array
576  {
577  $fields = $this->getRecordFields();
578  $editableFields = [];
579 
580  foreach ($fields as $field) {
581  $tableview_id = $this->http->wrapper()->post()->retrieve(
582  'tableview_id',
583  $this->refinery->kindlyTo()->int()
584  );
585  if (!$field->getViewSetting($tableview_id)->isLocked($creation_mode)) {
586  $editableFields[] = $field;
587  }
588  }
589 
590  return $editableFields;
591  }
592 
597  public function getExportableFields(): array
598  {
599  $fields = $this->getFields();
600  $exportableFields = [];
601  foreach ($fields as $field) {
602  if ($field->getExportable()) {
603  $exportableFields[] = $field;
604  }
605  }
606 
607  return $exportableFields;
608  }
609 
615  public function hasPermissionToEditRecord(int $ref_id, ilDclBaseRecordModel $record): bool
616  {
617  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
618  return false;
619  }
621  return true;
622  }
624  return false;
625  }
626  if ($this->getEditByOwner()) {
627  return $this->doesRecordBelongToUser($record);
628  }
629  if (!$this->checkLimit()) {
630  return false;
631  }
633  return true;
634  }
635  if ($this->getEditPerm() && !$this->getEditByOwner()) {
636  return true;
637  }
638 
639  return false;
640  }
641 
646  public function hasPermissionToDeleteRecord(int $ref_id, ilDclBaseRecordModel $record): bool
647  {
648  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
649  return false;
650  }
652  return true;
653  }
655  return false;
656  }
657  if (!$this->checkLimit()) {
658  return false;
659  }
660  if ($this->getDeletePerm() && !$this->getDeleteByOwner()) {
661  return true;
662  }
663  if ($this->getDeleteByOwner()) {
664  return $this->doesRecordBelongToUser($record);
665  }
666 
667  return false;
668  }
669 
674  public function hasPermissionToDeleteRecords(int $ref_id): bool
675  {
676  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
677  return false;
678  }
679 
680  return ((ilObjDataCollectionAccess::hasAddRecordAccess($ref_id) && $this->getDeletePerm())
682  }
683 
684  public function hasPermissionToViewRecord(int $ref_id, ilDclBaseRecordModel $record, int $user_id = 0): bool
685  {
686  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
687  return false;
688  }
690  $ref_id,
691  $user_id
693  return true;
694  }
696  // Check for view only own entries setting
697  if ($this->getViewOwnRecordsPerm() && ($user_id ?: $this->user->getId()) != $record->getOwner()) {
698  return false;
699  }
700 
701  return true;
702  }
703 
704  return false;
705  }
706 
707  protected function doesRecordBelongToUser(ilDclBaseRecordModel $record): bool
708  {
709  return ($this->user->getId() == $record->getOwner());
710  }
711 
712  public function checkLimit(): bool
713  {
714  if ($this->getLimited()) {
715  $from = null;
716  $to = null;
717  $now = new ilDateTime(date("Y-m-d H:i:s"), IL_CAL_DATE);
718 
719  if ($this->getLimitStart() != "") {
720  $from = new ilDateTime($this->getLimitStart(), IL_CAL_DATE);
721  }
722  if ($this->getLimitEnd() != "") {
723  $to = new ilDateTime($this->getLimitEnd(), IL_CAL_DATE);
724  }
725 
726  if ($from == null && $to == null) {
727  return true;
728  }
729  if ($from <= $now && $now <= $to) {
730  return true;
731  }
732  if ($from <= $now && $to == null) {
733  return true;
734  }
735  if ($from == null && $now <= $to) {
736  return true;
737  }
738 
739  return ($from <= $now && $now <= $to);
740  }
741 
742  return true;
743  }
744 
748  public function updateFields(): void
749  {
750  foreach ($this->getFields() as $field) {
751  $field->doUpdate();
752  }
753  }
754 
759  public function sortFields(array &$fields): void
760  {
761  $this->sortByOrder($fields);
762  //After sorting the array loses it's keys respectivly their keys are set form $field->id to 1,2,3... so we reset the keys.
763  $named = [];
764  foreach ($fields as $field) {
765  $named[$field->getId()] = $field;
766  }
767 
768  $fields = $named;
769  }
770 
774  protected function sortByOrder(array &$array): void
775  {
776  // php-bug: https://bugs.php.net/bug.php?id=50688
777  // fixed in php 7 but for now we need the @ a workaround
778  usort($array, [$this, "compareOrder"]);
779  }
780 
785  public function buildOrderFields(): void
786  {
787  $fields = $this->getFields();
788  $this->sortByOrder($fields);
789  $count = 10;
790  $offset = 10;
791  foreach ($fields as $field) {
792  if (!is_null($field->getOrder())) {
793  $field->setOrder($count);
794  $count = $count + $offset;
795  $field->doUpdate();
796  }
797  }
798  }
799 
803  public function getFieldByTitle(string $title): ?ilDclBaseFieldModel
804  {
805  $return = null;
806  foreach ($this->getFields() as $field) {
807  if ($field->getTitle() == $title) {
808  $return = $field;
809  break;
810  }
811  }
812 
813  return $return;
814  }
815 
816  public function setAddPerm(bool $add_perm): void
817  {
818  $this->add_perm = $add_perm;
819  }
820 
821  public function getAddPerm(): bool
822  {
823  return $this->add_perm;
824  }
825 
826  public function setDeletePerm(bool $delete_perm): void
827  {
828  $this->delete_perm = $delete_perm;
829  if (!$delete_perm) {
830  $this->setDeleteByOwner(false);
831  }
832  }
833 
834  public function getDeletePerm(): bool
835  {
836  return $this->delete_perm;
837  }
838 
839  public function setEditByOwner(bool $edit_by_owner): void
840  {
841  $this->edit_by_owner = $edit_by_owner;
842  if ($edit_by_owner) {
843  $this->setEditPerm(true);
844  }
845  }
846 
847  public function getEditByOwner(): bool
848  {
849  return $this->edit_by_owner;
850  }
851 
852  public function getDeleteByOwner(): bool
853  {
854  return $this->delete_by_owner;
855  }
856 
857  public function setDeleteByOwner(bool $delete_by_owner): void
858  {
859  $this->delete_by_owner = $delete_by_owner;
860  if ($delete_by_owner) {
861  $this->setDeletePerm(true);
862  }
863  }
864 
865  public function setEditPerm(bool $edit_perm): void
866  {
867  $this->edit_perm = $edit_perm;
868  if (!$edit_perm) {
869  $this->setEditByOwner(false);
870  }
871  }
872 
873  public function getEditPerm(): bool
874  {
875  return $this->edit_perm;
876  }
877 
878  public function setLimited(bool $limited): void
879  {
880  $this->limited = $limited;
881  }
882 
883  public function getLimited(): bool
884  {
885  return $this->limited;
886  }
887 
888  public function setLimitEnd(string $limit_end): void
889  {
890  $this->limit_end = $limit_end;
891  }
892 
893  public function getLimitEnd(): string
894  {
895  return $this->limit_end;
896  }
897 
898  public function setLimitStart(string $limit_start): void
899  {
900  $this->limit_start = $limit_start;
901  }
902 
903  public function getLimitStart(): string
904  {
905  return $this->limit_start;
906  }
907 
908  public function setIsVisible(bool $is_visible): void
909  {
910  $this->is_visible = $is_visible;
911  }
912 
913  public function getIsVisible(): bool
914  {
915  return $this->is_visible;
916  }
917 
918  public function setDescription(string $description): void
919  {
920  $this->description = $description;
921  }
922 
923  public function getDescription(): string
924  {
925  return $this->description;
926  }
927 
928  public function setDefaultSortField(string $default_sort_field): void
929  {
930  $default_sort_field = ($default_sort_field) ?: ""; // Change null or empty strings to zero
931  $this->default_sort_field = $default_sort_field;
932  }
933 
934  public function getDefaultSortField(): string
935  {
937  }
938 
939  public function setDefaultSortFieldOrder(string $default_sort_field_order): void
940  {
941  if (!in_array($default_sort_field_order, ['asc', 'desc'])) {
942  $default_sort_field_order = 'asc';
943  }
944  $this->default_sort_field_order = $default_sort_field_order;
945  }
946 
947  public function getDefaultSortFieldOrder(): string
948  {
950  }
951 
952  public function setPublicCommentsEnabled(bool $public_comments): void
953  {
954  $this->public_comments = $public_comments;
955  }
956 
957  public function getPublicCommentsEnabled(): bool
958  {
959  return $this->public_comments;
960  }
961 
962  public function setViewOwnRecordsPerm(bool $view_own_perm): void
963  {
964  $this->view_own_records_perm = (int) $view_own_perm;
965  }
966 
967  public function getViewOwnRecordsPerm(): bool
968  {
969  return (bool) $this->view_own_records_perm;
970  }
971 
972  public function getSaveConfirmation(): bool
973  {
975  }
976 
977  public function setSaveConfirmation(bool $save_confirmation): void
978  {
979  $this->save_confirmation = $save_confirmation;
980  }
981 
982  public function hasCustomFields(): bool
983  {
984  $this->loadCustomFields();
985 
986  return count($this->fields) > 0;
987  }
988 
990  {
991  if (is_null($a->getOrder() == null) && is_null($b->getOrder() == null)) {
992  return 0;
993  }
994  if (is_null($a->getOrder())) {
995  return 1;
996  }
997  if (is_null($b->getOrder())) {
998  return -1;
999  }
1000 
1001  return $a->getOrder() < $b->getOrder() ? -1 : 1;
1002  }
1003 
1004  public function cloneStructure(ilDclTable $original): void
1005  {
1006  $this->setTitle($original->getTitle());
1007  $this->setDescription($original->getDescription());
1008  $this->setIsVisible($original->getIsVisible());
1009  $this->setEditByOwner($original->getEditByOwner());
1010  $this->setAddPerm($original->getAddPerm());
1011  $this->setEditPerm($original->getEditPerm());
1012  $this->setDeleteByOwner($original->getDeleteByOwner());
1013  $this->setSaveConfirmation($original->getSaveConfirmation());
1014  $this->setDeletePerm($original->getDeletePerm());
1015  $this->setLimited($original->getLimited());
1016  $this->setLimitStart($original->getLimitStart());
1017  $this->setLimitEnd($original->getLimitEnd());
1018  $this->setViewOwnRecordsPerm($original->getViewOwnRecordsPerm());
1019  $this->setExportEnabled($original->getExportEnabled());
1020  $this->setImportEnabled($original->getImportEnabled());
1023  $this->setOrder($original->getOrder());
1024 
1025  $this->doCreate(true, false);
1026  // reset stdFields to get new for the created object
1027 
1028  $default_sort_field = 0;
1029  // Clone standard-fields
1030  $org_std_fields = $original->getStandardFields();
1031  foreach ($this->getStandardFields() as $element_key => $std_field) {
1032  $std_field->clone($org_std_fields[$element_key]);
1033  if ($std_field->getId() === $original->getDefaultSortField()) {
1034  $default_sort_field = $std_field->getId();
1035  }
1036  }
1037 
1038  // Clone fields
1039  $new_fields = [];
1040  foreach ($original->getFields() as $orig_field) {
1041  if (!$orig_field->isStandardField()) {
1042  $class_name = get_class($orig_field);
1043  $new_field = new $class_name();
1044  $new_field->setTableId($this->getId());
1045  $new_field->cloneStructure((int) $orig_field->getId());
1046  $new_fields[$orig_field->getId()] = $new_field;
1047 
1048  if ($orig_field->getId() === $original->getDefaultSortField()) {
1049  $default_sort_field = $new_field->getId();
1050  }
1051  }
1052  }
1053 
1054  $this->setDefaultSortField((string) $default_sort_field);
1055  $this->doUpdate();
1056 
1057  // Clone Records with recordfields
1058  foreach ($original->getRecords() as $orig_record) {
1059  $new_record = new ilDclBaseRecordModel();
1060  $new_record->setTableId($this->getId());
1061  $new_record->cloneStructure($orig_record->getId(), $new_fields);
1062  }
1063 
1064  //clone tableviews (includes pageobjects)
1065  foreach ($original->getTableViews() as $orig_tableview) {
1066  $new_tableview = new ilDclTableView();
1067  $new_tableview->setTableId($this->getId());
1068  $new_tableview->cloneStructure($orig_tableview, $new_fields);
1069  }
1070 
1071  // mandatory for all cloning functions
1072  ilDclCache::setCloneOf($original->getId(), $this->getId(), ilDclCache::TYPE_TABLE);
1073  }
1074 
1075  public function afterClone(): void
1076  {
1077  foreach ($this->getFields() as $field) {
1078  $field->afterClone($this->getRecords());
1079  }
1080  }
1081 
1085  public function _hasRecords(): bool
1086  {
1087  return count($this->getRecords()) > 0;
1088  }
1089 
1093  public function addField(ilDclBaseFieldModel $field): void
1094  {
1095  $this->all_fields[$field->getId()] = $field;
1096  }
1097 
1101  public static function _tableExists(int $table_id): bool
1102  {
1103  global $DIC;
1104  $ilDB = $DIC['ilDB'];
1105 
1106  $query = "SELECT * FROM il_dcl_table WHERE id = " . $table_id;
1107  $result = $ilDB->query($query);
1108 
1109  return $result->numRows() != 0;
1110  }
1111 
1115  public static function _getTableIdByTitle(string $title, int $obj_id): int
1116  {
1117  global $DIC;
1118  $ilDB = $DIC['ilDB'];
1119 
1120  $result = $ilDB->query(
1121  'SELECT id FROM il_dcl_table WHERE title = ' . $ilDB->quote($title, 'text') . ' AND obj_id = '
1122  . $ilDB->quote($obj_id, 'integer')
1123  );
1124  $id = 0;
1125  while ($rec = $ilDB->fetchAssoc($result)) {
1126  $id = $rec['id'];
1127  }
1128 
1129  return $id;
1130  }
1131 
1132  public function setExportEnabled(bool $export_enabled): void
1133  {
1134  $this->export_enabled = $export_enabled;
1135  }
1136 
1137  public function getExportEnabled(): bool
1138  {
1139  return $this->export_enabled;
1140  }
1141 
1142  public function getOrder(): int
1143  {
1144  if (!$this->table_order) {
1145  $this->updateOrder();
1146  }
1147 
1148  return $this->table_order;
1149  }
1150 
1151  public function updateOrder(): void
1152  {
1153  $result = $this->db->query('SELECT MAX(table_order) AS table_order FROM il_dcl_table WHERE obj_id = ' . $this->db->quote(
1154  $this->getCollectionObject()->getId(),
1155  'integer'
1156  ));
1157  $this->table_order = $this->db->fetchObject($result)->table_order + 10;
1158  $this->db->query('UPDATE il_dcl_table SET table_order = ' . $this->db->quote(
1159  $this->table_order,
1160  'integer'
1161  ) . ' WHERE id = ' . $this->db->quote($this->getId(), 'integer'));
1162  }
1163 
1164  public function setOrder(int $table_order): void
1165  {
1166  $this->table_order = $table_order;
1167  }
1168 
1169  public function setImportEnabled(bool $import_enabled): void
1170  {
1171  $this->import_enabled = $import_enabled;
1172  }
1173 
1174  public function getImportEnabled(): bool
1175  {
1176  return $this->import_enabled;
1177  }
1178 
1184  public static function _hasFieldByTitle(string $title, int $obj_id): bool
1185  {
1186  global $DIC;
1187  $ilDB = $DIC['ilDB'];
1188  $result = $ilDB->query(
1189  'SELECT * FROM il_dcl_field WHERE table_id = ' . $ilDB->quote($obj_id, 'integer') . ' AND title = '
1190  . $ilDB->quote($title, 'text')
1191  );
1192 
1193  return (bool) $ilDB->numRows($result);
1194  }
1195 
1205  public function getPartialRecords(
1206  string $ref_id,
1207  string $sort,
1208  string $direction,
1209  ?int $limit,
1210  int $offset,
1211  array $filter = []
1212  ): array {
1213  $sort_field = $this->getFieldByTitle($sort);
1214  $direction = strtolower($direction);
1215  $direction = (in_array($direction, ['desc', 'asc'])) ? $direction : 'asc';
1216 
1217  // Sorting by a status from an ILIAS Ref field. This column is added dynamically to the table, there is no field model
1218  $sort_by_status = false;
1219  if (substr($sort, 0, 8) == '_status_') {
1220  $sort_by_status = true;
1221  $sort_field = $this->getFieldByTitle(substr($sort, 8));
1222  }
1223 
1224  if (is_null($sort_field)) {
1225  $sort_field = $this->getField('id');
1226  }
1227 
1228  $sort_query_object = $sort_field->getRecordQuerySortObject($direction, $sort_by_status);
1229 
1230  $select_str = ($sort_query_object != null) ? $sort_query_object->getSelectStatement() : '';
1231  $join_str = ($sort_query_object != null) ? $sort_query_object->getJoinStatement() : '';
1232  $where_str = ($sort_query_object != null) ? $sort_query_object->getWhereStatement() : '';
1233  $order_str = ($sort_query_object != null) ? $sort_query_object->getOrderStatement() : '';
1234  $group_str = ($sort_query_object != null) ? $sort_query_object->getGroupStatement() : '';
1235 
1236  if (count($filter)) {
1237  foreach ($filter as $key => $filter_value) {
1238  $filter_field_id = substr($key, 7);
1239  $filter_field = $this->getField($filter_field_id);
1240  $filter_record_query_object = $filter_field->getRecordQueryFilterObject($filter_value, $sort_field);
1241 
1242  if ($filter_record_query_object) {
1243  $select_str .= $filter_record_query_object->getSelectStatement();
1244  $join_str .= $filter_record_query_object->getJoinStatement();
1245  $where_str .= $filter_record_query_object->getWhereStatement();
1246  $group_str .= $filter_record_query_object->getGroupStatement();
1247  }
1248  }
1249  }
1250 
1251  // Build the query string
1252  $sql = "SELECT DISTINCT record.id, record.owner";
1253  if ($select_str) {
1254  $sql .= ', ';
1255  }
1256 
1257  $as = ' AS ';
1258 
1259  $sql .= rtrim($select_str, ',') . " FROM il_dcl_record $as record ";
1260  $sql .= $join_str;
1261  $sql .= " WHERE record.table_id = " . $this->db->quote($this->getId(), 'integer');
1262 
1263  if (strlen($where_str) > 0) {
1264  $sql .= $where_str;
1265  }
1266 
1267  if (strlen($group_str) > 0) {
1268  $sql .= " GROUP BY " . $group_str;
1269  }
1270 
1271  if (strlen($order_str) > 0) {
1272  $sql .= " ORDER BY " . $order_str;
1273  }
1274 
1275  $set = $this->db->query($sql);
1276  $total_record_ids = [];
1277 
1278  $is_allowed_to_view = (ilObjDataCollectionAccess::hasWriteAccess((int) $ref_id) || ilObjDataCollectionAccess::hasEditAccess((int) $ref_id));
1279  while ($rec = $this->db->fetchAssoc($set)) {
1280  // Quick check if the current user is allowed to view the record
1281  if (!$is_allowed_to_view && ($this->getViewOwnRecordsPerm() && $this->user->getId() != $rec['owner'])) {
1282  continue;
1283  }
1284  $total_record_ids[] = $rec['id'];
1285  }
1286  // Save record-ids in session to enable prev/next links in detail view
1287  ilSession::set('dcl_table_id', $this->getId());
1288  ilSession::set('dcl_record_ids', $total_record_ids);
1289 
1290  if ($sort_query_object != null) {
1291  $total_record_ids = $sort_query_object->applyCustomSorting($sort_field, $total_record_ids, $direction);
1292  }
1293 
1294  if ($sort === 'n_comments') {
1295  global $DIC;
1296  $comments_nr = [];
1297  foreach ($total_record_ids as $id) {
1298  $comments_nr[$id] = $DIC->notes()->domain()->getNrOfCommentsForContext($DIC->notes()->data()->context($this->getObjId(), $id, 'dcl'));
1299  }
1300  uasort($comments_nr, static fn($a, $b) => ($direction === 'asc' ? 1 : -1) * ($a <=> $b));
1301  $total_record_ids = array_keys($comments_nr);
1302  }
1303 
1304  // Now slice the array to load only the needed records in memory
1305  $record_ids = array_slice($total_record_ids, $offset, $limit);
1306 
1307  $records = [];
1308  foreach ($record_ids as $id) {
1309  $records[] = ilDclCache::getRecordCache($id);
1310  }
1311 
1312  return ['records' => $records, 'total' => count($total_record_ids)];
1313  }
1314 
1315  public function showInvalidFields(bool $value): void
1316  {
1317  $this->show_invalid = $value;
1318  }
1319 }
getEditableFields(bool $creation_mode)
doDelete(bool $delete_only_content=false, bool $omit_notification=false)
Delete table Attention this does not delete the maintable of it&#39;s the maintable of the collection...
doRead()
Read table.
static createOrGetStandardView(int $table_id)
sortByOrder(array &$array)
static hasAccessToTableView(ilDclTableView $tableview, ?int $user_id=0)
int $view_own_records_perm
True if user can only view his/her own entries in the table.
getFieldByTitle(string $title)
Get a field by title.
setIsVisible(bool $is_visible)
ilObjDataCollection $obj
setId(int $a_id)
Set table id.
static preloadFieldProperties(array $fields)
Preloads field properties.
addField(ilDclBaseFieldModel $field)
setObjId(int $a_id)
static _getStandardFields(int $table_id)
deleteField(int $field_id)
getFieldsForFormula()
Returns all fields of this table including the standard fields, wich are supported for formulas...
ILIAS HTTP Services $http
hasPermissionToDeleteRecord(int $ref_id, ilDclBaseRecordModel $record)
static hasAddRecordAccess(int $ref, ?int $user_id=0)
array $all_fields
table fields and std fields combined
static getFieldCache(int $field_id=0)
ilObjUser $user
ilDclDetailedViewDefinitionGUI: ilPageEditorGUI, ilEditClipboardGUI, ilMediaPoolTargetSelector ilDcl...
setEditByOwner(bool $edit_by_owner)
setDeleteByOwner(bool $delete_by_owner)
setEditPerm(bool $edit_perm)
getFields()
Returns all fields of this table including the standard fields.
setLimitStart(string $limit_start)
static _getTableIdByTitle(string $title, int $obj_id)
getId()
Get table id.
showInvalidFields(bool $value)
__construct(int $a_id=0)
string $limit_start
setDefaultSortFieldOrder(string $default_sort_field_order)
doesRecordBelongToUser(ilDclBaseRecordModel $record)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
sortTableViews(?array $tableviews=null)
updateFields()
Update fields.
setOrder(int $table_order)
setTitle(string $a_title)
getVisibleTableViews(int $user_id=0, bool $with_active_detailedview=false)
getExportableFields()
Return all the fields that are marked as exportable.
$ref_id
Definition: ltiauth.php:65
static http()
Fetches the global http state from ILIAS.
sortFields(array &$fields)
sortFields
getPartialRecords(string $ref_id, string $sort, string $direction, ?int $limit, int $offset, array $filter=[])
Return only the needed subset of record objects for the table, according to sorting, paging and filters.
cloneStructure(ilDclTable $original)
static getAllDatatype(bool $force=false)
Get all possible Datatypes.
ILIAS Refinery Factory $refinery
getFirstTableViewId(int $user_id=0, bool $with_detailed_view=false)
ilDBInterface $db
global $DIC
Definition: shib_login.php:26
string $default_sort_field_order
Default sort-order (asc|desc)
getRecordFields()
Returns all fields of this table which are NOT standard fields.
static _lookupObjectId(int $ref_id)
static getCountForTableId(int $table_id)
setLimitEnd(string $limit_end)
_hasRecords()
_hasRecords
static hasWriteAccess(int $ref, ?int $user_id=0)
static setCloneOf(int $old, int $new, string $type)
hasPermissionToViewRecord(int $ref_id, ilDclBaseRecordModel $record, int $user_id=0)
string $description
Description for this table displayed above records.
bool $public_comments
True if users can add comments on each record of this table.
getField(string $field_id)
static _hasFieldByTitle(string $title, int $obj_id)
Checks if a table has a field with the given title.
string $default_sort_field
setExportEnabled(bool $export_enabled)
hasPermissionToEditRecord(int $ref_id, ilDclBaseRecordModel $record)
setSaveConfirmation(bool $save_confirmation)
static getRecordCache(?int $record_id)
const IL_CAL_DATE
setAddPerm(bool $add_perm)
compareOrder(ilDclBaseFieldModel $a, ilDclBaseFieldModel $b)
hasPermissionToDeleteRecords(int $ref_id)
static buildFieldFromRecord(array $rec)
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
static hasReadAccess(int $ref, ?int $user_id=0)
bool $save_confirmation
setDeletePerm(bool $delete_perm)
static getAllForTableId(int $table_id)
setImportEnabled(bool $import_enabled)
static hasEditAccess(int $ref, ?int $user_id=0)
buildOrderFields()
buildOrderFields orders the fields.
setDescription(string $description)
static _tableExists(int $table_id)
doCreate(bool $create_tablefield_setting=true, bool $create_standardview=true)
static set(string $a_var, $a_val)
Set a value.
setDefaultSortField(string $default_sort_field)
setViewOwnRecordsPerm(bool $view_own_perm)
setPublicCommentsEnabled(bool $public_comments)
setLimited(bool $limited)
getNewFieldOrder()
getNewOrder