ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilDataCollectionTable.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 include_once './Modules/DataCollection/classes/class.ilDataCollectionStandardField.php';
6 include_once './Modules/DataCollection/classes/class.ilDataCollectionRecord.php';
7 
21 
25  protected $id = 0;
29  protected $objId;
33  protected $obj;
37  protected $title;
41  protected $fields;
45  protected $stdFields;
49  protected $records;
53  protected $is_visible;
57  protected $add_perm;
61  protected $edit_perm;
65  protected $delete_perm;
69  protected $edit_by_owner;
73  protected $limited;
77  protected $limit_start;
81  protected $limit_end;
85  protected $export_enabled;
91  protected $default_sort_field = 0;
97  protected $default_sort_field_order = 'asc';
103  protected $description = '';
109  protected $public_comments = 0;
115  protected $view_own_records_perm = 0;
116 
117 
121  public function __construct($a_id = 0) {
122  if ($a_id != 0) {
123  $this->id = $a_id;
124  $this->doRead();
125  }
126  }
127 
128 
132  public function doRead() {
133  global $ilDB;
134 
135  $query = "SELECT * FROM il_dcl_table WHERE id = " . $ilDB->quote($this->getId(), "integer");
136  $set = $ilDB->query($query);
137  $rec = $ilDB->fetchAssoc($set);
138 
139  $this->setObjId($rec["obj_id"]);
140  $this->setTitle($rec["title"]);
141  $this->setAddPerm($rec["add_perm"]);
142  $this->setEditPerm($rec["edit_perm"]);
143  $this->setDeletePerm($rec["delete_perm"]);
144  $this->setEditByOwner($rec["edit_by_owner"]);
145  $this->setExportEnabled($rec["export_enabled"]);
146  $this->setLimited($rec["limited"]);
147  $this->setLimitStart($rec["limit_start"]);
148  $this->setLimitEnd($rec["limit_end"]);
149  $this->setIsVisible($rec["is_visible"]);
150  $this->setDescription($rec['description']);
151  $this->setDefaultSortField($rec['default_sort_field_id']);
152  $this->setDefaultSortFieldOrder($rec['default_sort_field_order']);
153  $this->setPublicCommentsEnabled($rec['public_comments']);
154  $this->setViewOwnRecordsPerm($rec['view_own_records_perm']);
155  }
156 
157 
165  public function doDelete($delete_main_table = false) {
166  global $ilDB;
167 
169  foreach ($this->getRecords() as $record) {
170  $record->doDelete();
171  }
172 
173  foreach ($this->getRecordFields() as $field) {
174  $field->doDelete();
175  }
176 
177  // SW: Fix #12794 und #11405
178  // Problem is that when the DC object gets deleted, $this::getCollectionObject() tries to load the DC but it's not in the DB anymore
179  // If $delete_main_table is true, avoid getting the collection object
180  $exec_delete = false;
181  if ($delete_main_table) {
182  $exec_delete = true;
183  }
184  if (! $exec_delete && $this->getCollectionObject()->getMainTableId() != $this->getId()) {
185  $exec_delete = true;
186  }
187  if ($exec_delete) {
188  $query = "DELETE FROM il_dcl_table WHERE id = " . $ilDB->quote($this->getId(), "integer");
189  $ilDB->manipulate($query);
190 
191  // Delete also view definitions
192  $set = $ilDB->query('SELECT * FROM il_dcl_view WHERE table_id = ' . $ilDB->quote($this->getId(), 'integer'));
193  $view_ids = array();
194  while ($row = $ilDB->fetchObject($set)) {
195  $view_ids[] = $row->id;
196  }
197  if (count($view_ids)) {
198  $ilDB->manipulate("DELETE FROM il_dcl_viewdefinition WHERE view_id IN (" . implode(',', $view_ids) . ")");
199  }
200  $ilDB->manipulate("DELETE FROM il_dcl_view WHERE table_id = " . $ilDB->quote($this->getId(), 'integer'));
201  }
202  }
203 
204 
208  public function doCreate($create_views = true) {
209  global $ilDB;
210 
211  $id = $ilDB->nextId("il_dcl_table");
212  $this->setId($id);
213  $query = "INSERT INTO il_dcl_table (" . "id" . ", obj_id" . ", title" . ", add_perm" . ", edit_perm" . ", delete_perm" . ", edit_by_owner"
214  . ", limited" . ", limit_start" . ", limit_end" . ", is_visible" . ", export_enabled" . ", default_sort_field_id"
215  . ", default_sort_field_order" . ", description" . ", public_comments" . ", view_own_records_perm" . " ) VALUES ("
216  . $ilDB->quote($this->getId(), "integer") . "," . $ilDB->quote($this->getObjId(), "integer") . ","
217  . $ilDB->quote($this->getTitle(), "text") . "," . $ilDB->quote($this->getAddPerm() ? 1 : 0, "integer") . ","
218  . $ilDB->quote($this->getEditPerm() ? 1 : 0, "integer") . "," . $ilDB->quote($this->getDeletePerm() ? 1 : 0, "integer") . ","
219  . $ilDB->quote($this->getEditByOwner() ? 1 : 0, "integer") . "," . $ilDB->quote($this->getLimited() ? 1 : 0, "integer") . ","
220  . $ilDB->quote($this->getLimitStart(), "timestamp") . "," . $ilDB->quote($this->getLimitEnd(), "timestamp") . ","
221  . $ilDB->quote($this->getIsVisible() ? 1 : 0, "integer") . "," . $ilDB->quote($this->getExportEnabled() ? 1 : 0, "integer") . ","
222  . $ilDB->quote($this->getDefaultSortField(), "text") . "," . $ilDB->quote($this->getDefaultSortFieldOrder(), "text") . ","
223  . $ilDB->quote($this->getDescription(), "text") . "," . $ilDB->quote($this->getPublicCommentsEnabled(), "integer") . ","
224  . $ilDB->quote($this->getViewOwnRecordsPerm(), "integer") . ")";
225 
226  $ilDB->manipulate($query);
227 
228  if ($create_views) {
229  //add view definition
230  $view_id = $ilDB->nextId("il_dcl_view");
231  $query = "INSERT INTO il_dcl_view (id, table_id, type, formtype) VALUES (" . $ilDB->quote($view_id, "integer") . ", "
232  . $ilDB->quote($this->id, "integer") . ", " . $ilDB->quote(ilDataCollectionField::VIEW_VIEW, "integer") . ", "
233  . $ilDB->quote(1, "integer") . ")";
234  $ilDB->manipulate($query);
235 
236  //add edit definition
237  $view_id = $ilDB->nextId("il_dcl_view");
238  $query = "INSERT INTO il_dcl_view (id, table_id, type, formtype) VALUES (" . $ilDB->quote($view_id, "integer") . ", "
239  . $ilDB->quote($this->id, "integer") . ", " . $ilDB->quote(ilDataCollectionField::EDIT_VIEW, "integer") . ", "
240  . $ilDB->quote(1, "integer") . ")";
241  $ilDB->manipulate($query);
242 
243  //add filter definition
244  $view_id = $ilDB->nextId("il_dcl_view");
245  $query = "INSERT INTO il_dcl_view (id, table_id, type, formtype) VALUES (" . $ilDB->quote($view_id, "integer") . ", "
246  . $ilDB->quote($this->id, "integer") . ", " . $ilDB->quote(ilDataCollectionField::FILTER_VIEW, "integer") . ", "
247  . $ilDB->quote(1, "integer") . ")";
248  $ilDB->manipulate($query);
249 
250  //add filter definition
251  $view_id = $ilDB->nextId("il_dcl_view");
252  $query = "INSERT INTO il_dcl_view (id, table_id, type, formtype) VALUES (" . $ilDB->quote($view_id, "integer") . ", "
253  . $ilDB->quote($this->id, "integer") . ", " . $ilDB->quote(ilDataCollectionField::EXPORTABLE_VIEW, "integer") . ", "
254  . $ilDB->quote(1, "integer") . ")";
255  $ilDB->manipulate($query);
256 
257  $this->buildOrderFields();
258  }
259  }
260 
261 
262  /*
263  * doUpdate
264  */
265  public function doUpdate() {
266  global $ilDB;
267 
268  $ilDB->update("il_dcl_table", array(
269  "obj_id" => array( "integer", $this->getObjId() ),
270  "title" => array( "text", $this->getTitle() ),
271  "add_perm" => array( "integer", $this->getAddPerm() ),
272  "edit_perm" => array( "integer", $this->getEditPerm() ),
273  "delete_perm" => array( "integer", $this->getDeletePerm() ),
274  "edit_by_owner" => array( "integer", $this->getEditByOwner() ),
275  "limited" => array( "integer", $this->getLimited() ),
276  "limit_start" => array( "timestamp", $this->getLimitStart() ),
277  "limit_end" => array( "timestamp", $this->getLimitEnd() ),
278  "is_visible" => array( "integer", $this->getIsVisible() ? 1 : 0 ),
279  "export_enabled" => array( "integer", $this->getExportEnabled() ? 1 : 0 ),
280  "description" => array( "text", $this->getDescription() ),
281  "default_sort_field_id" => array( "text", $this->getDefaultSortField() ),
282  "default_sort_field_order" => array( "text", $this->getDefaultSortFieldOrder() ),
283  "public_comments" => array( "integer", $this->getPublicCommentsEnabled() ? 1 : 0 ),
284  "view_own_records_perm" => array( "integer", $this->getViewOwnRecordsPerm() ),
285  ), array(
286  "id" => array( "integer", $this->getId() )
287  ));
288  }
289 
290 
296  public function setId($a_id) {
297  $this->id = $a_id;
298  }
299 
300 
306  public function getId() {
307  return $this->id;
308  }
309 
310 
314  public function setObjId($a_id) {
315  $this->objId = $a_id;
316  }
317 
318 
322  public function getObjId() {
323  return $this->objId;
324  }
325 
326 
330  public function setTitle($a_title) {
331  $this->title = $a_title;
332  }
333 
334 
338  public function getTitle() {
339  return $this->title;
340  }
341 
342 
346  public function getCollectionObject() {
347  $this->loadObj();
348 
349  return $this->obj;
350  }
351 
352 
353  protected function loadObj() {
354  if ($this->obj == NULL) {
355  $this->obj = new ilObjDataCollection($this->objId, false);
356  }
357  }
358 
359 
363  public function getRecords() {
364  $this->loadRecords();
365 
366  return $this->records;
367  }
368 
369 
381  public function getRecordsByFilter(array $filter = array()) {
382  $this->loadRecords();
383  // Only pass records trough filter if there is filtering required #performance-improvements
384  if (! count($filter)) {
385  return $this->records;
386  }
387  $filtered = array();
388  foreach ($this->getRecords() as $record) {
389  if ($record->passThroughFilter($filter)) {
390  $filtered[] = $record;
391  }
392  }
393 
394  return $filtered;
395  }
396 
397 
398  protected function loadRecords() {
399  if ($this->records == NULL) {
400  global $ilDB;
401 
402  $records = array();
403  $query = "SELECT id FROM il_dcl_record WHERE table_id = " . $ilDB->quote($this->id, "integer");
404  $set = $ilDB->query($query);
405 
406  while ($rec = $ilDB->fetchAssoc($set)) {
407  $records[$rec['id']] = ilDataCollectionCache::getRecordCache($rec['id']);
408  }
409 
410  $this->records = $records;
411  }
412  }
413 
414  //TODO: replace this method with DataCollection->getTables()
420  public function getAll($a_id) {
421  global $ilDB;
422 
423  // build query
424  $query = "SELECT * FROM il_dcl_table WHERE obj_id = " . $ilDB->quote($a_id, "integer");
425  $set = $ilDB->query($query);
426 
427  $all = array();
428  while ($rec = $ilDB->fetchAssoc($set)) {
429  $all[$rec['id']] = $rec;
430  }
431 
432  return $all;
433  }
434 
435 
439  public function deleteField($field_id) {
440  $field = ilDataCollectionCache::getFieldCache($field_id);
441  $records = $this->getRecords();
442 
443  foreach ($records as $record) {
444  $record->deleteField($field_id);
445  }
446 
447  $field->doDelete();
448  }
449 
450 
456  public function getField($field_id) {
457  $fields = $this->getFields();
458  $field = NULL;
459  foreach ($fields as $field_1) {
460  if ($field_1->getId() == $field_id) {
461  $field = $field_1;
462  }
463  }
464 
465  return $field;
466  }
467 
468 
472  public function getFieldIds() {
473  return array_keys($this->getFields());
474  }
475 
476 
477  protected function loadFields() {
478  if ($this->fields == NULL) {
479  global $ilDB;
480 
481  $query = "SELECT DISTINCT field.* FROM il_dcl_field AS field
482  INNER JOIN il_dcl_view AS view ON view.table_id = field.table_id
483  INNER JOIN il_dcl_viewdefinition AS def ON def.view_id = view.id
484  WHERE field.table_id =" . $ilDB->quote($this->getId(), "integer") . "
485  ORDER BY def.field_order DESC";
486  $fields = array();
487  $set = $ilDB->query($query);
488 
489  while ($rec = $ilDB->fetchAssoc($set)) {
491  $fields[$field->getId()] = $field;
492  }
493  $this->sortByOrder($fields);
494  $this->fields = $fields;
495  }
496  }
497 
498 
504  public function getNewOrder() {
505  $fields = $this->getFields();
506  $place = 0;
507  foreach ($fields as $field) {
508  if (! $field->isStandardField()) {
509  $place = $field->getOrder() + 1;
510  }
511  }
512 
513  return $place;
514  }
515 
516 
522  public function getFields() {
523  $this->loadFields();
524  $this->stdFields = $this->getStandardFields();
525  $fields = array_merge($this->fields, $this->stdFields);
526  $this->sortByOrder($fields);
527 
528  return $fields;
529  }
530 
531 
537  public function getFieldsForFormula() {
538  $unsupported = array(
547  );
548 
549  $this->loadFields();
550  $return = $this->getStandardFields();
554  foreach ($this->fields as $field) {
555  if (! in_array($field->getDatatypeId(), $unsupported)) {
556  $return[] = $field;
557  }
558  }
559 
560  return $return;
561  }
562 
563 
569  public function getStandardFields() {
570  if ($this->stdFields == NULL) {
571  $this->stdFields = ilDataCollectionStandardField::_getStandardFields($this->id);
572  // Don't return comments as field if this feature is not activated in the settings
573  if (! $this->getPublicCommentsEnabled()) {
575  foreach ($this->stdFields as $k => $field) {
576  if ($field->getId() == 'comments') {
577  unset($this->stdFields[$k]);
578  break;
579  }
580  }
581  }
582  }
583 
584  return $this->stdFields;
585  }
586 
587 
593  public function getRecordFields() {
594  $this->loadFields();
595 
596  return $this->fields;
597  }
598 
599 
605  public function getVisibleFields() {
606  $fields = $this->getFields();
607 
608  $visibleFields = array();
609 
610  foreach ($fields as $field) {
611  if ($field->isVisible()) {
612  $visibleFields[] = $field;
613  }
614  }
615 
616  return $visibleFields;
617  }
618 
619 
623  public function getEditableFields() {
624  $fields = $this->getRecordFields();
625  $editableFields = array();
626 
627  foreach ($fields as $field) {
628  if (! $field->getLocked()) {
629  $editableFields[] = $field;
630  }
631  }
632 
633  return $editableFields;
634  }
635 
636 
643  public function getFilterableFields() {
644  $fields = $this->getFields();
645  $filterableFields = array();
646 
647  foreach ($fields as $field) {
648  if ($field->isFilterable()) {
649  $filterableFields[] = $field;
650  }
651  }
652 
653  return $filterableFields;
654  }
655 
656 
662  public function getExportableFields() {
663  $fields = $this->getFields();
664  $exportableFields = array();
665  foreach ($fields as $field) {
666  if ($field->getExportable()) {
667  $exportableFields[] = $field;
668  }
669  }
670 
671  return $exportableFields;
672  }
673 
674 
680  public function hasPermissionToFields($ref_id) {
682  }
683 
684 
690  public function hasPermissionToAddTable($ref_id) {
692  }
693 
694 
703  return true;
704  }
706  return false;
707  }
708 
709  return ($this->getAddPerm() AND $this->checkLimit());
710  }
711 
712 
721  return true;
722  }
724  return false;
725  }
726  if (!$this->checkLimit()) {
727  return false;
728  }
729  if ($this->getEditPerm() && !$this->getEditByOwner()) {
730  return true;
731  }
732  if ($this->getEditByOwner()) {
733  // Edit by owner is set... user is only allowed to edit her own entries
734  return $this->checkEditByOwner($record);
735  }
736 
737  return false;
738  }
739 
740 
749  return true;
750  }
752  return false;
753  }
754  if (!$this->checkLimit()) {
755  return false;
756  }
757  if ($this->getDeletePerm() && !$this->getEditByOwner()) {
758  return true;
759  }
760  if ($this->getEditByOwner()) {
761  // Edit by owner is set... user is only allowed to edit her own entries
762  return $this->checkEditByOwner($record);
763  }
764 
765  return false;
766  }
767 
768 
776  }
777 
778 
785  public function hasPermissionToViewRecord($ref_id, $record) {
786  global $ilUser, $rbacreview;
789  return true;
790  }
792  // Check for view only own entries setting
793  if ($this->getViewOwnRecordsPerm() && $ilUser->getId() != $record->getOwner()) {
794  return false;
795  }
796 
797  return true;
798  }
799 
800  return false;
801  }
802 
803 
809  protected function checkEditByOwner(ilDataCollectionRecord $record) {
810  global $ilUser;
811 
812  return ($ilUser->getId() == $record->getOwner());
813  }
814 
815 
819  protected function checkLimit() {
820  if ($this->getLimited()) {
821  $now = new ilDateTime(date("Y-m-d H:i:s"), IL_CAL_DATE);
822  $from = new ilDateTime($this->getLimitStart(), IL_CAL_DATE);
823  $to = new ilDateTime($this->getLimitEnd(), IL_CAL_DATE);
824  return ($from <= $now && $now <= $to);
825  }
826 
827  return true;
828  }
829 
830 
834  public function updateFields() {
835  foreach ($this->getFields() as $field) {
836  $field->doUpdate();
837  }
838  }
839 
840 
846  public function sortFields(&$fields) {
847  $this->sortByOrder($fields);
848  //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.
849  $named = array();
850  foreach ($fields as $field) {
851  $named[$field->getId()] = $field;
852  }
853 
854  $fields = $named;
855  }
856 
857 
862  protected function sortByOrder(&$array) {
863  usort($array, array( $this, "compareOrder" ));
864  }
865 
866 
871  public function buildOrderFields() {
872  $fields = $this->getFields();
873  $this->sortByOrder($fields);
874  $count = 10;
875  $offset = 10;
876  foreach ($fields as $field) {
877  if (! is_null($field->getOrder())) {
878  $field->setOrder($count);
879  $count = $count + $offset;
880  $field->doUpdate();
881  }
882  }
883  }
884 
885 
893  public function getFieldByTitle($title) {
894  $return = NULL;
895  foreach ($this->getFields() as $field) {
896  if ($field->getTitle() == $title) {
897  $return = $field;
898  break;
899  }
900  }
901 
902  return $return;
903  }
904 
905 
909  public function setAddPerm($add_perm) {
910  $this->add_perm = $add_perm;
911  }
912 
913 
917  public function getAddPerm() {
918  return (bool) $this->add_perm;
919  }
920 
921 
925  public function setDeletePerm($delete_perm) {
926  $this->delete_perm = $delete_perm;
927  }
928 
929 
933  public function getDeletePerm() {
934 
935  return (bool) $this->delete_perm;
936  }
937 
938 
942  public function setEditByOwner($edit_by_owner) {
943  $this->edit_by_owner = $edit_by_owner;
944  }
945 
946 
950  public function getEditByOwner() {
951  return (bool) $this->edit_by_owner;
952  }
953 
954 
958  public function setEditPerm($edit_perm) {
959  $this->edit_perm = $edit_perm;
960  }
961 
962 
966  public function getEditPerm() {
967  return (bool) $this->edit_perm;
968  }
969 
970 
974  public function setLimited($limited) {
975  $this->limited = $limited;
976  }
977 
978 
982  public function getLimited() {
983  return $this->limited;
984  }
985 
986 
990  public function setLimitEnd($limit_end) {
991  $this->limit_end = $limit_end;
992  }
993 
994 
998  public function getLimitEnd() {
999  return $this->limit_end;
1000  }
1001 
1002 
1006  public function setLimitStart($limit_start) {
1007  $this->limit_start = $limit_start;
1008  }
1009 
1010 
1014  public function getLimitStart() {
1015  return $this->limit_start;
1016  }
1017 
1018 
1022  public function setIsVisible($is_visible) {
1023  $this->is_visible = $is_visible;
1024  }
1025 
1026 
1030  public function getIsVisible() {
1031  return $this->is_visible;
1032  }
1033 
1034 
1038  public function setDescription($description) {
1039  $this->description = $description;
1040  }
1041 
1042 
1046  public function getDescription() {
1047  return $this->description;
1048  }
1049 
1050 
1057  $default_sort_field = ($default_sort_field) ? $default_sort_field : 0; // Change null or empty strings to zero
1058  $this->default_sort_field = $default_sort_field;
1059  }
1060 
1061 
1065  public function getDefaultSortField() {
1067  }
1068 
1069 
1074  if (! in_array($default_sort_field_order, array( 'asc', 'desc' ))) {
1075  $default_sort_field_order = 'asc';
1076  }
1077  $this->default_sort_field_order = $default_sort_field_order;
1078  }
1079 
1080 
1084  public function getDefaultSortFieldOrder() {
1086  }
1087 
1088 
1093  $this->public_comments = $public_comments;
1094  }
1095 
1096 
1100  public function getPublicCommentsEnabled() {
1101  return $this->public_comments;
1102  }
1103 
1104 
1108  public function setViewOwnRecordsPerm($view_own_perm) {
1109  $this->view_own_records_perm = (int)$view_own_perm;
1110  }
1111 
1112 
1116  public function getViewOwnRecordsPerm() {
1117  return (bool)$this->view_own_records_perm;
1118  }
1119 
1120 
1126  public function hasCustomFields() {
1127  $this->loadFields();
1128 
1129  return (count($this->fields) > 0) ? true : false;
1130  }
1131 
1132 
1133  function compareOrder($a, $b) {
1134  if (is_null($a->getOrder() == NULL) && is_null($b->getOrder() == NULL)) {
1135  return 0;
1136  }
1137  if (is_null($a->getOrder())) {
1138  return 1;
1139  }
1140  if (is_null($b->getOrder())) {
1141  return - 1;
1142  }
1143 
1144  return $a->getOrder() < $b->getOrder() ? - 1 : 1;
1145  }
1146 
1147 
1151  public function cloneStructure(ilDataCollectionTable $original) {
1152  $this->setTitle($original->getTitle());
1153  $this->setDescription($original->getDescription());
1154  $this->setIsVisible($original->getIsVisible());
1155  $this->setEditByOwner($original->getEditByOwner());
1156  $this->setAddPerm($original->getAddPerm());
1157  $this->setEditPerm($original->getEditPerm());
1158  $this->setDeletePerm($original->getDeletePerm());
1159  $this->setLimited($original->getLimited());
1160  $this->setLimitStart($original->getLimitStart());
1161  $this->setLimitEnd($original->getLimitEnd());
1162  $this->setViewOwnRecordsPerm($original->getViewOwnRecordsPerm());
1163  $this->setExportEnabled($original->getExportEnabled());
1166 
1167  $this->doCreate();
1168  // reset stdFields to get new for the created object
1169 
1170  $default_sort_field = 0;
1171  // Clone standard-fields
1172  $org_std_fields = $original->getStandardFields();
1173  foreach ($this->getStandardFields() as $element_key => $std_field) {
1174  $std_field->cloneStructure($org_std_fields[$element_key]);
1175  if ($std_field->getId() == $original->getDefaultSortField()) {
1176  $default_sort_field = $std_field->getId();
1177  }
1178  }
1179 
1180  // Clone fields
1181  $new_fields = array();
1182  foreach ($original->getFields() as $orig_field) {
1183  if (! $orig_field->isStandardField()) {
1184  $new_field = new ilDataCollectionField();
1185  $new_field->setTableId($this->getId());
1186  $new_field->cloneStructure($orig_field->getId());
1187  $new_fields[$orig_field->getId()] = $new_field;
1188 
1189  if ($orig_field->getId() == $original->getDefaultSortField()) {
1190  $default_sort_field = $new_field->getId();
1191  }
1192  }
1193  }
1194 
1196  $this->doUpdate();
1197 
1198  //TODO: Find better way to copy data (include referenced data)
1199  // Clone Records with recordfields
1200  /*foreach($original->getRecords() as $orig_record){
1201  $new_record = new ilDataCollectionRecord();
1202  $new_record->setTableId($this->getId());
1203  $new_record->cloneStructure($orig_record->getId(), $new_fields);
1204  }*/
1205 
1206  if ($old_view_id = ilDataCollectionRecordViewViewdefinition::getIdByTableId($original->getId())) {
1207  $old_view = new ilDataCollectionRecordViewViewdefinition($old_view_id);
1208  $old_view->setTableId($original->getId());
1210  $viewdef->setTableId($this->id);
1211  $viewdef->setXMLContent($old_view->getXMLContent(false));
1212  $viewdef->create();
1213  }
1214  }
1215 
1216 
1222  public function _hasRecords() {
1223  return (count($this->getRecords()) > 0) ? true : false;
1224  }
1225 
1226 
1230  public function addField($field) {
1231  $this->fields[$field->getId()] = $field;
1232  }
1233 
1234 
1240  public static function _tableExists($table_id) {
1241  global $ilDB;
1242  $query = "SELECT * FROM il_dcl_table WHERE id = " . $table_id;
1243  $result = $ilDB->query($query);
1244 
1245  return $result->numRows() != 0;
1246  }
1247 
1248 
1255  public static function _getTableIdByTitle($title, $obj_id) {
1256  global $ilDB;
1257  $result = $ilDB->query('SELECT id FROM il_dcl_table WHERE title = ' . $ilDB->quote($title, 'text') . ' AND obj_id = '
1258  . $ilDB->quote($obj_id, 'integer'));
1259  $id = 0;
1260  while ($rec = $ilDB->fetchAssoc($result)) {
1261  $id = $rec['id'];
1262  }
1263 
1264  return $id;
1265  }
1266 
1267 
1272  $this->export_enabled = $export_enabled;
1273  }
1274 
1275 
1279  public function getExportEnabled() {
1280  return $this->export_enabled;
1281  }
1282 
1283 
1292  public static function _hasFieldByTitle($title, $obj_id) {
1293  global $ilDB;
1294  $result = $ilDB->query('SELECT * FROM il_dcl_field WHERE table_id = ' . $ilDB->quote($obj_id, 'integer') . ' AND title = '
1295  . $ilDB->quote($title, 'text'));
1296 
1297  return ($ilDB->numRows($result)) ? true : false;
1298  }
1299 
1300 
1312  public function getPartialRecords($sort, $direction, $limit, $offset, array $filter = array()) {
1313  global $ilDB, $ilUser, $rbacreview;
1314 
1315  $sort_field = ($sort) ? $this->getFieldByTitle($sort) : $this->getField('id');
1316  $direction = strtolower($direction);
1317  $direction = (in_array($direction, array( 'desc', 'asc' ))) ? $direction : 'asc';
1318 
1319  // Sorting by a status from an ILIAS Ref field. This column is added dynamically to the table, there is no field model
1320  $sort_by_status = false;
1321  if (substr($sort, 0, 8) == '_status_') {
1322  $sort_by_status = true;
1323  $sort_field = $this->getFieldByTitle(substr($sort, 8));
1324  }
1325 
1326  if (is_null($sort_field)) {
1327  $sort_field = $this->getField('id');
1328  }
1329 
1330  $id = $sort_field->getId();
1331  $stl = $sort_field->getStorageLocation();
1332  $select_str = '';
1333  $join_str = '';
1334  $where_additions = '';
1335  $has_nref = false;
1336 
1337  if ($sort_field->isStandardField()) {
1338  if ($id == 'owner' || $id == 'last_edit_by') {
1339  $join_str .= "LEFT JOIN usr_data AS sort_usr_data_{$id} ON (sort_usr_data_{$id}.usr_id = record.{$id})";
1340  $select_str .= " sort_usr_data_{$id}.login AS field_{$id},";
1341  } elseif ($id != 'comments') {
1342  $select_str .= " record.{$id} AS field_{$id},";
1343  }
1344  } else {
1345  switch ($sort_field->getDatatypeId()) {
1347  $rating_joined = true;
1348  // FSX Bugfix 0015735: The average is multiplied with 10000 and added to the amount of votes
1349  $join_str .= "LEFT JOIN (SELECT (ROUND(AVG(rating), 1) * 10000 + COUNT(rating)) as rating, obj_id FROM il_rating GROUP BY obj_id) AS average ON average.obj_id = record.id";
1350  $select_str .= " average.rating AS field_{$id},";
1351  break;
1353  $join_str .=
1354  "LEFT JOIN il_dcl_record_field AS sort_record_field_{$id} ON (sort_record_field_{$id}.record_id = record.id AND sort_record_field_{$id}.field_id = "
1355  . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
1356  $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS sort_stloc_{$id} ON (sort_stloc_{$id}.record_field_id = sort_record_field_{$id}.id) ";
1357  $join_str .= "LEFT JOIN object_reference AS sort_object_reference_{$id} ON (sort_object_reference_{$id}.ref_id = sort_stloc_{$id}.value AND sort_object_reference_{$id}.deleted IS NULL)";
1358  $join_str .= "LEFT JOIN object_data AS sort_object_data_{$id} ON (sort_object_data_{$id}.obj_id = sort_object_reference_{$id}.obj_id)";
1359  if ($sort_by_status) {
1360  global $ilUser;
1361  $join_str .= "LEFT JOIN ut_lp_marks AS ut ON (ut.obj_id = sort_object_data_{$id}.obj_id AND ut.usr_id = "
1362  . $ilDB->quote($ilUser->getId(), 'integer') . ") ";
1363  }
1364  $select_str .= (! $sort_by_status) ? " sort_object_data_{$id}.title AS field_{$id}," : " ut.status AS field_{$id}";
1365  break;
1368  $join_str .=
1369  "LEFT JOIN il_dcl_record_field AS sort_record_field_{$id} ON (sort_record_field_{$id}.record_id = record.id AND sort_record_field_{$id}.field_id = "
1370  . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
1371  $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS sort_stloc_{$id} ON (sort_stloc_{$id}.record_field_id = sort_record_field_{$id}.id) ";
1372  $join_str .= "LEFT JOIN object_data AS sort_object_data_{$id} ON (sort_object_data_{$id}.obj_id = sort_stloc_{$id}.value) ";
1373  $select_str .= " sort_object_data_{$id}.title AS field_{$id},";
1374  break;
1376  $prop = $sort_field->getPropertyvalues();
1377  $ref_field = ilDataCollectionCache::getFieldCache($sort_field->getFieldRef());
1379  if ($n_ref) {
1380  $has_nref = true;
1381  }
1382  $select_str .= ($n_ref) ? " GROUP_CONCAT(stloc_{$id}_joined.value) AS field_{$id}" : "stloc_{$id}_joined.value AS field_{$id},";
1383  $join_str .=
1384  "LEFT JOIN il_dcl_record_field AS record_field_{$id} ON (record_field_{$id}.record_id = record.id AND record_field_{$id}.field_id = "
1385  . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
1386  $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS stloc_{$id} ON (stloc_{$id}.record_field_id = record_field_{$id}.id) ";
1387  $join_str .=
1388  "LEFT JOIN il_dcl_record_field AS record_field_{$id}_joined ON (record_field_{$id}_joined.record_id = stloc_{$id}.value AND record_field_{$id}_joined.field_id = "
1389  . $ilDB->quote($ref_field->getId(), 'integer') . ") ";
1390  $join_str .= "LEFT JOIN il_dcl_stloc{$ref_field->getStorageLocation()}_value AS stloc_{$id}_joined ON (stloc_{$id}_joined.record_field_id = record_field_{$id}_joined.id) ";
1391  break;
1396  $select_str .= " sort_stloc_{$id}.value AS field_{$id},";
1397  $join_str .=
1398  "LEFT JOIN il_dcl_record_field AS sort_record_field_{$id} ON (sort_record_field_{$id}.record_id = record.id AND sort_record_field_{$id}.field_id = "
1399  . $ilDB->quote($sort_field->getId(), 'integer') . ") ";
1400  $join_str .= "LEFT JOIN il_dcl_stloc{$stl}_value AS sort_stloc_{$id} ON (sort_stloc_{$id}.record_field_id = sort_record_field_{$id}.id) ";
1401  break;
1402  }
1403  }
1404 
1405  if (count($filter)) {
1406  foreach ($filter as $key => $filter_value) {
1407  $filter_field_id = substr($key, 7);
1408  $filter_field = $this->getField($filter_field_id);
1409  switch ($filter_field->getDatatypeId()) {
1411  if(!$rating_joined) {
1412  $join_str .= "LEFT JOIN (SELECT (ROUND(AVG(rating), 1) * 10000 + COUNT(rating)) as rating, obj_id FROM il_rating GROUP BY obj_id) AS average ON average.obj_id = record.id";
1413  }
1414  // FSX Bugfix 0015735: The average is multiplied with 10000 and added to the amount of votes
1415  $where_additions .= " AND average.rating >= " . $ilDB->quote($filter_value * 10000, 'integer');
1416  break;
1418  $join_str .=
1419  "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1420  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1421  $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id) ";
1422  $join_str .= "INNER JOIN object_reference AS filter_object_reference_{$filter_field_id} ON (filter_object_reference_{$filter_field_id}.ref_id = filter_stloc_{$filter_field_id}.value ) ";
1423  $join_str .=
1424  "INNER JOIN object_data AS filter_object_data_{$filter_field_id} ON (filter_object_data_{$filter_field_id}.obj_id = filter_object_reference_{$filter_field_id}.obj_id AND filter_object_data_{$filter_field_id}.title LIKE "
1425  . $ilDB->quote("%$filter_value%", 'text') . ") ";
1426  break;
1429  $join_str .=
1430  "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1431  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1432  $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id) ";
1433  $join_str .=
1434  "INNER JOIN object_data AS filter_object_data_{$filter_field_id} ON (filter_object_data_{$filter_field_id}.obj_id = filter_stloc_{$filter_field_id}.value AND filter_object_data_{$filter_field_id}.title LIKE "
1435  . $ilDB->quote("%$filter_value%", 'text') . ") ";
1436  break;
1438  $date_from = (isset($filter_value['from']) && is_object($filter_value['from'])) ? $filter_value['from'] : NULL;
1439  $date_to = (isset($filter_value['to']) && is_object($filter_value['to'])) ? $filter_value['to'] : NULL;
1440  if ($filter_field->isStandardField()) {
1441  if ($date_from) {
1442  $where_additions .= " AND (record.{$filter_field_id} >= " . $ilDB->quote($date_from, 'date') . ")";
1443  }
1444  if ($date_to) {
1445  $where_additions .= " AND (record.{$filter_field_id} <= " . $ilDB->quote($date_to, 'date') . ")";
1446  }
1447  } else {
1448  $join_str .=
1449  "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1450  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1451  $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id ";
1452  if ($date_from) {
1453  $join_str .= "AND filter_stloc_{$filter_field_id}.value >= " . $ilDB->quote($date_from, 'date') . " ";
1454  }
1455  if ($date_to) {
1456  $join_str .= "AND filter_stloc_{$filter_field_id}.value <= " . $ilDB->quote($date_to, 'date') . " ";
1457  }
1458  $join_str .= ") ";
1459  }
1460  break;
1462  $from = (isset($filter_value['from'])) ? (int)$filter_value['from'] : NULL;
1463  $to = (isset($filter_value['to'])) ? (int)$filter_value['to'] : NULL;
1464  if ($filter_field->isStandardField()) {
1465  if (! is_null($from)) {
1466  $where_additions .= " AND record.{$filter_field_id} >= " . $ilDB->quote($from, 'integer');
1467  }
1468  if (! is_null($to)) {
1469  $where_additions .= " AND record.{$filter_field_id} <= " . $ilDB->quote($to, 'integer');
1470  }
1471  } else {
1472  $join_str .=
1473  "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1474  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1475  $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id";
1476  if (! is_null($from)) {
1477  $join_str .= " AND filter_stloc_{$filter_field_id}.value >= " . $ilDB->quote($from, 'integer');
1478  }
1479  if (! is_null($to)) {
1480  $join_str .= " AND filter_stloc_{$filter_field_id}.value <= " . $ilDB->quote($to, 'integer');
1481  }
1482  $join_str .= ") ";
1483  }
1484  break;
1486  if ($filter_value == "checked") {
1487  $join_str .=
1488  "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1489  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1490  $join_str .= "INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id";
1491  $join_str .= " AND filter_stloc_{$filter_field_id}.value = " . $ilDB->quote(1, 'integer');
1492  } else {
1493  $join_str .=
1494  "INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1495  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1496  $join_str .= "LEFT JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id";
1497  $where_additions .= " AND (filter_stloc_{$filter_field_id}.value <> " . $ilDB->quote(1, 'integer')
1498  . " OR filter_stloc_{$filter_field_id}.value is NULL)";
1499  }
1500  $join_str .= " ) ";
1501  break;
1503  if ($filter_field->isStandardField()) {
1504  $join_str .=
1505  "INNER JOIN usr_data AS filter_usr_data_{$filter_field_id} ON (filter_usr_data_{$filter_field_id}.usr_id = record.{$filter_field_id} AND filter_usr_data_{$filter_field_id}.login LIKE "
1506  . $ilDB->quote("%$filter_value%", 'text') . ") ";
1507  } else {
1508  $join_str .=
1509  " INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1510  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1511  $join_str .=
1512  " INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id AND filter_stloc_{$filter_field_id}.value LIKE "
1513  . $ilDB->quote("%$filter_value%", 'text') . ") ";
1514  }
1515  break;
1517  $join_str .=
1518  " INNER JOIN il_dcl_record_field AS filter_record_field_{$filter_field_id} ON (filter_record_field_{$filter_field_id}.record_id = record.id AND filter_record_field_{$filter_field_id}.field_id = "
1519  . $ilDB->quote($filter_field_id, 'integer') . ") ";
1520  $prop = $filter_field->getPropertyvalues();
1522  if ($n_ref) {
1523  $join_str .=
1524  " INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id AND filter_stloc_{$filter_field_id}.value LIKE "
1525  . $ilDB->quote("%$filter_value%", 'text') . ") ";
1526  } else {
1527  $join_str .=
1528  " INNER JOIN il_dcl_stloc{$filter_field->getStorageLocation()}_value AS filter_stloc_{$filter_field_id} ON (filter_stloc_{$filter_field_id}.record_field_id = filter_record_field_{$filter_field_id}.id AND filter_stloc_{$filter_field_id}.value = "
1529  . $ilDB->quote($filter_value, 'integer') . ") ";
1530  }
1531  break;
1532  }
1533  }
1534  }
1535 
1536  // Build the query string
1537  $sql = "SELECT DISTINCT record.id, record.owner";
1538  if($select_str) {
1539  $sql .= ', ';
1540  }
1541  $sql .= rtrim($select_str, ',') . " FROM il_dcl_record AS record ";
1542  $sql .= $join_str;
1543  $sql .= " WHERE record.table_id = " . $ilDB->quote($this->getId(), 'integer') . $where_additions;
1544  if ($has_nref) {
1545  $sql .= " GROUP BY record.id, record.owner";
1546  }
1547  if($id != 'comments' && $sort_field->getDatatypeId() != ilDataCollectionDatatype::INPUTFORMAT_FORMULA) {
1548  $sql .= " ORDER BY field_{$id} {$direction}";
1549  }
1550  $set = $ilDB->query($sql);
1551  $total_record_ids = array();
1552  // Save record-ids in session to enable prev/next links in detail view
1553  $_SESSION['dcl_record_ids'] = array();
1554  $_SESSION['dcl_table_id'] = $this->getId();
1555  $is_allowed_to_view = ilObjDataCollectionAccess::hasWriteAccess(array_pop(ilObject::_getAllReferences($this->getObjId())));
1556  while ($rec = $ilDB->fetchAssoc($set)) {
1557  // Quick check if the current user is allowed to view the record
1558  if (!$is_allowed_to_view && ($this->getViewOwnRecordsPerm() && $ilUser->getId() != $rec['owner'])) {
1559  continue;
1560  }
1561  $total_record_ids[] = $rec['id'];
1562  $_SESSION['dcl_record_ids'][] = $rec['id'];
1563  }
1564  // Sort by formula
1565  if ($sort_field->getDatatypeId() == ilDataCollectionDatatype::INPUTFORMAT_FORMULA) {
1566  $sort_array = array();
1567  foreach ($total_record_ids as $id) {
1568  $formula_field = ilDataCollectionCache::getRecordFieldCache(new ilDataCollectionRecord($id), $sort_field);
1569  $sort_array[$id] = $formula_field->getValue();
1570  }
1571  switch ($direction) {
1572  case 'asc':
1573  case 'ASC':
1574  asort($sort_array);
1575  break;
1576  case 'desc':
1577  case 'DESC':
1578  arsort($sort_array);
1579  break;
1580  }
1581  $total_record_ids = array_keys($sort_array);
1582  }
1583  // Now slice the array to load only the needed records in memory
1584  $record_ids = array_slice($total_record_ids, $offset, $limit);
1585  $records = array();
1586  foreach ($record_ids as $id) {
1588  }
1589 
1590  return array( 'records' => $records, 'total' => count($total_record_ids) );
1591  }
1592 }