@@ -525,12 +525,7 @@ public function findOne($condition=[])
525
525
return $ record ;
526
526
}
527
527
528
- // ORM handling
529
- $ this ->_readProperties = $ record ;
530
- // Primary key condition to ensure single query result
531
- $ this ->_selfCondition = $ record [$ this ->primaryKey ];
532
-
533
- return $ this ;
528
+ return $ this ->createActiveRecord ($ record , $ record [$ this ->primaryKey ]);
534
529
}
535
530
536
531
/**
@@ -562,14 +557,8 @@ public function findAll($condition=[])
562
557
if (!isset ($ record [$ this ->primaryKey ])) {
563
558
throw new Exception ("Model's primary key not set " , 500 );
564
559
}
565
- // Create an ActiveRecord
566
- $ activeRecord = new static ();
567
- // ORM handling
568
- $ activeRecord ->_readProperties = $ record ;
569
- // Primary key condition to ensure single query result
570
- $ activeRecord ->_selfCondition = $ record [$ this ->primaryKey ];
571
- // Collect
572
- $ set [] = $ activeRecord ;
560
+ // Create an ActiveRecord into collect
561
+ $ set [] = $ this ->createActiveRecord ($ record , $ record [$ this ->primaryKey ]);
573
562
}
574
563
575
564
return $ set ;
@@ -987,6 +976,24 @@ public function withAll()
987
976
return $ this ;
988
977
}
989
978
979
+ /**
980
+ * New a Active Record from Model by data
981
+ *
982
+ * @param array $readProperties
983
+ * @param array $selfCondition
984
+ * @return object ActiveRecord(Model)
985
+ */
986
+ public function createActiveRecord ($ readProperties , $ selfCondition )
987
+ {
988
+ $ activeRecord = new static ();
989
+ // ORM handling
990
+ $ activeRecord ->_readProperties = $ readProperties ;
991
+ // Primary key condition to ensure single query result
992
+ $ activeRecord ->_selfCondition = $ selfCondition ;
993
+
994
+ return $ activeRecord ;
995
+ }
996
+
990
997
/**
991
998
* Active Record (ORM) save for insert or update
992
999
*
@@ -1074,6 +1081,67 @@ public function afterSave($insert, $changedAttributes)
1074
1081
// overriding
1075
1082
}
1076
1083
1084
+ /**
1085
+ * Declares a has-many relation.
1086
+ *
1087
+ * @param string $modelName The model class name of the related record
1088
+ * @param string $foreignKey
1089
+ * @param string $localKey
1090
+ * @return object CI_DB_query_builder
1091
+ */
1092
+ public function hasMany ($ modelName , $ foreignKey =null , $ localKey =null )
1093
+ {
1094
+ return $ this ->_relationship ($ modelName , __FUNCTION__ , $ foreignKey , $ localKey );
1095
+ }
1096
+
1097
+ /**
1098
+ * Declares a has-many relation.
1099
+ *
1100
+ * @param string $modelName The model class name of the related record
1101
+ * @param string $foreignKey
1102
+ * @param string $localKey
1103
+ * @return object CI_DB_query_builder
1104
+ */
1105
+ public function hasOne ($ modelName , $ foreignKey =null , $ localKey =null )
1106
+ {
1107
+ return $ this ->_relationship ($ modelName , __FUNCTION__ , $ foreignKey , $ localKey );
1108
+ }
1109
+
1110
+ /**
1111
+ * Base relationship.
1112
+ *
1113
+ * @param string $modelName The model class name of the related record
1114
+ * @param string $relationship
1115
+ * @param string $foreignKey
1116
+ * @param string $localKey
1117
+ * @return object CI_DB_query_builder
1118
+ */
1119
+ protected function _relationship ($ modelName , $ relationship , $ foreignKey =null , $ localKey =null )
1120
+ {
1121
+ $ this ->load ->model ($ modelName );
1122
+
1123
+ $ libClass = __CLASS__ ;
1124
+
1125
+ // Check if is using same library
1126
+ if (!is_subclass_of ($ this ->$ modelName , $ libClass )) {
1127
+ throw new Exception ("Model ` {$ modelName }` does not extend {$ libClass }" , 500 );
1128
+ }
1129
+
1130
+ // Keys
1131
+ $ foreignKey = ($ foreignKey ) ? $ foreignKey : $ this ->primaryKey ;
1132
+ $ localKey = ($ localKey ) ? $ localKey : $ this ->primaryKey ;
1133
+
1134
+ $ query = $ this ->$ modelName ->find ()
1135
+ ->where ($ foreignKey , $ this ->$ localKey );
1136
+
1137
+ // Inject Model name into query builder for ORM relationships
1138
+ $ query ->modelName = $ modelName ;
1139
+ // Inject relationship type into query builder for ORM relationships
1140
+ $ query ->relationship = $ relationship ;
1141
+
1142
+ return $ query ;
1143
+ }
1144
+
1077
1145
/**
1078
1146
* Active Record transform to array record
1079
1147
*
@@ -1410,6 +1478,33 @@ public function __get($name)
1410
1478
1411
1479
return $ this ->_readProperties [$ name ];
1412
1480
}
1481
+ // ORM relationship check
1482
+ else if (method_exists ($ this , $ method = $ name )) {
1483
+
1484
+ $ query = call_user_func_array ([$ this , $ method ], []);
1485
+
1486
+ // Extract query builder injection property
1487
+ $ modelName = isset ($ query ->modelName ) ? $ query ->modelName : null ;
1488
+ $ relationship = isset ($ query ->relationship ) ? $ query ->relationship : null ;
1489
+
1490
+ if (!$ modelName || !$ relationship ) {
1491
+ throw new Exception ("ORM relationships error " , 500 );
1492
+ }
1493
+
1494
+ // Check return type
1495
+ if ($ relationship == 'hasOne ' ) {
1496
+
1497
+ // Keep same query builder from hasOne()
1498
+ return $ this ->$ modelName ->findOne (null );
1499
+
1500
+ } else {
1501
+
1502
+ // Keep same query builder from hasMany()
1503
+ return $ this ->$ modelName ->findAll (null );
1504
+ }
1505
+
1506
+ }
1507
+ // ORM schema check
1413
1508
else {
1414
1509
1415
1510
$ class = get_class ($ this );
0 commit comments