ILIAS  Release_4_4_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;
25 
29  protected $table_id;
30 
34  protected $title;
35 
39  protected $description;
40 
44  protected $datatypeId;
45 
49  protected $required;
50 
54  protected $order;
55 
59  protected $unique;
60 
64  protected $visible;
65 
69  protected $editable;
70 
74  protected $filterable;
75 
79  protected $locked;
80 
84  protected $property = array();
85 
89  protected $exportable;
90 
94  protected $datatype;
95 
96  const PROPERTYID_LENGTH = 1;
97  const PROPERTYID_REGEX = 2;
103  const PROPERTYID_URL = 4;
106  const PROPERTYID_WIDTH = 7;
107  const PROPERTYID_HEIGHT = 8;
111 
112 
113  // type of table il_dcl_view
114  const VIEW_VIEW = 1;
115  const EDIT_VIEW = 2;
116  const FILTER_VIEW = 3;
117  const EXPORTABLE_VIEW = 4;
118 
125  public function __construct($a_id = 0)
126  {
127  if($a_id != 0)
128  {
129  $this->id = $a_id;
130  $this->doRead();
131  }
132  }
133 
134 
141  public static function _getTitleValidChars($a_as_regex = true)
142  {
143  if( $a_as_regex )
144  {
145  return '/^[a-zA-Z\d \/\-.,äöüÄÖÜàéèÀÉÈç¢]*$/i';
146  }
147  else
148  {
149  return 'A-Z a-z 0-9 /-.,';
150  }
151  }
152 
158  public static function _getFieldIdByTitle($title, $table_id) {
159  global $ilDB;
160  $result = $ilDB->query('SELECT id FROM il_dcl_field WHERE title = ' . $ilDB->quote($title, 'text') . ' AND table_id = ' . $ilDB->quote($table_id, 'integer'));
161  $id = 0;
162  while($rec = $ilDB->fetchAssoc($result)) {
163  $id = $rec['id'];
164  }
165  return $id;
166  }
167 
168 
174  public function setId($a_id)
175  {
176  $this->id = $a_id;
177  }
178 
184  public function getId()
185  {
186  return $this->id;
187  }
188 
194  public function setTableId($a_id)
195  {
196  $this->table_id = $a_id;
197  }
198 
204  public function getTableId()
205  {
206  return $this->table_id;
207  }
208 
214  public function setTitle($a_title)
215  {
216  //title cannot begin with _ as this is saved for other purposes. make __ instead.
217  if(substr($a_title,0,1) == "_" && substr($a_title, 0, 2) != "__")
218  $a_title = "_".$a_title;
219  $this->title = $a_title;
220  }
221 
227  public function getTitle()
228  {
229  return $this->title;
230  }
231 
237  public function setDescription($a_desc)
238  {
239  $this->desc = $a_desc;
240  }
241 
247  public function getDescription()
248  {
249  return $this->desc;
250  }
251 
257  public function setDatatypeId($a_id)
258  {
259  //unset the cached datatype.
260  $this->datatype = NULL;
261  $this->datatypeId = $a_id;
262  }
263 
269  public function getDatatypeId()
270  {
271  if($this->isStandardField())
272  {
274  }
275  return $this->datatypeId;
276  }
277 
283  public function setRequired($a_required)
284  {
285  $this->required = $a_required;
286  }
287 
293  public function getRequired()
294  {
295  return $this->required;
296  }
297 
304  public function setPropertyvalue($a_value, $a_id)
305  {
306  $this->property[$a_id] = $a_value;
307  }
308 
309  /*
310  * isUnique
311  */
312  public function isUnique()
313  {
314  return $this->unique;
315  }
316 
317  /*
318  * setUnique
319  */
320  public function setUnique($unique)
321  {
322  $this->unique = $unique ? 1 : 0;
323  }
324 
331  public function getPropertyvalues()
332  {
333  if($this->property == null)
334  $this->loadProperties();
335  return $this->property;
336  }
337 
342  public function setVisible($visible)
343  {
344  if($visible == true && $this->order === NULL)
345  {
346  $this->setOrder(0);
347  }
348 
349  $this->visible = $visible;
350  }
351 
356  public function setFilterable($filterable)
357  {
358  if($filterable == true && $this->order === NULL)
359  {
360  $this->setOrder(0);
361  }
362 
363  $this->filterable = $filterable;
364  }
365 
366  /*
367  * getDatatype
368  */
369  public function getDatatype()
370  {
371  $this->loadDatatype();
372 
373  return $this->datatype;
374  }
375 
376  /*
377  * getLength
378  */
379  public function getLength()
380  {
381  $props = $this->getPropertyvalues();
383 
384  return $props[$l];
385  }
386 
390  public function getTextArea(){
391  $props = $this->getProperties();
393 
394  return $props[$t];
395  }
396 
400  public function getLearningProgress(){
401  $props = $this->getPropertyvalues();
403 
404  return $props[$p];
405  }
406 
407  /*
408  * getDatatypeTitle
409  */
410  public function getDatatypeTitle()
411  {
412  $this->loadDatatype();
413 
414  return $this->datatype->getTitle();
415  }
416 
417  /*
418  * getStorageLocation
419  */
420  public function getStorageLocation()
421  {
422  $this->loadDatatype();
423 
424  return $this->datatype->getStorageLocation();
425  }
426 
427  /*
428  * loadDatatype
429  */
430  private function loadDatatype()
431  {
432  if($this->datatype == NULL)
433  {
434  $this->datatype = new ilDataCollectionDatatype($this->datatypeId);
435  }
436  }
437 
438  /*
439  * isVisible
440  */
441  public function isVisible()
442  {
443  if(!isset($this->visible))
444  {
445  $this->loadVisibility();
446  }
447 
448  return $this->visible;
449  }
450 
451  /*
452  * loadVisibility
453  */
454  private function loadVisibility()
455  {
456  if($this->visible == NULL)
457  {
458  $this->loadViewDefinition(self::VIEW_VIEW);
459  }
460  }
461 
462  /*
463  * isFilterable
464  */
465  public function isFilterable()
466  {
467  if(!isset($this->filterable))
468  {
469  $this->loadFilterability();
470  }
471 
472  return $this->filterable;
473  }
474 
475  /*
476  * loadFilterable
477  */
478  private function loadFilterability()
479  {
480  if($this->filterable == NULL)
481  {
482  $this->loadViewDefinition(self::FILTER_VIEW);
483  }
484  }
485 
486 
491  private function loadViewDefinition($view)
492  {
493  global $ilDB;
494  $query = " SELECT view.table_id, def.field_order, def.is_set FROM il_dcl_viewdefinition def
495  INNER JOIN il_dcl_view view ON view.id = def.view_id AND view.type = ".$ilDB->quote($view, "integer")."
496  WHERE def.field LIKE '".$this->id."' AND view.table_id = ".$ilDB->quote($this->table_id, "integer");
497  $set = $ilDB->query($query);
498  $rec = $ilDB->fetchAssoc($set);
499  $prop = $rec['is_set'];
500 
501  switch($view)
502  {
503  case self::VIEW_VIEW:
504  $this->visible = $prop;
505  break;
506  case self::EDIT_VIEW:
507  $this->editable = $prop;
508  break;
509  case self::FILTER_VIEW:
510  $this->filterable = $prop;
511  break;
512  case self::EXPORTABLE_VIEW:
513  $this->exportable = $prop;
514  break;
515  }
516 
517  if(!$this->order)
518  $this->order = $rec['field_order'];
519  }
520 
525  public function isEditable()
526  {
527  if(!isset($this->editable))
528  {
529  $this->loadEditability();
530  }
531 
532  return $this->editable;
533  }
534 
535  /*
536  * editable
537  */
538  public function setEditable($editable)
539  {
540  $this->editable = $editable;
541  }
542 
543  public function getExportable(){
544  if(!isset($this->exportable))
545  $this->loadExportability();
546  return $this->exportable;
547  }
548  /*
549  * loadEditability
550  */
551  private function loadEditability()
552  {
553  if($this->editable == NULL)
554  {
555  $this->loadViewDefinition(self::EDIT_VIEW);
556  }
557  }
558 
562  private function loadExportability()
563  {
564  if($this->exportable == NULL)
565  {
566  $this->loadViewDefinition(self::EXPORTABLE_VIEW);
567  }
568  }
569 
570  /*
571  * toArray
572  */
573  public function toArray()
574  {
575  return (array) $this;
576  }
577 
578  /*
579  * isStandardField
580  */
581  public function isStandardField()
582  {
583  return false;
584  }
585 
589  public function doRead()
590  {
591  global $ilDB;
592 
593  //THEN 1 ELSE 0 END AS has_options FROM il_dcl_field f WHERE id = ".$ilDB->quote($this->getId(),"integer");
594  $query = "SELECT * FROM il_dcl_field WHERE id = ".$ilDB->quote($this->getId(),"integer");
595  $set = $ilDB->query($query);
596  $rec = $ilDB->fetchAssoc($set);
597 
598  $this->setTableId($rec["table_id"]);
599  $this->setTitle($rec["title"]);
600  $this->setDescription($rec["description"]);
601  $this->setDatatypeId($rec["datatype_id"]);
602  $this->setRequired($rec["required"]);
603  $this->setUnique($rec["is_unique"]);
604  $this->setLocked($rec["is_locked"]);
605  $this->loadProperties();
606  }
607 
608  /*
609  * buildFromDBRecord
610  */
611  public function buildFromDBRecord($rec)
612  {
613  $this->setId($rec["id"]);
614  $this->setTableId($rec["table_id"]);
615  $this->setTitle($rec["title"]);
616  $this->setDescription($rec["description"]);
617  $this->setDatatypeId($rec["datatype_id"]);
618  $this->setRequired($rec["required"]);
619  $this->setUnique($rec["is_unique"]);
620  $this->setLocked($rec["is_locked"]);
621  }
622 
626  public function doCreate()
627  {
628  global $ilDB;
629  $this->getLocked() == NULL?$this->setLocked(false):true;
630 
632  throw new ilException("The field does not have a related table!");
633 
634  $id = $ilDB->nextId("il_dcl_field");
635  $this->setId($id);
636  $query = "INSERT INTO il_dcl_field (".
637  "id".
638  ", table_id".
639  ", datatype_id".
640  ", title".
641  ", description".
642  ", required".
643  ", is_unique".
644  ", is_locked".
645  " ) VALUES (".
646  $ilDB->quote($this->getId(), "integer")
647  .",".$ilDB->quote($this->getTableId(), "integer")
648  .",".$ilDB->quote($this->getDatatypeId(), "integer")
649  .",".$ilDB->quote($this->getTitle(), "text")
650  .",".$ilDB->quote($this->getDescription(), "text")
651  .",".$ilDB->quote($this->getRequired(), "integer")
652  .",".$ilDB->quote($this->isUnique(), "integer")
653  .",".$ilDB->quote($this->getLocked()?1:0, "integer")
654  .")";
655  $ilDB->manipulate($query);
656 
657  $this->updateVisibility();
658  $this->updateFilterability();
659  $this->updateEditability();
660  $this->updateExportability();
661  }
662 
666  public function doUpdate()
667  {
668  global $ilDB;
669 
670  $ilDB->update("il_dcl_field", array(
671  "table_id" => array("integer", $this->getTableId()),
672  "datatype_id" => array("text", $this->getDatatypeId()),
673  "title" => array("text", $this->getTitle()),
674  "description" => array("text", $this->getDescription()),
675  "required" => array("integer",$this->getRequired()),
676  "is_unique" => array("integer",$this->isUnique()),
677  "is_locked" => array("integer",$this->getLocked()?1:0),
678  ), array(
679  "id" => array("integer", $this->getId())
680  ));
681  $this->updateVisibility();
682  $this->updateFilterability();
683  $this->updateEditability();
684  $this->updateExportability();
685  $this->updateProperties();
686  }
687 
691  protected function updateProperties() {
692  global $ilDB;
693  foreach ($this->property as $key => $value) {
694  $ilDB->update('il_dcl_field_prop', array(
695  'value' => array('integer', $value),
696  ), array(
697  'field_id' => array('integer', $this->getId()),
698  'datatype_prop_id' => array('integer', $key),
699  ));
700  }
701  }
702 
706  public function getFilterable()
707  {
708  return $this->isFilterable();
709  }
710 
711  /*
712  * updateVisibility
713  */
714  protected function updateVisibility()
715  {
716  $this->updateViewDefinition(self::VIEW_VIEW);
717  }
718 
719  /*
720  * updateFilterability
721  */
722  protected function updateFilterability()
723  {
724  $this->updateViewDefinition(self::FILTER_VIEW);
725  }
726 
727  protected function updateEditability(){
728  $this->updateViewDefinition(self::EDIT_VIEW);
729  }
730 
731  protected function updateExportability(){
732  $this->updateViewDefinition(self::EXPORTABLE_VIEW);
733  }
734 
739  private function updateViewDefinition($view)
740  {
741  global $ilDB;
742 
743  switch($view)
744  {
745  case self::EDIT_VIEW:
746  $set = $this->isEditable();
747  break;
748  case self::VIEW_VIEW:
749  $set = $this->isVisible();
750  if($set && $this->order === NULL)
751  $this->order = 0;
752  break;
753  case self::FILTER_VIEW:
754  $set = $this->isFilterable();
755  if($set && $this->order === NULL)
756  $this->order = 0;
757  break;
758  case self::EXPORTABLE_VIEW:
759  $set = $this->getExportable();
760  if($set && $this->order === NULL)
761  $this->order = 0;
762  break;
763  }
764 
765  if(!$set)
766  $set = 0;
767  else
768  $set = 1;
769 
770  if(!isset($this->order))
771  $this->order = 0;
772 
773  $query = "DELETE def FROM il_dcl_viewdefinition def INNER JOIN il_dcl_view ON il_dcl_view.type = "
774  .$ilDB->quote($view, "integer")." AND il_dcl_view.table_id = "
775  .$ilDB->quote($this->getTableId(), "integer")." WHERE def.view_id = il_dcl_view.id AND def.field = "
776  .$ilDB->quote($this->getId(), "text");
777 
778  $ilDB->manipulate($query);
779 
780  $query = "INSERT INTO il_dcl_viewdefinition (view_id, field, field_order, is_set) SELECT id, "
781  .$ilDB->quote($this->getId(), "text").", "
782  .$ilDB->quote($this->getOrder(), "integer").", "
783  .$ilDB->quote($set, "integer")." FROM il_dcl_view WHERE il_dcl_view.type = "
784  .$ilDB->quote($view, "integer")." AND il_dcl_view.table_id = "
785  .$ilDB->quote($this->getTableId(), "integer");
786 
787  $ilDB->manipulate($query);
788  }
789 
790 
791  /*
792  * deleteViewDefinition
793  */
794  private function deleteViewDefinition($view)
795  {
796  global $ilDB;
797 
798  $query = "DELETE def FROM il_dcl_viewdefinition def INNER JOIN il_dcl_view ON il_dcl_view.type = "
799  .$ilDB->quote($view, "integer")." AND il_dcl_view.table_id = "
800  .$ilDB->quote($this->getTableId(), "integer")." WHERE def.view_id = il_dcl_view.id AND def.field = "
801  .$ilDB->quote($this->getId(), "text");
802 
803  $ilDB->manipulate($query);
804  }
805 
806  /*
807  * doDelete
808  */
809  public function doDelete()
810  {
811  global $ilDB;
812 
813  // delete viewdefinitions.
814  $this->deleteViewDefinition(self::VIEW_VIEW);
815  $this->deleteViewDefinition(self::FILTER_VIEW);
816  $this->deleteViewDefinition(self::EDIT_VIEW);
817  $this->deleteViewDefinition(self::EXPORTABLE_VIEW);
818 
819  $query = "DELETE FROM il_dcl_field_prop WHERE field_id = ".$ilDB->quote($this->getId(), "text");
820  $ilDB->manipulate($query);
821 
822  $query = "DELETE FROM il_dcl_field WHERE id = ".$ilDB->quote($this->getId(), "text");
823  $ilDB->manipulate($query);
824 
825  }
826 
827  /*
828  * getOrder
829  */
830  public function getOrder()
831  {
832  if(!isset($this->order))
833  {
834  $this->loadVisibility();
835  }
836 
837  return !$this->order?0:$this->order;
838  }
839 
840  /*
841  * setOrder
842  */
843  public function setOrder($order)
844  {
845  $this->order = $order;
846  }
847 
848  /*
849  * getFieldRef
850  */
851  public function getFieldRef()
852  {
853  $props = $this->getPropertyvalues();
855 
856  return $props[$id];
857  }
858 
859  /*
860  * getFieldReflist
861  */
862  public function getFieldReflist()
863  {
864  $props = $this->getPropertyvalues();
866 
867  return $props[$id];
868  }
869 
873  public function isNRef()
874  {
875  $props = $this->getPropertyvalues();
877  return $props[$id];
878  }
879 
885  private function loadProperties()
886  {
887  global $ilDB;
888 
889  $query = "SELECT datatype_prop_id,
890  title,
891  value
892  FROM il_dcl_field_prop fp
893  LEFT JOIN il_dcl_datatype_prop AS p ON p.id = fp.datatype_prop_id
894  WHERE fp.field_id = ".$ilDB->quote($this->getId(),"integer");
895 
896  $set = $ilDB->query($query);
897 
898  while($rec = $ilDB->fetchAssoc($set))
899  {
900  $this->setPropertyvalue($rec['value'],$rec['datatype_prop_id']);
901  }
902  }
903 
909  public function getProperties()
910  {
911  if($this->property == null)
912  $this->loadProperties();
913 
914  return $this->property;
915  }
916 
917  public function setProperties($data){
918  $this->property = $data;
919  }
920 
924  public function setLocked($locked)
925  {
926  $this->locked = $locked;
927  }
928 
932  public function getLocked()
933  {
934  return $this->locked;
935  }
936 
937  /*
938  * checkValidity
939  */
940  public function checkValidity($value, $record_id = null)
941  {
942  //Don't check empty values
943  if($value == NULL)
944  {
945  return true;
946  }
947 
948 
950  {
952  }
953 
954  $properties = $this->getPropertyvalues();
958 
959  include_once 'Services/Utilities/classes/class.ilStr.php';
961  {
962  $regex = $properties[$regex_id];
963  if(substr($regex,0,1) != "/")
964  $regex = "/".$regex;
965  if(substr($regex, -1) != "/")
966  $regex .= "/";
967  if($properties[$length] < ilStr::strLen($value) && is_numeric($properties[$length]))
969  if(!($properties[$regex_id] == NULL || @preg_match($regex, $value)))
971  //email or url
972  if($properties[$url] && !(preg_match('~(^(news|(ht|f)tp(s?)\://){1}\S+)~i', $value) || 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)))
974  }
975 
976 
977  if($this->getDatatypeId() == ilDataCollectionDatatype::INPUTFORMAT_MOB AND $value['name'])
978  {
979  $arrMimeType = explode('/', ilObjMediaObject::getMimeType($value['name']));
980 
981  if($arrMimeType[0] != "image") {
983  }
984  }
985 
986 
987  if($this->isUnique() && $record_id === null)
988  {
990 
991  foreach($table->getRecords() as $record)
992  {
993  if($record->getRecordFieldValue($this->getId()) == $value && ($record->getId() != $record_id || $record_id == 0))
995 
996  //for text it has to be case insensitive.
998  {
999  if(strtolower($record->getRecordFieldValue($this->getId())) == strtolower($value) && ($record->getId() != $record_id || $record_id == 0))
1000  {
1002  }
1003 
1004  }
1005 
1007  {
1008  $datestring = $value["date"]." ".$value["time"];//["y"]."-".$value["date"]['m']."-".$value["date"]['d']." 00:00:00";
1009 
1010  if($record->getRecordFieldValue($this->getId()) == $datestring && ($record->getId() != $record_id || $record_id == 0))
1011  {
1013  }
1014  }
1015  }
1016  }
1017 
1018  return true;
1019  }
1020 
1021  /*
1022  * cloneStructure
1023  */
1024  public function cloneStructure($original_id)
1025  {
1026  $original = ilDataCollectionCache::getFieldCache($original_id);
1027  $this->setTitle($original->getTitle());
1028  $this->setDatatypeId($original->getDatatypeId());
1029  $this->setDescription($original->getDescription());
1030  $this->setEditable($original->isEditable());
1031  $this->setLocked($original->getLocked());
1032  $this->setFilterable($original->isFilterable());
1033  $this->setVisible($original->isVisible());
1034  $this->setOrder($original->getOrder());
1035  $this->setRequired($original->getRequired());
1036  $this->setUnique($original->isUnique());
1037  $this->setExportable($original->getExportable());
1038  $this->doCreate();
1039  $this->cloneProperties($original);
1040  }
1041 
1045  public function cloneProperties($originalField){
1046  $orgProps = $originalField->getProperties();
1047  if($orgProps == NULL)
1048  return;
1049  foreach($orgProps as $id => $value){
1050  $fieldprop_obj = new ilDataCollectionFieldProp();
1051  $fieldprop_obj->setDatatypePropertyId($id);
1052  $fieldprop_obj->setFieldId($this->getId());
1053  // If reference field, we must reset the referenced field, otherwise it will point to the old ID
1055  $value = null;
1056  }
1057  $fieldprop_obj->setValue($value);
1058  $fieldprop_obj->doCreate();
1059  }
1060  }
1061 
1065  public function setExportable($exportable)
1066  {
1067  $this->exportable = $exportable;
1068  }
1069 }
1070 
1071 ?>