Created
April 27, 2011 03:41
-
-
Save kanema/943676 to your computer and use it in GitHub Desktop.
kohana orm dynamic finder
This file contains 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
class ORM extends Kohana_ORM { | |
/** | |
* Dynamic Finder: | |
* $orm->find_by_name('eduardo'); | |
* $orm->find_all_by_name('eduardo'); | |
* $orm->count_by_name('eduardo'); | |
* $orm->find_all_by_name_or_email('eduardo'); | |
* $orm->find_all_by_name_and_email('eduardo', 'du@kanema.com.br'); | |
* $orm->find_all_by_name_and_email_and_is_active('eduardo', 'du@kanema.com.br', TRUE); | |
* $orm->find_all_by_name_and_email_and_is_active_limit('eduardo', 'du@kanema.com.br', TRUE, 5); | |
* $orm->first_by_name('eduardo'); | |
* $orm->last_by_name('eduardo'); | |
* | |
* @param string $method Call methods divide by underscore | |
* @param array $arguments Parameters | |
* @return ORM | |
*/ | |
public function __call($method, array $arguments) | |
{ | |
if (strpos($method, 'find_') === 0 OR strpos($method, 'count_') === 0 OR strpos($method, 'first_') === 0 OR strpos($method, 'last_by_') === 0) | |
{ | |
if (Kohana::$profiling === TRUE) | |
{ | |
// Start a new benchmark | |
$benchmark = Profiler::start('ORM', $method); | |
} | |
// Define find types | |
$method_types = array( | |
'find_all_by_' => 'find_all', | |
'find_by_' => 'find', | |
'first_by_' => 'first', | |
'last_by_' => 'last', | |
'count_by_' => 'count_all', | |
'count_all_by_' => 'count_all', | |
); | |
// Determine the find type | |
foreach ($method_types as $key => $value) | |
{ | |
if (strncmp($method, $key, strlen($key)) === 0) | |
{ | |
$method = substr($method, strlen($key)); | |
$find_type = $value; | |
break; | |
} | |
} | |
if (isset($find_type)) | |
{ | |
// Get the limit | |
$limit = explode('_limit', $method); | |
if (count($limit) === 2) | |
{ | |
$this->limit(array_pop($arguments)); | |
} | |
$method = $limit[0]; | |
// Get the first or last by primary key | |
if ($find_type === 'first' OR $find_type === 'last') | |
{ | |
$order = ($find_type === 'first') ? 'ASC' : 'DESC'; | |
$this->order_by($this->primary_key(), $order); | |
$find_type = 'find'; | |
} | |
else | |
{ | |
// Get the order part | |
$order_by = explode('_order_by_', $method); | |
if (count($order_by) === 2) | |
{ | |
$this->order_by($order_by[1]); | |
} | |
$method = $order_by[0]; | |
} | |
// Get the and parts | |
$and_parts = explode('_and_', $method); | |
foreach ($and_parts as $and_part) | |
{ | |
// Get the or parts | |
$or_parts = explode('_or_', $and_part); | |
if (count($or_parts) === 1) | |
{ | |
$last_argument = (count($arguments) !== 0) ? array_shift($arguments) : $last_argument; | |
$this->where($or_parts[0], '=', $last_argument); | |
} | |
else | |
{ | |
foreach($or_parts as $or_part) | |
{ | |
$last_argument = (count($arguments) !== 0) ? array_shift($arguments) : $last_argument; | |
$this->or_where($or_part, '=', $last_argument); | |
} | |
} | |
} | |
if (isset($benchmark)) | |
{ | |
// Record the benchmark | |
Profiler::stop($benchmark); | |
} | |
// Execute the query | |
return $this->{$find_type}(); | |
} | |
} | |
return parent::__call($method, $arguments); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment