Skip to content

Instantly share code, notes, and snippets.

@kanema
Created April 27, 2011 03:41
Show Gist options
  • Save kanema/943676 to your computer and use it in GitHub Desktop.
Save kanema/943676 to your computer and use it in GitHub Desktop.
kohana orm dynamic finder
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