Fixing DatabaseSession handler to correctly close the session before the model object is destroyed by php.

This allows to remove an old hack in ConnectionManager
This commit is contained in:
Jose Lorenzo Rodriguez 2011-10-06 23:01:49 -04:30
parent 5eb4c5c6da
commit a14abd6281
2 changed files with 34 additions and 26 deletions

View file

@ -66,7 +66,6 @@ class ConnectionManager {
if (class_exists('DATABASE_CONFIG')) { if (class_exists('DATABASE_CONFIG')) {
self::$config = new DATABASE_CONFIG(); self::$config = new DATABASE_CONFIG();
} }
register_shutdown_function('ConnectionManager::shutdown');
self::$_init = true; self::$_init = true;
} }
@ -257,15 +256,4 @@ class ConnectionManager {
} }
return compact('package', 'classname', 'plugin'); return compact('package', 'classname', 'plugin');
} }
/**
* Destructor.
*
* @return void
*/
public static function shutdown() {
if (Configure::read('Session.defaults') == 'database' && function_exists('session_write_close')) {
session_write_close();
}
}
} }

View file

@ -23,6 +23,20 @@
*/ */
class DatabaseSession implements CakeSessionHandlerInterface { class DatabaseSession implements CakeSessionHandlerInterface {
/**
* Reference to the model handling the session data
*
* @var Model
*/
protected $_model;
/**
* Number of seconds to mark the session as expired
*
* @var int
*/
protected $_timeout;
/** /**
* Constructor. Looks at Session configuration information and * Constructor. Looks at Session configuration information and
* sets up the session model. * sets up the session model.
@ -43,7 +57,8 @@ class DatabaseSession implements CakeSessionHandlerInterface {
'alias' => 'Session', 'alias' => 'Session',
); );
} }
ClassRegistry::init($settings); $this->_model = ClassRegistry::init($settings);
$this->_timeout = Configure::read('Session.timeout') * 60;
} }
/** /**
@ -75,17 +90,15 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return mixed The value of the key or false if it does not exist * @return mixed The value of the key or false if it does not exist
*/ */
public function read($id) { public function read($id) {
$model = ClassRegistry::getObject('Session'); $row = $this->_model->find('first', array(
'conditions' => array($this->_model->primaryKey => $id)
$row = $model->find('first', array(
'conditions' => array($model->primaryKey => $id)
)); ));
if (empty($row[$model->alias]['data'])) { if (empty($row[$this->_model->alias]['data'])) {
return false; return false;
} }
return $row[$model->alias]['data']; return $row[$this->_model->alias]['data'];
} }
/** /**
@ -99,11 +112,10 @@ class DatabaseSession implements CakeSessionHandlerInterface {
if (!$id) { if (!$id) {
return false; return false;
} }
$expires = time() + (Configure::read('Session.timeout') * 60); $expires = time() + $this->_timeout;
$Session = ClassRegistry::getObject('Session');
$record = compact('id', 'data', 'expires'); $record = compact('id', 'data', 'expires');
$record[$Session->primaryKey] = $id; $record[$this->_model->primaryKey] = $id;
return $Session->save($record); return $this->_model->save($record);
} }
/** /**
@ -113,7 +125,7 @@ class DatabaseSession implements CakeSessionHandlerInterface {
* @return boolean True for successful delete, false otherwise. * @return boolean True for successful delete, false otherwise.
*/ */
public function destroy($id) { public function destroy($id) {
return ClassRegistry::getObject('Session')->delete($id); return $this->_model->delete($id);
} }
/** /**
@ -126,7 +138,15 @@ class DatabaseSession implements CakeSessionHandlerInterface {
if (!$expires) { if (!$expires) {
$expires = time(); $expires = time();
} }
$model = ClassRegistry::getObject('Session'); return $this->_model->deleteAll(array($model->alias . ".expires <" => $expires), false, false);
return $model->deleteAll(array($model->alias . ".expires <" => $expires), false, false); }
/**
* Closes the session before the objects handling it become unavailable
*
* @return void
*/
public function __destruct() {
session_write_close();
} }
} }