ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilDclTable.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
23
25{
26 protected int $id = 0;
27 protected ?int $objId = null;
28 protected ?ilObjDataCollection $obj = 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(
192 "text"
193 ) . ","
194 . $this->db->quote($this->getDescription(), "text") . "," . $this->db->quote(
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)) {
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 {
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
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,
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
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 {
850 }
851
852 public function getDeleteByOwner(): bool
853 {
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
940 {
941 if (!in_array($default_sort_field_order, ['asc', 'desc'])) {
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 {
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
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) {
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}
Builds data types.
Definition: Factory.php:36
Class Services.
Definition: Services.php:38
const IL_CAL_DATE
@classDescription Date and time handling
static getRecordCache(?int $record_id)
static getFieldCache(int $field_id=0)
static buildFieldFromRecord(array $rec)
static preloadFieldProperties(array $fields)
Preloads field properties.
static setCloneOf(int $old, int $new, string $type)
static getAllDatatype(bool $force=false)
Get all possible Datatypes.
@ilCtrl_Calls ilDclDetailedViewDefinitionGUI: ilPageEditorGUI, ilEditClipboardGUI,...
static _getStandardFields(int $table_id)
static createOrGetStandardView(int $table_id)
static getAllForTableId(int $table_id)
static getCountForTableId(int $table_id)
hasPermissionToDeleteRecords(int $ref_id)
int $view_own_records_perm
True if user can only view his/her own entries in the table.
updateFields()
Update fields.
setDefaultSortField(string $default_sort_field)
getFieldsForFormula()
Returns all fields of this table including the standard fields, wich are supported for formulas.
_hasRecords()
_hasRecords
ilObjUser $user
setEditByOwner(bool $edit_by_owner)
getRecordFields()
Returns all fields of this table which are NOT standard fields.
setDeletePerm(bool $delete_perm)
addField(ilDclBaseFieldModel $field)
setSaveConfirmation(bool $save_confirmation)
static _tableExists(int $table_id)
buildOrderFields()
buildOrderFields orders the fields.
setEditPerm(bool $edit_perm)
string $default_sort_field
doesRecordBelongToUser(ilDclBaseRecordModel $record)
setDeleteByOwner(bool $delete_by_owner)
showInvalidFields(bool $value)
getExportableFields()
Return all the fields that are marked as exportable.
string $limit_start
getFirstTableViewId(int $user_id=0, bool $with_detailed_view=false)
sortTableViews(?array $tableviews=null)
setIsVisible(bool $is_visible)
sortByOrder(array &$array)
deleteField(int $field_id)
setLimitStart(string $limit_start)
getNewFieldOrder()
getNewOrder
setOrder(int $table_order)
getField(string $field_id)
array $all_fields
table fields and std fields combined
sortFields(array &$fields)
sortFields
hasPermissionToEditRecord(int $ref_id, ilDclBaseRecordModel $record)
cloneStructure(ilDclTable $original)
setImportEnabled(bool $import_enabled)
setObjId(int $a_id)
compareOrder(ilDclBaseFieldModel $a, ilDclBaseFieldModel $b)
setTitle(string $a_title)
hasPermissionToDeleteRecord(int $ref_id, ilDclBaseRecordModel $record)
setId(int $a_id)
Set table id.
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,...
ilObjDataCollection $obj
setDescription(string $description)
doCreate(bool $create_tablefield_setting=true, bool $create_standardview=true)
string $default_sort_field_order
Default sort-order (asc|desc)
getFields()
Returns all fields of this table including the standard fields.
getEditableFields(bool $creation_mode)
setDefaultSortFieldOrder(string $default_sort_field_order)
setPublicCommentsEnabled(bool $public_comments)
setAddPerm(bool $add_perm)
doRead()
Read table.
__construct(int $a_id=0)
getFieldByTitle(string $title)
Get a field by title.
setLimited(bool $limited)
getId()
Get table id.
ILIAS Refinery Factory $refinery
static _getTableIdByTitle(string $title, int $obj_id)
ilDBInterface $db
string $description
Description for this table displayed above records.
static _hasFieldByTitle(string $title, int $obj_id)
Checks if a table has a field with the given title.
bool $save_confirmation
doDelete(bool $delete_only_content=false, bool $omit_notification=false)
Delete table Attention this does not delete the maintable of it's the maintable of the collection.
ILIAS HTTP Services $http
setLimitEnd(string $limit_end)
hasPermissionToViewRecord(int $ref_id, ilDclBaseRecordModel $record, int $user_id=0)
setExportEnabled(bool $export_enabled)
bool $public_comments
True if users can add comments on each record of this table.
setViewOwnRecordsPerm(bool $view_own_perm)
getVisibleTableViews(int $user_id=0, bool $with_active_detailedview=false)
static hasWriteAccess(int $ref, ?int $user_id=0)
static hasReadAccess(int $ref, ?int $user_id=0)
static hasAccessToTableView(ilDclTableView $tableview, ?int $user_id=0)
static hasEditAccess(int $ref, ?int $user_id=0)
static hasAddRecordAccess(int $ref, ?int $user_id=0)
User class.
static _lookupObjectId(int $ref_id)
static set(string $a_var, $a_val)
Set a value.
Interface ilDBInterface.
$ref_id
Definition: ltiauth.php:66
static http()
Fetches the global http state from ILIAS.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
global $DIC
Definition: shib_login.php:26