class Model_User extends \Orm\Model { protected static $_properties = array( 'username' => array( 'label' => 'Username', 'validation' => array( 'required', 'min_length' => array(2), 'max_length' => array(50), ) ) ); }In my controller, I have
$val = Validation::forge()->add_model('Model_User'); if ($val->run()) { try { $user = Model_User::forge(array( ....... 'username' => Input::post('username'), ....... )); $user->save(); ..... } catch (Orm\ValidationFailed $e) { $errors = $e->getMessage(); } } else { $errors = $val->error(); }In the model, I want to add validation on the username property to ensure the username is unique. It needs to be checked for uniqueness before creation and before updating (only if it has been changed). At first I thought ORM observers would be perfect for this, but I'm not sure how to tie in the ORM's validation with the observers and also have the errors found in the observer sent all the way back up to the controller. Any ideas? P.S. It would also be nice if I could specify a callback in ORM properties' validation key, such as Model_User::is_username_unique. Is that possible and just not documented?
<?php class Model_User extends \Orm\Model { protected static $_properties = array( 'id', 'first_name', 'last_name', 'username', 'password', 'email', ); public static function get_validation(\Validation $val) { $val->add_callable('\Model_User'); $val->add_field('first_name', 'First Name', 'required|min_length[2]|max_length[50]'); $val->add_field('last_name', 'Last Name', 'required|min_length[2]|max_length[50]'); $val->add_field('username', 'Username', 'required|min_length[2]|max_length[50]'); $val->add_field('password', 'Password', 'required|min_length[6]|max_length[100]'); $val->add_field('email', 'Email Address', 'required|valid_email|min_length[5]|max_length[250]'); return $val; } public static function _validation_unique_username($username, Model_User $user) { if ( ! $user->is_new() and $user->username === $username) { return true; } $exists = DB::select(DB::expr('COUNT(*) as total_count'))->from($user->table()) ->where('username', '=', $username)->execute()->get('total_count'); return (bool) !$exists; } public static function _validation_unique_email($email, Model_User $user) { if ( ! $user->is_new() and $user->email === $email) { return true; } $exists = DB::select(DB::expr('COUNT(*) as total_count'))->from($user->table())->where('email', '=', $email) ->execute()->get('total_count'); return (bool) !$exists; } }In one of my controllers:
if ('POST' == Input::method()) { $user = Model_User::forge(); $val = Validation::forge(); $val = Model_User::get_validation($val); $val->field('username')->add_rule('unique_username', $user); $val->field('email')->add_rule('unique_email', $user); $val->add_field('password_confirm', 'Confirm Password', 'required|match_field[password]'); if ($val->run()) { $user->values(array( 'first_name' => Input::post('first_name'), 'last_name' => Input::post('last_name'), 'username' => Input::post('username'), 'password' => Input::post('password'), 'email' => Input::post('email'), 'activation_token' => Str::random('alnum', 40), )); $user->save(); // ... do something after save // e.g. Response::redirect( Router::get('register_success') ); } else { $errors = $val->error(); } }
It looks like you're new here. If you want to get involved, click one of these buttons!