1: <?php
2:
3: namespace Alpha\Model;
4:
5: use Alpha\Model\Type\Integer;
6: use Alpha\Model\Type\Timestamp;
7: use Alpha\Model\Type\Enum;
8: use Alpha\Model\Type\Relation;
9: use Alpha\Util\Config\ConfigProvider;
10: use Alpha\Util\Logging\Logger;
11: use Alpha\Util\Cache\CacheProviderFactory;
12: use Alpha\Util\Http\Session\SessionProviderFactory;
13: use Alpha\Exception\AlphaException;
14: use Alpha\Exception\FailedSaveException;
15: use Alpha\Exception\FailedDeleteException;
16: use Alpha\Exception\ValidationException;
17: use Alpha\Exception\RecordNotFoundException;
18: use Alpha\Exception\IllegalArguementException;
19: use Alpha\Exception\NotImplementedException;
20: use ReflectionClass;
21: use ReflectionProperty;
22:
23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64:
65: abstract class ActiveRecord
66: {
67: 68: 69: 70: 71: 72: 73:
74: protected $OID;
75:
76: 77: 78: 79: 80: 81: 82:
83: protected $lastQuery;
84:
85: 86: 87: 88: 89: 90: 91:
92: protected $version_num;
93:
94: 95: 96: 97: 98: 99: 100:
101: protected $created_ts;
102:
103: 104: 105: 106: 107: 108: 109:
110: protected $created_by;
111:
112: 113: 114: 115: 116: 117: 118:
119: protected $updated_ts;
120:
121: 122: 123: 124: 125: 126: 127:
128: protected $updated_by;
129:
130: 131: 132: 133: 134: 135: 136:
137: protected $defaultAttributes = array('OID', 'lastQuery', 'version_num', 'dataLabels', 'created_ts', 'created_by', 'updated_ts', 'updated_by', 'defaultAttributes', 'transientAttributes', 'uniqueAttributes', 'TABLE_NAME', 'logger');
138:
139: 140: 141: 142: 143: 144: 145:
146: protected $transientAttributes = array('lastQuery', 'dataLabels', 'defaultAttributes', 'transientAttributes', 'uniqueAttributes', 'TABLE_NAME', 'logger');
147:
148: 149: 150: 151: 152: 153: 154:
155: protected $uniqueAttributes = array();
156:
157: 158: 159: 160: 161: 162: 163:
164: protected $dataLabels = array();
165:
166: 167: 168: 169: 170: 171: 172:
173: private static $logger = null;
174:
175: 176: 177: 178: 179: 180: 181:
182: private $maintainHistory = false;
183:
184: 185: 186: 187: 188:
189: public function __construct()
190: {
191: self::$logger = new Logger('ActiveRecord');
192: self::$logger->debug('>>__construct()');
193:
194: $config = ConfigProvider::getInstance();
195: $sessionProvider = $config->get('session.provider.name');
196: $session = SessionProviderFactory::getInstance($sessionProvider);
197:
198: set_exception_handler('Alpha\Util\ErrorHandlers::catchException');
199: set_error_handler('Alpha\Util\ErrorHandlers::catchError', $config->get('php.error.log.level'));
200:
201: $this->version_num = new Integer(0);
202: $this->created_ts = new Timestamp(date('Y-m-d H:i:s'));
203: $person_ID = ($session->get('currentUser') != null ? $session->get('currentUser')->getOID() : 0);
204: $this->created_by = new Integer($person_ID);
205: $this->updated_ts = new Timestamp(date('Y-m-d H:i:s'));
206: $this->updated_by = new Integer($person_ID);
207:
208: self::$logger->debug('<<__construct');
209: }
210:
211: 212: 213: 214: 215:
216: public static function disconnect()
217: {
218: $config = ConfigProvider::getInstance();
219:
220: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'));
221: $provider->disconnect();
222: }
223:
224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234:
235: public function query($sqlQuery)
236: {
237: self::$logger->debug('>>query(sqlQuery=['.$sqlQuery.'])');
238:
239: $config = ConfigProvider::getInstance();
240:
241: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
242: $result = $provider->query($sqlQuery);
243:
244: self::$logger->debug('<<query ['.print_r($result, true).']');
245:
246: return $result;
247: }
248:
249: 250: 251: 252: 253: 254: 255: 256: 257: 258:
259: public function load($OID, $version = 0)
260: {
261: self::$logger->debug('>>load(OID=['.$OID.'], version=['.$version.'])');
262:
263: if (method_exists($this, 'before_load_callback')) {
264: $this->before_load_callback();
265: }
266:
267: $config = ConfigProvider::getInstance();
268:
269: $this->OID = $OID;
270:
271: if ($config->get('cache.provider.name') != '' && $this->loadFromCache()) {
272:
273: } else {
274: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
275: $provider->load($OID, $version);
276:
277: if ($config->get('cache.provider.name') != '') {
278: $this->addToCache();
279: }
280: }
281:
282: $this->setEnumOptions();
283:
284: if (method_exists($this, 'after_load_callback')) {
285: $this->after_load_callback();
286: }
287:
288: self::$logger->debug('<<load');
289: }
290:
291: 292: 293: 294: 295: 296: 297: 298: 299: 300: 301:
302: public function loadAllOldVersions($OID)
303: {
304: self::$logger->debug('>>loadAllOldVersions(OID=['.$OID.'])');
305:
306: $config = ConfigProvider::getInstance();
307:
308: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
309: $objects = $provider->loadAllOldVersions($OID);
310:
311: self::$logger->debug('<<loadAllOldVersions['.count($objects).']');
312:
313: return $objects;
314: }
315:
316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327:
328: public function loadByAttribute($attribute, $value, $ignoreClassType = false, $loadAttributes = array())
329: {
330: self::$logger->debug('>>loadByAttribute(attribute=['.$attribute.'], value=['.$value.'], ignoreClassType=['.$ignoreClassType.'],
331: loadAttributes=['.var_export($loadAttributes, true).'])');
332:
333: if (method_exists($this, 'before_loadByAttribute_callback')) {
334: $this->before_loadByAttribute_callback();
335: }
336:
337: $config = ConfigProvider::getInstance();
338:
339: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
340: $provider->loadByAttribute($attribute, $value, $ignoreClassType, $loadAttributes);
341:
342: $this->setEnumOptions();
343:
344: if ($config->get('cache.provider.name') != '' && count($loadAttributes) == 0) {
345: $this->addToCache();
346: }
347:
348: if (method_exists($this, 'after_loadByAttribute_callback')) {
349: $this->after_loadByAttribute_callback();
350: }
351:
352: self::$logger->debug('<<loadByAttribute');
353: }
354:
355: 356: 357: 358: 359: 360: 361: 362: 363: 364: 365: 366: 367: 368: 369:
370: public function loadAll($start = 0, $limit = 0, $orderBy = 'OID', $order = 'ASC', $ignoreClassType = false)
371: {
372: self::$logger->debug('>>loadAll(start=['.$start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.']');
373:
374: if (method_exists($this, 'before_loadAll_callback')) {
375: $this->before_loadAll_callback();
376: }
377:
378: $config = ConfigProvider::getInstance();
379:
380: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
381: $objects = $provider->loadAll($start, $limit, $orderBy, $order, $ignoreClassType);
382:
383: if (method_exists($this, 'after_loadAll_callback')) {
384: $this->after_loadAll_callback();
385: }
386:
387: self::$logger->debug('<<loadAll ['.count($objects).']');
388:
389: return $objects;
390: }
391:
392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406: 407: 408: 409: 410:
411: public function loadAllByAttribute($attribute, $value, $start = 0, $limit = 0, $orderBy = 'OID', $order = 'ASC', $ignoreClassType = false, $constructorArgs = array())
412: {
413: self::$logger->debug('>>loadAllByAttribute(attribute=['.$attribute.'], value=['.$value.'], start=['.$start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.'], constructorArgs=['.print_r($constructorArgs, true).']');
414:
415: if (method_exists($this, 'before_loadAllByAttribute_callback')) {
416: $this->before_loadAllByAttribute_callback();
417: }
418:
419: $config = ConfigProvider::getInstance();
420:
421: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
422: $objects = $provider->loadAllByAttribute($attribute, $value, $start, $limit, $orderBy, $order, $ignoreClassType);
423:
424: if (method_exists($this, 'after_loadAllByAttribute_callback')) {
425: $this->after_loadAllByAttribute_callback();
426: }
427:
428: self::$logger->debug('<<loadAllByAttribute ['.count($objects).']');
429:
430: return $objects;
431: }
432:
433: 434: 435: 436: 437: 438: 439: 440: 441: 442: 443: 444: 445: 446: 447: 448: 449: 450:
451: public function loadAllByAttributes($attributes = array(), $values = array(), $start = 0, $limit = 0, $orderBy = 'OID', $order = 'ASC', $ignoreClassType = false)
452: {
453: self::$logger->debug('>>loadAllByAttributes(attributes=['.var_export($attributes, true).'], values=['.var_export($values, true).'], start=['.
454: $start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.']');
455:
456: if (method_exists($this, 'before_loadAllByAttributes_callback')) {
457: $this->before_loadAllByAttributes_callback();
458: }
459:
460: $config = ConfigProvider::getInstance();
461:
462: if (!is_array($attributes) || !is_array($values)) {
463: throw new IllegalArguementException('Illegal arrays attributes=['.var_export($attributes, true).'] and values=['.var_export($values, true).
464: '] provided to loadAllByAttributes');
465: }
466:
467: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
468: $objects = $provider->loadAllByAttributes($attributes, $values, $start, $limit, $orderBy, $order, $ignoreClassType);
469:
470: if (method_exists($this, 'after_loadAllByAttributes_callback')) {
471: $this->after_loadAllByAttributes_callback();
472: }
473:
474: self::$logger->debug('<<loadAllByAttributes ['.count($objects).']');
475:
476: return $objects;
477: }
478:
479: 480: 481: 482: 483: 484: 485: 486: 487: 488: 489: 490: 491: 492: 493: 494:
495: public function loadAllByDayUpdated($date, $start = 0, $limit = 0, $orderBy = 'OID', $order = 'ASC', $ignoreClassType = false)
496: {
497: self::$logger->debug('>>loadAllByDayUpdated(date=['.$date.'], start=['.$start.'], limit=['.$limit.'], orderBy=['.$orderBy.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.']');
498:
499: if (method_exists($this, 'before_loadAllByDayUpdated_callback')) {
500: $this->before_loadAllByDayUpdated_callback();
501: }
502:
503: $config = ConfigProvider::getInstance();
504:
505: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
506: $objects = $provider->loadAllByDayUpdated($date, $start, $limit, $orderBy, $order, $ignoreClassType);
507:
508: if (method_exists($this, 'after_loadAllByDayUpdated_callback')) {
509: $this->after_loadAllByDayUpdated_callback();
510: }
511:
512: self::$logger->debug('<<loadAllByDayUpdated ['.count($objects).']');
513:
514: return $objects;
515: }
516:
517: 518: 519: 520: 521: 522: 523: 524: 525: 526: 527: 528: 529: 530: 531: 532:
533: public function loadAllFieldValuesByAttribute($attribute, $value, $returnAttribute, $order = 'ASC', $ignoreClassType = false)
534: {
535: self::$logger->debug('>>loadAllFieldValuesByAttribute(attribute=['.$attribute.'], value=['.$value.'], returnAttribute=['.$returnAttribute.'], order=['.$order.'], ignoreClassType=['.$ignoreClassType.']');
536:
537: $config = ConfigProvider::getInstance();
538:
539: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
540: $values = $provider->loadAllFieldValuesByAttribute($attribute, $value, $returnAttribute, $order, $ignoreClassType);
541:
542: self::$logger->debug('<<loadAllFieldValuesByAttribute ['.count($values).']');
543:
544: return $values;
545: }
546:
547: 548: 549: 550: 551: 552: 553: 554: 555:
556: public function save()
557: {
558: self::$logger->debug('>>save()');
559:
560: if (method_exists($this, 'before_save_callback')) {
561: $this->before_save_callback();
562: }
563:
564: $config = ConfigProvider::getInstance();
565:
566:
567: if (!$this->validate()) {
568: throw new FailedSaveException('Could not save due to a validation error.');
569:
570: return;
571: } else {
572: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
573: $provider->save();
574:
575: if ($config->get('cache.provider.name') != '') {
576: $this->removeFromCache();
577: $this->addToCache();
578: }
579:
580: if (method_exists($this, 'after_save_callback')) {
581: $this->after_save_callback();
582: }
583: }
584: }
585:
586: 587: 588: 589: 590: 591: 592: 593: 594: 595: 596: 597:
598: public function saveAttribute($attribute, $value)
599: {
600: self::$logger->debug('>>saveAttribute(attribute=['.$attribute.'], value=['.$value.'])');
601:
602: if (method_exists($this, 'before_saveAttribute_callback')) {
603: $this->before_saveAttribute_callback();
604: }
605:
606: $config = ConfigProvider::getInstance();
607:
608: if (!isset($this->$attribute)) {
609: throw new IllegalArguementException('Could not perform save, as the attribute ['.$attribute.'] is not present on the class['.get_class($this).']');
610: }
611:
612: if ($this->isTransient()) {
613: throw new FailedSaveException('Cannot perform saveAttribute method on transient BO!');
614: }
615:
616: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
617: $provider->saveAttribute($attribute, $value);
618:
619: if ($config->get('cache.provider.name') != '') {
620: $this->removeFromCache();
621: $this->addToCache();
622: }
623:
624: if (method_exists($this, 'after_saveAttribute_callback')) {
625: $this->after_saveAttribute_callback();
626: }
627:
628: self::$logger->debug('<<saveAttribute');
629: }
630:
631: 632: 633: 634: 635: 636: 637:
638: public function saveHistory()
639: {
640: self::$logger->debug('>>saveHistory()');
641:
642: if (method_exists($this, 'before_saveHistory_callback')) {
643: $this->before_saveHistory_callback();
644: }
645:
646: $config = ConfigProvider::getInstance();
647:
648: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
649: $provider->saveHistory();
650:
651: if (method_exists($this, 'after_saveHistory_callback')) {
652: $this->after_saveHistory_callback();
653: }
654: }
655:
656: 657: 658: 659: 660: 661: 662: 663: 664:
665: protected function validate()
666: {
667: self::$logger->debug('>>validate()');
668:
669: if (method_exists($this, 'before_validate_callback')) {
670: $this->before_validate_callback();
671: }
672:
673: $valid = true;
674:
675:
676: $reflection = new ReflectionClass(get_class($this));
677: $properties = $reflection->getProperties();
678:
679: foreach ($properties as $propObj) {
680: $propName = $propObj->name;
681: if (!in_array($propName, $this->defaultAttributes) && !in_array($propName, $this->transientAttributes)) {
682: $propClass = new ReflectionClass($this->getPropObject($propName));
683: $propClass = $propClass->getShortname();
684: if (mb_strtoupper($propClass) != 'ENUM' &&
685: mb_strtoupper($propClass) != 'DENUM' &&
686: mb_strtoupper($propClass) != 'DENUMITEM' &&
687: mb_strtoupper($propClass) != 'BOOLEAN') {
688: if ($this->getPropObject($propName) != false && !preg_match($this->getPropObject($propName)->getRule(), $this->getPropObject($propName)->getValue())) {
689: throw new ValidationException('Failed to save, validation error is: '.$this->getPropObject($propName)->getHelper());
690: $valid = false;
691: }
692: }
693: }
694: }
695:
696: if (method_exists($this, 'after_validate_callback')) {
697: $this->after_validate_callback();
698: }
699:
700: self::$logger->debug('<<validate ['.$valid.']');
701:
702: return $valid;
703: }
704:
705: 706: 707: 708: 709: 710: 711:
712: public function delete()
713: {
714: self::$logger->debug('>>delete()');
715:
716: if (method_exists($this, 'before_delete_callback')) {
717: $this->before_delete_callback();
718: }
719:
720: $config = ConfigProvider::getInstance();
721:
722:
723: $reflection = new ReflectionClass(get_class($this));
724: $properties = $reflection->getProperties();
725:
726:
727: foreach ($properties as $propObj) {
728: $propName = $propObj->name;
729:
730: if (!$propObj->isPrivate() && isset($this->$propName) && $this->$propName instanceof Relation) {
731: $prop = $this->getPropObject($propName);
732:
733:
734: if ($prop->getRelationType() == 'MANY-TO-MANY') {
735: self::$logger->debug('Deleting MANY-TO-MANY lookup objects...');
736:
737: try {
738:
739: $side = $prop->getSide(get_class($this));
740: } catch (IllegalArguementException $iae) {
741: $side = $prop->getSide(get_parent_class($this));
742: }
743:
744: self::$logger->debug('Side is ['.$side.']'.$this->getOID());
745:
746: $lookUp = $prop->getLookup();
747: self::$logger->debug('Lookup object['.var_export($lookUp, true).']');
748:
749:
750: if ($side == 'left') {
751: $lookUp->deleteAllByAttribute('leftID', $this->getOID());
752: } else {
753: $lookUp->deleteAllByAttribute('rightID', $this->getOID());
754: }
755: self::$logger->debug('...done deleting!');
756: }
757:
758:
759: if ($prop->getRelationType() == 'ONE-TO-MANY' && !$prop->getRelatedClass() == 'Alpha\Model\Tag') {
760: $relatedObjects = $prop->getRelatedObjects();
761:
762: foreach ($relatedObjects as $object) {
763: $object->set($prop->getRelatedClassField(), null);
764: $object->save();
765: }
766: }
767:
768:
769: if ($prop->getRelationType() == 'ONE-TO-MANY' && $prop->getRelatedClass() == 'Alpha\Model\Tag') {
770:
771: $prop->setValue($this->getOID());
772: $relatedObjects = $prop->getRelatedObjects();
773:
774: foreach ($relatedObjects as $object) {
775: $object->delete();
776: }
777: }
778: }
779: }
780:
781: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
782: $provider->delete();
783:
784: if ($config->get('cache.provider.name') != '') {
785: $this->removeFromCache();
786: }
787:
788: if (method_exists($this, 'after_delete_callback')) {
789: $this->after_delete_callback();
790: }
791:
792: $this->clear();
793: self::$logger->debug('<<delete');
794: }
795:
796: 797: 798: 799: 800: 801: 802: 803: 804: 805: 806: 807:
808: public function deleteAllByAttribute($attribute, $value)
809: {
810: self::$logger->debug('>>deleteAllByAttribute(attribute=['.$attribute.'], value=['.$value.'])');
811:
812: if (method_exists($this, 'before_deleteAllByAttribute_callback')) {
813: $this->before_deleteAllByAttribute_callback();
814: }
815:
816: try {
817: $doomedObjects = $this->loadAllByAttribute($attribute, $value);
818: $deletedRowCount = 0;
819:
820: foreach ($doomedObjects as $object) {
821: $object->delete();
822: ++$deletedRowCount;
823: }
824: } catch (RecordNotFoundException $bonf) {
825:
826: self::$logger->warn($bonf->getMessage());
827:
828: return 0;
829: } catch (AlphaException $e) {
830: throw new FailedDeleteException('Failed to delete objects, error is ['.$e->getMessage().']');
831: self::$logger->debug('<<deleteAllByAttribute [0]');
832:
833: return 0;
834: }
835:
836: if (method_exists($this, 'after_deleteAllByAttribute_callback')) {
837: $this->after_deleteAllByAttribute_callback();
838: }
839:
840: self::$logger->debug('<<deleteAllByAttribute ['.$deletedRowCount.']');
841:
842: return $deletedRowCount;
843: }
844:
845: 846: 847: 848: 849: 850: 851: 852: 853:
854: public function getVersion()
855: {
856: self::$logger->debug('>>getVersion()');
857:
858: if (method_exists($this, 'before_getVersion_callback')) {
859: $this->before_getVersion_callback();
860: }
861:
862: $config = ConfigProvider::getInstance();
863:
864: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
865: $ver = $provider->getVersion();
866:
867: if (method_exists($this, 'after_getVersion_callback')) {
868: $this->after_getVersion_callback();
869: }
870:
871: self::$logger->debug('<<getVersion ['.$ver.']');
872:
873: return $ver;
874: }
875:
876: 877: 878: 879: 880: 881: 882:
883: public function makeTable()
884: {
885: self::$logger->debug('>>makeTable()');
886:
887: if (method_exists($this, 'before_makeTable_callback')) {
888: $this->before_makeTable_callback();
889: }
890:
891: $config = ConfigProvider::getInstance();
892:
893: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
894: $provider->makeTable();
895:
896: if (method_exists($this, 'after_makeTable_callback')) {
897: $this->after_makeTable_callback();
898: }
899:
900: self::$logger->info('Successfully created the table ['.$this->getTableName().'] for the class ['.get_class($this).']');
901:
902: self::$logger->debug('<<makeTable');
903: }
904:
905: 906: 907: 908: 909: 910: 911:
912: public function makeHistoryTable()
913: {
914: self::$logger->debug('>>makeHistoryTable()');
915:
916: if (method_exists($this, 'before_makeHistoryTable_callback')) {
917: $this->before_makeHistoryTable_callback();
918: }
919:
920: $config = ConfigProvider::getInstance();
921:
922: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
923: $provider->makeHistoryTable();
924:
925: if (method_exists($this, 'after_makeHistoryTable_callback')) {
926: $this->after_makeHistoryTable_callback();
927: }
928:
929: self::$logger->info('Successfully created the table ['.$this->getTableName().'_history] for the class ['.get_class($this).']');
930:
931: self::$logger->debug('<<makeHistoryTable');
932: }
933:
934: 935: 936: 937: 938: 939: 940:
941: public function rebuildTable()
942: {
943: self::$logger->debug('>>rebuildTable()');
944:
945: if (method_exists($this, 'before_rebuildTable_callback')) {
946: $this->before_rebuildTable_callback();
947: }
948:
949: $config = ConfigProvider::getInstance();
950:
951: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
952: $provider->rebuildTable();
953:
954: if (method_exists($this, 'after_rebuildTable_callback')) {
955: $this->after_rebuildTable_callback();
956: }
957:
958: self::$logger->debug('<<rebuildTable');
959: }
960:
961: 962: 963: 964: 965: 966: 967: 968: 969:
970: public function dropTable($tableName = null)
971: {
972: self::$logger->debug('>>dropTable()');
973:
974: if (method_exists($this, 'before_dropTable_callback')) {
975: $this->before_dropTable_callback();
976: }
977:
978: $config = ConfigProvider::getInstance();
979:
980: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
981: $provider->dropTable($tableName);
982:
983: if (method_exists($this, 'after_dropTable_callback')) {
984: $this->after_dropTable_callback();
985: }
986:
987: self::$logger->debug('<<dropTable');
988: }
989:
990: 991: 992: 993: 994: 995: 996: 997: 998: 999:
1000: public function addProperty($propName)
1001: {
1002: self::$logger->debug('>>addProperty(propName=['.$propName.'])');
1003:
1004: $config = ConfigProvider::getInstance();
1005:
1006: if (method_exists($this, 'before_addProperty_callback')) {
1007: $this->before_addProperty_callback();
1008: }
1009:
1010: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1011: $provider->addProperty($propName);
1012:
1013: if (method_exists($this, 'after_addProperty_callback')) {
1014: $this->after_addProperty_callback();
1015: }
1016:
1017: self::$logger->debug('<<addProperty');
1018: }
1019:
1020: 1021: 1022: 1023: 1024: 1025: 1026:
1027: public function populateFromArray($hashArray)
1028: {
1029: self::$logger->debug('>>populateFromArray(hashArray=['.print_r($hashArray, true).'])');
1030:
1031:
1032: $reflection = new ReflectionClass(get_class($this));
1033: $properties = $reflection->getProperties();
1034:
1035: foreach ($properties as $propObj) {
1036: $propName = $propObj->name;
1037:
1038: if (isset($hashArray[$propName])) {
1039: if (!in_array($propName, $this->defaultAttributes) && !in_array($propName, $this->transientAttributes)) {
1040: $propClass = get_class($this->getPropObject($propName));
1041:
1042: if (isset($hashArray[$propName])) {
1043: if (mb_strtoupper($propClass) != 'DATE' && mb_strtoupper($propClass) != 'TIMESTAMP') {
1044: $this->getPropObject($propName)->setValue($hashArray[$propName]);
1045: } else {
1046: $this->getPropObject($propName)->populateFromString($hashArray[$propName]);
1047: }
1048: }
1049: }
1050:
1051: if ($propName == 'version_num' && isset($hashArray['version_num'])) {
1052: $this->version_num->setValue($hashArray['version_num']);
1053: }
1054:
1055: if ($this->getPropObject($propName) instanceof Relation) {
1056: $rel = $this->getPropObject($propName);
1057:
1058: if ($rel->getRelationType() == 'MANY-TO-MANY') {
1059: $OIDs = explode(',', $hashArray[$propName]);
1060: $rel->setRelatedOIDs($OIDs);
1061: $this->$propName = $rel;
1062: }
1063: }
1064: }
1065: }
1066:
1067: self::$logger->debug('<<populateFromArray');
1068: }
1069:
1070: 1071: 1072: 1073: 1074: 1075: 1076: 1077: 1078:
1079: public function getMAX()
1080: {
1081: self::$logger->debug('>>getMAX()');
1082:
1083: if (method_exists($this, 'before_getMAX_callback')) {
1084: $this->before_getMAX_callback();
1085: }
1086:
1087: $config = ConfigProvider::getInstance();
1088:
1089: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1090: $max = $provider->getMAX();
1091:
1092: if (method_exists($this, 'after_getMAX_callback')) {
1093: $this->after_getMAX_callback();
1094: }
1095:
1096: self::$logger->debug('<<getMAX ['.$max.']');
1097:
1098: return $max;
1099: }
1100:
1101: 1102: 1103: 1104: 1105: 1106: 1107: 1108: 1109: 1110: 1111: 1112: 1113:
1114: public function getCount($attributes = array(), $values = array())
1115: {
1116: self::$logger->debug('>>getCount(attributes=['.var_export($attributes, true).'], values=['.var_export($values, true).'])');
1117:
1118: if (method_exists($this, 'before_getCount_callback')) {
1119: $this->before_getCount_callback();
1120: }
1121:
1122: $config = ConfigProvider::getInstance();
1123:
1124: if (!is_array($attributes) || !is_array($values)) {
1125: throw new IllegalArguementException('Illegal arrays attributes=['.var_export($attributes, true).'] and values=['.var_export($values, true).'] provided to loadAllByAttributes');
1126: }
1127:
1128: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1129: $count = $provider->getCount($attributes, $values);
1130:
1131: if (method_exists($this, 'after_getCount_callback')) {
1132: $this->after_getCount_callback();
1133: }
1134:
1135: self::$logger->debug('<<getCount ['.$count.']');
1136:
1137: return $count;
1138: }
1139:
1140: 1141: 1142: 1143: 1144: 1145: 1146: 1147: 1148: 1149:
1150: public function getHistoryCount()
1151: {
1152: self::$logger->debug('>>getHistoryCount()');
1153:
1154: if (method_exists($this, 'before_getHistoryCount_callback')) {
1155: $this->before_getHistoryCount_callback();
1156: }
1157:
1158: $config = ConfigProvider::getInstance();
1159:
1160: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1161: $count = $provider->getHistoryCount();
1162:
1163: if (method_exists($this, 'after_getHistoryCount_callback')) {
1164: $this->after_getHistoryCount_callback();
1165: }
1166:
1167: self::$logger->debug('<<getHistoryCount ['.$count.']');
1168:
1169: return $count;
1170: }
1171:
1172: 1173: 1174: 1175: 1176: 1177: 1178: 1179: 1180:
1181: public function getID()
1182: {
1183: self::$logger->debug('>>getID()');
1184: $oid = str_pad($this->OID, 11, '0', STR_PAD_LEFT);
1185: self::$logger->debug('<<getID ['.$oid.']');
1186:
1187: return $oid;
1188: }
1189:
1190: 1191: 1192: 1193: 1194: 1195: 1196: 1197:
1198: final public function getOID()
1199: {
1200: if (self::$logger == null) {
1201: self::$logger = new Logger('ActiveRecord');
1202: }
1203: self::$logger->debug('>>getOID()');
1204: $oid = str_pad($this->OID, 11, '0', STR_PAD_LEFT);
1205: self::$logger->debug('<<getOID ['.$oid.']');
1206:
1207: return $oid;
1208: }
1209:
1210: 1211: 1212: 1213: 1214: 1215: 1216:
1217: public function getVersionNumber()
1218: {
1219: self::$logger->debug('>>getVersionNumber()');
1220: self::$logger->debug('<<getVersionNumber ['.$this->version_num.']');
1221:
1222: return $this->version_num;
1223: }
1224:
1225: 1226: 1227: 1228: 1229: 1230: 1231:
1232: protected function setEnumOptions()
1233: {
1234: self::$logger->debug('>>setEnumOptions()');
1235:
1236: if (method_exists($this, 'before_setEnumOptions_callback')) {
1237: $this->before_setEnumOptions_callback();
1238: }
1239:
1240: $config = ConfigProvider::getInstance();
1241:
1242: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1243: try {
1244: $provider->setEnumOptions();
1245: } catch (NotImplementedException $e) {
1246: self::$logger->debug($e->getMessage());
1247: }
1248:
1249: self::$logger->debug('<<setEnumOptions');
1250: }
1251:
1252: 1253: 1254: 1255: 1256: 1257: 1258: 1259: 1260: 1261: 1262: 1263: 1264: 1265: 1266:
1267: public function get($prop, $noChildMethods = false)
1268: {
1269: if (self::$logger == null) {
1270: self::$logger = new Logger('ActiveRecord');
1271: }
1272:
1273: self::$logger->debug('>>get(prop=['.$prop.'], noChildMethods=['.$noChildMethods.'])');
1274:
1275: if (method_exists($this, 'before_get_callback')) {
1276: $this->before_get_callback();
1277: }
1278:
1279: if (empty($prop)) {
1280: throw new IllegalArguementException('Cannot call get with empty $prop arguement!');
1281: }
1282:
1283:
1284: if (!$noChildMethods && method_exists($this, 'get'.ucfirst($prop))) {
1285: if (method_exists($this, 'after_get_callback')) {
1286: $this->after_get_callback();
1287: }
1288:
1289: $methodName = 'get'.ucfirst($prop);
1290:
1291: self::$logger->debug('<<get ['.print_r($this->$methodName(), true).'])');
1292:
1293: return $this->$methodName();
1294: } else {
1295:
1296: if (isset($this->$prop) && is_object($this->$prop) && method_exists($this->$prop, 'getValue')) {
1297: if (method_exists($this, 'after_get_callback')) {
1298: $this->after_get_callback();
1299: }
1300:
1301:
1302: self::$logger->debug('<<get ['.$this->$prop->getValue().'])');
1303:
1304: return $this->$prop->getValue();
1305: } elseif (isset($this->$prop)) {
1306: if (method_exists($this, 'after_get_callback')) {
1307: $this->after_get_callback();
1308: }
1309:
1310:
1311: self::$logger->debug('<<get ['.print_r($this->$prop, true).'])');
1312:
1313: return $this->$prop;
1314: } else {
1315: throw new AlphaException('Could not access the property ['.$prop.'] on the object of class ['.get_class($this).']');
1316: self::$logger->debug('<<get [false])');
1317:
1318: return false;
1319: }
1320: }
1321: }
1322:
1323: 1324: 1325: 1326: 1327: 1328: 1329: 1330: 1331: 1332: 1333: 1334: 1335:
1336: public function set($prop, $value, $noChildMethods = false)
1337: {
1338: self::$logger->debug('>>set(prop=['.$prop.'], $value=['.print_r($value, true).'], noChildMethods=['.$noChildMethods.'])');
1339:
1340: if (method_exists($this, 'before_set_callback')) {
1341: $this->before_set_callback();
1342: }
1343:
1344:
1345: if (!$noChildMethods && method_exists($this, 'set'.ucfirst($prop))) {
1346: if (method_exists($this, 'after_set_callback')) {
1347: $this->after_set_callback();
1348: }
1349:
1350: $methodName = 'set'.ucfirst($prop);
1351:
1352: $this->$methodName($value);
1353: } else {
1354:
1355: if (isset($this->$prop)) {
1356: if (method_exists($this, 'after_set_callback')) {
1357: $this->after_set_callback();
1358: }
1359:
1360:
1361: if (is_object($this->$prop) && get_class($this->$prop) != false) {
1362: if (mb_strtoupper(get_class($this->$prop)) != 'DATE' && mb_strtoupper(get_class($this->$prop)) != 'TIMESTAMP') {
1363: $this->$prop->setValue($value);
1364: } else {
1365:
1366: $this->$prop->populateFromString($value);
1367: }
1368: } else {
1369:
1370: $this->$prop = $value;
1371: }
1372: } else {
1373: throw new AlphaException('Could not set the property ['.$prop.'] on the object of the class ['.get_class($this).']. Property may not exist, or else does not have a setValue() method and is private or protected.');
1374: }
1375: }
1376: self::$logger->debug('<<set');
1377: }
1378:
1379: 1380: 1381: 1382: 1383: 1384: 1385: 1386: 1387: 1388: 1389: 1390:
1391: public function getPropObject($prop)
1392: {
1393: self::$logger->debug('>>getPropObject(prop=['.$prop.'])');
1394:
1395: if (method_exists($this, 'before_getPropObject_callback')) {
1396: $this->before_getPropObject_callback();
1397: }
1398:
1399:
1400: $reflection = new \ReflectionObject($this);
1401: $properties = $reflection->getProperties();
1402:
1403:
1404: $attribute = new ReflectionProperty($this, $prop);
1405:
1406: if ($attribute->isPrivate()) {
1407: if (method_exists($this, 'after_getPropObject_callback')) {
1408: $this->after_getPropObject_callback();
1409: }
1410:
1411: self::$logger->debug('<<getPropObject [false]');
1412:
1413: return false;
1414: }
1415:
1416: foreach ($properties as $propObj) {
1417: $propName = $propObj->name;
1418:
1419: if ($prop == $propName) {
1420: if (method_exists($this, 'after_getPropObject_callback')) {
1421: $this->after_getPropObject_callback();
1422: }
1423:
1424: self::$logger->debug('<<getPropObject ['.var_export($this->$prop, true).']');
1425:
1426: return $this->$prop;
1427: }
1428: }
1429: throw new IllegalArguementException('Could not access the property object ['.$prop.'] on the object of class ['.get_class($this).']');
1430: self::$logger->debug('<<getPropObject [false]');
1431:
1432: return false;
1433: }
1434:
1435: 1436: 1437: 1438: 1439: 1440: 1441: 1442: 1443: 1444: 1445:
1446: public function checkTableExists($checkHistoryTable = false)
1447: {
1448: self::$logger->debug('>>checkTableExists()');
1449:
1450: if (method_exists($this, 'before_checkTableExists_callback')) {
1451: $this->before_checkTableExists_callback();
1452: }
1453:
1454: $config = ConfigProvider::getInstance();
1455:
1456: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1457: $tableExists = $provider->checkTableExists($checkHistoryTable);
1458:
1459: if (method_exists($this, 'after_checkTableExists_callback')) {
1460: $this->after_checkTableExists_callback();
1461: }
1462:
1463: self::$logger->debug('<<checkTableExists ['.$tableExists.']');
1464:
1465: return $tableExists;
1466: }
1467:
1468: 1469: 1470: 1471: 1472: 1473: 1474: 1475: 1476: 1477: 1478: 1479: 1480:
1481: public static function checkBOTableExists($BOClassName, $checkHistoryTable = false)
1482: {
1483: if (self::$logger == null) {
1484: self::$logger = new Logger('ActiveRecord');
1485: }
1486: self::$logger->debug('>>checkBOTableExists(BOClassName=['.$BOClassName.'])');
1487:
1488: $config = ConfigProvider::getInstance();
1489:
1490: $provider = $config->get('db.provider.name');
1491:
1492: $tableExists = $provider::checkBOTableExists($BOClassName, $checkHistoryTable);
1493:
1494: self::$logger->debug('<<checkBOTableExists ['.($tableExists ? 'true' : 'false').']');
1495:
1496: return $tableExists;
1497: }
1498:
1499: 1500: 1501: 1502: 1503: 1504: 1505: 1506: 1507: 1508:
1509: public function checkTableNeedsUpdate()
1510: {
1511: self::$logger->debug('>>checkTableNeedsUpdate()');
1512:
1513: $config = ConfigProvider::getInstance();
1514:
1515: if (method_exists($this, 'before_checkTableNeedsUpdate_callback')) {
1516: $this->before_checkTableNeedsUpdate_callback();
1517: }
1518:
1519: $tableExists = $this->checkTableExists();
1520:
1521: if (!$tableExists) {
1522: self::$logger->debug('<<checkTableNeedsUpdate [true]');
1523:
1524: return true;
1525: } else {
1526: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1527: $updateRequired = $provider->checkTableNeedsUpdate();
1528:
1529: if (method_exists($this, 'after_checkTableNeedsUpdate_callback')) {
1530: $this->after_checkTableNeedsUpdate_callback();
1531: }
1532:
1533: self::$logger->debug('<<checkTableNeedsUpdate ['.$updateRequired.']');
1534:
1535: return $updateRequired;
1536: }
1537: }
1538:
1539: 1540: 1541: 1542: 1543: 1544: 1545: 1546: 1547: 1548:
1549: public function findMissingFields()
1550: {
1551: self::$logger->debug('>>findMissingFields()');
1552:
1553: $config = ConfigProvider::getInstance();
1554:
1555: if (method_exists($this, 'before_findMissingFields_callback')) {
1556: $this->before_findMissingFields_callback();
1557: }
1558:
1559: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1560: $missingFields = $provider->findMissingFields();
1561:
1562: if (method_exists($this, 'after_findMissingFields_callback')) {
1563: $this->after_findMissingFields_callback();
1564: }
1565:
1566: self::$logger->debug('<<findMissingFields ['.var_export($missingFields, true).']');
1567:
1568: return $missingFields;
1569: }
1570:
1571: 1572: 1573: 1574: 1575: 1576: 1577: 1578: 1579:
1580: public function getTableName()
1581: {
1582: self::$logger->debug('>>getTableName()');
1583:
1584: $className = get_class($this);
1585:
1586: $tableName = $className::TABLE_NAME;
1587:
1588: if (!empty($tableName)) {
1589: self::$logger->debug('<<getTableName ['.$tableName.']');
1590:
1591: return $tableName;
1592: } else {
1593: throw new AlphaException('Error: no TABLE_NAME constant set for the class '.get_class($this));
1594: }
1595: }
1596:
1597: 1598: 1599: 1600: 1601: 1602: 1603:
1604: public function getCreatorId()
1605: {
1606: self::$logger->debug('>>getCreatorId()');
1607: self::$logger->debug('<<getCreatorId ['.$this->created_by.']');
1608:
1609: return $this->created_by;
1610: }
1611:
1612: 1613: 1614: 1615: 1616: 1617: 1618:
1619: public function getUpdatorId()
1620: {
1621: self::$logger->debug('>>getUpdatorId()');
1622: self::$logger->debug('<<getUpdatorId ['.$this->updated_by.']');
1623:
1624: return $this->updated_by;
1625: }
1626:
1627: 1628: 1629: 1630: 1631: 1632: 1633:
1634: public function getCreateTS()
1635: {
1636: self::$logger->debug('>>getCreateTS()');
1637: self::$logger->debug('<<getCreateTS ['.$this->created_ts.']');
1638:
1639: return $this->created_ts;
1640: }
1641:
1642: 1643: 1644: 1645: 1646: 1647: 1648:
1649: public function getUpdateTS()
1650: {
1651: self::$logger->debug('>>getUpdateTS()');
1652: self::$logger->debug('<<getUpdateTS ['.$this->updated_ts.']');
1653:
1654: return $this->updated_ts;
1655: }
1656:
1657: 1658: 1659: 1660: 1661: 1662: 1663:
1664: public function markTransient($attributeName)
1665: {
1666: self::$logger->debug('>>markTransient(attributeName=['.$attributeName.'])');
1667: self::$logger->debug('<<markTransient');
1668: array_push($this->transientAttributes, $attributeName);
1669: }
1670:
1671: 1672: 1673: 1674: 1675: 1676: 1677: 1678:
1679: public function markPersistent($attributeName)
1680: {
1681: self::$logger->debug('>>markPersistent(attributeName=['.$attributeName.'])');
1682: self::$logger->debug('<<markPersistent');
1683: $this->transientAttributes = array_diff($this->transientAttributes, array($attributeName));
1684: }
1685:
1686: 1687: 1688: 1689: 1690: 1691: 1692: 1693: 1694:
1695: protected function markUnique($attribute1Name, $attribute2Name = '', $attribute3Name = '')
1696: {
1697: self::$logger->debug('>>markUnique(attribute1Name=['.$attribute1Name.'], attribute2Name=['.$attribute2Name.'], attribute3Name=['.$attribute3Name.'])');
1698:
1699: if (empty($attribute2Name)) {
1700: array_push($this->uniqueAttributes, $attribute1Name);
1701: } else {
1702:
1703: if ($attribute3Name == '') {
1704: $attributes = $attribute1Name.'+'.$attribute2Name;
1705: } else {
1706: $attributes = $attribute1Name.'+'.$attribute2Name.'+'.$attribute3Name;
1707: }
1708:
1709: array_push($this->uniqueAttributes, $attributes);
1710: }
1711:
1712: self::$logger->debug('<<markUnique');
1713: }
1714:
1715: 1716: 1717: 1718: 1719: 1720: 1721:
1722: public function getUniqueAttributes()
1723: {
1724: self::$logger->debug('>>getUniqueAttributes()');
1725: self::$logger->debug('<<getUniqueAttributes: ['.print_r($this->uniqueAttributes, true).']');
1726:
1727: return $this->uniqueAttributes;
1728: }
1729:
1730: 1731: 1732: 1733: 1734: 1735: 1736: 1737: 1738:
1739: public function getIndexes()
1740: {
1741: self::$logger->debug('>>getIndexes()');
1742:
1743: $config = ConfigProvider::getInstance();
1744:
1745: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1746: $indexNames = $provider->getIndexes();
1747:
1748: self::$logger->debug('<<getIndexes ['.print_r($indexNames, true).']');
1749:
1750: return $indexNames;
1751: }
1752:
1753: 1754: 1755: 1756: 1757: 1758: 1759: 1760: 1761: 1762: 1763: 1764: 1765:
1766: public function createForeignIndex($attributeName, $relatedClass, $relatedClassAttribute, $indexName = null)
1767: {
1768: self::$logger->debug('>>createForeignIndex(attributeName=['.$attributeName.'], relatedClass=['.$relatedClass.'], relatedClassAttribute=['.$relatedClassAttribute.'], indexName=['.$indexName.']');
1769:
1770: $config = ConfigProvider::getInstance();
1771:
1772: if (method_exists($this, 'before_createForeignIndex_callback')) {
1773: $this->before_createForeignIndex_callback();
1774: }
1775:
1776: $relatedBO = new $relatedClass();
1777: $tableName = $relatedBO->getTableName();
1778:
1779:
1780: if ($this->getTableName() == $tableName) {
1781: self::$logger->debug('<<createForeignIndex');
1782:
1783: return;
1784: }
1785:
1786: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1787: $provider->createForeignIndex($attributeName, $relatedClass, $relatedClassAttribute, $indexName);
1788:
1789: if (method_exists($this, 'after_createForeignIndex_callback')) {
1790: $this->after_createForeignIndex_callback();
1791: }
1792:
1793: self::$logger->debug('<<createForeignIndex');
1794: }
1795:
1796: 1797: 1798: 1799: 1800: 1801: 1802: 1803: 1804: 1805: 1806:
1807: public function createUniqueIndex($attribute1Name, $attribute2Name = '', $attribute3Name = '')
1808: {
1809: self::$logger->debug('>>createUniqueIndex(attribute1Name=['.$attribute1Name.'], attribute2Name=['.$attribute2Name.'], attribute3Name=['.$attribute3Name.'])');
1810:
1811: if (method_exists($this, 'before_createUniqueIndex_callback')) {
1812: $this->before_createUniqueIndex_callback();
1813: }
1814:
1815: $config = ConfigProvider::getInstance();
1816:
1817: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
1818: $provider->createUniqueIndex($attribute1Name, $attribute2Name, $attribute3Name);
1819:
1820: if (method_exists($this, 'after_createUniqueIndex_callback')) {
1821: $this->before_createUniqueIndex_callback();
1822: }
1823:
1824: self::$logger->debug('<<createUniqueIndex');
1825: }
1826:
1827: 1828: 1829: 1830: 1831: 1832: 1833:
1834: public function getDataLabels()
1835: {
1836: self::$logger->debug('>>getDataLabels()');
1837: self::$logger->debug('<<getDataLabels() ['.var_export($this->dataLabels, true).'])');
1838:
1839: return $this->dataLabels;
1840: }
1841:
1842: 1843: 1844: 1845: 1846: 1847: 1848: 1849: 1850:
1851: public function setDataLabels($labels)
1852: {
1853: self::$logger->debug('>>setDataLabels(labels=['.print_r($labels, true).'])');
1854:
1855: if (is_array($labels)) {
1856: $this->dataLabels = $labels;
1857: } else {
1858: throw new IllegalArguementException('The value ['.print_r($labels, true).'] provided to setDataLabels() is not a valid array!');
1859: }
1860:
1861: self::$logger->debug('<<setDataLabels()');
1862: }
1863:
1864: 1865: 1866: 1867: 1868: 1869: 1870: 1871: 1872: 1873: 1874:
1875: public function getDataLabel($att)
1876: {
1877: self::$logger->debug('>>getDataLabel(att=['.$att.'])');
1878:
1879: if (in_array($att, array_keys($this->dataLabels))) {
1880: self::$logger->debug('<<getDataLabel ['.$this->dataLabels[$att].'])');
1881:
1882: return $this->dataLabels[$att];
1883: } else {
1884: throw new IllegalArguementException('No data label found on the class ['.get_class($this).'] for the attribute ['.$att.']');
1885: self::$logger->debug('<<getDataLabel [])');
1886:
1887: return '';
1888: }
1889: }
1890:
1891: 1892: 1893: 1894: 1895: 1896: 1897:
1898: public static function getBOClassNames()
1899: {
1900: if (self::$logger == null) {
1901: self::$logger = new Logger('ActiveRecord');
1902: }
1903: self::$logger->debug('>>getBOClassNames()');
1904:
1905: $config = ConfigProvider::getInstance();
1906:
1907: $classNameArray = array();
1908:
1909: if (file_exists($config->get('app.root').'src/Model')) {
1910:
1911: $handle = opendir($config->get('app.root').'src/Model');
1912:
1913:
1914: while (false !== ($file = readdir($handle))) {
1915: if (preg_match('/.php/', $file)) {
1916: $classname = 'Model\\'.mb_substr($file, 0, -4);
1917:
1918: if (class_exists($classname)) {
1919: array_push($classNameArray, $classname);
1920: }
1921: }
1922: }
1923: }
1924:
1925:
1926: if (file_exists($config->get('app.root').'Alpha/Model')) {
1927: $handle = opendir($config->get('app.root').'Alpha/Model');
1928: } elseif ($config->get('app.root').'vendor/alphadevx/alpha/Alpha/Model') {
1929: $handle = opendir($config->get('app.root').'vendor/alphadevx/alpha/Alpha/Model');
1930: }
1931:
1932:
1933: while (false !== ($file = readdir($handle))) {
1934: if (preg_match('/.php/', $file)) {
1935: $classname = 'Alpha\\Model\\'.mb_substr($file, 0, -4);
1936:
1937: if (class_exists($classname) && substr($classname, 0, 24) != 'Alpha\\Model\\ActiveRecord') {
1938: array_push($classNameArray, $classname);
1939: }
1940: }
1941: }
1942:
1943: asort($classNameArray);
1944: self::$logger->debug('<<getBOClassNames ['.var_export($classNameArray, true).']');
1945:
1946: return $classNameArray;
1947: }
1948:
1949: 1950: 1951: 1952: 1953: 1954: 1955:
1956: public function getDefaultAttributes()
1957: {
1958: self::$logger->debug('>>getDefaultAttributes()');
1959: self::$logger->debug('<<getDefaultAttributes ['.var_export($this->defaultAttributes, true).']');
1960:
1961: return $this->defaultAttributes;
1962: }
1963:
1964: 1965: 1966: 1967: 1968: 1969: 1970:
1971: public function getTransientAttributes()
1972: {
1973: self::$logger->debug('>>getTransientAttributes()');
1974: self::$logger->debug('<<getTransientAttributes ['.var_export($this->transientAttributes, true).']');
1975:
1976: return $this->transientAttributes;
1977: }
1978:
1979: 1980: 1981: 1982: 1983: 1984: 1985:
1986: public function getPersistentAttributes()
1987: {
1988: self::$logger->debug('>>getPersistentAttributes()');
1989:
1990: $attributes = array();
1991:
1992:
1993: $reflection = new ReflectionClass(get_class($this));
1994: $properties = $reflection->getProperties();
1995:
1996: foreach ($properties as $propObj) {
1997: $propName = $propObj->name;
1998:
1999:
2000: if (!in_array($propName, $this->transientAttributes)) {
2001: array_push($attributes, $propName);
2002: }
2003: }
2004:
2005: self::$logger->debug('<<getPersistentAttributes ['.var_export($attributes, true).']');
2006:
2007: return $attributes;
2008: }
2009:
2010: 2011: 2012: 2013: 2014: 2015: 2016:
2017: public function setOID($OID)
2018: {
2019: self::$logger->debug('>>setOID(OID=['.$OID.'])');
2020: self::$logger->debug('<<setOID');
2021: $this->OID = $OID;
2022: }
2023:
2024: 2025: 2026: 2027: 2028: 2029: 2030:
2031: public function isTransient()
2032: {
2033: self::$logger->debug('>>isTransient()');
2034:
2035: if (empty($this->OID) || !isset($this->OID) || $this->OID == '00000000000') {
2036: self::$logger->debug('<<isTransient [true]');
2037:
2038: return true;
2039: } else {
2040: self::$logger->debug('<<isTransient [false]');
2041:
2042: return false;
2043: }
2044: }
2045:
2046: 2047: 2048: 2049: 2050: 2051: 2052:
2053: public function getLastQuery()
2054: {
2055: self::$logger->debug('>>getLastQuery()');
2056: self::$logger->debug('<<getLastQuery ['.$this->lastQuery.']');
2057:
2058: return $this->lastQuery;
2059: }
2060:
2061: 2062: 2063: 2064: 2065:
2066: private function clear()
2067: {
2068: self::$logger->debug('>>clear()');
2069:
2070:
2071: $reflection = new ReflectionClass(get_class($this));
2072: $properties = $reflection->getProperties();
2073:
2074: foreach ($properties as $propObj) {
2075: $propName = $propObj->name;
2076: if (!$propObj->isPrivate()) {
2077: unset($this->$propName);
2078: }
2079: }
2080:
2081: self::$logger->debug('<<clear');
2082: }
2083:
2084: 2085: 2086: 2087: 2088: 2089: 2090:
2091: public function reload()
2092: {
2093: self::$logger->debug('>>reload()');
2094:
2095: if (!$this->isTransient()) {
2096: $this->load($this->getOID());
2097: } else {
2098: throw new AlphaException('Cannot reload transient object from database!');
2099: }
2100: self::$logger->debug('<<reload');
2101: }
2102:
2103: 2104: 2105: 2106: 2107: 2108: 2109: 2110: 2111: 2112: 2113:
2114: public static function loadClassDef($classname)
2115: {
2116: if (self::$logger == null) {
2117: self::$logger = new Logger('ActiveRecord');
2118: }
2119: self::$logger->debug('>>loadClassDef(classname=['.$classname.'])');
2120:
2121: $config = ConfigProvider::getInstance();
2122:
2123: if (file_exists($config->get('app.root').'Model/'.$classname.'.php')) {
2124: require_once $config->get('app.root').'Model/'.$classname.'.php';
2125: } elseif (file_exists($config->get('app.root').'alpha/Alpha/Model/'.$classname.'.php')) {
2126: require_once $config->get('app.root').'alpha/Alpha/Model/'.$classname.'.php';
2127: } elseif (file_exists($config->get('app.root').'alpha/Alpha/Model/Types/'.$classname.'.php')) {
2128: require_once $config->get('app.root').'alpha/Alpha/Model/Types/'.$classname.'.php';
2129: } else {
2130: throw new IllegalArguementException('The class ['.$classname.'] is not defined anywhere!');
2131: }
2132:
2133: self::$logger->debug('<<loadClassDef');
2134: }
2135:
2136: 2137: 2138: 2139: 2140: 2141: 2142: 2143: 2144: 2145: 2146:
2147: public function checkRecordExists($OID)
2148: {
2149: self::$logger->debug('>>checkRecordExists(OID=['.$OID.'])');
2150:
2151: if (method_exists($this, 'before_checkRecordExists_callback')) {
2152: $this->before_checkRecordExists_callback();
2153: }
2154:
2155: $config = ConfigProvider::getInstance();
2156:
2157: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
2158: $recordExists = $provider->checkRecordExists($OID);
2159:
2160: if (method_exists($this, 'after_checkRecordExists_callback')) {
2161: $this->after_checkRecordExists_callback();
2162: }
2163:
2164: self::$logger->debug('<<checkRecordExists ['.$recordExists.']');
2165:
2166: return $recordExists;
2167: }
2168:
2169: 2170: 2171: 2172: 2173: 2174: 2175: 2176: 2177: 2178: 2179:
2180: public function isTableOverloaded()
2181: {
2182: self::$logger->debug('>>isTableOverloaded()');
2183:
2184: $config = ConfigProvider::getInstance();
2185:
2186: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $this);
2187: $isOverloaded = $provider->isTableOverloaded();
2188:
2189: self::$logger->debug('<<isTableOverloaded ['.$isOverloaded.']');
2190:
2191: return $isOverloaded;
2192: }
2193:
2194: 2195: 2196: 2197: 2198: 2199: 2200: 2201: 2202:
2203: public static function begin($BO = null)
2204: {
2205: if (self::$logger == null) {
2206: self::$logger = new Logger('ActiveRecord');
2207: }
2208: self::$logger->debug('>>begin()');
2209:
2210: $config = ConfigProvider::getInstance();
2211:
2212: if (isset($BO)) {
2213: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $BO);
2214: } else {
2215: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), new Person());
2216: }
2217:
2218: try {
2219: $provider->begin();
2220: } catch (\Exception $e) {
2221: throw new AlphaException('Error beginning a new transaction, error is ['.$e->getMessage().']');
2222: }
2223:
2224: self::$logger->debug('<<begin');
2225: }
2226:
2227: 2228: 2229: 2230: 2231: 2232: 2233: 2234: 2235:
2236: public static function commit($BO = null)
2237: {
2238: if (self::$logger == null) {
2239: self::$logger = new Logger('ActiveRecord');
2240: }
2241: self::$logger->debug('>>commit()');
2242:
2243: $config = ConfigProvider::getInstance();
2244:
2245: if (isset($BO)) {
2246: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $BO);
2247: } else {
2248: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), new Person());
2249: }
2250:
2251: try {
2252: $provider->commit();
2253: } catch (\Exception $e) {
2254: throw new FailedSaveException('Error commiting a transaction, error is ['.$e->getMessage().']');
2255: }
2256:
2257: self::$logger->debug('<<commit');
2258: }
2259:
2260: 2261: 2262: 2263: 2264: 2265: 2266: 2267: 2268:
2269: public static function rollback($BO = null)
2270: {
2271: if (self::$logger == null) {
2272: self::$logger = new Logger('ActiveRecord');
2273: }
2274: self::$logger->debug('>>rollback()');
2275:
2276: $config = ConfigProvider::getInstance();
2277:
2278: if (isset($BO)) {
2279: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), $BO);
2280: } else {
2281: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), new Person());
2282: }
2283:
2284: try {
2285: $provider->rollback();
2286: } catch (\Exception $e) {
2287: throw new FailedSaveException('Error aborting a transaction, error is ['.$e->getMessage().']');
2288: }
2289:
2290: self::$logger->debug('<<rollback');
2291: }
2292:
2293: 2294: 2295: 2296: 2297: 2298: 2299:
2300: public static function isInstalled()
2301: {
2302: if (self::$logger == null) {
2303: self::$logger = new Logger('ActiveRecord');
2304: }
2305: self::$logger->debug('>>isInstalled()');
2306:
2307: $config = ConfigProvider::getInstance();
2308:
2309: 2310: 2311: 2312: 2313: 2314:
2315: if (self::checkBOTableExists('Alpha\Model\Person') && self::checkBOTableExists('Alpha\Model\Rights')) {
2316: self::$logger->debug('<<isInstalled [true]');
2317:
2318: return true;
2319: } else {
2320: self::$logger->debug('<<isInstalled [false]');
2321:
2322: return false;
2323: }
2324: }
2325:
2326: 2327: 2328: 2329: 2330: 2331: 2332:
2333: public function isTagged()
2334: {
2335: if (isset($this->taggedAttributes) && isset($this->tags) && $this->tags instanceof \Alpha\Model\Type\Relation) {
2336: return true;
2337: } else {
2338: return false;
2339: }
2340: }
2341:
2342: 2343: 2344: 2345: 2346: 2347: 2348:
2349: public function getTaggedAttributes()
2350: {
2351: if ($this->isTagged()) {
2352: return $this->taggedAttributes;
2353: } else {
2354: return array();
2355: }
2356: }
2357:
2358: 2359: 2360: 2361: 2362: 2363: 2364:
2365: private function setVersion($versionNumber)
2366: {
2367: $this->version_num->setValue($versionNumber);
2368: }
2369:
2370: 2371: 2372: 2373: 2374: 2375: 2376: 2377: 2378: 2379: 2380: 2381:
2382: public function cast($targetClassName, $originalBO)
2383: {
2384: $BO = new $targetClassName();
2385: $BO->setOID($originalBO->getOID());
2386: $BO->setVersion($originalBO->getVersion());
2387:
2388:
2389: $originalBOreflection = new ReflectionClass(get_class($originalBO));
2390: $originalBOproperties = $originalBOreflection->getProperties();
2391: $newBOreflection = new ReflectionClass($targetClassName);
2392: $newBOproperties = $newBOreflection->getProperties();
2393:
2394:
2395:
2396: if (count($originalBOproperties) < count($newBOproperties)) {
2397:
2398: foreach ($originalBOproperties as $propObj) {
2399: $propName = $propObj->name;
2400: if (!in_array($propName, $this->transientAttributes)) {
2401: $BO->set($propName, $originalBO->get($propName));
2402: }
2403: }
2404: } else {
2405:
2406: foreach ($newBOproperties as $propObj) {
2407: $propName = $propObj->name;
2408: if (!in_array($propName, $this->transientAttributes)) {
2409: $BO->set($propName, $originalBO->get($propName));
2410: }
2411: }
2412: }
2413:
2414: return $BO;
2415: }
2416:
2417: 2418: 2419: 2420: 2421: 2422: 2423:
2424: public function getFriendlyClassName()
2425: {
2426: $name = mb_substr(get_class($this), 0, -6);
2427:
2428: $reflectClass = new ReflectionClass($this);
2429:
2430: return $reflectClass->getShortname();
2431: }
2432:
2433: 2434: 2435: 2436: 2437: 2438: 2439: 2440: 2441:
2442: public function hasAttribute($attribute)
2443: {
2444: try {
2445: $exists = $this->$attribute;
2446:
2447: return true;
2448: } catch (\Exception $e) {
2449: return false;
2450: }
2451: }
2452:
2453: 2454: 2455: 2456: 2457:
2458: public function addToCache()
2459: {
2460: self::$logger->debug('>>addToCache()');
2461: $config = ConfigProvider::getInstance();
2462:
2463: try {
2464: $cache = CacheProviderFactory::getInstance($config->get('cache.provider.name'));
2465: $cache->set(get_class($this).'-'.$this->getOID(), $this, 3600);
2466: } catch (\Exception $e) {
2467: self::$logger->error('Error while attempting to store a business object to the ['.$config->get('cache.provider.name').']
2468: instance: ['.$e->getMessage().']');
2469: }
2470:
2471: self::$logger->debug('<<addToCache');
2472: }
2473:
2474: 2475: 2476: 2477: 2478:
2479: public function removeFromCache()
2480: {
2481: self::$logger->debug('>>removeFromCache()');
2482: $config = ConfigProvider::getInstance();
2483:
2484: try {
2485: $cache = CacheProviderFactory::getInstance($config->get('cache.provider.name'));
2486: $cache->delete(get_class($this).'-'.$this->getOID());
2487: } catch (\Exception $e) {
2488: self::$logger->error('Error while attempting to remove a business object from ['.$config->get('cache.provider.name').']
2489: instance: ['.$e->getMessage().']');
2490: }
2491:
2492: self::$logger->debug('<<removeFromCache');
2493: }
2494:
2495: 2496: 2497: 2498: 2499: 2500: 2501:
2502: public function loadFromCache()
2503: {
2504: self::$logger->debug('>>loadFromCache()');
2505: $config = ConfigProvider::getInstance();
2506:
2507: try {
2508: $cache = CacheProviderFactory::getInstance($config->get('cache.provider.name'));
2509: $BO = $cache->get(get_class($this).'-'.$this->getOID());
2510:
2511: if (!$BO) {
2512: self::$logger->debug('Cache miss on key ['.get_class($this).'-'.$this->getOID().']');
2513: self::$logger->debug('<<loadFromCache: [false]');
2514:
2515: return false;
2516: } else {
2517:
2518: $reflection = new ReflectionClass(get_class($this));
2519: $properties = $reflection->getProperties();
2520:
2521: foreach ($properties as $propObj) {
2522: $propName = $propObj->name;
2523:
2524:
2525: if (!in_array($propName, $this->transientAttributes)) {
2526: $this->set($propName, $BO->get($propName, true));
2527: } elseif (!$propObj->isPrivate() && isset($this->$propName) && $this->$propName instanceof Relation) {
2528: $prop = $this->getPropObject($propName);
2529:
2530:
2531: if ($prop->getRelationType() == 'ONE-TO-MANY') {
2532: $this->set($propObj->name, $this->getOID());
2533: }
2534: }
2535: }
2536:
2537: self::$logger->debug('<<loadFromCache: [true]');
2538:
2539: return true;
2540: }
2541: } catch (Exception $e) {
2542: self::$logger->error('Error while attempting to load a business object from ['.$config->get('cache.provider.name').']
2543: instance: ['.$e->getMessage().']');
2544:
2545: self::$logger->debug('<<loadFromCache: [false]');
2546:
2547: return false;
2548: }
2549: }
2550:
2551: 2552: 2553: 2554: 2555: 2556: 2557:
2558: public function setLastQuery($query)
2559: {
2560: self::$logger->sql($query);
2561: $this->lastQuery = $query;
2562: }
2563:
2564: 2565: 2566: 2567: 2568: 2569:
2570: public function __wakeup()
2571: {
2572: if (self::$logger == null) {
2573: self::$logger = new Logger(get_class($this));
2574: }
2575: }
2576:
2577: 2578: 2579: 2580: 2581: 2582: 2583: 2584: 2585:
2586: public function setMaintainHistory($maintainHistory)
2587: {
2588: if (!is_bool($maintainHistory)) {
2589: throw new IllegalArguementException('Non-boolean value ['.$maintainHistory.'] passed to setMaintainHistory method!');
2590: }
2591:
2592: $this->maintainHistory = $maintainHistory;
2593: }
2594:
2595: 2596: 2597: 2598: 2599: 2600: 2601:
2602: public function getMaintainHistory()
2603: {
2604: return $this->maintainHistory;
2605: }
2606:
2607: 2608: 2609: 2610: 2611: 2612: 2613:
2614: public function toArray()
2615: {
2616:
2617: $reflection = new ReflectionClass(get_class($this));
2618: $properties = $reflection->getProperties();
2619:
2620: $propArray = array();
2621:
2622: foreach ($properties as $propObj) {
2623: $propName = $propObj->name;
2624:
2625: if (!in_array($propName, $this->transientAttributes)) {
2626: $val = $this->get($propName);
2627:
2628: if (is_object($val)) {
2629: $val = $val->getValue();
2630: }
2631:
2632: $propArray[$propName] = $val;
2633: }
2634: }
2635:
2636: return $propArray;
2637: }
2638:
2639: 2640: 2641: 2642: 2643: 2644: 2645:
2646: public static function checkDatabaseExists()
2647: {
2648: $config = ConfigProvider::getInstance();
2649:
2650: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), new Person());
2651:
2652: return $provider->checkDatabaseExists();
2653: }
2654:
2655: 2656: 2657: 2658: 2659: 2660: 2661:
2662: public static function createDatabase()
2663: {
2664: $config = ConfigProvider::getInstance();
2665:
2666: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), new Person());
2667: $provider->createDatabase();
2668: }
2669:
2670: 2671: 2672: 2673: 2674: 2675: 2676:
2677: public static function dropDatabase()
2678: {
2679: $config = ConfigProvider::getInstance();
2680:
2681: $provider = ActiveRecordProviderFactory::getInstance($config->get('db.provider.name'), new Person());
2682: $provider->dropDatabase();
2683: }
2684: }
2685: