ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ActiveRecord.php
Go to the documentation of this file.
1 <?php
2 require_once('class.ActiveRecordList.php');
3 require_once('Connector/class.arConnector.php');
4 require_once('Connector/class.arConnectorDB.php');
5 require_once('Cache/class.arObjectCache.php');
6 require_once('Fields/class.arFieldList.php');
7 require_once('Cache/class.arFieldCache.php');
8 require_once('Storage/int.arStorageInterface.php');
9 require_once('Factory/class.arFactory.php');
10 require_once('Cache/class.arCalledClassCache.php');
11 require_once('Connector/class.arConnectorMap.php');
12 
24 abstract class ActiveRecord implements arStorageInterface
25 {
26  const ACTIVE_RECORD_VERSION = '2.0.7';
30  protected $ar_safe_read = true;
34  protected $connector_container_name = '';
35 
36 
40  public function getArConnector()
41  {
42  return arConnectorMap::get($this);
43  }
44 
45 
49  public function getArFieldList()
50  {
51  return arFieldCache::get($this);
52  }
53 
54 
59  public static function returnDbTableName()
60  {
61  throw new arException(arException::UNKNONWN_EXCEPTION, 'Implement getConnectorContainerName in your child-class');
62  }
63 
64 
69  public function getConnectorContainerName()
70  {
71  // WILL BE ABSTRACT TO REPLACE returnDbTableName() IN NEXT VERSION
72  if ($this->connector_container_name) {
74  } else {
75  $ar = self::getCalledClass();
76 
77  return $ar::returnDbTableName();
78  }
79  }
80 
81 
86  {
87  $this->connector_container_name = $connector_container_name;
88  }
89 
90 
94  public function getPrimaryFieldValue()
95  {
96  $primary_fieldname = arFieldCache::getPrimaryFieldName($this);
97 
98  return $this->{$primary_fieldname};
99  }
100 
101 
105  public function setPrimaryFieldValue($value)
106  {
107  $primary_fieldname = arFieldCache::getPrimaryFieldName($this);
108 
109  $this->{$primary_fieldname} = $value;
110  }
111 
112 
117  public function __construct($primary_key = 0, arConnector $connector = null)
118  {
119  // if ($connector == null) {
120  // $connector = new arConnectorDB();
121  // }
122  // arConnectorMap::register($this, $connector);
123 
124  $arFieldList = arFieldCache::get($this);
125 
126  $key = $arFieldList->getPrimaryFieldName();
127  $this->{$key} = $primary_key;
128  if ($primary_key !== 0 and $primary_key !== null and $primary_key !== false) {
129  $this->read();
130  }
131  }
132 
133 
134  public function storeObjectToCache()
135  {
136  arObjectCache::store($this);
137  }
138 
139 
145  public function __getConvertedDateFieldsAsArray($format = null)
146  {
147  $converted_dates = array();
148  foreach ($this->getArFieldList()->getFields() as $field) {
149  if ($field->isDateField()) {
150  $name = $field->getName();
151  $value = $this->{$name};
152  $converted_dates[$name] = array(
153  'unformatted' => $value,
154  'unix' => strtotime($value),
155  );
156  if ($format) {
157  $converted_dates[$name]['formatted'] = date($format, strtotime($value));
158  }
159  }
160  }
161 
162  return $converted_dates;
163  }
164 
165 
172  public function __asCsv($separator = ';', $header = false)
173  {
174  $line = '';
175  if ($header) {
176  $line .= implode($separator, array_keys($this->getArFieldList()->getRawFields()));
177  $line .= "\n";
178  }
179  $array = array();
180  foreach ($this->__asArray() as $field_name => $value) {
181  $serialized = $this->serializeToCSV($field_name);
182  if ($serialized === null) {
183  $array[$field_name] = $this->{$field_name};
184  } else {
185  $array[$field_name] = $serialized;
186  }
187  }
188  $line .= implode($separator, array_values($array));
189 
190  return $line;
191  }
192 
193 
202  protected function serializeToCSV($field)
203  {
204  return null;
205  }
206 
207 
211  public function __asArray()
212  {
213  $return = array();
214  foreach ($this->getArFieldList()->getFields() as $field) {
215  $fieldname = $field->getName();
216  $return[$fieldname] = $this->{$fieldname};
217  }
218 
219  return $return;
220  }
221 
222 
226  public function __asStdClass()
227  {
228  $return = new stdClass();
229  foreach ($this->getArFieldList()->getFields() as $field) {
230  $fieldname = $field->getName();
231  $return->{$fieldname} = $this->{$fieldname};
232  }
233 
234  return $return;
235  }
236 
237 
241  public function __asSerializedObject()
242  {
243  return serialize($this);
244  }
245 
246 
252  public function buildFromArray(array $array)
253  {
254  $class = get_class($this);
255  $primary = $this->getArFieldList()->getPrimaryFieldName();
256  $primary_value = $array[$primary];
257  if ($primary_value and arObjectCache::isCached($class, $primary_value)) {
258  return arObjectCache::get($class, $primary_value);
259  }
260  foreach ($array as $field_name => $value) {
261  $waked = $this->wakeUp($field_name, $value);
262  $this->{$field_name} = ($waked === null) ? $value : $waked;
263  }
264  arObjectCache::store($this);
265  $this->afterObjectLoad();
266 
267  return $this;
268  }
269 
270 
276  public function fixDateField($field_name, $value)
277  {
278  if ($this->getArFieldList()->getFieldByName($field_name)->isDateField()) {
279  return $this->getArConnector()->fixDate($value);
280  }
281 
282  return $value;
283  }
284 
285 
291  public function sleep($field_name)
292  {
293  return null;
294  }
295 
296 
303  public function wakeUp($field_name, $field_value)
304  {
305  return null;
306  }
307 
308 
313  final public function getArrayForDb()
314  {
315  return $this->getArrayForConnector();
316  }
317 
318 
322  final public function getArrayForConnector()
323  {
324  $data = array();
325  foreach ($this->getArFieldList()->getFields() as $field) {
326  $field_name = $field->getName();
327  $sleeped = $this->sleep($field_name);
328  $var = ($sleeped === null) ? ($this->{$field_name}) : $sleeped;
329  $data[$field_name] = array( $field->getFieldType(), $var );
330  }
331 
332  return $data;
333  }
334 
335 
336 
337 
338  //
339  // Collector Modifications
340  //
341 
348  protected static function getCalledClass()
349  {
350  $class = get_called_class();
351 
352  return arCalledClassCache::get($class);
353  }
354 
355 
364  final public static function installDB()
365  {
366  return self::getCalledClass()->installDatabase();
367  }
368 
369 
375  public function installConnector()
376  {
377  return $this->installDatabase();
378  }
379 
380 
387  final public static function renameDBField($old_name, $new_name)
388  {
389  return self::getCalledClass()->getArConnector()->renameField(self::getCalledClass(), $old_name, $new_name);
390  }
391 
392 
396  final public static function tableExists()
397  {
398  return self::getCalledClass()->getArConnector()->checkTableExists(self::getCalledClass());
399  }
400 
401 
407  final public static function fieldExists($field_name)
408  {
409  return self::getCalledClass()->getArConnector()->checkFieldExists(self::getCalledClass(), $field_name);
410  }
411 
412 
418  final public static function removeDBField($field_name)
419  {
420  return self::getCalledClass()->getArConnector()->removeField(self::getCalledClass(), $field_name);
421  }
422 
423 
427  final protected function installDatabase()
428  {
429  if (!$this->tableExists()) {
430  $fields = array();
431  foreach ($this->getArFieldList()->getFields() as $field) {
432  $fields[$field->getName()] = $field->getAttributesForConnector();
433  }
434 
435  return $this->getArConnector()->installDatabase($this, $fields);
436  } else {
437  return $this->getArConnector()->updateDatabase($this);
438  }
439  }
440 
441 
445  final public static function updateDB()
446  {
447  if (!self::tableExists()) {
448  self::getCalledClass()->installDatabase();
449 
450  return true;
451  }
452 
453  return self::getCalledClass()->getArConnector()->updateDatabase(self::getCalledClass());
454  }
455 
456 
460  final public static function resetDB()
461  {
462  return self::getCalledClass()->getArConnector()->resetDatabase(self::getCalledClass());
463  }
464 
465 
469  final public static function truncateDB()
470  {
471  return self::getCalledClass()->getArConnector()->truncateDatabase(self::getCalledClass());
472  }
473 
474 
478  final public static function flushDB()
479  {
480  return self::truncateDB();
481  }
482 
483  //
484  // CRUD
485  //
486  public function store()
487  {
488  $primary_fieldname = arFieldCache::getPrimaryFieldName($this);
489  $primary_value = $this->getPrimaryFieldValue();
490 
491  if (!self::where(array( $primary_fieldname => $primary_value ))->hasSets()) {
492  $this->create();
493  } else {
494  $this->update();
495  }
496  }
497 
498 
499  public function save()
500  {
501  $this->store();
502  }
503 
504 
505  public function create()
506  {
507  if ($this->getArFieldList()->getPrimaryField()->getSequence()) {
508  $primary_fieldname = arFieldCache::getPrimaryFieldName($this);
509  $this->{$primary_fieldname} = $this->getArConnector()->nextID($this);
510  }
511 
512  $this->getArConnector()->create($this, $this->getArrayForConnector());
513  arObjectCache::store($this);
514  }
515 
516 
523  public function copy($new_id = 0)
524  {
525  if (self::where(array( $this->getArFieldList()->getPrimaryFieldName() => $new_id ))->hasSets()) {
527  }
528  $new_obj = clone($this);
529  $new_obj->setPrimaryFieldValue($new_id);
530 
531  return $new_obj;
532  }
533 
534 
535  public function afterObjectLoad()
536  {
537  }
538 
539 
543  public function read()
544  {
545  $records = $this->getArConnector()->read($this);
546  if (is_array($records) && count($records) === 0 && $this->ar_safe_read === true) {
548  } elseif (is_array($records) && count($records) === 0 && $this->ar_safe_read === false) {
549  $this->is_new = true;
550  }
551  $records = is_array($records) ? $records : array();
552  foreach ($records as $rec) {
553  foreach ($this->getArrayForConnector() as $k => $v) {
554  $waked = $this->wakeUp($k, $rec->{$k});
555  $this->{$k} = ($waked === null) ? $rec->{$k} : $waked;
556  }
557  arObjectCache::store($this);
558  $this->afterObjectLoad();
559  }
560  }
561 
562 
563  public function update()
564  {
565  $this->getArConnector()->update($this);
566  arObjectCache::store($this);
567  }
568 
569 
570  public function delete()
571  {
572  $this->getArConnector()->delete($this);
573  arObjectCache::purge($this);
574  }
575 
576 
577 
578  //
579  // Collection
580  //
584  public static function preloadObjects()
585  {
586  return self::get();
587  }
588 
589 
595  public static function additionalParams(array $additional_params)
596  {
597  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
598  $srModelObjectList->additionalParams($additional_params);
599 
600  return $srModelObjectList;
601  }
602 
603 
610  public static function find($primary_key, array $add_constructor_args = array())
611  {
615  try {
616  $class_name = get_called_class();
617  if (!arObjectCache::isCached($class_name, $primary_key)) {
618  $obj = arFactory::getInstance($class_name, $primary_key, $add_constructor_args);
619  $obj->storeObjectToCache();
620 
621  return $obj;
622  }
623  } catch (arException $e) {
624  return null;
625  }
626 
627  try {
628  $obj = arObjectCache::get($class_name, $primary_key);
629  } catch (arException $e) {
630  return null;
631  }
632 
633  return $obj;
634  }
635 
636 
645  public static function findOrFail($primary_key, array $add_constructor_args = array())
646  {
647  $obj = self::find($primary_key, $add_constructor_args);
648  if (is_null($obj)) {
650  }
651 
652  return $obj;
653  }
654 
655 
664  public static function findOrGetInstance($primary_key, array $add_constructor_args = array())
665  {
666  $obj = self::find($primary_key, $add_constructor_args);
667  if ($obj !== null) {
668  return $obj;
669  } else {
670  $class_name = get_called_class();
671  $obj = arFactory::getInstance($class_name, 0, $add_constructor_args);
672  $obj->setPrimaryFieldValue($primary_key);
673  $obj->is_new = true;
674  $obj->storeObjectToCache();
675 
676  return $obj;
677  }
678  }
679 
680 
687  public static function where($where, $operator = null)
688  {
689  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
690  $srModelObjectList->where($where, $operator);
691 
692  return $srModelObjectList;
693  }
694 
695 
705  public static function innerjoinAR(ActiveRecord $ar, $on_this, $on_external, $fields = array( '*' ), $operator = '=', $both_external = false)
706  {
707  return self::innerjoin($ar->getConnectorContainerName(), $on_this, $on_external, $fields, $operator, $both_external);
708  }
709 
710 
720  public static function innerjoin($tablename, $on_this, $on_external, $fields = array( '*' ), $operator = '=', $both_external = false)
721  {
722  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
723 
724  return $srModelObjectList->innerjoin($tablename, $on_this, $on_external, $fields, $operator, $both_external);
725  }
726 
727 
737  public static function leftjoin($tablename, $on_this, $on_external, $fields = array( '*' ), $operator = '=', $both_external = false)
738  {
739  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
740 
741  return $srModelObjectList->leftjoin($tablename, $on_this, $on_external, $fields, $operator, $both_external);
742  }
743 
744 
751  public static function orderBy($orderBy, $orderDirection = 'ASC')
752  {
753  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
754  $srModelObjectList->orderBy($orderBy, $orderDirection);
755 
756  return $srModelObjectList;
757  }
758 
759 
765  public static function dateFormat($date_format = 'd.m.Y - H:i:s')
766  {
767  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
768  $srModelObjectList->dateFormat($date_format);
769 
770  return $srModelObjectList;
771  }
772 
773 
780  public static function limit($start, $end)
781  {
782  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
783  $srModelObjectList->limit($start, $end);
784 
785  return $srModelObjectList;
786  }
787 
788 
792  public static function affectedRows()
793  {
794  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
795 
796  return $srModelObjectList->affectedRows();
797  }
798 
799 
803  public static function count()
804  {
805  return self::affectedRows();
806  }
807 
808 
812  public static function get()
813  {
814  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
815 
816  return $srModelObjectList->get();
817  }
818 
819 
823  public static function debug()
824  {
825  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
826 
827  return $srModelObjectList->debug();
828  }
829 
830 
834  public static function first()
835  {
836  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
837 
838  return $srModelObjectList->first();
839  }
840 
841 
845  public static function getCollection()
846  {
847  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
848 
849  return $srModelObjectList;
850  }
851 
852 
856  public static function last()
857  {
858  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
859 
860  return $srModelObjectList->last();
861  }
862 
863 
868  public static function getFirstFromLastQuery()
869  {
870  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
871 
872  return $srModelObjectList->getFirstFromLastQuery();
873  }
874 
875 
881  public static function connector(arConnector $connector)
882  {
883  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
884 
885  return $srModelObjectList->connector($connector);
886  }
887 
888 
894  public static function raw($set_raw = true)
895  {
896  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
897 
898  return $srModelObjectList->raw($set_raw);
899  }
900 
901 
908  public static function getArray($key = null, $values = null)
909  {
910  $srModelObjectList = new ActiveRecordList(self::getCalledClass());
911 
912  return $srModelObjectList->getArray($key, $values);
913  }
914 
915  //
916  // Magic Methods & Helpers
917  //
924  public function __call($name, $arguments)
925  {
926  // Getter
927  if (preg_match("/get([a-zA-Z]*)/u", $name, $matches) and count($arguments) == 0) {
928  return $this->{self::fromCamelCase($matches[1])};
929  }
930  // Setter
931  if (preg_match("/set([a-zA-Z]*)/u", $name, $matches) and count($arguments) == 1) {
932  $this->{self::fromCamelCase($matches[1])} = $arguments[0];
933  }
934  if (preg_match("/findBy([a-zA-Z]*)/u", $name, $matches) and count($arguments) == 1) {
935  return self::where(array( self::fromCamelCase($matches[1]) => $arguments[0] ))->getFirst();
936  }
937  }
938 
939 
946  public static function _toCamelCase($str, $capitalise_first_char = false)
947  {
948  if ($capitalise_first_char) {
949  $str[0] = strtoupper($str[0]);
950  }
951 
952  return preg_replace_callback('/_([a-z])/', function ($c) {
953  return strtoupper($c[1]);
954  }, $str);
955  }
956 
957 
963  protected static function fromCamelCase($str)
964  {
965  $str[0] = strtolower($str[0]);
966 
967  return preg_replace_callback('/([A-Z])/', function ($c) {
968  return "_" . strtolower($c[1]);
969  }, $str);
970  }
971 }
static removeDBField($field_name)
static limit($start, $end)
static getFirstFromLastQuery()
buildFromArray(array $array)
Class arStorageInterface.
static getPrimaryFieldName(ActiveRecord $ar)
const UNKNONWN_EXCEPTION
static leftjoin($tablename, $on_this, $on_external, $fields=array(' *'), $operator='=', $both_external=false)
$format
Definition: metadata.php:141
static renameDBField($old_name, $new_name)
static connector(arConnector $connector)
static innerjoinAR(ActiveRecord $ar, $on_this, $on_external, $fields=array(' *'), $operator='=', $both_external=false)
Class ActiveRecord.
static innerjoin($tablename, $on_this, $on_external, $fields=array(' *'), $operator='=', $both_external=false)
static fieldExists($field_name)
Class ActiveRecordList.
static purge(ActiveRecord $object)
sleep($field_name)
static returnDbTableName()
__call($name, $arguments)
Class arConnector.
static fromCamelCase($str)
__construct($primary_key=0, arConnector $connector=null)
$records
Definition: simple_test.php:22
static dateFormat($date_format='d.m.Y - H:i:s')
static where($where, $operator=null)
static raw($set_raw=true)
const COPY_DESTINATION_ID_EXISTS
$start
Definition: bench.php:8
setPrimaryFieldValue($value)
__getConvertedDateFieldsAsArray($format=null)
__asCsv($separator=';', $header=false)
static findOrFail($primary_key, array $add_constructor_args=array())
Tries to find the object and throws an Exception if object is not found, instead of returning null...
$values
static store(ActiveRecord $object)
get(string $class_name)
static get($class, $id)
wakeUp($field_name, $field_value)
static isCached($class, $id)
Class arException.
fixDateField($field_name, $value)
static findOrGetInstance($primary_key, array $add_constructor_args=array())
static getArray($key=null, $values=null)
static get(ActiveRecord $ar)
setConnectorContainerName($connector_container_name)
serializeToCSV($field)
This method is called for every field of your instance if you use __asCsv.
static get(ActiveRecord $ar)
static orderBy($orderBy, $orderDirection='ASC')
$key
Definition: croninfo.php:18
static additionalParams(array $additional_params)
$data
Definition: bench.php:6
static _toCamelCase($str, $capitalise_first_char=false)