core/model/modx/modsessionhandler.class.php
<?php
/*
* This file is part of MODX Revolution.
*
* Copyright (c) MODX, LLC. All Rights Reserved.
*
* For complete copyright and license information, see the COPYRIGHT and LICENSE
* files found in the top-level directory of this distribution.
*/
/**
* Default database session handler class for MODX.
*
* @package modx
*/
class modSessionHandler {
/**
* @var modX A reference to the modX instance controlling this session
* handler.
* @access public
*/
public $modx= null;
/**
* @var int The maximum lifetime of the session
*/
public $gcMaxLifetime= 0;
/**
* @var int The maximum lifetime of the cache of the session
*/
public $cacheLifetime= false;
/**
* @var modSession The Session object
*/
private $session = null;
/**
* Creates an instance of a modSessionHandler class.
*
* @param modX &$modx A reference to a {@link modX} instance.
* @return modSessionHandler
*/
function __construct(modX &$modx) {
$this->modx= & $modx;
$gcMaxlifetime = (integer) $this->modx->getOption('session_gc_maxlifetime');
if ($gcMaxlifetime > 0) {
$this->gcMaxLifetime= $gcMaxlifetime;
} else {
$this->gcMaxLifetime= (integer) @ini_get('session.gc_maxlifetime');
}
if ($this->modx->getOption('cache_db_session', null, false)) {
$cacheLifetime = $this->modx->getOption('cache_db_session_lifetime', null, false);
if ((integer) $cacheLifetime > 0) {
$this->cacheLifetime = (integer) $cacheLifetime;
} elseif ($cacheLifetime !== false && $this->gcMaxLifetime > 0) {
$this->cacheLifetime = $this->gcMaxLifetime / 4;
}
}
}
/**
* Opens the connection for the session handler.
*
* @access public
* @return boolean Always returns true; actual connection is managed by
* {@link modX}.
*/
public function open() {
return true;
}
/**
* Closes the connection for the session handler.
*
* @access public
* @return boolean Always returns true; actual connection is managed by
* {@link modX}
*/
public function close() {
return true;
}
/**
* Reads a specific {@link modSession} record's data.
*
* @access public
* @param integer $id The pk of the {@link modSession} object.
* @return string The data read from the {@link modSession} object.
*/
public function read($id) {
if ($this->_getSession($id)) {
$data= $this->session->get('data');
} else {
$data= '';
}
return (string) $data;
}
/**
* Writes data to a specific {@link modSession} object.
*
* @access public
* @param integer $id The PK of the modSession object.
* @param mixed $data The data to write to the session.
* @return boolean True if successfully written.
*/
public function write($id, $data) {
$written= false;
if ($this->_getSession($id, true)) {
$this->session->set('data', $data);
if ($this->session->isNew() || $this->session->isDirty('data') || ($this->cacheLifetime > 0 && (time() - strtotime($this->session->get('access'))) > $this->cacheLifetime)) {
$this->session->set('access', time());
}
$written= $this->session->save($this->cacheLifetime);
}
return $written;
}
/**
* Destroy a specific {@link modSession} record.
*
* @access public
* @param integer $id
* @return boolean True if the session record was destroyed.
*/
public function destroy($id) {
if ($this->_getSession($id)) {
$destroyed= $this->session->remove();
} else {
$destroyed= true;
}
return $destroyed;
}
/**
* Remove any expired sessions.
*
* @access public
* @param integer $max The amount of time since now to expire any session
* longer than.
* @return boolean True if session records were removed.
*/
public function gc($max) {
$maxtime= time() - $this->gcMaxLifetime;
return $this->modx->removeCollection('modSession', array("{$this->modx->escape('access')} < {$maxtime}"));
}
/**
* Gets the {@link modSession} object, respecting the cache flag represented by cacheLifetime.
*
* @access protected
* @param integer $id The PK of the {@link modSession} record.
* @param boolean $autoCreate If true, will automatically create the session
* record if none is found.
* @return modSession|null The modSession instance loaded from db or auto-created; null if it
* could not be retrieved and/or created.
*/
protected function _getSession($id, $autoCreate= false) {
$this->session= $this->modx->getObject('modSession', array('id' => $id), $this->cacheLifetime);
if ($autoCreate && !is_object($this->session)) {
$this->session= $this->modx->newObject('modSession');
$this->session->set('id', $id);
}
if (!($this->session instanceof modSession) || $id != $this->session->get('id') || !$this->session->validate()) {
if ($this->modx->getSessionState() == modX::SESSION_STATE_INITIALIZED) {
$this->modx->log(modX::LOG_LEVEL_INFO, 'There was an error retrieving or creating session id: ' . $id);
}
}
return $this->session;
}
}