ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ActiveRecord.php
Go to the documentation of this file.
1<?php
2require_once('class.ActiveRecordList.php');
3require_once('Connector/class.arConnector.php');
4require_once('Connector/class.arConnectorDB.php');
5require_once('Cache/class.arObjectCache.php');
6require_once('Fields/class.arFieldList.php');
7require_once('Cache/class.arFieldCache.php');
8require_once('Storage/int.arStorageInterface.php');
9require_once('Factory/class.arFactory.php');
10require_once('Cache/class.arCalledClassCache.php');
11require_once('Connector/class.arConnectorMap.php');
12
24abstract class ActiveRecord implements arStorageInterface
25{
26 const ACTIVE_RECORD_VERSION = '2.0.7';
30 protected $ar_safe_read = true;
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 {
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 {
137 }
138
139
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 }
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());
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) {
547 throw new arException(arException::RECORD_NOT_FOUND, $this->getPrimaryFieldValue());
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 }
558 $this->afterObjectLoad();
559 }
560 }
561
562
563 public function update()
564 {
565 $this->getArConnector()->update($this);
567 }
568
569
570 public function delete()
571 {
572 $this->getArConnector()->delete($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}
Class ActiveRecordList.
Class ActiveRecord.
static renameDBField($old_name, $new_name)
static _toCamelCase($str, $capitalise_first_char=false)
__getConvertedDateFieldsAsArray($format=null)
setPrimaryFieldValue($value)
serializeToCSV($field)
This method is called for every field of your instance if you use __asCsv.
static where($where, $operator=null)
static returnDbTableName()
fixDateField($field_name, $value)
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.
static connector(arConnector $connector)
sleep($field_name)
__call($name, $arguments)
static findOrGetInstance($primary_key, array $add_constructor_args=array())
static fieldExists($field_name)
buildFromArray(array $array)
static getArray($key=null, $values=null)
static limit($start, $end)
static fromCamelCase($str)
setConnectorContainerName($connector_container_name)
static dateFormat($date_format='d.m.Y - H:i:s')
static removeDBField($field_name)
static leftjoin($tablename, $on_this, $on_external, $fields=array(' *'), $operator='=', $both_external=false)
wakeUp($field_name, $field_value)
static innerjoinAR(ActiveRecord $ar, $on_this, $on_external, $fields=array(' *'), $operator='=', $both_external=false)
static raw($set_raw=true)
static getFirstFromLastQuery()
static additionalParams(array $additional_params)
static orderBy($orderBy, $orderDirection='ASC')
static innerjoin($tablename, $on_this, $on_external, $fields=array(' *'), $operator='=', $both_external=false)
__construct($primary_key=0, arConnector $connector=null)
__asCsv($separator=';', $header=false)
An exception for terminatinating execution or to throw for unit testing.
static get(ActiveRecord $ar)
Class arConnector.
Class arException.
const COPY_DESTINATION_ID_EXISTS
const UNKNONWN_EXCEPTION
static getPrimaryFieldName(ActiveRecord $ar)
static get(ActiveRecord $ar)
static isCached($class, $id)
static store(ActiveRecord $object)
static purge(ActiveRecord $object)
static get($class, $id)
$c
Definition: cli.php:37
Class arStorageInterface.
if($format !==null) $name
Definition: metadata.php:230
$format
Definition: metadata.php:218
get(string $class_name)
$data
Definition: storeScorm.php:23