Created
March 31, 2009 02:47
-
-
Save speedmax/88016 to your computer and use it in GitHub Desktop.
concept for better active_record in CakePHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Person extends Model { | |
var $hasMany = 'hobbies'; | |
} | |
class Hobby extends Model { | |
var $belongsTo = 'person'; | |
} | |
echo Person::create(array( | |
'name' => 'taylor luk'; | |
'hobbies_attributes' => array( | |
array('title'=>'swimming'), | |
array('title'=>'watch tv'), | |
) | |
)) | |
# <Person id:1, "taylor luk"> | |
echo Person::find(1)->name; | |
# "taylor luk" | |
echo Person::find(1)->hobbies->first; | |
# <Hobby id:1, "swimming"> | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Backward compat version of get_called_class | |
*/ | |
if (!function_exists('get_called_class')): | |
function get_called_class() { | |
$bt = debug_backtrace(); | |
$lines = file($bt[1]['file']); | |
preg_match('/([a-zA-Z0-9\_]+)::'.$bt[1]['function'].'/', $lines[$bt[1]['line']-1], $matches); | |
return $matches[1]; | |
} | |
endif; | |
function set_static($class, $var) { | |
return eval('return ' . $class. '::$'. $var . ' = $value;'); | |
} | |
function get_static($class, $var) { | |
return eval('return ' . $class. '::$'. $var . ';'); | |
} | |
function call_static($callback) { | |
$args = func_get_args(); | |
array_shift($args); | |
if (strpos('::', $callback) !== false) | |
$callback = explode('::', $callback); | |
return user_call_func_array($callback, $args); | |
} | |
class Model { | |
static $table; | |
static $inherited = array(); | |
static $inheritColumn; | |
protected $associations; | |
protected $attributes; | |
/* | |
Class methods for table wide operation | |
*/ | |
static create($attributes) { | |
$class = get_called_class(); | |
$parents = class_parents($class); | |
$db =& Connection::dataSource('default'); | |
$db->save('insert into '.get_static($class, 'table'). ' values (' . $db->toSql($attributes) . ')'); | |
$instance = new $class($attributes); | |
$instance->id = $db->getLastInsertId(); | |
return $instance; | |
} | |
static find($type, $conditions = array()) { | |
$class = get_called_class(); | |
$db =& Connection::dataSource('default'); | |
$rs = $db->query('select * from '. get_static($class, 'table') . ';'); | |
return new ResultCollection($rs, $class); | |
} | |
static updateAll() {} | |
static deleteAll() {} | |
/* | |
instance methods for row wide operations | |
*/ | |
# anyone suggestions about instance method of find? | |
# function find() {} | |
function delete() { } | |
function update() { } | |
function save() { } | |
# Magic | |
function __construct($attributes = array(), $ds = null) { | |
$class = get_called_class(); | |
set_static($class, 'table', pluralize($class)); | |
if (!empty($attributes)) | |
return call_static("{$class}::create", $attributes); | |
} | |
function __get($attr) { | |
if (isset($this->attributes[$attr])) | |
return $this->attributes[$attr]; | |
if (isset($this->associations[$attr])) | |
return $this->__fetchAssociation($attr); | |
} | |
function __set() {} | |
function __call() {} | |
function __toString() {} | |
function __find() { } | |
function __fetchAssociation() { | |
extract($this->associations[$attr]); // Extrac $className, $foreignKey, $conditions | |
$foreignKey = strtolower(__CLASS__)'_id'; | |
$rs = call_static("{$className}::find", array( | |
'conditions'=> array($foreignKey = $this->id) | |
)); | |
return new ResultCollection($rs, $className); | |
} | |
} | |
class ResultCollection extends ArrayObject { | |
function __construct($rs, $class) { | |
parent::__construct($rs); | |
foreach ($this as & $attributes) { | |
$item = new $class($attributes); | |
} | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment