ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilDataCollectionField.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once('./Services/Exceptions/classes/class.ilException.php');
5 require_once('class.ilDataCollectionCache.php');
6 require_once('class.ilDataCollectionFieldProp.php');
7 
20 
24  protected $id;
28  protected $table_id;
32  protected $title;
36  protected $description;
40  protected $datatypeId;
44  protected $required;
48  protected $order;
52  protected $unique;
56  protected $visible;
60  protected $editable;
64  protected $filterable;
68  protected $locked;
72  protected $property = array();
76  protected $exportable;
80  protected $datatype;
81  const PROPERTYID_LENGTH = 1;
82  const PROPERTYID_REGEX = 2;
87  const PROPERTYID_URL = 4;
90  const PROPERTYID_WIDTH = 7;
91  const PROPERTYID_HEIGHT = 8;
100  // type of table il_dcl_view
101  const VIEW_VIEW = 1;
102  const EDIT_VIEW = 2;
103  const FILTER_VIEW = 3;
104  const EXPORTABLE_VIEW = 4;
105 
106 
110  public function __construct($a_id = 0) {
111  if ($a_id != 0) {
112  $this->id = $a_id;
113  $this->doRead();
114  }
115  }
116 
117 
125  public static function _getTitleValidChars($a_as_regex = true) {
126  if ($a_as_regex) {
127  return '/^[a-zA-Z\d \/\-.,äöüÄÖÜàéèÀÉÈç¢]*$/i';
128  } else {
129  return 'A-Z a-z 0-9 /-.,';
130  }
131  }
132 
133 
140  public static function _getFieldIdByTitle($title, $table_id) {
141  global $ilDB;
142  $result = $ilDB->query('SELECT id FROM il_dcl_field WHERE title = ' . $ilDB->quote($title, 'text') . ' AND table_id = '
143  . $ilDB->quote($table_id, 'integer'));
144  $id = 0;
145  while ($rec = $ilDB->fetchAssoc($result)) {
146  $id = $rec['id'];
147  }
148 
149  return $id;
150  }
151 
152 
158  public function setId($a_id) {
159  $this->id = $a_id;
160  }
161 
162 
168  public function getId() {
169  return $this->id;
170  }
171 
172 
178  public function setTableId($a_id) {
179  $this->table_id = $a_id;
180  }
181 
182 
188  public function getTableId() {
189  return $this->table_id;
190  }
191 
192 
198  public function setTitle($a_title) {
199  //title cannot begin with _ as this is saved for other purposes. make __ instead.
200  if (substr($a_title, 0, 1) == "_" && substr($a_title, 0, 2) != "__") {
201  $a_title = "_" . $a_title;
202  }
203  $this->title = $a_title;
204  }
205 
206 
212  public function getTitle() {
213  return $this->title;
214  }
215 
216 
222  public function setDescription($a_desc) {
223  $this->description = $a_desc;
224  }
225 
226 
232  public function getDescription() {
233  return $this->description;
234  }
235 
236 
242  public function setDatatypeId($a_id) {
243  //unset the cached datatype.
244  $this->datatype = NULL;
245  $this->datatypeId = $a_id;
246  }
247 
248 
254  public function getDatatypeId() {
255  if ($this->isStandardField()) {
257  }
258 
259  return $this->datatypeId;
260  }
261 
262 
268  public function setRequired($a_required) {
269  $this->required = $a_required;
270  }
271 
272 
278  public function getRequired() {
279  return $this->required;
280  }
281 
282 
289  public function setPropertyvalue($a_value, $a_id) {
290  $this->property[$a_id] = $a_value;
291  }
292 
293 
294  /*
295  * isUnique
296  */
297  public function isUnique() {
298  return $this->unique;
299  }
300 
301 
302  /*
303  * setUnique
304  */
305  public function setUnique($unique) {
306  $this->unique = $unique ? 1 : 0;
307  }
308 
309 
317  public function getPropertyvalues() {
318  if ($this->property == NULL) {
319  $this->loadProperties();
320  }
321 
322  return $this->property;
323  }
324 
325 
331  public function setVisible($visible) {
332  if ($visible == true && $this->order === NULL) {
333  $this->setOrder(0);
334  }
335 
336  $this->visible = $visible;
337  }
338 
339 
345  public function setFilterable($filterable) {
346  if ($filterable == true && $this->order === NULL) {
347  $this->setOrder(0);
348  }
349 
350  $this->filterable = $filterable;
351  }
352 
353 
354  /*
355  * getDatatype
356  */
357  public function getDatatype() {
358  $this->loadDatatype();
359 
360  return $this->datatype;
361  }
362 
363 
364  /*
365  * getLength
366  */
367  public function getLength() {
368  $props = $this->getPropertyvalues();
370 
371  return $props[$l];
372  }
373 
374 
378  public function getTextArea() {
379  $props = $this->getProperties();
381 
382  return $props[$t];
383  }
384 
385 
389  public function getLearningProgress() {
390  $props = $this->getPropertyvalues();
392 
393  return $props[$p];
394  }
395 
396 
397  /*
398  * getDatatypeTitle
399  */
400  public function getDatatypeTitle() {
401  $this->loadDatatype();
402 
403  return $this->datatype->getTitle();
404  }
405 
406 
407  /*
408  * getStorageLocation
409  */
410  public function getStorageLocation() {
411  $this->loadDatatype();
412 
413  return $this->datatype->getStorageLocation();
414  }
415 
416 
417  protected function loadDatatype() {
418  if ($this->datatype == NULL) {
419  $this->datatype = new ilDataCollectionDatatype($this->datatypeId);
420  }
421  }
422 
423 
427  public function isVisible() {
428  if (!isset($this->visible)) {
429  $this->loadVisibility();
430  }
431 
432  return $this->visible;
433  }
434 
435 
436  protected function loadVisibility() {
437  if ($this->visible == NULL) {
438  $this->loadViewDefinition(self::VIEW_VIEW);
439  }
440  }
441 
442 
446  public function isFilterable() {
447  if (!isset($this->filterable)) {
448  $this->loadFilterability();
449  }
450 
451  return $this->filterable;
452  }
453 
454 
455  protected function loadFilterability() {
456  if ($this->filterable == NULL) {
457  $this->loadViewDefinition(self::FILTER_VIEW);
458  }
459  }
460 
461 
467  protected function loadViewDefinition($view) {
468  global $ilDB;
469  $query = " SELECT view.table_id, def.field_order, def.is_set FROM il_dcl_viewdefinition def
470  INNER JOIN il_dcl_view view ON view.id = def.view_id AND view.type = " . $ilDB->quote($view, "integer") . "
471  WHERE def.field LIKE '" . $this->id . "' AND view.table_id = " . $ilDB->quote($this->table_id, "integer");
472  $set = $ilDB->query($query);
473  $rec = $ilDB->fetchAssoc($set);
474  $prop = $rec['is_set'];
475 
476  switch ($view) {
477  case self::VIEW_VIEW:
478  $this->visible = $prop;
479  break;
480  case self::EDIT_VIEW:
481  $this->editable = $prop;
482  break;
483  case self::FILTER_VIEW:
484  $this->filterable = $prop;
485  break;
486  case self::EXPORTABLE_VIEW:
487  $this->exportable = $prop;
488  break;
489  }
490 
491  if (!$this->order) {
492  $this->order = $rec['field_order'];
493  }
494  }
495 
496 
502  public function isEditable() {
503  if (!isset($this->editable)) {
504  $this->loadEditability();
505  }
506 
507  return $this->editable;
508  }
509 
510 
511  /*
512  * editable
513  */
514  public function setEditable($editable) {
515  $this->editable = $editable;
516  }
517 
518 
519  public function getExportable() {
520  if (!isset($this->exportable)) {
521  $this->loadExportability();
522  }
523 
524  return $this->exportable;
525  }
526 
527 
528  /*
529  * loadEditability
530  */
531  private function loadEditability() {
532  if ($this->editable == NULL) {
533  $this->loadViewDefinition(self::EDIT_VIEW);
534  }
535  }
536 
537 
541  private function loadExportability() {
542  if ($this->exportable == NULL) {
543  $this->loadViewDefinition(self::EXPORTABLE_VIEW);
544  }
545  }
546 
547 
548  /*
549  * toArray
550  */
551  public function toArray() {
552  return (array)$this;
553  }
554 
555 
556  /*
557  * isStandardField
558  */
559  public function isStandardField() {
560  return false;
561  }
562 
563 
567  public function doRead() {
568  global $ilDB;
569 
570  //THEN 1 ELSE 0 END AS has_options FROM il_dcl_field f WHERE id = ".$ilDB->quote($this->getId(),"integer");
571  $query = "SELECT * FROM il_dcl_field WHERE id = " . $ilDB->quote($this->getId(), "integer");
572  $set = $ilDB->query($query);
573  $rec = $ilDB->fetchAssoc($set);
574 
575  $this->setTableId($rec["table_id"]);
576  $this->setTitle($rec["title"]);
577  $this->setDescription($rec["description"]);
578  $this->setDatatypeId($rec["datatype_id"]);
579  $this->setRequired($rec["required"]);
580  $this->setUnique($rec["is_unique"]);
581  $this->setLocked($rec["is_locked"]);
582  $this->loadProperties();
583  }
584 
585 
586  /*
587  * buildFromDBRecord
588  */
589  public function buildFromDBRecord($rec) {
590  $this->setId($rec["id"]);
591  $this->setTableId($rec["table_id"]);
592  $this->setTitle($rec["title"]);
593  $this->setDescription($rec["description"]);
594  $this->setDatatypeId($rec["datatype_id"]);
595  $this->setRequired($rec["required"]);
596  $this->setUnique($rec["is_unique"]);
597  $this->setLocked($rec["is_locked"]);
598  }
599 
600 
604  public function doCreate() {
605  global $ilDB;
606  $this->getLocked() == NULL ? $this->setLocked(false) : true;
607 
609  throw new ilException("The field does not have a related table!");
610  }
611 
612  $id = $ilDB->nextId("il_dcl_field");
613  $this->setId($id);
614  $query = "INSERT INTO il_dcl_field (" . "id" . ", table_id" . ", datatype_id" . ", title" . ", description" . ", required" . ", is_unique"
615  . ", is_locked" . " ) VALUES (" . $ilDB->quote($this->getId(), "integer") . "," . $ilDB->quote($this->getTableId(), "integer") . ","
616  . $ilDB->quote($this->getDatatypeId(), "integer") . "," . $ilDB->quote($this->getTitle(), "text") . ","
617  . $ilDB->quote($this->getDescription(), "text") . "," . $ilDB->quote($this->getRequired(), "integer") . ","
618  . $ilDB->quote($this->isUnique(), "integer") . "," . $ilDB->quote($this->getLocked() ? 1 : 0, "integer") . ")";
619  $ilDB->manipulate($query);
620 
621  $this->updateVisibility();
622  $this->updateFilterability();
623  $this->updateEditability();
624  $this->updateExportability();
625  }
626 
627 
631  public function doUpdate() {
632  global $ilDB;
633 
634  $ilDB->update("il_dcl_field", array(
635  "table_id" => array( "integer", $this->getTableId() ),
636  "datatype_id" => array( "text", $this->getDatatypeId() ),
637  "title" => array( "text", $this->getTitle() ),
638  "description" => array( "text", $this->getDescription() ),
639  "required" => array( "integer", $this->getRequired() ),
640  "is_unique" => array( "integer", $this->isUnique() ),
641  "is_locked" => array( "integer", $this->getLocked() ? 1 : 0 ),
642  ), array(
643  "id" => array( "integer", $this->getId() )
644  ));
645  $this->updateVisibility();
646  $this->updateFilterability();
647  $this->updateEditability();
648  $this->updateExportability();
649  $this->updateProperties();
650  }
651 
652 
656  protected function updateProperties() {
657  global $ilDB;
658  foreach ($this->property as $key => $value) {
659  $ilDB->update('il_dcl_field_prop', array(
660  'value' => array( 'integer', $value ),
661  ), array(
662  'field_id' => array( 'integer', $this->getId() ),
663  'datatype_prop_id' => array( 'integer', $key ),
664  ));
665  }
666  }
667 
668 
672  public function getFilterable() {
673  return $this->isFilterable();
674  }
675 
676 
677  /*
678  * updateVisibility
679  */
680  protected function updateVisibility() {
681  $this->updateViewDefinition(self::VIEW_VIEW);
682  }
683 
684 
685  /*
686  * updateFilterability
687  */
688  protected function updateFilterability() {
689  $this->updateViewDefinition(self::FILTER_VIEW);
690  }
691 
692 
693  protected function updateEditability() {
694  $this->updateViewDefinition(self::EDIT_VIEW);
695  }
696 
697 
698  protected function updateExportability() {
699  $this->updateViewDefinition(self::EXPORTABLE_VIEW);
700  }
701 
702 
708  private function updateViewDefinition($view) {
709  global $ilDB;
710 
711  switch ($view) {
712  case self::EDIT_VIEW:
713  $set = $this->isEditable();
714  break;
715  case self::VIEW_VIEW:
716  $set = $this->isVisible();
717  if ($set && $this->order === NULL) {
718  $this->order = 0;
719  }
720  break;
721  case self::FILTER_VIEW:
722  $set = $this->isFilterable();
723  if ($set && $this->order === NULL) {
724  $this->order = 0;
725  }
726  break;
727  case self::EXPORTABLE_VIEW:
728  $set = $this->getExportable();
729  if ($set && $this->order === NULL) {
730  $this->order = 0;
731  }
732  break;
733  }
734 
735  if (!$set) {
736  $set = 0;
737  } else {
738  $set = 1;
739  }
740 
741  if (!isset($this->order)) {
742  $this->order = 0;
743  }
744 
745  $query = "DELETE def FROM il_dcl_viewdefinition def INNER JOIN il_dcl_view ON il_dcl_view.type = " . $ilDB->quote($view, "integer")
746  . " AND il_dcl_view.table_id = " . $ilDB->quote($this->getTableId(), "integer") . " WHERE def.view_id = il_dcl_view.id AND def.field = "
747  . $ilDB->quote($this->getId(), "text");
748 
749  $ilDB->manipulate($query);
750 
751  $query = "INSERT INTO il_dcl_viewdefinition (view_id, field, field_order, is_set) SELECT id, " . $ilDB->quote($this->getId(), "text") . ", "
752  . $ilDB->quote($this->getOrder(), "integer") . ", " . $ilDB->quote($set, "integer") . " FROM il_dcl_view WHERE il_dcl_view.type = "
753  . $ilDB->quote($view, "integer") . " AND il_dcl_view.table_id = " . $ilDB->quote($this->getTableId(), "integer");
754 
755  $ilDB->manipulate($query);
756  }
757 
758 
759  /*
760  * deleteViewDefinition
761  */
762  private function deleteViewDefinition($view) {
763  global $ilDB;
764 
765  $query = "DELETE def FROM il_dcl_viewdefinition def INNER JOIN il_dcl_view ON il_dcl_view.type = " . $ilDB->quote($view, "integer")
766  . " AND il_dcl_view.table_id = " . $ilDB->quote($this->getTableId(), "integer") . " WHERE def.view_id = il_dcl_view.id AND def.field = "
767  . $ilDB->quote($this->getId(), "text");
768 
769  $ilDB->manipulate($query);
770  }
771 
772 
773  /*
774  * doDelete
775  */
776  public function doDelete() {
777  global $ilDB;
778 
779  // delete viewdefinitions.
780  $this->deleteViewDefinition(self::VIEW_VIEW);
781  $this->deleteViewDefinition(self::FILTER_VIEW);
782  $this->deleteViewDefinition(self::EDIT_VIEW);
783  $this->deleteViewDefinition(self::EXPORTABLE_VIEW);
784 
785  $query = "DELETE FROM il_dcl_field_prop WHERE field_id = " . $ilDB->quote($this->getId(), "text");
786  $ilDB->manipulate($query);
787 
788  $query = "DELETE FROM il_dcl_field WHERE id = " . $ilDB->quote($this->getId(), "text");
789  $ilDB->manipulate($query);
790  }
791 
792 
793  /*
794  * getOrder
795  */
796  public function getOrder() {
797  if (!isset($this->order)) {
798  $this->loadVisibility();
799  }
800 
801  return !$this->order ? 0 : $this->order;
802  }
803 
804 
805  /*
806  * setOrder
807  */
808  public function setOrder($order) {
809  $this->order = $order;
810  }
811 
812 
813  /*
814  * getFieldRef
815  */
816  public function getFieldRef() {
817  $props = $this->getPropertyvalues();
819 
820  return $props[$id];
821  }
822 
823 
824  /*
825  * getFieldReflist
826  */
827  public function getFieldReflist() {
828  $props = $this->getPropertyvalues();
830 
831  return $props[$id];
832  }
833 
834 
838  public function isNRef() {
839  $props = $this->getPropertyvalues();
841 
842  return $props[$id];
843  }
844 
845 
851  private function loadProperties() {
852  global $ilDB;
853 
854  $query = "SELECT datatype_prop_id,
855  title,
856  value
857  FROM il_dcl_field_prop fp
858  LEFT JOIN il_dcl_datatype_prop AS p ON p.id = fp.datatype_prop_id
859  WHERE fp.field_id = " . $ilDB->quote($this->getId(), "integer");
860 
861  $set = $ilDB->query($query);
862 
863  while ($rec = $ilDB->fetchAssoc($set)) {
864  $this->setPropertyvalue($rec['value'], $rec['datatype_prop_id']);
865  }
866  }
867 
868 
874  public function getProperties() {
875  if ($this->property == NULL) {
876  $this->loadProperties();
877  }
878 
879  return $this->property;
880  }
881 
882 
883  public function setProperties($data) {
884  $this->property = $data;
885  }
886 
887 
891  public function setLocked($locked) {
892  $this->locked = $locked;
893  }
894 
895 
899  public function getLocked() {
900  return $this->locked;
901  }
902 
903 
904  /*
905  * checkValidity
906  */
907  public function checkValidity($value, $record_id = NULL) {
908  //Don't check empty values
909  if ($value == NULL) {
910  return true;
911  }
912 
915  }
916 
917  $properties = $this->getPropertyvalues();
921 
923  $regex = $properties[$regex_id];
924  if (substr($regex, 0, 1) != "/") {
925  $regex = "/" . $regex;
926  }
927  if (substr($regex, - 1) != "/") {
928  $regex .= "/";
929  }
930 
931  if ($properties[$length] < mb_strlen($value, 'UTF-8') AND is_numeric($properties[$length])) {
933  }
934  if (!($properties[$regex_id] == NULL OR @preg_match($regex, $value))) {
936  }
937  //email or url
938  if ($properties[$url]
939  && !(preg_match('~(^(news|(ht|f)tp(s?)\://){1}\S+)~i', $value)
940  || preg_match("/^[a-z0-9!#$%&'*+=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i", $value))
941  ) {
943  }
944  }
945 
946  if ($this->isUnique() && $record_id === NULL) {
948 
949  foreach ($table->getRecords() as $record) {
950  if ($record->getRecordFieldValue($this->getId()) == $value && ($record->getId() != $record_id || $record_id == 0)) {
952  }
953 
954  //for text it has to be case insensitive.
956  if (strtolower($record->getRecordFieldValue($this->getId())) == strtolower($value)
957  && ($record->getId() != $record_id
958  || $record_id == 0)
959  ) {
961  }
962  }
963 
965  $datestring = $value["date"] . " " . $value["time"];//["y"]."-".$value["date"]['m']."-".$value["date"]['d']." 00:00:00";
966 
967  if ($record->getRecordFieldValue($this->getId()) == $datestring && ($record->getId() != $record_id || $record_id == 0)) {
969  }
970  }
971  }
972  }
973 
974  return true;
975  }
976 
977 
983  public function cloneStructure($original_id) {
984  $original = ilDataCollectionCache::getFieldCache($original_id);
985  $this->setTitle($original->getTitle());
986  $this->setDatatypeId($original->getDatatypeId());
987  $this->setDescription($original->getDescription());
988  $this->setEditable($original->isEditable());
989  $this->setLocked($original->getLocked());
990  $this->setFilterable($original->isFilterable());
991  $this->setVisible($original->isVisible());
992  $this->setOrder($original->getOrder());
993  $this->setRequired($original->getRequired());
994  $this->setUnique($original->isUnique());
995  $this->setExportable($original->getExportable());
996  $this->doCreate();
997  $this->cloneProperties($original);
998  }
999 
1000 
1004  public function cloneProperties(ilDataCollectionField $originalField) {
1005  $orgProps = $originalField->getProperties();
1006  if ($orgProps == NULL) {
1007  return;
1008  }
1009  foreach ($orgProps as $id => $value) {
1010  $fieldprop_obj = new ilDataCollectionFieldProp();
1011  $fieldprop_obj->setDatatypePropertyId($id);
1012  $fieldprop_obj->setFieldId($this->getId());
1013  // If reference field, we must reset the referenced field, otherwise it will point to the old ID
1016  ) {
1017  $value = NULL;
1018  }
1019  $fieldprop_obj->setValue($value);
1020  $fieldprop_obj->doCreate();
1021  }
1022  }
1023 
1024 
1028  public function setExportable($exportable) {
1029  $this->exportable = $exportable;
1030  }
1031 }
1032 
1033 ?>