ILIAS  release_8 Revision v8.23
class.ilDclTable.php
Go to the documentation of this file.
1 <?php
2 
20 {
21  protected int $id = 0;
22  protected ?int $objId = null;
23  protected ?ilObjDataCollection $obj = null;
24  protected string $title = "";
28  protected array $fields = [];
32  protected array $stdFields = [];
36  protected array $records = [];
37  protected bool $is_visible = false;
38  protected bool $add_perm = false;
39  protected bool $edit_perm = false;
40  protected bool $delete_perm = false;
41  protected bool $edit_by_owner = false;
42  protected bool $delete_by_owner = false;
43  protected bool $save_confirmation = false;
44  protected bool $limited = false;
45  protected ?string $limit_start = null;
46  protected ?string $limit_end = null;
47  protected bool $export_enabled = false;
48  protected int $table_order = 0;
49  protected bool $import_enabled = false;
54  protected $default_sort_field = 0;
58  protected string $default_sort_field_order = 'asc';
62  protected string $description = '';
66  protected int $public_comments = 0;
70  protected int $view_own_records_perm = 0;
74  protected ?array $all_fields = null;
77  protected ilObjUser $user;
78  protected ilDBInterface $db;
79  protected bool $show_invalid = false;
80 
81  public function __construct(int $a_id = 0)
82  {
83  global $DIC;
84 
85  $this->http = $DIC->http();
86  $this->refinery = $DIC->refinery();
87  $this->db = $DIC->database();
88  $this->user = $DIC->user();
89 
90  if ($a_id != 0) {
91  $this->id = $a_id;
92  $this->doRead();
93  }
94  }
95 
99  public function doRead(): void
100  {
101  $query = "SELECT * FROM il_dcl_table WHERE id = " . $this->db->quote($this->getId(), "integer");
102  $set = $this->db->query($query);
103  $rec = $this->db->fetchAssoc($set);
104 
105  $this->setObjId($rec["obj_id"]);
106  if (null !== $rec["title"]) {
107  $this->setTitle($rec["title"]);
108  }
109  $this->setAddPerm($rec["add_perm"]);
110  $this->setEditPerm($rec["edit_perm"]);
111  $this->setDeletePerm($rec["delete_perm"]);
112  $this->setEditByOwner($rec["edit_by_owner"]);
113  if (null !== $rec["export_enabled"]) {
114  $this->setExportEnabled((bool) $rec["export_enabled"]);
115  }
116  $this->setImportEnabled($rec["import_enabled"]);
117  $this->setLimited($rec["limited"]);
118  $this->setLimitStart($rec["limit_start"]);
119  $this->setLimitEnd($rec["limit_end"]);
120  $this->setIsVisible($rec["is_visible"]);
121  if (null !== $rec['description']) {
122  $this->setDescription($rec['description']);
123  }
124  $this->setDefaultSortField($rec['default_sort_field_id']);
125  $this->setDefaultSortFieldOrder($rec['default_sort_field_order']);
126  $this->setPublicCommentsEnabled($rec['public_comments']);
127  $this->setViewOwnRecordsPerm($rec['view_own_records_perm']);
128  $this->setDeleteByOwner($rec['delete_by_owner']);
129  $this->setSaveConfirmation($rec['save_confirmation']);
130  if (null !== $rec['table_order']) {
131  $this->setOrder($rec['table_order']);
132  }
133  }
134 
140  public function doDelete(bool $delete_only_content = false, bool $omit_notification = false): void
141  {
142  foreach ($this->getRecords() as $record) {
143  $record->doDelete($omit_notification);
144  }
145 
146  foreach ($this->getRecordFields() as $field) {
147  $field->doDelete();
148  }
149 
150  // // SW: Fix #12794 und #11405
151  // // Problem is that when the DC object gets deleted, $this::getCollectionObject() tries to load the DC but it's not in the DB anymore
152  // // If $delete_main_table is true, avoid getting the collection object
153  // $exec_delete = false;
154  // if ($delete_main_table) {
155  // $exec_delete = true;
156  // }
157  // if (!$exec_delete && $this->getCollectionObject()->getFirstVisibleTableId() != $this->getId()) {
158  // $exec_delete = true;
159  // }
160  if (!$delete_only_content) {
161  $query = "DELETE FROM il_dcl_table WHERE id = " . $this->db->quote($this->getId(), "integer");
162  $this->db->manipulate($query);
163  }
164  }
165 
166  public function doCreate(bool $create_tablefield_setting = true, bool $create_standardview = true): void
167  {
168  $id = $this->db->nextId("il_dcl_table");
169  $this->setId($id);
170  $query = "INSERT INTO il_dcl_table (" . "id" . ", obj_id" . ", title" . ", add_perm" . ", edit_perm" . ", delete_perm" . ", edit_by_owner"
171  . ", limited" . ", limit_start" . ", limit_end" . ", is_visible" . ", export_enabled" . ", import_enabled" . ", default_sort_field_id"
172  . ", default_sort_field_order" . ", description" . ", public_comments" . ", view_own_records_perm"
173  . ", delete_by_owner, save_confirmation , table_order ) VALUES (" . $this->db->quote(
174  $this->getId(),
175  "integer"
176  ) . ","
177  . $this->db->quote($this->getObjId(), "integer") . "," . $this->db->quote($this->getTitle(), "text") . ","
178  . $this->db->quote($this->getAddPerm() ? 1 : 0, "integer") . "," . $this->db->quote(
179  $this->getEditPerm() ? 1 : 0,
180  "integer"
181  ) . ","
182  . $this->db->quote(
183  $this->getDeletePerm() ? 1 : 0,
184  "integer"
185  ) . "," . $this->db->quote($this->getEditByOwner() ? 1 : 0, "integer") . ","
186  . $this->db->quote($this->getLimited() ? 1 : 0, "integer") . "," . $this->db->quote(
187  $this->getLimitStart(),
188  "timestamp"
189  ) . ","
190  . $this->db->quote($this->getLimitEnd(), "timestamp") . "," . $this->db->quote(
191  $this->getIsVisible() ? 1 : 0,
192  "integer"
193  ) . ","
194  . $this->db->quote(
195  $this->getExportEnabled() ? 1 : 0,
196  "integer"
197  ) . "," . $this->db->quote($this->getImportEnabled() ? 1 : 0, "integer") . ","
198  . $this->db->quote($this->getDefaultSortField(), "text") . "," . $this->db->quote(
199  $this->getDefaultSortFieldOrder(),
200  "text"
201  ) . ","
202  . $this->db->quote($this->getDescription(), "text") . "," . $this->db->quote(
203  $this->getPublicCommentsEnabled(),
204  "integer"
205  ) . ","
206  . $this->db->quote(
207  $this->getViewOwnRecordsPerm(),
208  "integer"
209  ) . "," . $this->db->quote($this->getDeleteByOwner() ? 1 : 0, 'integer') . ","
210  . $this->db->quote($this->getSaveConfirmation() ? 1 : 0, 'integer') . "," . $this->db->quote(
211  $this->getOrder(),
212  'integer'
213  ) . ")";
214 
215  $this->db->manipulate($query);
216 
217  if ($create_standardview) {
218  //standard tableview
220  }
221 
222  if ($create_tablefield_setting) {
223  $this->buildOrderFields();
224  }
225  }
226 
227  public function doUpdate(): void
228  {
229  $this->db->update(
230  "il_dcl_table",
231  [
232  "obj_id" => ["integer", $this->getObjId()],
233  "title" => ["text", $this->getTitle()],
234  "add_perm" => ["integer", (int) $this->getAddPerm()],
235  "edit_perm" => ["integer", (int) $this->getEditPerm()],
236  "delete_perm" => ["integer", (int) $this->getDeletePerm()],
237  "edit_by_owner" => ["integer", (int) $this->getEditByOwner()],
238  "limited" => ["integer", $this->getLimited()],
239  "limit_start" => ["timestamp", $this->getLimitStart()],
240  "limit_end" => ["timestamp", $this->getLimitEnd()],
241  "is_visible" => ["integer", $this->getIsVisible() ? 1 : 0],
242  "export_enabled" => ["integer", $this->getExportEnabled() ? 1 : 0],
243  "import_enabled" => ["integer", $this->getImportEnabled() ? 1 : 0],
244  "description" => ["text", $this->getDescription()],
245  "default_sort_field_id" => ["text", $this->getDefaultSortField()],
246  "default_sort_field_order" => ["text", $this->getDefaultSortFieldOrder()],
247  "public_comments" => ["integer", $this->getPublicCommentsEnabled() ? 1 : 0],
248  "view_own_records_perm" => ["integer", $this->getViewOwnRecordsPerm()],
249  'delete_by_owner' => ['integer', $this->getDeleteByOwner() ? 1 : 0],
250  'save_confirmation' => ['integer', $this->getSaveConfirmation() ? 1 : 0],
251  'table_order' => ['integer', $this->getOrder()],
252  ],
253  [
254  "id" => ["integer", $this->getId()],
255  ]
256  );
257  }
258 
262  public function setId(int $a_id): void
263  {
264  $this->id = $a_id;
265  }
266 
270  public function getId(): int
271  {
272  return $this->id;
273  }
274 
275  public function setObjId(int $a_id): void
276  {
277  $this->objId = $a_id;
278  }
279 
280  public function getObjId(): ?int
281  {
282  return $this->objId;
283  }
284 
285  public function setTitle(string $a_title): void
286  {
287  $this->title = $a_title;
288  }
289 
290  public function getTitle(): string
291  {
292  return $this->title;
293  }
294 
296  {
297  $this->loadObj();
298 
299  return $this->obj;
300  }
301 
302  protected function loadObj(): void
303  {
304  if ($this->obj == null) {
305  $this->obj = new ilObjDataCollection($this->objId, false);
306  }
307  }
308 
312  public function getRecords(): array
313  {
314  if ($this->records == null) {
315  $this->loadRecords();
316  }
317 
318  return $this->records;
319  }
320 
321  public function loadRecords(): void
322  {
323  $records = [];
324  $query = "SELECT id FROM il_dcl_record WHERE table_id = " . $this->db->quote($this->id, "integer");
325  $set = $this->db->query($query);
326 
327  while ($rec = $this->db->fetchAssoc($set)) {
328  $records[$rec['id']] = ilDclCache::getRecordCache($rec['id']);
329  }
330 
331  $this->records = $records;
332  }
333 
334  public function deleteField(int $field_id): void
335  {
336  $field = ilDclCache::getFieldCache($field_id);
337  $records = $this->getRecords();
338 
339  foreach ($records as $record) {
340  $record->deleteField($field_id);
341  }
342 
343  $field->doDelete();
344  }
345 
346  public function getField(string $field_id): ?ilDclBaseFieldModel
347  {
348  $fields = $this->getFields();
349  $field = null;
350  foreach ($fields as $field_1) {
351  if ($field_1->getId() == $field_id) {
352  $field = $field_1;
353  }
354  }
355 
356  return $field;
357  }
358 
362  public function getFieldIds(): array
363  {
364  $field_ids = [];
365  foreach ($this->getFields() as $field) {
366  if ($field->getId()) {
367  $field_ids[] = $field->getId();
368  }
369  }
370 
371  return $field_ids;
372  }
373 
374  protected function loadCustomFields(): void
375  {
376  if (!$this->fields) {
377  $query
378  = "SELECT DISTINCT il_dcl_field.*, il_dcl_tfield_set.field_order
379  FROM il_dcl_field
380  INNER JOIN il_dcl_tfield_set
381  ON ( il_dcl_tfield_set.field NOT IN ('owner',
382  'last_update',
383  'last_edit_by',
384  'id',
385  'create_date')
386  AND il_dcl_tfield_set.table_id = il_dcl_field.table_id
387  AND il_dcl_tfield_set.field = " . $this->db->cast("il_dcl_field.id", "text") . ")
388  WHERE il_dcl_field.table_id = %s
389  ORDER BY il_dcl_tfield_set.field_order ASC";
390 
391  $set = $this->db->queryF($query, ['integer'], [$this->getId()]);
392  $fields = [];
393  while ($rec = $this->db->fetchAssoc($set)) {
394  $field = ilDclCache::buildFieldFromRecord($rec);
395  if ($this->show_invalid || in_array($field->getDatatypeId(), array_keys(ilDclDatatype::getAllDatatype()))) {
396  $fields[] = $field;
397  }
398  }
399  $this->fields = $fields;
400 
402  }
403  }
404 
408  public function getCustomFields(): array
409  {
410  if (!$this->fields) {
411  $this->loadCustomFields();
412  }
413 
414  return $this->fields;
415  }
416 
421  public function getNewFieldOrder(): int
422  {
423  $fields = $this->getFields();
424  $place = 0;
425  foreach ($fields as $field) {
426  if (!$field->isStandardField()) {
427  $place = $field->getOrder() + 1;
428  }
429  }
430 
431  return $place;
432  }
433 
437  public function getNewTableviewOrder(): int
438  {
439  return (ilDclTableView::getCountForTableId($this->getId()) + 1) * 10;
440  }
441 
445  public function sortTableViews(array $tableviews = null): void
446  {
447  if ($tableviews == null) {
448  $tableviews = $this->getTableViews();
449  }
450 
451  $order = 10;
452  foreach ($tableviews as $tableview) {
453  $tableview->setTableviewOrder($order);
454  $tableview->update();
455  $order += 10;
456  }
457  }
458 
464  public function getFields(): array
465  {
466  if ($this->all_fields == null) {
467  $this->reloadFields();
468  }
469 
470  return $this->all_fields;
471  }
472 
473  public function reloadFields(): void
474  {
475  $this->loadCustomFields();
476  $this->stdFields = $this->getStandardFields();
477  $fields = array_merge($this->fields, $this->stdFields);
478 
479  $this->sortByOrder($fields);
480 
481  $this->all_fields = $fields;
482  }
483 
487  public function getTableViews(): array
488  {
489  return ilDclTableView::getAllForTableId($this->getId());
490  }
491 
496  public function getVisibleTableViews(int $ref_id, bool $with_active_detailedview = false, int $user_id = 0): array
497  {
498  if (ilObjDataCollectionAccess::hasWriteAccess($ref_id, $user_id) && !$with_active_detailedview) {
499  return $this->getTableViews();
500  }
501 
502  $visible_views = [];
503  foreach ($this->getTableViews() as $tableView) {
504  if (ilObjDataCollectionAccess::hasAccessToTableView($tableView, $user_id)) {
505  if (!$with_active_detailedview || ilDclDetailedViewDefinition::isActive($tableView->getId())) {
506  $visible_views[] = $tableView;
507  }
508  }
509  }
510 
511  return $visible_views;
512  }
513 
517  public function getFirstTableViewId(int $ref_id, int $user_id = 0, bool $with_detailed_view = false): ?int
518  {
519  $uid = $user_id;
520  $array = $this->getVisibleTableViews($ref_id, $with_detailed_view, $uid);
521  $tableview = array_shift($array);
522 
523  return $tableview ? $tableview->getId() : false;
524  }
525 
530  public function getFieldsForFormula(): array
531  {
532  $syntax_chars = array_merge(
535  ['(', ')', ',']
536  );
537  foreach ($this->getFields() as $field) {
538  if (in_array($field->getDatatypeId(), ilDclFormulaFieldModel::SUPPORTED_FIELDS)) {
539  foreach ($syntax_chars as $element) {
540  if (str_contains($field->getTitle(), $element)) {
541  continue 2;
542  }
543  }
544  $return[] = $field;
545  }
546  }
547 
548  return $return;
549  }
550 
556  public function getStandardFields(): array
557  {
558  if ($this->stdFields == null) {
559  $this->stdFields = ilDclStandardField::_getStandardFields($this->id);
560  // Don't return comments as field if this feature is not activated in the settings
561  if (!$this->getPublicCommentsEnabled()) {
563  foreach ($this->stdFields as $k => $field) {
564  if ($field->getId() == 'comments') {
565  unset($this->stdFields[$k]);
566  break;
567  }
568  }
569  }
570  }
571 
572  return $this->stdFields;
573  }
574 
579  public function getRecordFields(): array
580  {
581  $this->loadCustomFields();
582 
583  return $this->fields;
584  }
585 
590  public function getEditableFields(bool $creation_mode): array
591  {
592  $fields = $this->getRecordFields();
593  $editableFields = [];
594 
595  foreach ($fields as $field) {
596  $tableview_id = $this->http->wrapper()->post()->retrieve(
597  'tableview_id',
598  $this->refinery->kindlyTo()->int()
599  );
600  if (!$field->getViewSetting($tableview_id)->isLocked($creation_mode)) {
601  $editableFields[] = $field;
602  }
603  }
604 
605  return $editableFields;
606  }
607 
612  public function getExportableFields(): array
613  {
614  $fields = $this->getFields();
615  $exportableFields = [];
616  foreach ($fields as $field) {
617  if ($field->getExportable()) {
618  $exportableFields[] = $field;
619  }
620  }
621 
622  return $exportableFields;
623  }
624 
630  public function hasPermissionToEditRecord(int $ref_id, ilDclBaseRecordModel $record): bool
631  {
632  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
633  return false;
634  }
636  return true;
637  }
639  return false;
640  }
641  if (!$this->checkLimit()) {
642  return false;
643  }
644  if ($this->getEditPerm() && !$this->getEditByOwner()) {
645  return true;
646  }
647  if ($this->getEditByOwner()) {
648  return $this->doesRecordBelongToUser($record);
649  }
650 
651  return false;
652  }
653 
658  public function hasPermissionToDeleteRecord(int $ref_id, ilDclBaseRecordModel $record): bool
659  {
660  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
661  return false;
662  }
664  return true;
665  }
667  return false;
668  }
669  if (!$this->checkLimit()) {
670  return false;
671  }
672  if ($this->getDeletePerm() && !$this->getDeleteByOwner()) {
673  return true;
674  }
675  if ($this->getDeleteByOwner()) {
676  return $this->doesRecordBelongToUser($record);
677  }
678 
679  return false;
680  }
681 
686  public function hasPermissionToDeleteRecords(int $ref_id): bool
687  {
688  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
689  return false;
690  }
691 
692  return ((ilObjDataCollectionAccess::hasAddRecordAccess($ref_id) && $this->getDeletePerm())
694  }
695 
696  public function hasPermissionToViewRecord(int $ref_id, ilDclBaseRecordModel $record, int $user_id = 0): bool
697  {
698  if ($this->getObjId() != ilObjDataCollection::_lookupObjectId($ref_id)) {
699  return false;
700  }
702  $ref_id,
703  $user_id
704  ) || ilObjDataCollectionAccess::hasEditAccess($ref_id, $user_id)) {
705  return true;
706  }
708  // Check for view only own entries setting
709  if ($this->getViewOwnRecordsPerm() && ($user_id ?: $this->user->getId()) != $record->getOwner()) {
710  return false;
711  }
712 
713  return true;
714  }
715 
716  return false;
717  }
718 
719  protected function doesRecordBelongToUser(ilDclBaseRecordModel $record): bool
720  {
721  return ($this->user->getId() == $record->getOwner());
722  }
723 
724  public function checkLimit(): bool
725  {
726  if ($this->getLimited()) {
727  $now = new ilDateTime(date("Y-m-d H:i:s"), IL_CAL_DATE);
728  $from = new ilDateTime($this->getLimitStart(), IL_CAL_DATE);
729  $to = new ilDateTime($this->getLimitEnd(), IL_CAL_DATE);
730 
731  return ($from <= $now && $now <= $to);
732  }
733 
734  return true;
735  }
736 
740  public function updateFields(): void
741  {
742  foreach ($this->getFields() as $field) {
743  $field->doUpdate();
744  }
745  }
746 
751  public function sortFields(array &$fields): void
752  {
753  $this->sortByOrder($fields);
754  //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.
755  $named = [];
756  foreach ($fields as $field) {
757  $named[$field->getId()] = $field;
758  }
759 
760  $fields = $named;
761  }
762 
766  protected function sortByOrder(array &$array): void
767  {
768  // php-bug: https://bugs.php.net/bug.php?id=50688
769  // fixed in php 7 but for now we need the @ a workaround
770  usort($array, [$this, "compareOrder"]);
771  }
772 
777  public function buildOrderFields(): void
778  {
779  $fields = $this->getFields();
780  $this->sortByOrder($fields);
781  $count = 10;
782  $offset = 10;
783  foreach ($fields as $field) {
784  if (!is_null($field->getOrder())) {
785  $field->setOrder($count);
786  $count = $count + $offset;
787  $field->doUpdate();
788  }
789  }
790  }
791 
795  public function getFieldByTitle(string $title): ?ilDclBaseFieldModel
796  {
797  $return = null;
798  foreach ($this->getFields() as $field) {
799  if ($field->getTitle() == $title) {
800  $return = $field;
801  break;
802  }
803  }
804 
805  return $return;
806  }
807 
808  public function setAddPerm(bool $add_perm): void
809  {
810  $this->add_perm = $add_perm;
811  }
812 
813  public function getAddPerm(): bool
814  {
815  return $this->add_perm;
816  }
817 
818  public function setDeletePerm(bool $delete_perm): void
819  {
820  $this->delete_perm = $delete_perm;
821  if (!$delete_perm) {
822  $this->setDeleteByOwner(false);
823  }
824  }
825 
826  public function getDeletePerm(): bool
827  {
828  return $this->delete_perm;
829  }
830 
831  public function setEditByOwner(bool $edit_by_owner): void
832  {
833  $this->edit_by_owner = $edit_by_owner;
834  if ($edit_by_owner) {
835  $this->setEditPerm(true);
836  }
837  }
838 
839  public function getEditByOwner(): bool
840  {
841  return $this->edit_by_owner;
842  }
843 
844  public function getDeleteByOwner(): bool
845  {
846  return $this->delete_by_owner;
847  }
848 
849  public function setDeleteByOwner(bool $delete_by_owner): void
850  {
851  $this->delete_by_owner = $delete_by_owner;
852  if ($delete_by_owner) {
853  $this->setDeletePerm(true);
854  }
855  }
856 
857  public function setEditPerm(bool $edit_perm): void
858  {
859  $this->edit_perm = $edit_perm;
860  if (!$edit_perm) {
861  $this->setEditByOwner(false);
862  }
863  }
864 
865  public function getEditPerm(): bool
866  {
867  return $this->edit_perm;
868  }
869 
870  public function setLimited(bool $limited): void
871  {
872  $this->limited = $limited;
873  }
874 
875  public function getLimited(): bool
876  {
877  return $this->limited;
878  }
879 
880  public function setLimitEnd(?string $limit_end): void
881  {
882  $this->limit_end = $limit_end;
883  }
884 
885  public function getLimitEnd(): ?string
886  {
887  return $this->limit_end;
888  }
889 
890  public function setLimitStart(?string $limit_start): void
891  {
892  $this->limit_start = $limit_start;
893  }
894 
895  public function getLimitStart(): ?string
896  {
897  return $this->limit_start;
898  }
899 
900  public function setIsVisible(bool $is_visible): void
901  {
902  $this->is_visible = $is_visible;
903  }
904 
905  public function getIsVisible(): bool
906  {
907  return $this->is_visible;
908  }
909 
910  public function setDescription(string $description): void
911  {
912  $this->description = $description;
913  }
914 
915  public function getDescription(): string
916  {
917  return $this->description;
918  }
919 
920  public function setDefaultSortField(string $default_sort_field): void
921  {
922  $default_sort_field = ($default_sort_field) ?: 0; // Change null or empty strings to zero
923  $this->default_sort_field = $default_sort_field;
924  }
925 
926  public function getDefaultSortField(): string
927  {
929  }
930 
931  public function setDefaultSortFieldOrder(string $default_sort_field_order): void
932  {
933  if (!in_array($default_sort_field_order, ['asc', 'desc'])) {
934  $default_sort_field_order = 'asc';
935  }
936  $this->default_sort_field_order = $default_sort_field_order;
937  }
938 
939  public function getDefaultSortFieldOrder(): string
940  {
942  }
943 
944  public function setPublicCommentsEnabled(bool $public_comments): void
945  {
946  $this->public_comments = $public_comments;
947  }
948 
949  public function getPublicCommentsEnabled(): bool
950  {
951  return $this->public_comments;
952  }
953 
954  public function setViewOwnRecordsPerm(bool $view_own_perm): void
955  {
956  $this->view_own_records_perm = (int) $view_own_perm;
957  }
958 
959  public function getViewOwnRecordsPerm(): bool
960  {
961  return (bool) $this->view_own_records_perm;
962  }
963 
964  public function getSaveConfirmation(): bool
965  {
967  }
968 
969  public function setSaveConfirmation(bool $save_confirmation): void
970  {
971  $this->save_confirmation = $save_confirmation;
972  }
973 
978  public function hasCustomFields(): bool
979  {
980  $this->loadCustomFields();
981 
982  return count($this->fields) > 0;
983  }
984 
986  {
987  if (is_null($a->getOrder() == null) && is_null($b->getOrder() == null)) {
988  return 0;
989  }
990  if (is_null($a->getOrder())) {
991  return 1;
992  }
993  if (is_null($b->getOrder())) {
994  return -1;
995  }
996 
997  return $a->getOrder() < $b->getOrder() ? -1 : 1;
998  }
999 
1000  public function cloneStructure(ilDclTable $original): void
1001  {
1002  $this->setTitle($original->getTitle());
1003  $this->setDescription($original->getDescription());
1004  $this->setIsVisible($original->getIsVisible());
1005  $this->setEditByOwner($original->getEditByOwner());
1006  $this->setAddPerm($original->getAddPerm());
1007  $this->setEditPerm($original->getEditPerm());
1008  $this->setDeleteByOwner($original->getDeleteByOwner());
1009  $this->setSaveConfirmation($original->getSaveConfirmation());
1010  $this->setDeletePerm($original->getDeletePerm());
1011  $this->setLimited($original->getLimited());
1012  $this->setLimitStart($original->getLimitStart());
1013  $this->setLimitEnd($original->getLimitEnd());
1014  $this->setViewOwnRecordsPerm($original->getViewOwnRecordsPerm());
1015  $this->setExportEnabled($original->getExportEnabled());
1016  $this->setImportEnabled($original->getImportEnabled());
1019  $this->setOrder($original->getOrder());
1020 
1021  $this->doCreate(true, false);
1022  // reset stdFields to get new for the created object
1023 
1024  $default_sort_field = 0;
1025  // Clone standard-fields
1026  $org_std_fields = $original->getStandardFields();
1027  foreach ($this->getStandardFields() as $element_key => $std_field) {
1028  $std_field->clone($org_std_fields[$element_key]);
1029  if ($std_field->getId() === $original->getDefaultSortField()) {
1030  $default_sort_field = $std_field->getId();
1031  }
1032  }
1033 
1034  // Clone fields
1035  $new_fields = [];
1036  foreach ($original->getFields() as $orig_field) {
1037  if (!$orig_field->isStandardField()) {
1038  $class_name = get_class($orig_field);
1039  $new_field = new $class_name();
1040  if ($new_field instanceof ilDclReferenceFieldModel && $new_field->getFieldRef()->getTableId() === 0) {
1041  continue;
1042  }
1043  $new_field->setTableId($this->getId());
1044  $new_field->cloneStructure($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 
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($ref_id) || ilObjDataCollectionAccess::hasEditAccess($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...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
doRead()
Read table.
setLimitStart(?string $limit_start)
static createOrGetStandardView(int $table_id, bool $create_default_settings=true)
sortByOrder(array &$array)
getFirstTableViewId(int $ref_id, int $user_id=0, bool $with_detailed_view=false)
get id of first (for current user) available view
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)
$errors fields
Definition: imgupload.php:67
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)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
getFields()
Returns all fields of this table including the standard fields.
getVisibleTableViews(int $ref_id, bool $with_active_detailedview=false, int $user_id=0)
For current user.
static _getTableIdByTitle(string $title, int $obj_id)
getId()
Get table id.
showInvalidFields(bool $value)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
__construct(int $a_id=0)
string $limit_start
setDefaultSortFieldOrder(string $default_sort_field_order)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
doesRecordBelongToUser(ilDclBaseRecordModel $record)
global $DIC
Definition: feed.php:28
updateFields()
Update fields.
setOrder(int $table_order)
setTitle(string $a_title)
getExportableFields()
Return all the fields that are marked as exportable.
$ref_id
Definition: ltiauth.php:67
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)
hasCustomFields()
hasCustomFields
static getAllDatatype(bool $force=false)
Get all possible Datatypes.
$default_sort_field
ID of the default sorting field.
ILIAS Refinery Factory $refinery
ilDBInterface $db
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
string $default_sort_field_order
Default sort-order (asc|desc)
getRecordFields()
Returns all fields of this table which are NOT standard fields.
string $key
Consumer key/client ID value.
Definition: System.php:193
static _lookupObjectId(int $ref_id)
static getCountForTableId(int $table_id)
$query
_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.
setLimitEnd(?string $limit_end)
getField(string $field_id)
static _hasFieldByTitle(string $title, int $obj_id)
Checks if a table has a field with the given title.
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 hasAccessToTableView($tableview, ?int $user_id=0)
This only checks access to the tableview - if the full access check is required, use hasAccessTo($ref...
static hasReadAccess(int $ref, ?int $user_id=0)
bool $save_confirmation
setDeletePerm(bool $delete_perm)
int $public_comments
True if users can add comments on each record of this table.
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)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
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