* Copyright 2001-2012 Strangecode, LLC
*
* This file is part of The Strangecode Codebase.
*
* The Strangecode Codebase is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* The Strangecode Codebase is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* The Strangecode Codebase. If not, see .
*/
/**
* DBSessionHandler.inc.php
*
*
* @author Quinn Comendant
* @version 2.1
* @since 1999
*/
class DBSessionHandler
{
public $db; // DB object.
protected $_params = array(
'db_table' => 'session_tbl',
// Automatically create table and verify columns. Better set to false after site launch.
// This value is overwritten by the $app->getParam('db_create_tables') setting if it is available.
'create_table' => true,
);
/**
* Constructor
*
* @access public
* @param
* @return
* @author Quinn Comendant
* @since 18 Jul 2005 11:02:50
*/
public function __construct($db, $params=array())
{
$app =& App::getInstance();
$this->_params = array_merge($this->_params, $params);
if (!method_exists($db, 'isConnected')) {
$app->logMsg(sprintf('Provided object (%s) is not a valid DB object.', get_class($db)), LOG_ERR, __FILE__, __LINE__);
} else {
if (!$db->isConnected()) {
$app->logMsg('Provided DB object is not connected.', LOG_ERR, __FILE__, __LINE__);
} else {
// OK! We have a valid, connected DB object.
$this->db =& $db;
// Get create tables config from global context.
if (!is_null($app->getParam('db_create_tables'))) {
$this->_params['create_table'] = $app->getParam('db_create_tables');
}
// Ensure db table is fit.
$this->initDB();
session_set_save_handler(
array(&$this, 'dbSessionOpen'),
array(&$this, 'dbSessionClose'),
array(&$this, 'dbSessionRead'),
array(&$this, 'dbSessionWrite'),
array(&$this, 'dbSessionDestroy'),
array(&$this, 'dbSessionGarbage')
);
register_shutdown_function('session_write_close');
}
}
}
/**
* Setup the database table for this class.
*
* @access public
* @author Quinn Comendant
* @since 26 Aug 2005 17:09:36
*/
public function initDB($recreate_db=false)
{
$app =& App::getInstance();
static $_db_tested = false;
if ($recreate_db || !$_db_tested && $this->_params['create_table']) {
if ($recreate_db) {
$this->db->query("DROP TABLE IF EXISTS " . $this->db->escapeString($this->_params['db_table']));
$app->logMsg(sprintf('Dropping and recreating table %s.', $this->_params['db_table']), LOG_INFO, __FILE__, __LINE__);
}
$this->db->query("CREATE TABLE IF NOT EXISTS " . $this->db->escapeString($this->_params['db_table']) . " (
`session_id` VARCHAR(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT '',
`session_data` MEDIUMTEXT NOT NULL,
`last_access` TIMESTAMP NOT NULL,
PRIMARY KEY `session_id` (`session_id`),
KEY `last_access` (`last_access`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
if (!$this->db->columnExists($this->_params['db_table'], array(
'session_id',
'session_data',
'last_access'
), false, false)) {
$app->logMsg(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->_params['db_table']), LOG_ALERT, __FILE__, __LINE__);
trigger_error(sprintf('Database table %s has invalid columns. Please update this table manually.', $this->_params['db_table']), E_USER_ERROR);
}
}
$_db_tested = true;
}
public function dbSessionOpen($save_path, $sess_name)
{
return true;
}
public function dbSessionClose()
{
return true;
}
public function dbSessionRead($session_id)
{
// Select the data belonging to session $session_id from the session table
$qid = $this->db->query("SELECT session_data FROM " . $this->db->escapeString($this->_params['db_table']) . " WHERE session_id = '" . $this->db->escapeString($session_id) . "'");
// Return the session data that was found
if (mysql_num_rows($qid) == 1) {
$row = mysql_fetch_row($qid);
return $row[0];
}
// NOTICE: Output is expected to be an empty string always rather than 'false'.
return '';
}
public function dbSessionWrite($session_id, $session_data)
{
// Write the serialized session data ($session_data) to the session table
$this->db->query("REPLACE INTO " . $this->db->escapeString($this->_params['db_table']) . "(session_id, session_data, last_access) VALUES ('" . $this->db->escapeString($session_id) . "', '" . $this->db->escapeString($session_data) . "', null)");
return true;
}
public function dbSessionDestroy($session_id)
{
// Delete from the table all data for the session $session_id
$this->db->query("DELETE FROM " . $this->db->escapeString($this->_params['db_table']) . " WHERE session_id = '" . $this->db->escapeString($session_id) . "'");
return true;
}
public function dbSessionGarbage($max_lifetime=72000)
{
// Delete old values from the session table.
$qid = $this->db->query("DELETE FROM " . $this->db->escapeString($this->_params['db_table']) . " WHERE UNIX_TIMESTAMP(last_access) < " . (time() - $max_lifetime));
return true;
}
}