Skip to content
Permalink
Browse files

Refactoring core session library to use a proper Session model instea…

…d of hard-coded SQL.
  • Loading branch information...
jperras committed Apr 13, 2009
1 parent 643651f commit 740c712fb59374469e0aa603d3f99b0b9b1e5cd9
Showing with 81 additions and 71 deletions.
  1. +61 −70 cake/libs/session.php
  2. +20 −1 cake/tests/cases/libs/session.test.php
@@ -27,16 +27,7 @@
* @lastmodified $Date$
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*/
/**
* Database name for cake sessions.
*
*/
if (!class_exists('Set')) {
require LIBS . 'set.php';
}
if (!class_exists('Security')) {
require LIBS . 'security.php';
}
/**
* Session class for Cake.
*
@@ -125,32 +116,49 @@ class CakeSession extends Object {
* @access public
*/
function __construct($base = null, $start = true) {
if (Configure::read('Session.save') === 'database' && !class_exists('ConnectionManager')) {
App::import('Core', 'ConnectionManager');
}
App::import('Core', 'Security');
$this->time = time();
if (Configure::read('Session.checkAgent') === true || Configure::read('Session.checkAgent') === null) {
if (env('HTTP_USER_AGENT') != null) {
$this->_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
}
}
$this->time = time();
if ($start === true) {
$this->host = env('HTTP_HOST');
if (Configure::read('Session.save') === 'database') {
$modelName = Configure::read('Session.model');
$database = Configure::read('Session.database');
$table = Configure::read('Session.table');
if (empty($base) || strpos($base, '?') === 0 || strpos($base, 'index.php') === 0) {
$this->path = '/';
if (empty($database)) {
$database = 'default';
}
if (empty($modelName)) {
ClassRegistry::init(array(
'class' => Inflector::classify($table),
'alias' => 'Session'
));
} else {
$this->path = $base;
ClassRegistry::init(array(
'class' => $modelName,
'alias' => 'Session'
));
}
}
if ($start === true) {
$this->host = env('HTTP_HOST');
if (strpos($this->host, ':') !== false) {
$this->host = substr($this->host, 0, strpos($this->host, ':'));
}
if (!class_exists('Security')) {
App::import('Core', 'Security');
if (empty($base) || strpos($base, '?') === 0 || strpos($base, 'index.php') === 0) {
$this->path = '/';
} else {
$this->path = $base;
}
$this->sessionTime = $this->time + (Security::inactiveMins() * Configure::read('Session.timeout'));
@@ -685,81 +693,60 @@ function __close() {
/**
* Method used to read from a database session.
*
* @param mixed $key The key of the value to read
* @param mixed $id The key of the value to read
* @return mixed The value of the key or false if it does not exist
* @access private
*/
function __read($key) {
$db =& ConnectionManager::getDataSource(Configure::read('Session.database'));
$table = $db->fullTableName(Configure::read('Session.table'), false);
$row = $db->query("SELECT " . $db->name($table.'.data') . " FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key), false);
function __read($id) {
$model = ClassRegistry::getObject('Session');
if ($row && !isset($row[0][$table]) && isset($row[0][0])) {
$table = 0;
}
$row = $model->find('first', array(
'conditions' => array($model->primaryKey => $id)
));
if ($row && $row[0][$table]['data']) {
return $row[0][$table]['data'];
} else {
if (empty($row[$model->alias]['data'])) {
return false;
}
return $row[$model->alias]['data'];
}
/**
* Helper function called on write for database sessions.
*
* @param mixed $key The name of the var
* @param mixed $value The value of the var
* @return boolean Success
* @param integer $id ID that uniquely identifies session in database
* @param mixed $data The value of the the data to be saved.
* @return boolean True for successful write, false otherwise.
* @access private
*/
function __write($key, $value) {
$db =& ConnectionManager::getDataSource(Configure::read('Session.database'));
$table = $db->fullTableName(Configure::read('Session.table'));
function __write($id, $data) {
switch (Configure::read('Security.level')) {
case 'high':
$factor = 10;
break;
case 'medium':
$factor = 100;
break;
case 'low':
$factor = 300;
break;
case 'high':
default:
$factor = 10;
break;
}
$expires = time() + Configure::read('Session.timeout') * $factor;
$row = $db->query("SELECT COUNT(id) AS count FROM " . $db->name($table) . " WHERE "
. $db->name('id') . " = "
. $db->value($key), false);
if ($row[0][0]['count'] > 0) {
$db->execute("UPDATE " . $db->name($table) . " SET " . $db->name('data') . " = "
. $db->value($value) . ", " . $db->name('expires') . " = "
. $db->value($expires) . " WHERE " . $db->name('id') . " = "
. $db->value($key));
} else {
$db->execute("INSERT INTO " . $db->name($table) . " (" . $db->name('data') . ","
. $db->name('expires') . "," . $db->name('id')
. ") VALUES (" . $db->value($value) . ", " . $db->value($expires) . ", "
. $db->value($key) . ")");
}
return true;
$expires = time() + Configure::read('Session.timeout') * $factor;
$return = ClassRegistry::getObject('Session')->save(compact('id', 'data', 'expires'));
return $return;
}
/**
* Method called on the destruction of a database session.
*
* @param integer $key Key that uniquely identifies session in database
* @return boolean Success
* @param integer $id ID that uniquely identifies session in database
* @return boolean True for successful delete, false otherwise.
* @access private
*/
function __destroy($key) {
$db =& ConnectionManager::getDataSource(Configure::read('Session.database'));
$table = $db->fullTableName(Configure::read('Session.table'));
$db->execute("DELETE FROM " . $db->name($table) . " WHERE " . $db->name($table.'.id') . " = " . $db->value($key));
return true;
function __destroy($id) {
$return = ClassRegistry::getObject('Session')->delete($id);
return $return;
}
/**
* Helper function called on gc for database sessions.
@@ -769,10 +756,14 @@ function __destroy($key) {
* @access private
*/
function __gc($expires = null) {
$db =& ConnectionManager::getDataSource(Configure::read('Session.database'));
$table = $db->fullTableName(Configure::read('Session.table'));
$db->execute("DELETE FROM " . $db->name($table) . " WHERE " . $db->name($table.'.expires') . " < ". $db->value(time()));
return true;
$model = ClassRegistry::getObject('Session');
if (!$expires) {
$expires = time();
}
$return = $model->deleteAll(array("$alias.expires <" => $expires), false, false);
return $return;
}
}
?>
?>
@@ -34,6 +34,12 @@
* @subpackage cake.tests.cases.libs
*/
class SessionTest extends CakeTestCase {
/**
* Fixtures used in the SessionTest
*
* @var array
* @access public
*/
var $fixtures = array('core.session');
/**
* setUp method
@@ -46,6 +52,16 @@ function setUp() {
$this->Session->start();
$this->Session->_checkValid();
}
/**
* tearDown method
*
* @access public
* @return void
*/
function tearDown() {
unset($_SESSION);
session_destroy();
}
/**
* testCheck method
*
@@ -366,6 +382,9 @@ function testReadAndWriteWithDatabaseStorage() {
$this->Session->write('SessionTestCase', 'This is a Test');
$this->assertEqual($this->Session->read('SessionTestCase'), 'This is a Test');
$this->Session->write('SessionTestCase', 'Some additional data');
$this->assertEqual($this->Session->read('SessionTestCase'), 'Some additional data');
$this->Session->destroy();
$this->assertFalse($this->Session->read('SessionTestCase'));
session_write_close();
@@ -376,4 +395,4 @@ function testReadAndWriteWithDatabaseStorage() {
$this->setUp();
}
}
?>
?>

0 comments on commit 740c712

Please sign in to comment.
You can’t perform that action at this time.