ILIAS  release_4-3 Revision
 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 $datatype;
90 
91  const PROPERTYID_LENGTH = 1;
92  const PROPERTYID_REGEX = 2;
97  const PROPERTYID_URL = 4;
100  const PROPERTYID_WIDTH = 7;
101  const PROPERTYID_HEIGHT = 8;
104 
105 
106  // type of table il_dcl_view
107  const VIEW_VIEW = 1;
108  const EDIT_VIEW = 2;
109  const FILTER_VIEW = 3;
110 
117  public function __construct($a_id = 0)
118  {
119  if($a_id != 0)
120  {
121  $this->id = $a_id;
122  $this->doRead();
123  }
124  }
125 
126 
133  public static function _getTitleValidChars($a_as_regex = true)
134  {
135  if( $a_as_regex )
136  {
137  return '/^[a-zA-Z\d \/\-.,äöüÄÖÜàéèÀÉÈç¢]*$/i';
138  }
139  else
140  {
141  return 'A-Z a-z 0-9 /-.,';
142  }
143  }
144 
145 
151  public static function _getFieldIdByTitle($title, $table_id) {
152  global $ilDB;
153  $result = $ilDB->query('SELECT id FROM il_dcl_field WHERE title = ' . $ilDB->quote($title, 'text') . ' AND table_id = ' . $ilDB->quote($table_id, 'integer'));
154  $id = 0;
155  while($rec = $ilDB->fetchAssoc($result)) {
156  $id = $rec['id'];
157  }
158  return $id;
159  }
160 
166  public function setId($a_id)
167  {
168  $this->id = $a_id;
169  }
170 
176  public function getId()
177  {
178  return $this->id;
179  }
180 
186  public function setTableId($a_id)
187  {
188  $this->table_id = $a_id;
189  }
190 
196  public function getTableId()
197  {
198  return $this->table_id;
199  }
200 
206  public function setTitle($a_title)
207  {
208  //title cannot begin with _ as this is saved for other purposes. make __ instead.
209  if(substr($a_title,0,1) == "_" && substr($a_title, 0, 2) != "__")
210  $a_title = "_".$a_title;
211  $this->title = $a_title;
212  }
213 
219  public function getTitle()
220  {
221  return $this->title;
222  }
223 
229  public function setDescription($a_desc)
230  {
231  $this->desc = $a_desc;
232  }
233 
239  public function getDescription()
240  {
241  return $this->desc;
242  }
243 
249  public function setDatatypeId($a_id)
250  {
251  //unset the cached datatype.
252  $this->datatype = NULL;
253  $this->datatypeId = $a_id;
254  }
255 
261  public function getDatatypeId()
262  {
263  if($this->isStandardField())
264  {
266  }
267  return $this->datatypeId;
268  }
269 
275  public function setRequired($a_required)
276  {
277  $this->required = $a_required;
278  }
279 
285  public function getRequired()
286  {
287  return $this->required;
288  }
289 
296  public function setPropertyvalue($a_value, $a_id)
297  {
298  $this->property[$a_id] = $a_value;
299  }
300 
301  /*
302  * isUnique
303  */
304  public function isUnique()
305  {
306  return $this->unique;
307  }
308 
309  /*
310  * setUnique
311  */
312  public function setUnique($unique)
313  {
314  $this->unique = $unique ? 1 : 0;
315  }
316 
323  public function getPropertyvalues()
324  {
325  if($this->property == null)
326  $this->loadProperties();
327  return $this->property;
328  }
329 
334  public function setVisible($visible)
335  {
336  if($visible == true && $this->order === NULL)
337  {
338  $this->setOrder(0);
339  }
340 
341  $this->visible = $visible;
342  }
343 
348  public function setFilterable($filterable)
349  {
350  if($filterable == true && $this->order === NULL)
351  {
352  $this->setOrder(0);
353  }
354 
355  $this->filterable = $filterable;
356  }
357 
358  /*
359  * getDatatype
360  */
361  public function getDatatype()
362  {
363  $this->loadDatatype();
364 
365  return $this->datatype;
366  }
367 
368  /*
369  * getLength
370  */
371  public function getLength()
372  {
373  $props = $this->getPropertyvalues();
375 
376  return $props[$l];
377  }
378 
382  public function getTextArea(){
383  $props = $this->getProperties();
385 
386  return $props[$t];
387  }
388 
392  public function getLearningProgress(){
393  $props = $this->getPropertyvalues();
395 
396  return $props[$p];
397  }
398 
399  /*
400  * getDatatypeTitle
401  */
402  public function getDatatypeTitle()
403  {
404  $this->loadDatatype();
405 
406  return $this->datatype->getTitle();
407  }
408 
409  /*
410  * getStorageLocation
411  */
412  public function getStorageLocation()
413  {
414  $this->loadDatatype();
415 
416  return $this->datatype->getStorageLocation();
417  }
418 
419  /*
420  * loadDatatype
421  */
422  private function loadDatatype()
423  {
424  if($this->datatype == NULL)
425  {
426  $this->datatype = new ilDataCollectionDatatype($this->datatypeId);
427  }
428  }
429 
430  /*
431  * isVisible
432  */
433  public function isVisible()
434  {
435  if(!isset($this->visible))
436  {
437  $this->loadVisibility();
438  }
439 
440  return $this->visible;
441  }
442 
443  /*
444  * loadVisibility
445  */
446  private function loadVisibility()
447  {
448  if($this->visible == NULL)
449  {
450  $this->loadViewDefinition(self::VIEW_VIEW);
451  }
452  }
453 
454  /*
455  * isFilterable
456  */
457  public function isFilterable()
458  {
459  if(!isset($this->filterable))
460  {
461  $this->loadFilterability();
462  }
463 
464  return $this->filterable;
465  }
466 
467  /*
468  * loadFilterable
469  */
470  private function loadFilterability()
471  {
472  if($this->filterable == NULL)
473  {
474  $this->loadViewDefinition(self::FILTER_VIEW);
475  }
476  }
477 
478 
483  private function loadViewDefinition($view)
484  {
485  global $ilDB;
486  $query = " SELECT view.table_id, def.field_order, def.is_set FROM il_dcl_viewdefinition def
487  INNER JOIN il_dcl_view view ON view.id = def.view_id AND view.type = ".$ilDB->quote($view, "integer")."
488  WHERE def.field LIKE '".$this->id."' AND view.table_id = ".$ilDB->quote($this->table_id, "integer");
489  $set = $ilDB->query($query);
490  $rec = $ilDB->fetchAssoc($set);
491  $prop = $rec['is_set'];
492 
493  switch($view)
494  {
495  case self::VIEW_VIEW:
496  $this->visible = $prop;
497  break;
498  case self::EDIT_VIEW:
499  $this->editable = $prop;
500  break;
501  case self::FILTER_VIEW:
502  $this->filterable = $prop;
503  break;
504  }
505 
506  if(!$this->order)
507  $this->order = $rec['field_order'];
508  }
509 
514  public function isEditable()
515  {
516  if(!isset($this->editable))
517  {
518  $this->loadEditability();
519  }
520 
521  return $this->editable;
522  }
523 
524  /*
525  * editable
526  */
527  public function setEditable($editable)
528  {
529  $this->editable = $editable;
530  }
531 
532  /*
533  * loadEditability
534  */
535  private function loadEditability()
536  {
537  if($this->editable == NULL)
538  {
539  $this->loadViewDefinition(self::EDIT_VIEW);
540  }
541  }
542 
543  /*
544  * toArray
545  */
546  public function toArray()
547  {
548  return (array) $this;
549  }
550 
551  /*
552  * isStandardField
553  */
554  public function isStandardField()
555  {
556  return false;
557  }
558 
562  public function doRead()
563  {
564  global $ilDB;
565 
566  //THEN 1 ELSE 0 END AS has_options FROM il_dcl_field f WHERE id = ".$ilDB->quote($this->getId(),"integer");
567  $query = "SELECT * FROM il_dcl_field WHERE id = ".$ilDB->quote($this->getId(),"integer");
568  $set = $ilDB->query($query);
569  $rec = $ilDB->fetchAssoc($set);
570 
571  $this->setTableId($rec["table_id"]);
572  $this->setTitle($rec["title"]);
573  $this->setDescription($rec["description"]);
574  $this->setDatatypeId($rec["datatype_id"]);
575  $this->setRequired($rec["required"]);
576  $this->setUnique($rec["is_unique"]);
577  $this->setLocked($rec["is_locked"]);
578  $this->loadProperties();
579  }
580 
581  /*
582  * buildFromDBRecord
583  */
584  public function buildFromDBRecord($rec)
585  {
586  $this->setId($rec["id"]);
587  $this->setTableId($rec["table_id"]);
588  $this->setTitle($rec["title"]);
589  $this->setDescription($rec["description"]);
590  $this->setDatatypeId($rec["datatype_id"]);
591  $this->setRequired($rec["required"]);
592  $this->setUnique($rec["is_unique"]);
593  $this->setLocked($rec["is_locked"]);
594  }
595 
599  public function doCreate()
600  {
601  global $ilDB;
602  $this->getLocked() == NULL?$this->setLocked(false):true;
603 
605  throw new ilException("The field does not have a related table!");
606 
607  $id = $ilDB->nextId("il_dcl_field");
608  $this->setId($id);
609  $query = "INSERT INTO il_dcl_field (".
610  "id".
611  ", table_id".
612  ", datatype_id".
613  ", title".
614  ", description".
615  ", required".
616  ", is_unique".
617  ", is_locked".
618  " ) VALUES (".
619  $ilDB->quote($this->getId(), "integer")
620  .",".$ilDB->quote($this->getTableId(), "integer")
621  .",".$ilDB->quote($this->getDatatypeId(), "integer")
622  .",".$ilDB->quote($this->getTitle(), "text")
623  .",".$ilDB->quote($this->getDescription(), "text")
624  .",".$ilDB->quote($this->getRequired(), "integer")
625  .",".$ilDB->quote($this->isUnique(), "integer")
626  .",".$ilDB->quote($this->getLocked()?1:0, "integer")
627  .")";
628  $ilDB->manipulate($query);
629 
630  $this->updateVisibility();
631  $this->updateFilterability();
632  $this->updateEditability();
633  }
634 
638  public function doUpdate()
639  {
640  global $ilDB;
641 
642  $ilDB->update("il_dcl_field", array(
643  "table_id" => array("integer", $this->getTableId()),
644  "datatype_id" => array("text", $this->getDatatypeId()),
645  "title" => array("text", $this->getTitle()),
646  "description" => array("text", $this->getDescription()),
647  "required" => array("integer",$this->getRequired()),
648  "is_unique" => array("integer",$this->isUnique()),
649  "is_locked" => array("integer",$this->getLocked()?1:0)
650  ), array(
651  "id" => array("integer", $this->getId())
652  ));
653  $this->updateVisibility();
654  $this->updateFilterability();
655  $this->updateEditability();
656  $this->updateProperties();
657  }
658 
662  protected function updateProperties() {
663  global $ilDB;
664  foreach ($this->property as $key => $value) {
665  $ilDB->update('il_dcl_field_prop', array(
666  'value' => array('integer', $value),
667  ), array(
668  'field_id' => array('integer', $this->getId()),
669  'datatype_prop_id' => array('integer', $key),
670  ));
671  }
672  }
673 
674  /*
675  * getFilterable
676  */
677  /*public function getFilterable()
678  {
679 
680  }*/
681 
682  /*
683  * updateVisibility
684  */
685  protected function updateVisibility()
686  {
687  $this->updateViewDefinition(self::VIEW_VIEW);
688  }
689 
690  /*
691  * updateFilterability
692  */
693  protected function updateFilterability()
694  {
695  $this->updateViewDefinition(self::FILTER_VIEW);
696  }
697 
698  protected function updateEditability(){
699  $this->updateViewDefinition(self::EDIT_VIEW);
700  }
701 
706  private function updateViewDefinition($view)
707  {
708  global $ilDB;
709 
710  switch($view)
711  {
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  break;
720  case self::FILTER_VIEW:
721  $set = $this->isFilterable();
722  if($set && $this->order === NULL)
723  $this->order = 0;
724  break;
725  }
726 
727  if(!$set)
728  $set = 0;
729  else
730  $set = 1;
731 
732  if(!isset($this->order))
733  $this->order = 0;
734 
735  $query = "DELETE def FROM il_dcl_viewdefinition def INNER JOIN il_dcl_view ON il_dcl_view.type = "
736  .$ilDB->quote($view, "integer")." AND il_dcl_view.table_id = "
737  .$ilDB->quote($this->getTableId(), "integer")." WHERE def.view_id = il_dcl_view.id AND def.field = "
738  .$ilDB->quote($this->getId(), "text");
739 
740  $ilDB->manipulate($query);
741 
742  $query = "INSERT INTO il_dcl_viewdefinition (view_id, field, field_order, is_set) SELECT id, "
743  .$ilDB->quote($this->getId(), "text").", "
744  .$ilDB->quote($this->getOrder(), "integer").", "
745  .$ilDB->quote($set, "integer")." FROM il_dcl_view WHERE il_dcl_view.type = "
746  .$ilDB->quote($view, "integer")." AND il_dcl_view.table_id = "
747  .$ilDB->quote($this->getTableId(), "integer");
748 
749  $ilDB->manipulate($query);
750  }
751 
752 
753  /*
754  * deleteViewDefinition
755  */
756  private function deleteViewDefinition($view)
757  {
758  global $ilDB;
759 
760  $query = "DELETE def FROM il_dcl_viewdefinition def INNER JOIN il_dcl_view ON il_dcl_view.type = "
761  .$ilDB->quote($view, "integer")." AND il_dcl_view.table_id = "
762  .$ilDB->quote($this->getTableId(), "integer")." WHERE def.view_id = il_dcl_view.id AND def.field = "
763  .$ilDB->quote($this->getId(), "text");
764 
765  $ilDB->manipulate($query);
766  }
767 
768  /*
769  * doDelete
770  */
771  public function doDelete()
772  {
773  global $ilDB;
774 
775  // delete viewdefinitions.
776  $this->deleteViewDefinition(self::VIEW_VIEW);
777  $this->deleteViewDefinition(self::FILTER_VIEW);
778  $this->deleteViewDefinition(self::EDIT_VIEW);
779 
780  $query = "DELETE FROM il_dcl_field_prop WHERE field_id = ".$ilDB->quote($this->getId(), "text");
781  $ilDB->manipulate($query);
782 
783  $query = "DELETE FROM il_dcl_field WHERE id = ".$ilDB->quote($this->getId(), "text");
784  $ilDB->manipulate($query);
785 
786  }
787 
788  /*
789  * getOrder
790  */
791  public function getOrder()
792  {
793  if(!isset($this->order))
794  {
795  $this->loadVisibility();
796  }
797 
798  return !$this->order?0:$this->order;
799  }
800 
801  /*
802  * setOrder
803  */
804  public function setOrder($order)
805  {
806  $this->order = $order;
807  }
808 
809  /*
810  * getFieldRef
811  */
812  public function getFieldRef()
813  {
814  $props = $this->getPropertyvalues();
816 
817  return $props[$id];
818  }
819 
825  private function loadProperties()
826  {
827  global $ilDB;
828 
829  $query = "SELECT datatype_prop_id,
830  title,
831  value
832  FROM il_dcl_field_prop fp
833  LEFT JOIN il_dcl_datatype_prop AS p ON p.id = fp.datatype_prop_id
834  WHERE fp.field_id = ".$ilDB->quote($this->getId(),"integer");
835 
836  $set = $ilDB->query($query);
837 
838  while($rec = $ilDB->fetchAssoc($set))
839  {
840  $this->setPropertyvalue($rec['value'],$rec['datatype_prop_id']);
841  }
842  }
843 
849  public function getProperties()
850  {
851  if($this->property == null)
852  $this->loadProperties();
853 
854  return $this->property;
855  }
856 
857  public function setProperties($data){
858  $this->property = $data;
859  }
860 
864  public function setLocked($locked)
865  {
866  $this->locked = $locked;
867  }
868 
872  public function getLocked()
873  {
874  return $this->locked;
875  }
876 
877  /*
878  * checkValidity
879  */
880  public function checkValidity($value, $record_id = null)
881  {
882  //Don't check empty values
883  if($value == NULL)
884  {
885  return true;
886  }
887 
888 
890  {
892  }
893 
894  $properties = $this->getPropertyvalues();
898 
900  {
901  $regex = $properties[$regex_id];
902  if(substr($regex,0,1) != "/")
903  $regex = "/".$regex;
904  if(substr($regex, -1) != "/")
905  $regex .= "/";
906  if($properties[$length] < strlen($value) && is_numeric($properties[$length]))
908  if(!($properties[$regex_id] == NULL || @preg_match($regex, $value)))
910  //email or url
911  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)))
913  }
914 
915 
916  if($this->getDatatypeId() == ilDataCollectionDatatype::INPUTFORMAT_MOB AND $value['name'])
917  {
918  $arrMimeType = explode('/', ilObjMediaObject::getMimeType($value['name']));
919 
920  if($arrMimeType[0] != "image") {
922  }
923  }
924 
925 
926  if($this->isUnique() && $record_id === null)
927  {
929 
930  foreach($table->getRecords() as $record)
931  {
932  if($record->getRecordFieldValue($this->getId()) == $value && ($record->getId() != $record_id || $record_id == 0))
934 
935  //for text it has to be case insensitive.
937  {
938  if(strtolower($record->getRecordFieldValue($this->getId())) == strtolower($value) && ($record->getId() != $record_id || $record_id == 0))
939  {
941  }
942 
943  }
944 
946  {
947  $datestring = $value["date"]." ".$value["time"];//["y"]."-".$value["date"]['m']."-".$value["date"]['d']." 00:00:00";
948 
949  if($record->getRecordFieldValue($this->getId()) == $datestring && ($record->getId() != $record_id || $record_id == 0))
950  {
952  }
953  }
954  }
955  }
956 
957  return true;
958  }
959 
960  /*
961  * cloneStructure
962  */
963  public function cloneStructure($original_id)
964  {
965  $original = ilDataCollectionCache::getFieldCache($original_id);
966  $this->setTitle($original->getTitle());
967  $this->setDatatypeId($original->getDatatypeId());
968  $this->setDescription($original->getDescription());
969  $this->setEditable($original->isEditable());
970  $this->setLocked($original->getLocked());
971  $this->setFilterable($original->isFilterable());
972  $this->setVisible($original->isVisible());
973  $this->setOrder($original->getOrder());
974  $this->setRequired($original->getRequired());
975  $this->setUnique($original->isUnique());
976  $this->doCreate();
977  $this->cloneProperties($original);
978  }
979 
983  public function cloneProperties($originalField){
984  $orgProps = $originalField->getProperties();
985  if($orgProps == NULL)
986  return;
987  foreach($orgProps as $id => $value){
988  $fieldprop_obj = new ilDataCollectionFieldProp();
989  $fieldprop_obj->setDatatypePropertyId($id);
990  $fieldprop_obj->setFieldId($this->getId());
991  // If reference field, we must reset the referenced field, otherwise it will point to the old ID
993  $value = null;
994  }
995  $fieldprop_obj->setValue($value);
996  $fieldprop_obj->doCreate();
997  }
998  }
999 }
1000 
1001 ?>