/** * Enables the use of dynamic finders. * * Dynamic finders are just an easy way to do queries quickly without having to * specify an options array with conditions in it. * * <code> * SomeModel::findByFirstName('Tito'); * SomeModel::findByFirstNameAndLastName('Tito','the Grief'); * SomeModel::findByFirstNameOrLastName('Tito','the Grief'); * SomeModel::findAllByLastName('Smith'); * SomeModel::countByName('Bob') * SomeModel::countByNameOrState('Bob','VA') * SomeModel::countByNameAndState('Bob','VA') * </code> * * You can also create the model if the find call returned no results: * * <code> * Person::findOrCreateByName('Tito'); * * # would be the equivalent of * if (!Person::findByName('Tito')) * Person::create(array('Tito')); * </code> * * Some other examples of find_or_create_by: * * <code> * Person::findOrCreateByNameAndId('Tito',1); * Person::findOrCreateByNameAndId(array('name' => 'Tito', 'id' => 1)); * </code> * * @param string $method Name of method * @param mixed $args Method args * @return Model * @throws {@link ActiveRecordException} if invalid query * @see find */ public static function __callStatic($method, $args) { // TODO: Remove this bad fix, rewrite the code below properly. $method = strtolower(Inflector::instance()->underscorify($method)); $options = static::extractAndValidateOptions($args); $create = false; if (substr($method, 0, 17) == 'find_or_create_by') { $attributes = substr($method, 17); // can't take any finders with OR in it when doing a find_or_create_by if (strpos($attributes, '_or_') !== false) { throw new ActiveRecordException("Cannot use OR'd attributes in find_or_create_by"); } $create = true; $method = 'find_by' . substr($method, 17); } if (substr($method, 0, 7) === 'find_by') { $attributes = substr($method, 8); $options['conditions'] = SQLBuilder::createConditionsFromUnderscoredString(static::connection(), $attributes, $args, static::$aliasAttribute); if (!($ret = static::find('first', $options)) && $create) { return static::create(SQLBuilder::createHashFromUnderscoredString($attributes, $args, static::$aliasAttribute)); } return $ret; } elseif (substr($method, 0, 11) === 'find_all_by') { $options['conditions'] = SQLBuilder::createConditionsFromUnderscoredString(static::connection(), substr($method, 12), $args, static::$aliasAttribute); return static::find('all', $options); } elseif (substr($method, 0, 8) === 'count_by') { $options['conditions'] = SQLBuilder::createConditionsFromUnderscoredString(static::connection(), substr($method, 9), $args, static::$aliasAttribute); return static::count($options); } throw new ActiveRecordException("Call to undefined method: {$method}"); }