240 lines
5.7 KiB
PHP
240 lines
5.7 KiB
PHP
|
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||
|
/**
|
||
|
* Default auth user
|
||
|
*
|
||
|
* @package Kohana/Auth
|
||
|
* @author Kohana Team
|
||
|
* @copyright (c) 2007-2011 Kohana Team
|
||
|
* @license http://kohanaframework.org/license
|
||
|
*/
|
||
|
class Model_Auth_User extends ORM {
|
||
|
|
||
|
/**
|
||
|
* A user has many tokens and roles
|
||
|
*
|
||
|
* @var array Relationhips
|
||
|
*/
|
||
|
protected $_has_many = array(
|
||
|
'user_tokens' => array('model' => 'user_token'),
|
||
|
'roles' => array('model' => 'role', 'through' => 'roles_users'),
|
||
|
);
|
||
|
|
||
|
/**
|
||
|
* Rules for the user model. Because the password is _always_ a hash
|
||
|
* when it's set,you need to run an additional not_empty rule in your controller
|
||
|
* to make sure you didn't hash an empty string. The password rules
|
||
|
* should be enforced outside the model or with a model helper method.
|
||
|
*
|
||
|
* @return array Rules
|
||
|
*/
|
||
|
public function rules()
|
||
|
{
|
||
|
return array(
|
||
|
'username' => array(
|
||
|
array('not_empty'),
|
||
|
array('min_length', array(':value', 4)),
|
||
|
array('max_length', array(':value', 32)),
|
||
|
array('regex', array(':value', '/^[-\pL\pN_.]++$/uD')),
|
||
|
array(array($this, 'username_available'), array(':validation', ':field')),
|
||
|
),
|
||
|
'password' => array(
|
||
|
array('not_empty'),
|
||
|
),
|
||
|
'email' => array(
|
||
|
array('not_empty'),
|
||
|
array('min_length', array(':value', 4)),
|
||
|
array('max_length', array(':value', 127)),
|
||
|
array('email'),
|
||
|
array(array($this, 'email_available'), array(':validation', ':field')),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Filters to run when data is set in this model. The password filter
|
||
|
* automatically hashes the password when it's set in the model.
|
||
|
*
|
||
|
* @return array Filters
|
||
|
*/
|
||
|
public function filters()
|
||
|
{
|
||
|
return array(
|
||
|
'password' => array(
|
||
|
array(array(Auth::instance(), 'hash'))
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Labels for fields in this model
|
||
|
*
|
||
|
* @return array Labels
|
||
|
*/
|
||
|
public function labels()
|
||
|
{
|
||
|
return array(
|
||
|
'username' => 'username',
|
||
|
'email' => 'email address',
|
||
|
'password' => 'password',
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Complete the login for a user by incrementing the logins and saving login timestamp
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function complete_login()
|
||
|
{
|
||
|
if ($this->_loaded)
|
||
|
{
|
||
|
// Update the number of logins
|
||
|
$this->logins = new Database_Expression('logins + 1');
|
||
|
|
||
|
// Set the last login date
|
||
|
$this->last_login = time();
|
||
|
|
||
|
// Save the user
|
||
|
$this->update();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the reverse of unique_key_exists() by triggering error if username exists.
|
||
|
* Validation callback.
|
||
|
*
|
||
|
* @param Validation Validation object
|
||
|
* @param string Field name
|
||
|
* @return void
|
||
|
*/
|
||
|
public function username_available(Validation $validation, $field)
|
||
|
{
|
||
|
if ($this->unique_key_exists($validation[$field], 'username'))
|
||
|
{
|
||
|
$validation->error($field, 'username_available', array($validation[$field]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Does the reverse of unique_key_exists() by triggering error if email exists.
|
||
|
* Validation callback.
|
||
|
*
|
||
|
* @param Validation Validation object
|
||
|
* @param string Field name
|
||
|
* @return void
|
||
|
*/
|
||
|
public function email_available(Validation $validation, $field)
|
||
|
{
|
||
|
if ($this->unique_key_exists($validation[$field], 'email'))
|
||
|
{
|
||
|
$validation->error($field, 'email_available', array($validation[$field]));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Tests if a unique key value exists in the database.
|
||
|
*
|
||
|
* @param mixed the value to test
|
||
|
* @param string field name
|
||
|
* @return boolean
|
||
|
*/
|
||
|
public function unique_key_exists($value, $field = NULL)
|
||
|
{
|
||
|
if ($field === NULL)
|
||
|
{
|
||
|
// Automatically determine field by looking at the value
|
||
|
$field = $this->unique_key($value);
|
||
|
}
|
||
|
|
||
|
return (bool) DB::select(array('COUNT("*")', 'total_count'))
|
||
|
->from($this->_table_name)
|
||
|
->where($field, '=', $value)
|
||
|
->where($this->_primary_key, '!=', $this->pk())
|
||
|
->execute($this->_db)
|
||
|
->get('total_count');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Allows a model use both email and username as unique identifiers for login
|
||
|
*
|
||
|
* @param string unique value
|
||
|
* @return string field name
|
||
|
*/
|
||
|
public function unique_key($value)
|
||
|
{
|
||
|
return Valid::email($value) ? 'email' : 'username';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Password validation for plain passwords.
|
||
|
*
|
||
|
* @param array $values
|
||
|
* @return Validation
|
||
|
*/
|
||
|
public static function get_password_validation($values)
|
||
|
{
|
||
|
return Validation::factory($values)
|
||
|
->rule('password', 'min_length', array(':value', 8))
|
||
|
->rule('password_confirm', 'matches', array(':validation', ':field', 'password'));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Create a new user
|
||
|
*
|
||
|
* Example usage:
|
||
|
* ~~~
|
||
|
* $user = ORM::factory('user')->create_user($_POST, array(
|
||
|
* 'username',
|
||
|
* 'password',
|
||
|
* 'email',
|
||
|
* );
|
||
|
* ~~~
|
||
|
*
|
||
|
* @param array $values
|
||
|
* @param array $expected
|
||
|
* @throws ORM_Validation_Exception
|
||
|
*/
|
||
|
public function create_user($values, $expected)
|
||
|
{
|
||
|
// Validation for passwords
|
||
|
$extra_validation = Model_User::get_password_validation($values)
|
||
|
->rule('password', 'not_empty');
|
||
|
|
||
|
return $this->values($values, $expected)->create($extra_validation);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update an existing user
|
||
|
*
|
||
|
* [!!] We make the assumption that if a user does not supply a password, that they do not wish to update their password.
|
||
|
*
|
||
|
* Example usage:
|
||
|
* ~~~
|
||
|
* $user = ORM::factory('user')
|
||
|
* ->where('username', '=', 'kiall')
|
||
|
* ->find()
|
||
|
* ->update_user($_POST, array(
|
||
|
* 'username',
|
||
|
* 'password',
|
||
|
* 'email',
|
||
|
* );
|
||
|
* ~~~
|
||
|
*
|
||
|
* @param array $values
|
||
|
* @param array $expected
|
||
|
* @throws ORM_Validation_Exception
|
||
|
*/
|
||
|
public function update_user($values, $expected = NULL)
|
||
|
{
|
||
|
if (empty($values['password']))
|
||
|
{
|
||
|
unset($values['password'], $values['password_confirm']);
|
||
|
}
|
||
|
|
||
|
// Validation for passwords
|
||
|
$extra_validation = Model_User::get_password_validation($values);
|
||
|
|
||
|
return $this->values($values, $expected)->update($extra_validation);
|
||
|
}
|
||
|
|
||
|
} // End Auth User Model
|