protected function _dynamicFinder($method, $args)
{
$method = Inflector::underscore($method);
preg_match('/^find_([\\w]+)_by_/', $method, $matches);
if (empty($matches)) {
// find_by_ is 8 characters.
$fields = substr($method, 8);
$findType = 'all';
} else {
$fields = substr($method, strlen($matches[0]));
$findType = Inflector::variable($matches[1]);
}
$hasOr = strpos($fields, '_or_');
$hasAnd = strpos($fields, '_and_');
$makeConditions = function ($fields, $args) {
$conditions = [];
if (count($args) < count($fields)) {
throw new BadMethodCallException(sprintf('Not enough arguments for magic finder. Got %s required %s', count($args), count($fields)));
}
foreach ($fields as $field) {
$conditions[$this->aliasField($field)] = array_shift($args);
}
return $conditions;
};
if ($hasOr !== false && $hasAnd !== false) {
throw new BadMethodCallException('Cannot mix "and" & "or" in a magic finder. Use find() instead.');
}
$conditions = [];
if ($hasOr === false && $hasAnd === false) {
$conditions = $makeConditions([$fields], $args);
} elseif ($hasOr !== false) {
$fields = explode('_or_', $fields);
$conditions = ['OR' => $makeConditions($fields, $args)];
} elseif ($hasAnd !== false) {
$fields = explode('_and_', $fields);
$conditions = $makeConditions($fields, $args);
}
return $this->find($findType, ['conditions' => $conditions]);
}