ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
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;
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(
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  if (!$with_active_detailedview || ilDclDetailedViewDefinition::isActive($tableView->getId())) {
494  $visible_views[] = $tableView;
495  }
496  }
497  }
498 
499  return $visible_views;
500  }
501 
502  public function getFirstTableViewId(int $user_id = 0, bool $with_detailed_view = false): ?int
503  {
504  $array = $this->getVisibleTableViews($user_id, $with_detailed_view);
505  $tableview = array_shift($array);
506 
507  return $tableview?->getId();
508  }
509 
514  public function getFieldsForFormula(): array
515  {
516  $syntax_chars = array_merge(
517  array_map(static fn(Operators $function): string => $function->value, Operators::cases()),
518  array_map(static fn(Functions $function): string => $function->value, Functions::cases()),
519  ['(', ')', ',']
520  );
521  foreach ($this->getFields() as $field) {
522  if (in_array($field->getDatatypeId(), ilDclFormulaFieldModel::SUPPORTED_FIELDS)) {
523  foreach ($syntax_chars as $element) {
524  if (str_contains($field->getTitle(), $element)) {
525  continue 2;
526  }
527  }
528  $return[] = $field;
529  }
530  }
531 
532  return $return;
533  }
534 
540  public function getStandardFields(): array
541  {
542  if ($this->stdFields == null) {
543  $this->stdFields = ilDclStandardField::_getStandardFields($this->id);
544  // Don't return comments as field if this feature is not activated in the settings
545  if (!$this->getPublicCommentsEnabled()) {
547  foreach ($this->stdFields as $k => $field) {
548  if ($field->getId() == 'comments') {
549  unset($this->stdFields[$k]);
550  break;
551  }
552  }
553  }
554  }
555 
556  return $this->stdFields;
557  }
558 
563  public function getRecordFields(): array
564  {
565  $this->loadCustomFields();
566 
567  return $this->fields;
568  }
569 
574  public function getEditableFields(bool $creation_mode): array
575  {
576  $fields = $this->getRecordFields();
577  $editableFields = [];
578 
579  foreach ($fields as $field) {
580  $tableview_id = $this->http->wrapper()->post()->retrieve(
581  'tableview_id',
582  $this->refinery->kindlyTo()->int()
583  );
584  if (!$field->getViewSetting($tableview_id)->isLocked($creation_mode)) {
585  $editableFields[] = $field;
586  }
587  }
588 
589  return $editableFields;
590  }
591 
596  public function getExportableFields(): array
597  {
598  $fields = $this->getFields();
599  $exportableFields = [];
600  foreach ($fields as $field) {
601  if ($field->getExportable()) {
602  $exportableFields[] = $field;
603  }
604  }
605 
606  return $exportableFields;
607  }
608 
614  public function hasPermissionToEditRecord(int $ref_id, ilDclBaseRecordModel $record): bool
615  {
616  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
617  return false;
618  }
620  return true;
621  }
623  return false;
624  }
625  if ($this->getEditByOwner()) {
626  return $this->doesRecordBelongToUser($record);
627  }
628  if (!$this->checkLimit()) {
629  return false;
630  }
632  return true;
633  }
634  if ($this->getEditPerm() && !$this->getEditByOwner()) {
635  return true;
636  }
637 
638  return false;
639  }
640 
645  public function hasPermissionToDeleteRecord(int $ref_id, ilDclBaseRecordModel $record): bool
646  {
647  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
648  return false;
649  }
651  return true;
652  }
654  return false;
655  }
656  if (!$this->checkLimit()) {
657  return false;
658  }
659  if ($this->getDeletePerm() && !$this->getDeleteByOwner()) {
660  return true;
661  }
662  if ($this->getDeleteByOwner()) {
663  return $this->doesRecordBelongToUser($record);
664  }
665 
666  return false;
667  }
668 
673  public function hasPermissionToDeleteRecords(int $ref_id): bool
674  {
675  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
676  return false;
677  }
678 
679  return ((ilObjDataCollectionAccess::hasAddRecordAccess($ref_id) && $this->getDeletePerm())
681  }
682 
683  public function hasPermissionToViewRecord(int $ref_id, ilDclBaseRecordModel $record, int $user_id = 0): bool
684  {
685  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
686  return false;
687  }
689  $ref_id,
690  $user_id
692  return true;
693  }
695  // Check for view only own entries setting
696  if ($this->getViewOwnRecordsPerm() && ($user_id ?: $this->user->getId()) != $record->getOwner()) {
697  return false;
698  }
699 
700  return true;
701  }
702 
703  return false;
704  }
705 
706  protected function doesRecordBelongToUser(ilDclBaseRecordModel $record): bool
707  {
708  return ($this->user->getId() == $record->getOwner());
709  }
710 
711  public function checkLimit(): bool
712  {
713  if ($this->getLimited()) {
714  $from = null;
715  $to = null;
716  $now = new ilDateTime(date("Y-m-d H:i:s"), IL_CAL_DATE);
717 
718  if ($this->getLimitStart() != "") {
719  $from = new ilDateTime($this->getLimitStart(), IL_CAL_DATE);
720  }
721  if ($this->getLimitEnd() != "") {
722  $to = new ilDateTime($this->getLimitEnd(), IL_CAL_DATE);
723  }
724 
725  if ($from == null && $to == null) {
726  return true;
727  }
728  if ($from <= $now && $now <= $to) {
729  return true;
730  }
731  if ($from <= $now && $to == null) {
732  return true;
733  }
734  if ($from == null && $now <= $to) {
735  return true;
736  }
737 
738  return ($from <= $now && $now <= $to);
739  }
740 
741  return true;
742  }
743 
747  public function updateFields(): void
748  {
749  foreach ($this->getFields() as $field) {
750  $field->doUpdate();
751  }
752  }
753 
758  public function sortFields(array &$fields): void
759  {
760  $this->sortByOrder($fields);
761  //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.
762  $named = [];
763  foreach ($fields as $field) {
764  $named[$field->getId()] = $field;
765  }
766 
767  $fields = $named;
768  }
769 
773  protected function sortByOrder(array &$array): void
774  {
775  // php-bug: https://bugs.php.net/bug.php?id=50688
776  // fixed in php 7 but for now we need the @ a workaround
777  usort($array, [$this, "compareOrder"]);
778  }
779 
784  public function buildOrderFields(): void
785  {
786  $fields = $this->getFields();
787  $this->sortByOrder($fields);
788  $count = 10;
789  $offset = 10;
790  foreach ($fields as $field) {
791  if (!is_null($field->getOrder())) {
792  $field->setOrder($count);
793  $count = $count + $offset;
794  $field->doUpdate();
795  }
796  }
797  }
798 
802  public function getFieldByTitle(string $title): ?ilDclBaseFieldModel
803  {
804  $return = null;
805  foreach ($this->getFields() as $field) {
806  if ($field->getTitle() == $title) {
807  $return = $field;
808  break;
809  }
810  }
811 
812  return $return;
813  }
814 
815  public function setAddPerm(bool $add_perm): void
816  {
817  $this->add_perm = $add_perm;
818  }
819 
820  public function getAddPerm(): bool
821  {
822  return $this->add_perm;
823  }
824 
825  public function setDeletePerm(bool $delete_perm): void
826  {
827  $this->delete_perm = $delete_perm;
828  if (!$delete_perm) {
829  $this->setDeleteByOwner(false);
830  }
831  }
832 
833  public function getDeletePerm(): bool
834  {
835  return $this->delete_perm;
836  }
837 
838  public function setEditByOwner(bool $edit_by_owner): void
839  {
840  $this->edit_by_owner = $edit_by_owner;
841  if ($edit_by_owner) {
842  $this->setEditPerm(true);
843  }
844  }
845 
846  public function getEditByOwner(): bool
847  {
848  return $this->edit_by_owner;
849  }
850 
851  public function getDeleteByOwner(): bool
852  {
853  return $this->delete_by_owner;
854  }
855 
856  public function setDeleteByOwner(bool $delete_by_owner): void
857  {
858  $this->delete_by_owner = $delete_by_owner;
859  if ($delete_by_owner) {
860  $this->setDeletePerm(true);
861  }
862  }
863 
864  public function setEditPerm(bool $edit_perm): void
865  {
866  $this->edit_perm = $edit_perm;
867  if (!$edit_perm) {
868  $this->setEditByOwner(false);
869  }
870  }
871 
872  public function getEditPerm(): bool
873  {
874  return $this->edit_perm;
875  }
876 
877  public function setLimited(bool $limited): void
878  {
879  $this->limited = $limited;
880  }
881 
882  public function getLimited(): bool
883  {
884  return $this->limited;
885  }
886 
887  public function setLimitEnd(string $limit_end): void
888  {
889  $this->limit_end = $limit_end;
890  }
891 
892  public function getLimitEnd(): string
893  {
894  return $this->limit_end;
895  }
896 
897  public function setLimitStart(string $limit_start): void
898  {
899  $this->limit_start = $limit_start;
900  }
901 
902  public function getLimitStart(): string
903  {
904  return $this->limit_start;
905  }
906 
907  public function setIsVisible(bool $is_visible): void
908  {
909  $this->is_visible = $is_visible;
910  }
911 
912  public function getIsVisible(): bool
913  {
914  return $this->is_visible;
915  }
916 
917  public function setDescription(string $description): void
918  {
919  $this->description = $description;
920  }
921 
922  public function getDescription(): string
923  {
924  return $this->description;
925  }
926 
927  public function setDefaultSortField(string $default_sort_field): void
928  {
929  $default_sort_field = ($default_sort_field) ?: ""; // Change null or empty strings to zero
930  $this->default_sort_field = $default_sort_field;
931  }
932 
933  public function getDefaultSortField(): string
934  {
936  }
937 
938  public function setDefaultSortFieldOrder(string $default_sort_field_order): void
939  {
940  if (!in_array($default_sort_field_order, ['asc', 'desc'])) {
941  $default_sort_field_order = 'asc';
942  }
943  $this->default_sort_field_order = $default_sort_field_order;
944  }
945 
946  public function getDefaultSortFieldOrder(): string
947  {
949  }
950 
951  public function setPublicCommentsEnabled(bool $public_comments): void
952  {
953  $this->public_comments = $public_comments;
954  }
955 
956  public function getPublicCommentsEnabled(): bool
957  {
958  return $this->public_comments;
959  }
960 
961  public function setViewOwnRecordsPerm(bool $view_own_perm): void
962  {
963  $this->view_own_records_perm = (int) $view_own_perm;
964  }
965 
966  public function getViewOwnRecordsPerm(): bool
967  {
968  return (bool) $this->view_own_records_perm;
969  }
970 
971  public function getSaveConfirmation(): bool
972  {
974  }
975 
976  public function setSaveConfirmation(bool $save_confirmation): void
977  {
978  $this->save_confirmation = $save_confirmation;
979  }
980 
981  public function hasCustomFields(): bool
982  {
983  $this->loadCustomFields();
984 
985  return count($this->fields) > 0;
986  }
987 
989  {
990  if (is_null($a->getOrder() == null) && is_null($b->getOrder() == null)) {
991  return 0;
992  }
993  if (is_null($a->getOrder())) {
994  return 1;
995  }
996  if (is_null($b->getOrder())) {
997  return -1;
998  }
999 
1000  return $a->getOrder() < $b->getOrder() ? -1 : 1;
1001  }
1002 
1003  public function cloneStructure(ilDclTable $original): void
1004  {
1005  $this->setTitle($original->getTitle());
1006  $this->setDescription($original->getDescription());
1007  $this->setIsVisible($original->getIsVisible());
1008  $this->setEditByOwner($original->getEditByOwner());
1009  $this->setAddPerm($original->getAddPerm());
1010  $this->setEditPerm($original->getEditPerm());
1011  $this->setDeleteByOwner($original->getDeleteByOwner());
1012  $this->setSaveConfirmation($original->getSaveConfirmation());
1013  $this->setDeletePerm($original->getDeletePerm());
1014  $this->setLimited($original->getLimited());
1015  $this->setLimitStart($original->getLimitStart());
1016  $this->setLimitEnd($original->getLimitEnd());
1017  $this->setViewOwnRecordsPerm($original->getViewOwnRecordsPerm());
1018  $this->setExportEnabled($original->getExportEnabled());
1019  $this->setImportEnabled($original->getImportEnabled());
1022  $this->setOrder($original->getOrder());
1023 
1024  $this->doCreate(true, false);
1025  // reset stdFields to get new for the created object
1026 
1027  $default_sort_field = 0;
1028  // Clone standard-fields
1029  $org_std_fields = $original->getStandardFields();
1030  foreach ($this->getStandardFields() as $element_key => $std_field) {
1031  $std_field->clone($org_std_fields[$element_key]);
1032  if ($std_field->getId() === $original->getDefaultSortField()) {
1033  $default_sort_field = $std_field->getId();
1034  }
1035  }
1036 
1037  // Clone fields
1038  $new_fields = [];
1039  foreach ($original->getFields() as $orig_field) {
1040  if (!$orig_field->isStandardField()) {
1041  $class_name = get_class($orig_field);
1042  $new_field = new $class_name();
1043  $new_field->setTableId($this->getId());
1044  $new_field->cloneStructure((int) $orig_field->getId());
1045  $new_fields[$orig_field->getId()] = $new_field;
1046 
1047  if ($orig_field->getId() === $original->getDefaultSortField()) {
1048  $default_sort_field = $new_field->getId();
1049  }
1050  }
1051  }
1052 
1053  $this->setDefaultSortField((string) $default_sort_field);
1054  $this->doUpdate();
1055 
1056  // Clone Records with recordfields
1057  foreach ($original->getRecords() as $orig_record) {
1058  $new_record = new ilDclBaseRecordModel();
1059  $new_record->setTableId($this->getId());
1060  $new_record->cloneStructure($orig_record->getId(), $new_fields);
1061  }
1062 
1063  //clone tableviews (includes pageobjects)
1064  foreach ($original->getTableViews() as $orig_tableview) {
1065  $new_tableview = new ilDclTableView();
1066  $new_tableview->setTableId($this->getId());
1067  $new_tableview->cloneStructure($orig_tableview, $new_fields);
1068  }
1069 
1070  // mandatory for all cloning functions
1071  ilDclCache::setCloneOf($original->getId(), $this->getId(), ilDclCache::TYPE_TABLE);
1072  }
1073 
1074  public function afterClone(): void
1075  {
1076  foreach ($this->getFields() as $field) {
1077  $field->afterClone($this->getRecords());
1078  }
1079  }
1080 
1084  public function _hasRecords(): bool
1085  {
1086  return count($this->getRecords()) > 0;
1087  }
1088 
1092  public function addField(ilDclBaseFieldModel $field): void
1093  {
1094  $this->all_fields[$field->getId()] = $field;
1095  }
1096 
1100  public static function _tableExists(int $table_id): bool
1101  {
1102  global $DIC;
1103  $ilDB = $DIC['ilDB'];
1104 
1105  $query = "SELECT * FROM il_dcl_table WHERE id = " . $table_id;
1106  $result = $ilDB->query($query);
1107 
1108  return $result->numRows() != 0;
1109  }
1110 
1114  public static function _getTableIdByTitle(string $title, int $obj_id): int
1115  {
1116  global $DIC;
1117  $ilDB = $DIC['ilDB'];
1118 
1119  $result = $ilDB->query(
1120  'SELECT id FROM il_dcl_table WHERE title = ' . $ilDB->quote($title, 'text') . ' AND obj_id = '
1121  . $ilDB->quote($obj_id, 'integer')
1122  );
1123  $id = 0;
1124  while ($rec = $ilDB->fetchAssoc($result)) {
1125  $id = $rec['id'];
1126  }
1127 
1128  return $id;
1129  }
1130 
1131  public function setExportEnabled(bool $export_enabled): void
1132  {
1133  $this->export_enabled = $export_enabled;
1134  }
1135 
1136  public function getExportEnabled(): bool
1137  {
1138  return $this->export_enabled;
1139  }
1140 
1141  public function getOrder(): int
1142  {
1143  if (!$this->table_order) {
1144  $this->updateOrder();
1145  }
1146 
1147  return $this->table_order;
1148  }
1149 
1150  public function updateOrder(): void
1151  {
1152  $result = $this->db->query('SELECT MAX(table_order) AS table_order FROM il_dcl_table WHERE obj_id = ' . $this->db->quote(
1153  $this->getCollectionObject()->getId(),
1154  'integer'
1155  ));
1156  $this->table_order = $this->db->fetchObject($result)->table_order + 10;
1157  $this->db->query('UPDATE il_dcl_table SET table_order = ' . $this->db->quote(
1158  $this->table_order,
1159  'integer'
1160  ) . ' WHERE id = ' . $this->db->quote($this->getId(), 'integer'));
1161  }
1162 
1163  public function setOrder(int $table_order): void
1164  {
1165  $this->table_order = $table_order;
1166  }
1167 
1168  public function setImportEnabled(bool $import_enabled): void
1169  {
1170  $this->import_enabled = $import_enabled;
1171  }
1172 
1173  public function getImportEnabled(): bool
1174  {
1175  return $this->import_enabled;
1176  }
1177 
1183  public static function _hasFieldByTitle(string $title, int $obj_id): bool
1184  {
1185  global $DIC;
1186  $ilDB = $DIC['ilDB'];
1187  $result = $ilDB->query(
1188  'SELECT * FROM il_dcl_field WHERE table_id = ' . $ilDB->quote($obj_id, 'integer') . ' AND title = '
1189  . $ilDB->quote($title, 'text')
1190  );
1191 
1192  return (bool) $ilDB->numRows($result);
1193  }
1194 
1204  public function getPartialRecords(
1205  string $ref_id,
1206  string $sort,
1207  string $direction,
1208  ?int $limit,
1209  int $offset,
1210  array $filter = []
1211  ): array {
1212  $sort_field = $this->getFieldByTitle($sort);
1213  $direction = strtolower($direction);
1214  $direction = (in_array($direction, ['desc', 'asc'])) ? $direction : 'asc';
1215 
1216  // Sorting by a status from an ILIAS Ref field. This column is added dynamically to the table, there is no field model
1217  $sort_by_status = false;
1218  if (substr($sort, 0, 8) == '_status_') {
1219  $sort_by_status = true;
1220  $sort_field = $this->getFieldByTitle(substr($sort, 8));
1221  }
1222 
1223  if (is_null($sort_field)) {
1224  $sort_field = $this->getField('id');
1225  }
1226 
1227  $sort_query_object = $sort_field->getRecordQuerySortObject($direction, $sort_by_status);
1228 
1229  $select_str = ($sort_query_object != null) ? $sort_query_object->getSelectStatement() : '';
1230  $join_str = ($sort_query_object != null) ? $sort_query_object->getJoinStatement() : '';
1231  $where_str = ($sort_query_object != null) ? $sort_query_object->getWhereStatement() : '';
1232  $order_str = ($sort_query_object != null) ? $sort_query_object->getOrderStatement() : '';
1233  $group_str = ($sort_query_object != null) ? $sort_query_object->getGroupStatement() : '';
1234 
1235  if (count($filter)) {
1236  foreach ($filter as $key => $filter_value) {
1237  $filter_field_id = substr($key, 7);
1238  $filter_field = $this->getField($filter_field_id);
1239  $filter_record_query_object = $filter_field->getRecordQueryFilterObject($filter_value, $sort_field);
1240 
1241  if ($filter_record_query_object) {
1242  $select_str .= $filter_record_query_object->getSelectStatement();
1243  $join_str .= $filter_record_query_object->getJoinStatement();
1244  $where_str .= $filter_record_query_object->getWhereStatement();
1245  $group_str .= $filter_record_query_object->getGroupStatement();
1246  }
1247  }
1248  }
1249 
1250  // Build the query string
1251  $sql = "SELECT DISTINCT record.id, record.owner";
1252  if ($select_str) {
1253  $sql .= ', ';
1254  }
1255 
1256  $as = ' AS ';
1257 
1258  $sql .= rtrim($select_str, ',') . " FROM il_dcl_record $as record ";
1259  $sql .= $join_str;
1260  $sql .= " WHERE record.table_id = " . $this->db->quote($this->getId(), 'integer');
1261 
1262  if (strlen($where_str) > 0) {
1263  $sql .= $where_str;
1264  }
1265 
1266  if (strlen($group_str) > 0) {
1267  $sql .= " GROUP BY " . $group_str;
1268  }
1269 
1270  if (strlen($order_str) > 0) {
1271  $sql .= " ORDER BY " . $order_str;
1272  }
1273 
1274  $set = $this->db->query($sql);
1275  $total_record_ids = [];
1276 
1277  $is_allowed_to_view = (ilObjDataCollectionAccess::hasWriteAccess((int) $ref_id) || ilObjDataCollectionAccess::hasEditAccess((int) $ref_id));
1278  while ($rec = $this->db->fetchAssoc($set)) {
1279  // Quick check if the current user is allowed to view the record
1280  if (!$is_allowed_to_view && ($this->getViewOwnRecordsPerm() && $this->user->getId() != $rec['owner'])) {
1281  continue;
1282  }
1283  $total_record_ids[] = $rec['id'];
1284  }
1285  // Save record-ids in session to enable prev/next links in detail view
1286  ilSession::set('dcl_table_id', $this->getId());
1287  ilSession::set('dcl_record_ids', $total_record_ids);
1288 
1289  if ($sort_query_object != null) {
1290  $total_record_ids = $sort_query_object->applyCustomSorting($sort_field, $total_record_ids, $direction);
1291  }
1292 
1293  if ($sort === 'n_comments') {
1294  global $DIC;
1295  $comments_nr = [];
1296  foreach ($total_record_ids as $id) {
1297  $comments_nr[$id] = $DIC->notes()->domain()->getNrOfCommentsForContext($DIC->notes()->data()->context($this->getObjId(), $id, 'dcl'));
1298  }
1299  uasort($comments_nr, static fn($a, $b) => ($direction === 'asc' ? 1 : -1) * ($a <=> $b));
1300  $total_record_ids = array_keys($comments_nr);
1301  }
1302 
1303  // Now slice the array to load only the needed records in memory
1304  $record_ids = array_slice($total_record_ids, $offset, $limit);
1305 
1306  $records = [];
1307  foreach ($record_ids as $id) {
1308  $records[] = ilDclCache::getRecordCache($id);
1309  }
1310 
1311  return ['records' => $records, 'total' => count($total_record_ids)];
1312  }
1313 
1314  public function showInvalidFields(bool $value): void
1315  {
1316  $this->show_invalid = $value;
1317  }
1318 }
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
sortTableViews(array $tableviews=null)
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
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)
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:66
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:25
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