HOHO,既然用到了数据库,一般人应该也离不开 ORM 的吧?
自己修改的ko3 auth module,增加了非orm方式的auth驱动
modules\auth\classes\auth\database.php
<?php defined('SYSPATH') OR die('No direct access allowed.');
class Auth_Database extends Kohana_Auth_Database {}
modules\auth\classes\kohana\auth\database.php
<?php defined('SYSPATH') OR die('No direct access allowed.');
/**
* ORM Auth driver.
*
* $Id: database.php 4335 2009-12-23 10:21:02 Hutchin $
*
* @package Auth
* @author Hutchin
* @copyright (c) 2009-2010 Hutchin
* @license http://kohanaphp.com/license.html
*/
class Kohana_Auth_Database extends Auth {
/**
* Checks if a session is active.
*
* @param string role name
* @param array collection of role names
* @return boolean
*/
public function logged_in($role = NULL)
{
$status = FALSE;
// Get the user from the session
$user = $this->session->get($this->config['session_key']);
if (is_array($user) AND $user['id'] > 0)
{
// Everything is okay so far
$status = TRUE;
if ( ! empty($role))
{
// If role is an array
if (is_array($role))
{
// Check each role
foreach ($role as $role_iteration)
{
if ( ! is_array($role_iteration))
{
$role_iteration = DB::select('id','name')
->from('roles')
->where('name','=',$role_iteration)
->execute()
->get_first();
}
$count = DB::select(DB::expr('COUNT(*) AS mycount'))
->from('roles_users')
->where('role_id', '=', $role_iteration['id'])
->and_where('user_id', '=', $user['id'])
->execute()
->get('mycount');
// If the user doesn't have the role
if( ! $count )
{
// Set the status false and get outta here
$status = FALSE;
break;
}
}
}
else
{
// Else just check the one supplied roles
if ( ! is_array($role))
{
// Load the role
$role = DB::select('id','name')
->from('roles')
->where('name','=',$role)
->execute()
->get_first();
}
// Check that the user has the given role
$status = DB::select(DB::expr('COUNT(*) AS mycount'))
->from('roles_users')
->where('role_id', '=', $role['id'])
->andwhere('user_id', '=', $user['id'])
->execute()
->get('mycount');
}
}
}
return $status;
}
/**
* Logs a user in.
*
* @param string username
* @param string password
* @param boolean enable auto-login
* @return boolean
*/
public function _login($user, $password, $remember)
{
if ( ! is_array($user))
{
// Load the user
$user = DB::select('id','username','password','email','logins','last_login')
->from('users')
->where($this->config['login_key'],'=',$user)
->execute()
->get_first();
}
$role = DB::select('id','name')
->from('roles')
->where('name','=','login')
->execute()
->get_first();
$user_has_role = DB::select(DB::expr('COUNT(*) AS mycount'))
->from('roles_users')
->where('role_id', '=', $role['id'])
->and_where('user_id', '=', $user['id'])
->execute()
->get('mycount');
// If the passwords match, perform a login
if ($user_has_role AND $user['password'] === $password)
{
if ($remember === TRUE)
{
$token = $this->create_token();
// Create a new autologin token
DB::insert('tokens_users', array('user_id','expires','user_agent','created','token'))
->values(array($user['id'], time() + $this->config['lifetime'], sha1(Request::$user_agent), time(),$token))
->execute();
// Set the autologin cookie
cookie::set('authautologin', $token, $this->config['lifetime']);
}
// Finish the login
$this->complete_login($user);
return TRUE;
}
// Login failed
return FALSE;
}
/**
* Forces a user to be logged in, without specifying a password.
*
* @param mixed username
* @return boolean
*/
public function force_login($user)
{
if ( ! is_array($user))
{
// Load the user
$user = DB::select('id','username','password','email','logins','last_login')
->from('users')
->where($this->config['login_key'],'=',$user)
->execute()
->get_first();
}
// Mark the session as forced, to prevent users from changing account information
$this->session->set('auth_forced', TRUE);
// Run the standard completion
$this->complete_login($user);
}
/**
* Logs a user in, based on the authautologin cookie.
*
* @return boolean
*/
public function auto_login()
{
if ($token = cookie::get('authautologin'))
{
// Load the token and user
$token = DB::select('id','user_id','expires','user_agent','created','token')
->from('tokens_users')
->where('token','=',$token)
->execute()
->get_first();
$user = DB::select('id','username','password','email','logins','last_login')
->from('users')
->where('id','=',$token['user_id'])
->execute()
->get_first();
if ($token['user_id'] AND $user['id'])
{
if ($token['user_agent'] === sha1(Request::$user_agent))
{
$new_token = $this->create_token();
// Save the token to create a new unique token
DB::update('tokens_users')
->set(array('token'=>$new_token))
->where('id','=',$token['id'])
->execute();
// Set the new token
cookie::set('authautologin', $new_token, $token['expires'] - time());
// Complete the login with the found data
$this->complete_login($user);
// Automatic login was successful
return TRUE;
}
}
}
return FALSE;
}
/**
* Log a user out and remove any auto-login cookies.
*
* @param boolean completely destroy the session
* @param boolean remove all tokens for user
* @return boolean
*/
public function logout($destroy = FALSE, $logout_all = FALSE)
{
if ($token = cookie::get('authautologin'))
{
// Delete the autologin cookie to prevent re-login
cookie::delete('authautologin');
// Clear the autologin token from the database
$token = DB::select('id','user_id','expires','user_agent','created','token')
->from('tokens_users')
->where('token','=',$token)
->execute()
->get_first();
if ($token['id'] AND $logout_all)
{
DB::delete('tokens_users')
->where('user_id', '=', $token['user_id'])
->execute();
}
elseif ($token['id'])
{
DB::delete('tokens_users')
->where('id', '=', $token['id'])
->execute();
}
}
return parent::logout($destroy);
}
/**
* Get the stored password for a username.
*
* @param mixed username
* @return string
*/
public function password($user)
{
if ( ! is_array($user))
{
// Load the user
$user = DB::select('id','username','password','email','logins','last_login')
->from('users')
->where($this->config['login_key'],'=',$user)
->execute()
->get_first();;
}
return $user['password'];
}
/**
* Complete the login for a user by incrementing the logins and setting
* session data: user_id, username, roles
*
* @param object user model object
* @return void
*/
protected function complete_login($user)
{
$total_rows = DB::update('users')
->set(array('logins'=>$user['logins'] + 1, 'last_login'=>time()))
->where('id','=',$user['id'])
->execute();
return parent::complete_login($user);
}
/**
* Finds a new unique token, using a loop to make sure that the token does
* not already exist in the database. This could potentially become an
* infinite loop, but the chances of that happening are very unlikely.
*
* @return string
*/
protected function create_token()
{
while (TRUE)
{
// Create a random token
$token = text::random('alnum', 32);
// Make sure the token does not already exist
$count = DB::select('id')
->where('token', '=', $token)
->from('tokens_users')
->execute()
->count();
if ($count === 0)
{
// A unique token has been found
return $token;
}
}
}
} // End Auth_Database_Driver
在config中设置'driver' => 'Database',就可正常使用
返回的user模型为数组
HOHO,既然用到了数据库,一般人应该也离不开 ORM 的吧?
据我了解orm似乎需要mysql的innodb引擎支持,但我只想用myisam引擎,所以改了下
我觉得innodb引擎蛮好,外键功能蛮好。呵呵
呃。没有强制需要的,是不是你的哪里没有调试好。
目前本论坛的数据库表是纯 MyISAM 引擎的..
哦?那可能真的是我没调试好,不知道orm需要外键支持不?
如果是需要的话只能用innodb引擎了,
另外,我做的项目是查询量大,而insert,update不多,所以用myisam还是不错的,
查询中有很多sql语句非常复杂,没办法用orm去完成,还是手写的sql效率高些,呵呵.
不管怎么说,经过我的补充,auth已经很完整了,可以不依赖orm扩展就可以运行
ORM 不涉及数据库引擎的,数据库逻辑是大部分支持的,因为 Database 支持 PDO 的,所以并不存在“专政”一个数据库的。
看来是我误会orm了,不过orm的效率到底是不太高,还是自己写的sql来的更快
发表讨论