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