├── lib
├── ActiveRecord
│ └── Connection.php
└── ActiveRecord.php
├── example
└── example.php
└── README.textile
/lib/ActiveRecord/Connection.php:
--------------------------------------------------------------------------------
1 | getMessage());
21 | } catch (\Exception $e) {
22 | die($e->getMessage());
23 | }
24 |
25 | }
26 | return self::$instance;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/example/example.php:
--------------------------------------------------------------------------------
1 | array('class'=>'User')
16 | );
17 | static $hasMany = array(
18 | 'tags' => array('class'=>'Tag','joinTable'=>'post_tag')
19 | );
20 | }
21 |
22 | class User extends ActiveRecord
23 | {
24 | public $posts;
25 | static $hasMany = array(
26 | 'posts' => array('class'=>'Post')
27 | );
28 | }
29 |
30 | class Tag extends ActiveRecord
31 | {
32 | static $hasMany = array(
33 | 'posts' => array('class'=>'Post','joinTable'=>'post_tag')
34 | );
35 |
36 | }
37 |
38 | var_dump(User::find(1)->posts);
39 |
40 | // membuat data baru
41 |
42 | $user = new User();
43 | $user->name = 'Ata';
44 | $user->email = 'ata@javan.co.id';
45 | $user->save();
46 |
47 | // memperbaharui data
48 | $user = User::find(2);// mengambil data dengan id =2
49 | $user->name = 'Seseorang Lagi';
50 | $user->save();// menyimpanya kembali
51 |
52 | // Mengambil data dengan relasi
53 |
54 | $users = User::all(array('limit'=>2));
55 |
56 | foreach($users as $user){
57 | echo 'nama: '. $user->name ."
\n";
58 | echo 'email: '. $user->name ."
\n";
59 | echo 'posts:
';
60 | foreach($user->posts as $post){//relasi 'hasMany'
61 | echo ' title' . $post->title . "
\n";
62 | echo ' content' . $post->content . "
\n";
63 | foreach($post->tags as $tag) {
64 | echo ' tag: '.$tag->name . "
\n";
65 | }
66 | }
67 |
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/README.textile:
--------------------------------------------------------------------------------
1 | h1. SAMPLE CODE:
2 |
3 |
4 | array('class'=>'User')
19 | );
20 | static $hasMany = array(
21 | 'tags' => array('class'=>'Tag','joinTable'=>'post_tag')
22 | );
23 | }
24 |
25 | class User extends ActiveRecord
26 | {
27 | public $posts;
28 | static $hasMany = array(
29 | 'posts' => array('class'=>'Post')
30 | );
31 | }
32 |
33 | class Tag extends ActiveRecord
34 | {
35 | static $hasMany = array(
36 | 'posts' => array('class'=>'Post','joinTable'=>'post_tag')
37 | );
38 |
39 | }
40 |
41 | var_dump(User::find(1)->posts);
42 |
43 | // membuat data baru
44 |
45 | $user = new User();
46 | $user->name = 'Ata';
47 | $user->email = 'ata@javan.co.id';
48 | $user->save();
49 |
50 | // memperbaharui data
51 | $user = User::find(2);// mengambil data dengan id =2
52 | $user->name = 'Seseorang Lagi';
53 | $user->save();// menyimpanya kembali
54 |
55 | // Mengambil data dengan relasi
56 |
57 | $users = User::all(array('limit'=>2));
58 |
59 | foreach($users as $user){
60 | echo 'nama: '. $user->name ."
\n";
61 | echo 'email: '. $user->name ."
\n";
62 | echo 'posts:
';
63 | foreach($user->posts as $post){//relasi 'hasMany'
64 | echo ' title' . $post->title . "
\n";
65 | echo ' content' . $post->content . "
\n";
66 | foreach($post->tags as $tag) {
67 | echo ' tag: '.$tag->name . "
\n";
68 | }
69 | }
70 |
71 | }
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/lib/ActiveRecord.php:
--------------------------------------------------------------------------------
1 | setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
25 | }
26 |
27 | public static function getDb()
28 | {
29 | return self::$db;
30 | }
31 |
32 | public static function getTable()
33 | {
34 | if (!isset(static::$table)) {
35 | $short_class = static::getReflection()->getShortName();
36 | return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $short_class));
37 | }
38 | return static::$table;
39 | }
40 |
41 | public static function getReflection()
42 | {
43 | return new \ReflectionClass(get_called_class());
44 | }
45 |
46 | public static function getPrimaryKey()
47 | {
48 | if (!isset(static::$primaryKey)) {
49 | return 'id';
50 | } else {
51 | return static::$primaryKey;
52 | }
53 | }
54 |
55 | /** return array('id','name','email')
56 | */
57 | public static function getColumns()
58 | {
59 | if(isset(self::$columns[get_called_class()])) {
60 | return self::$columns[get_called_class()];
61 | }
62 |
63 | $table = static::getTable();
64 | $sql = "SHOW COLUMNS FROM $table";
65 | $statement = self::$db->prepare($sql);
66 | $statement->execute();
67 | $dbcolumns = $statement->fetchAll(\PDO::FETCH_ASSOC);
68 | $columns = array();
69 | foreach ($dbcolumns as $dc) {
70 | $columns[] = $dc['Field'];
71 | }
72 | return self::$columns[get_called_class()] = $columns;
73 |
74 | }
75 |
76 | protected static function unsetRelationProperties($object)
77 | {
78 | $class = get_class($object);
79 | if (isset(static::$belongsTo)){
80 | foreach (array_keys(static::$belongsTo) as $property) {
81 | if (property_exists($object,$property)){
82 | unset($object->$property);
83 | }
84 | }
85 | }
86 | if (isset(static::$hasOne)){
87 | foreach (array_keys(static::$hasOne) as $property) {
88 | if (property_exists($object,$property)) {
89 | unset($object->$property);
90 | }
91 | }
92 | }
93 | if (isset(static::$hasMany)){
94 | foreach (array_keys(static::$hasMany) as $property) {
95 | if(property_exists($object,$property)){
96 | unset($object->$property);
97 | }
98 | }
99 | }
100 |
101 | }
102 |
103 | public function __get($property)
104 | {
105 |
106 | if(isset(static::$belongsTo) && array_key_exists($property,static::$belongsTo)) {
107 | return $this->getBelongsToProperty($property);
108 | }
109 | if(isset(static::$hasOne) && array_key_exists($property,static::$hasOne)) {
110 | return $this->getHasOneProperty($property);
111 | }
112 |
113 | if(isset(static::$hasMany) && array_key_exists($property,static::$hasMany)) {
114 | return $this->getHasManyProperty($property);
115 | }
116 |
117 | }
118 |
119 |
120 | protected function getBelongsToProperty($property)
121 | {
122 | if(isset(static::$belongsTo) && array_key_exists($property,static::$belongsTo)) {
123 | $primaryKey = static::getPrimaryKey();
124 | $ref = static::$belongsTo[$property];
125 | $associationClass = $ref['class'];
126 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']:$property . '_id';
127 | return $this->$property = $associationClass::find($this->$foreignKey);
128 | }
129 | return false;
130 | }
131 |
132 | protected function getHasOneProperty($property)
133 | {
134 | if(isset(static::$hasOne) && array_key_exists($property,static::$hasOne)) {
135 | $ref = static::$hasOne[$property];
136 | $class = $ref['class'];
137 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']: static::getTable() . '_id';
138 | $primaryKey = static::getPrimaryKey();
139 | $table = $class::getTable();
140 | $statement = $class::query("SELECT * FROM $table WHERE $foreignKey = ? ",
141 | array($this->$primaryKey));
142 | return $this->$propery = $statement->fetch();
143 | }
144 | return false;
145 | }
146 |
147 | protected function getHasManyProperty($property)
148 | {
149 | if(isset(static::$hasMany) && array_key_exists($property,static::$hasMany)) {
150 | $ref = static::$hasMany[$property];
151 | $class = $ref['class'];
152 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']: static::getTable() . '_id';
153 | $associationTable = $class::getTable();
154 | $primaryKey = static::getPrimaryKey();
155 |
156 | if (isset($ref['joinTable'])) {
157 | $associationForeignKey = isset($ref['associationForeignKey'])?
158 | $ref['associationForeignKey']:$class::getTable() . '_id';
159 | $associationPrimaryKey = $class::getPrimaryKey();
160 | $joinTable = $ref['joinTable'];
161 |
162 | $statement = $class::query("SELECT * FROM $associationTable
163 | WHERE $associationPrimaryKey IN (
164 | SELECT $associationForeignKey
165 | FROM $joinTable
166 | WHERE $foreignKey = ?
167 | )",array($this->$primaryKey));
168 |
169 | return $this->$property = $statement->fetchAll();
170 |
171 | }
172 | $statement = $class::query("SELECT * FROM $associationTable
173 | WHERE $foreignKey = ? ",
174 | array($this->$primaryKey));
175 | return $this->$property = $statement->fetchAll();
176 |
177 | }
178 | return false;
179 | }
180 |
181 | public function __set($property,$value)
182 | {
183 | if(isset(static::$belongsTo) && array_key_exists($property,static::$belongsTo)) {
184 | $ref = static::$belongsTo[$property];
185 | $class = $ref['class'];
186 | $foreignKey = isset($ref['foreignKey'])?$ref['foreignKey']:$property . '_id';
187 | $primaryKey = $class::getPrimaryKey();
188 | //return $this->$property = $class::find($this->$foreignKey);
189 | $this->$foreignKey = $value->$primaryKey;
190 |
191 | }
192 | $this->$property = $value;
193 | }
194 |
195 |
196 |
197 |
198 | //======Retriving data method========
199 |
200 | /**
201 | * return @type PDOStatement
202 | */
203 | public static function query($query, $params = array())
204 | {
205 | $class = get_called_class();
206 | try {
207 | $statement = self::$db->prepare($query);
208 | $object = new $class();
209 | static::unsetRelationProperties($object);
210 | $statement->setFetchMode(\PDO::FETCH_INTO,$object);
211 | $statement->execute($params);
212 | return self::$statement[$class] = $statement;
213 | } catch (PDOStatement $e) {
214 | die($e->getMessage());
215 | }
216 | }
217 | /**
218 | * $options = array(
219 | * 'select' => 'name,message',
220 | * 'where' => '',
221 | * 'limit' =>
222 | * 'offset' =>
223 | * 'order' => ''
224 | * );
225 | */
226 | protected function findAll($options = array())
227 | {
228 | $select = 'SELECT *';
229 | $limit = '';
230 | $offset = '';
231 | $where = '';
232 | $order = '';
233 |
234 | if (isset($options['select'])) {
235 | $select = 'SELECT ' . $options['select'];
236 | if (count(array_keys(array_map(function($v){return trim($v);},
237 | explode(',',$options['select'])),static::getPrimaryKey())) === 0) {
238 |
239 | $select .= ', ' . static::getPrimaryKey();
240 | }
241 | }
242 | if (isset($options['where'])) {
243 | $where = 'where ' . $options['where'];
244 | }
245 |
246 | if (isset($options['order'])) {
247 | $offset = 'ORDER BY ' . $options['order'];
248 | }
249 |
250 | if (isset($options['limit'])) {
251 | $limit = 'LIMIT ' . $options['limit'];
252 | }
253 |
254 | if (isset($options['offset'])) {
255 | $offset = 'OFFSET ' . $options['offset'];
256 | }
257 |
258 | $table = static::getTable();
259 |
260 | return static::query("$select from $table $where $order $limit $offset");
261 |
262 | }
263 |
264 |
265 | public static function all($options = array())
266 | {
267 | return static::findAll($options)->fetchAll();
268 | }
269 |
270 | public static function first($options = array()){
271 | $options['limit'] = '1';
272 | return static::findAll($options)->fetch();
273 | }
274 | /**
275 | * find(1) --> return single object with id = 1
276 | * find(1,2) --> return array of object with id = 1 and 2
277 | * find('name','Ata') --> return array objek with field 'name' is 'Ata'
278 | */
279 |
280 |
281 | public static function find()
282 | {
283 | $class = get_called_class();
284 | if (func_num_args() === 1) {
285 | return static::findByPrimaryKey(func_get_arg(0));
286 | }
287 | if (property_exists($class,func_get_arg(0)) && func_num_args() > 1) {
288 |
289 | } else {
290 | return call_user_func_array(array($class,'findByPrimaryKeys'),
291 | func_get_args());
292 | }
293 |
294 | }
295 |
296 | protected static function findByPrimaryKey($id)
297 | {
298 | $table = static::getTable();
299 | $primaryKey = static::getPrimaryKey();
300 | $statement = static::query("SELECT * FROM $table
301 | WHERE $primaryKey = :id",
302 | array('id' => $id));
303 | return $statement->fetch();
304 |
305 | }
306 |
307 | protected static function findByPrimaryKeys()
308 | {
309 | $ids = func_get_args();
310 | $q1 = implode(',',array_map(function($v){return '?';},$ids));
311 |
312 | $table = static::getTable();
313 | $primaryKey = static::getPrimaryKey();
314 | $statement = static::query("SELECT * FROM $table
315 | WHERE $primaryKey in ($q1)",$ids);
316 | return $statement->fetchAll();
317 | }
318 |
319 |
320 | /* ===== Saving data =========*/
321 | public function save()
322 | {
323 | $primaryKey = static::getPrimaryKey();
324 | $class = get_class($this);
325 |
326 | if(isset($this->$primaryKey)){
327 | if($this->$primaryKey !== null) {
328 | return static::update($this);
329 | } else {
330 | return static::insert($this);
331 | }
332 | } else {
333 | return static::insert($this);
334 | }
335 | }
336 |
337 | protected static function update($object)
338 | {
339 | $table = static::getTable();
340 | $primaryKey = static::getPrimaryKey();
341 | $sets = array();
342 | $params = array();
343 | foreach (static::getColumns() as $c) {
344 | if(property_exists($object,$c) && $object->$c !== null){
345 | $sets[] = "$c = :$c ";
346 | $params[$c] = $object->$c;
347 | }
348 | }
349 |
350 | $params['primaryKey'] = $object->$primaryKey;
351 | $sets = join(',',$sets);
352 | $statement = self::$db->prepare("UPDATE $table SET $sets
353 | WHERE $primaryKey = :primaryKey");
354 | return $statement->execute($params);
355 |
356 | }
357 |
358 | protected static function insert($object)
359 | {
360 | $table = static::getTable();
361 | $columns = array();
362 | $values = array();
363 | $params = array();
364 | foreach (static::getColumns() as $c) {
365 | if(property_exists($object,$c) && $object->$c !== null){
366 | $columns[] = $c;
367 | $values[] = ':'.$c;
368 | $params[$c] = $object->$c;
369 | }
370 | }
371 |
372 | $sql_columns = join(',',$columns);
373 | $sql_values = join(',',$values);
374 | $statement = self::$db->prepare("INSERT INTO $table($sql_columns) VALUES($sql_values)");
375 | return $statement->execute($params);
376 | }
377 |
378 |
379 | //====== DESTROYING DATA ==========
380 | /**
381 | * destroy(1) -> destroy with primary key = 1
382 | * destroy(1,2,3) -> destroy with primary is 1,2 and 3
383 | */
384 | public static function destroy($id)
385 | {
386 | $table = static::getTable();
387 | $primaryKey = static::getPrimaryKey();
388 | if(func_num_args() == 1){
389 | $statement = self::$db->prepare("DELETE from $table WHERE $primaryKey = ?");
390 | return $statement->execute(array($id));
391 | } else {
392 | $ids = func_get_args();
393 | $q1 = implode(',',array_map(function($v){return '?';},$ids));
394 |
395 | $statement = self::$db->prepare("DELETE from $table WHERE $primaryKey IN ($q1)");
396 | return $statement->execute($ids);
397 | }
398 |
399 | return false;
400 | }
401 |
402 | public function delete()
403 | {
404 | $primaryKey = static::getPrimaryKey();
405 | $class = get_class($this);
406 |
407 | if (isset($this->$primaryKey) && $this->$primaryKey !== null) {
408 | return static::destroy($this->$primaryKey);
409 | }
410 | return false;
411 | }
412 | }
413 |
--------------------------------------------------------------------------------