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
View
@@ -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.