diff --git a/includes/http/Session.php b/includes/http/Session.php index 8171d8684d34f6626ebc78d55d9517c1b4fe5e69..d81a69e3b2f3bf7fdd3fe5970dc13844b15805b5 100644 --- a/includes/http/Session.php +++ b/includes/http/Session.php @@ -9,7 +9,7 @@ ************************************************************************************/ // Import dependencies -include_once 'libraries/HTTP_Session/Session.php'; +include_once 'libraries/HTTP_Session2/HTTP/Session2.php'; /** * Session class @@ -27,7 +27,7 @@ class Vtiger_Session { * Destroy session */ static function destroy($sessionid = false) { - HTTP_Session::destroy($sessionid); + HTTP_Session2::destroy($sessionid); } /** @@ -35,13 +35,13 @@ class Vtiger_Session { */ static function init($sessionid = false) { if(empty($sessionid)) { - HTTP_Session::start(null, null); - $sessionid = HTTP_Session::id(); + HTTP_Session2::start(null, null); + $sessionid = HTTP_Session2::id(); } else { - HTTP_Session::start(null, $sessionid); + HTTP_Session2::start(null, $sessionid); } - if(HTTP_Session::isIdle() || HTTP_Session::isExpired()) { + if(HTTP_Session2::isIdle() || HTTP_Session2::isExpired()) { return false; } return $sessionid; @@ -51,21 +51,21 @@ class Vtiger_Session { * Is key defined in session? */ static function has($key) { - return HTTP_Session::is_set($key); + return HTTP_Session2::is_set($key); } /** * Get value for the key. */ static function get($key, $defvalue = '') { - return HTTP_Session::get($key, $defvalue); + return HTTP_Session2::get($key, $defvalue); } /** * Set value for the key. */ static function set($key, $value) { - HTTP_Session::set($key, $value); + HTTP_Session2::set($key, $value); } } \ No newline at end of file diff --git a/libraries/HTTP_Session/Session.php b/libraries/HTTP_Session/Session.php deleted file mode 100644 index c811c0ba78230ce37b42a4b34c3821f654ca1cba..0000000000000000000000000000000000000000 --- a/libraries/HTTP_Session/Session.php +++ /dev/null @@ -1,804 +0,0 @@ -<?php - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Class for managing HTTP sessions - * - * Provides access to session-state values as well as session-level - * settings and lifetime management methods. - * Based on the standart PHP session handling mechanism - * it provides for you more advanced features such as - * database container, idle and expire timeouts, etc. - * - * PHP version 4 - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @category HTTP - * @package HTTP_Session - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: Session.php,v 1.15 2007/07/14 12:11:54 troehr Exp $ - * @link http://pear.php.net/package/HTTP_Session - * @since File available since Release 0.4.0 - */ - -// @const HTTP_SESSION_STARTED - The session was started with the current request -define("HTTP_SESSION_STARTED", 1); -// @const HTTP_SESSION_STARTED - No new session was started with the current request -define("HTTP_SESSION_CONTINUED", 2); - -/** - * Class for managing HTTP sessions - * - * Provides access to session-state values as well as session-level - * settings and lifetime management methods. - * Based on the standart PHP session handling mechanism - * it provides for you more advanced features such as - * database container, idle and expire timeouts, etc. - * - * Example 1: - * - * <code> - * // Setting some options and detecting of a new session - * HTTP_Session::setCookieless(false); - * HTTP_Session::start('MySessionID'); - * HTTP_Session::set('variable', 'Tet string'); - * if (HTTP_Session::isNew()) { - * echo('new session was created with the current request'); - * $visitors++; // Increase visitors count - * } - * - * //HTTP_Session::regenerateId(); - * </code> - * - * Example 2: - * - * <code> - * // Using database container - * HTTP_Session::setContainer('DB'); - * HTTP_Session::start(); - * </code> - * - * Example 3: - * - * <code> - * // Setting timeouts - * HTTP_Session::start(); - * HTTP_Session::setExpire(time() + 60 * 60); // expires in one hour - * HTTP_Session::setIdle(time()+ 10 * 60); // idles in ten minutes - * if (HTTP_Session::isExpired()) { - * // expired - * echo('Your session is expired!'); - * HTTP_Session::destroy(); - * } - * if (HTTP_Session::isIdle()) { - * // idle - * echo('You've been idle for too long!'); - * HTTP_Session::destroy(); - * } - * HTTP_Session::updateIdle(); - * </code> - * - * @category HTTP - * @package HTTP_Session - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTTP_Session - * @since Class available since Release 0.4.0 - */ -class HTTP_Session -{ - /** - * Sets user-defined session storage functions - * - * Sets the user-defined session storage functions which are used - * for storing and retrieving data associated with a session. - * This is most useful when a storage method other than - * those supplied by PHP sessions is preferred. - * i.e. Storing the session data in a local database. - * - * @param string $container Container name - * @param array $container_options Container options - * - * @static - * @access public - * @return void - * @see session_set_save_handler() - */ - function setContainer($container, $container_options = null) - { - $container_class = 'HTTP_Session_Container_' . $container; - $container_classfile = 'HTTP/Session/Container/' . $container . '.php'; - - include_once $container_classfile; - $container = new $container_class($container_options); - - $container->set(); - } - - /** - * Initializes session data - * - * Creates a session (or resumes the current one - * based on the session id being passed - * via a GET variable or a cookie). - * You can provide your own name and/or id for a session. - * - * @param string $name string Name of a session, default is 'SessionID' - * @param string $id string Id of a session which will be used - * only when the session is new - * - * @static - * @access public - * @return void - * @see session_name() - * @see session_id() - * @see session_start() - */ - function start($name = 'SessionID', $id = null) - { - HTTP_Session::name($name); - if ($id) { - HTTP_Session::id($id); - } elseif (is_null(HTTP_Session::detectID())) { - HTTP_Session::id($id ? $id : uniqid(dechex(rand()))); - } - session_start(); - if (!isset($_SESSION['__HTTP_Session_Info'])) { - $_SESSION['__HTTP_Session_Info'] = HTTP_SESSION_STARTED; - } else { - $_SESSION['__HTTP_Session_Info'] = HTTP_SESSION_CONTINUED; - } - } - - /** - * Writes session data and ends session - * - * Session data is usually stored after your script - * terminated without the need to call HTTP_Session::stop(), - * but as session data is locked to prevent concurrent - * writes only one script may operate on a session at any time. - * When using framesets together with sessions you will - * experience the frames loading one by one due to this - * locking. You can reduce the time needed to load all the - * frames by ending the session as soon as all changes - * to session variables are done. - * - * @static - * @access public - * @return void - * @see session_write_close() - */ - function pause() - { - session_write_close(); - } - - /** - * Frees all session variables and destroys all data - * registered to a session - * - * This method resets the $_SESSION variable and - * destroys all of the data associated - * with the current session in its storage (file or DB). - * It forces new session to be started after this method - * is called. It does not unset the session cookie. - * - * @static - * @access public - * @return void - * @see session_unset() - * @see session_destroy() - */ - function destroy() - { - session_unset(); - session_destroy(); - - // set session handlers again to avoid fatal error in case - // HTTP_Session::start() will be called afterwards - if (isset($GLOBALS['HTTP_Session_Container']) && - is_a($GLOBALS['HTTP_Session_Container'], 'HTTP_Session_Container')) { - $GLOBALS['HTTP_Session_Container']->set(); - } - } - - /** - * Calls session_regenerate_id() if available - * - * @param bool $deleteOldSessionData Whether to delete data of old session - * - * @static - * @access public - * @return bool - */ - function regenerateId($deleteOldSessionData = false) - { - if (function_exists('session_regenerate_id')) { - return session_regenerate_id($deleteOldSessionData); - - // emulate session_regenerate_id() - } else { - - do { - $newId = uniqid(dechex(rand())); - } while ($newId === session_id()); - - if ($deleteOldSessionData) { - session_unset(); - } - - session_id($newId); - - return true; - } - } - - /** - * This function copies session data of specified id to specified table - * - * @param string $targetTable Table to replicate data to - * @param string $id ID of the session - * - * @static - * @access public - * @return bool - */ - function replicate($targetTable, $id = null) - { - return $GLOBALS['HTTP_Session_Container']->replicate($targetTable, $id); - } - - /** - * Free all session variables - * - * @todo TODO Save expire and idle timestamps? - * @static - * @access public - * @return void - */ - function clear() - { - $info = $_SESSION['__HTTP_Session_Info']; - session_unset(); - $_SESSION['__HTTP_Session_Info'] = $info; - } - - /** - * Tries to find any session id in $_GET, $_POST or $_COOKIE - * - * @static - * @access private - * @return string Session ID (if exists) or null - */ - function detectID() - { - if (HTTP_Session::useCookies()) { - if (isset($_COOKIE[HTTP_Session::name()])) { - return $_COOKIE[HTTP_Session::name()]; - } - } else { - if (isset($_GET[HTTP_Session::name()])) { - return $_GET[HTTP_Session::name()]; - } - if (isset($_POST[HTTP_Session::name()])) { - return $_POST[HTTP_Session::name()]; - } - } - return null; - } - - /** - * Sets new name of a session - * - * @param string $name New name of a session - * - * @static - * @access public - * @return string Previous name of a session - * @see session_name() - */ - function name($name = null) - { - return isset($name) ? session_name($name) : session_name(); - } - - /** - * Sets new ID of a session - * - * @param string $id New ID of a session - * - * @static - * @access public - * @return string Previous ID of a session - * @see session_id() - */ - function id($id = null) - { - return isset($id) ? session_id($id) : session_id(); - } - - /** - * Sets the maximum expire time - * - * @param integer $time Time in seconds - * @param bool $add Add time to current expire time or not - * - * @static - * @access public - * @return void - */ - function setExpire($time, $add = false) - { - if ($add) { - if (!isset($_SESSION['__HTTP_Session_Expire_TS'])) { - $_SESSION['__HTTP_Session_Expire_TS'] = time() + $time; - } - - // update session.gc_maxlifetime - $currentGcMaxLifetime = HTTP_Session::setGcMaxLifetime(null); - HTTP_Session::setGcMaxLifetime($currentGcMaxLifetime + $time); - - } elseif (!isset($_SESSION['__HTTP_Session_Expire_TS'])) { - $_SESSION['__HTTP_Session_Expire_TS'] = $time; - } - } - - /** - * Sets the maximum idle time - * - * Sets the time-out period allowed - * between requests before the session-state - * provider terminates the session. - * - * @param int $time Time in seconds - * @param bool $add Add time to current maximum idle time or not - * - * @static - * @access public - * @return void - */ - function setIdle($time, $add = false) - { - if ($add) { - $_SESSION['__HTTP_Session_Idle'] = $time; - } else { - // substract time again because it doesn't make any sense to provide - // the idle time as a timestamp - // keep $add functionality to provide BC - $_SESSION['__HTTP_Session_Idle'] = $time - time(); - } - } - - /** - * Returns the time up to the session is valid - * - * @static - * @access public - * @return integer Time when the session idles - */ - function sessionValidThru() - { - if (!isset($_SESSION['__HTTP_Session_Idle_TS']) || - !isset($_SESSION['__HTTP_Session_Idle'])) { - return 0; - } else { - return $_SESSION['__HTTP_Session_Idle_TS'] + - $_SESSION['__HTTP_Session_Idle']; - } - } - - /** - * Check if session is expired - * - * @static - * @access public - * @return bool - */ - function isExpired() - { - if (isset($_SESSION['__HTTP_Session_Expire_TS']) && - $_SESSION['__HTTP_Session_Expire_TS'] < time()) { - return true; - } else { - return false; - } - } - - /** - * Check if session is idle - * - * @static - * @access public - * @return bool - */ - function isIdle() - { - if (isset($_SESSION['__HTTP_Session_Idle_TS']) && - (($_SESSION['__HTTP_Session_Idle_TS'] + - $_SESSION['__HTTP_Session_Idle']) < time())) { - return true; - } else { - return false; - } - } - - /** - * Updates the idletime - * - * @static - * @access public - * @return void - */ - function updateIdle() - { - $_SESSION['__HTTP_Session_Idle_TS'] = time(); - } - - /** - * If optional parameter is specified it indicates - * whether the module will use cookies to store - * the session id on the client side - * - * It returns the previous value of this property - * - * @param bool $useCookies If specified it will replace the previous value - * of this property - * - * @static - * @access public - * - * @return bool The previous value of the property - */ - function useCookies($useCookies = null) - { - $return = ini_get('session.use_cookies') ? true : false; - if (isset($useCookies)) { - ini_set('session.use_cookies', $useCookies ? 1 : 0); - } - return $return; - } - - /** - * Gets a value indicating whether the session - * was created with the current request - * - * You MUST call this method only after you have started - * the session with the HTTP_Session::start() method. - * - * @static - * @access public - * @return bool True if the session was created - * with the current request, false otherwise - */ - function isNew() - { - // The best way to check if a session is new is to check - // for existence of a session data storage - // with the current session id, but this is impossible - // with the default PHP module wich is 'files'. - // So we need to emulate it. - return !isset($_SESSION['__HTTP_Session_Info']) || - $_SESSION['__HTTP_Session_Info'] == HTTP_SESSION_STARTED; - } - - /** - * Register variable with the current session - * - * @param string $name Name of a global variable - * - * @deprecated Use set()/setRef() instead - * - * @static - * @access public - * @return bool - * @see session_register() - */ - function register($name) - { - return session_register($name); - } - - /** - * Unregister a variable from the current session - * - * @param string $name Name of a global variable - * - * @deprecated Use get()/getRef() instead - * - * @static - * @access public - * @return bool - * @see session_unregister() - */ - function unregister($name) - { - return session_unregister($name); - } - - /** - * Checks if a session variable is registered - * - * @param string $name Variable name - * - * @deprecated Use is_set() instead - * - * @static - * @access public - * @return bool - */ - function registered($name) - { - return session_is_registered($name); - } - - /** - * Returns session variable - * - * @param string $name Name of a variable - * @param mixed $default Default value of a variable if not set - * - * @static - * @access public - * @return mixed Value of a variable - */ - function get($name, $default = null) - { - if (!isset($_SESSION[$name]) && isset($default)) { - $_SESSION[$name] = $default; - } - $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null; - return $return; - } - - /** - * Returns session variable by reference - * - * @param string $name Name of a variable - * - * @static - * @access public - * @return mixed Value of a variable - */ - function &getRef($name) - { - if (isset($_SESSION[$name])) { - $return =& $_SESSION[$name]; - } else { - $return = null; - } - - return $return; - } - - /** - * Sets session variable - * - * @param string $name Name of a variable - * @param mixed $value Value of a variable - * - * @static - * @access public - * @return mixed Old value of a variable - */ - function set($name, $value) - { - $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null; - if (null === $value) { - unset($_SESSION[$name]); - } else { - $_SESSION[$name] = $value; - } - return $return; - } - - /** - * Sets session variable by reference - * - * @param string $name Name of a variable - * @param mixed $value Value of a variable - * - * @static - * @access public - * @return mixed Old value of a variable - */ - function setRef($name, &$value) - { - $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null; - - $_SESSION[$name] =& $value; - - return $return; - } - - /** - * Checks if a session variable is set - * - * @param string $name Variable name - * - * @static - * @access public - * @return bool - */ - function is_set($name) - { - return isset($_SESSION[$name]); - } - - /** - * Returns local variable of a script - * - * Two scripts can have local variables with the same names - * - * @param string $name Name of a variable - * @param mixed $default Default value of a variable if not set - * - * @static - * @access public - * @return mixed Value of a local variable - */ - function &getLocal($name, $default = null) - { - $local = md5(HTTP_Session::localName()); - if (!isset($_SESSION[$local]) || !is_array($_SESSION[$local])) { - $_SESSION[$local] = array(); - } - if (!isset($_SESSION[$local][$name]) && isset($default)) { - $_SESSION[$local][$name] = $default; - } - return $_SESSION[$local][$name]; - } - - /** - * Sets local variable of a script. - * Two scripts can have local variables with the same names. - * - * @param string $name Name of a local variable - * @param mixed $value Value of a local variable - * - * @static - * @access public - * @return mixed Old value of a local variable - */ - function setLocal($name, $value) - { - $local = md5(HTTP_Session::localName()); - if (!isset($_SESSION[$local]) || !is_array($_SESSION[$local])) { - $_SESSION[$local] = array(); - } - $return = (isset($_SESSION[$local][$name])) ? $_SESSION[$local][$name] - : null; - - if (null === $value) { - unset($_SESSION[$local][$name]); - } else { - $_SESSION[$local][$name] = $value; - } - return $return; - } - - /** - * Sets new local name - * - * @param string $name New local name - * - * @static - * @access public - * @return string Previous local name - */ - function localName($name = null) - { - $return = (isset($GLOBALS['__HTTP_Session_Localname'])) ? $GLOBALS['__HTTP_Session_Localname'] - : null; - - if (!empty($name)) { - $GLOBALS['__HTTP_Session_Localname'] = $name; - } - return $return; - } - - /** - * Initialize - * - * @static - * @access private - * @return void - */ - function _init() - { - // Disable auto-start of a sesion - ini_set('session.auto_start', 0); - - // Set local name equal to the current script name - HTTP_Session::localName($_SERVER['PHP_SELF']); - } - - /** - * If optional parameter is specified it indicates - * whether the session id will automatically be appended to - * all links - * - * It returns the previous value of this property - * - * @param bool $useTransSID If specified it will replace the previous value - * of this property - * - * @static - * @access public - * @return bool The previous value of the property - */ - function useTransSID($useTransSID = null) - { - $return = ini_get('session.use_trans_sid') ? true : false; - if (isset($useTransSID)) { - ini_set('session.use_trans_sid', $useTransSID ? 1 : 0); - } - return $return; - } - - /** - * If optional parameter is specified it determines the number of seconds - * after which session data will be seen as 'garbage' and cleaned up - * - * It returns the previous value of this property - * - * @param bool $gcMaxLifetime If specified it will replace the previous value - * of this property - * - * @static - * @access public - * @return bool The previous value of the property - */ - function setGcMaxLifetime($gcMaxLifetime = null) - { - $return = ini_get('session.gc_maxlifetime'); - if (isset($gcMaxLifetime) && is_int($gcMaxLifetime) && $gcMaxLifetime >= 1) { - ini_set('session.gc_maxlifetime', $gcMaxLifetime); - } - return $return; - } - - /** - * If optional parameter is specified it determines the - * probability that the gc (garbage collection) routine is started - * and session data is cleaned up - * - * It returns the previous value of this property - * - * @param bool $gcProbability If specified it will replace the previous value - * of this property - * - * @static - * @access public - * @return bool The previous value of the property - */ - function setGcProbability($gcProbability = null) - { - $return = ini_get('session.gc_probability'); - if (isset($gcProbability) && - is_int($gcProbability) && - $gcProbability >= 1 && - $gcProbability <= 100) { - ini_set('session.gc_probability', $gcProbability); - } - return $return; - } -} - -HTTP_Session::_init(); -?> \ No newline at end of file diff --git a/libraries/HTTP_Session/Session/Container.php b/libraries/HTTP_Session/Session/Container.php deleted file mode 100644 index ba85fa2a7a94e6625820431dc7ca8b93291b6cf4..0000000000000000000000000000000000000000 --- a/libraries/HTTP_Session/Session/Container.php +++ /dev/null @@ -1,280 +0,0 @@ -<?php - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Container class for storing session data - * - * PHP version 4 - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @category HTTP - * @package HTTP_Session - * @author Alexander Radivanovich <info@wwwlab.net> - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: Container.php,v 1.8 2007/07/14 12:11:54 troehr Exp $ - * @link http://pear.php.net/package/HTTP_Session - * @since File available since Release 0.4.0 - */ - -/** - * Container class for storing session data - * - * @category HTTP - * @package HTTP_Session - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTTP_Session - * @since Class available since Release 0.4.0 - */ -class HTTP_Session_Container -{ - /** - * Additional options for the container object - * - * @var array - * @access private - */ - var $options = array(); - - /** - * Constrtuctor method - * - * @param array $options Additional options for the container object - * - * @access public - * @return object - */ - function HTTP_Session_Container($options = null) - { - $this->_setDefaults(); - if (is_array($options)) { - $this->_parseOptions(); - } - } - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - } - - /** - * Parse options passed to the container class - * - * @param array $options Options - * - * @access private - * @return void - */ - function _parseOptions($options) - { - foreach ($options as $option => $value) { - if (in_array($option, array_keys($this->options))) { - $this->options[$option] = $value; - } - } - } - - /** - * This function is called by the session handler to initialize things - * - * @param string $save_path Save path - * @param string $session_name Session name - * - * @access public - * @return bool - */ - function open($save_path, $session_name) - { - return true; - } - - /** - * This function is called when the page is finished - * executing and the session handler needs to close things off - * - * Has to be overwritten by each container class - * - * @access public - * @return bool - */ - function close() - { - return true; - } - - /** - * This function is called by the session handler - * to read the data associated with a given session ID. - * This function must retrieve and return the session data - * for the session identified by $id. - * - * Has to be overwritten by each container class - * - * @param string $id ID of the session - * - * @access public - * @return string - */ - function read($id) - { - return ''; - } - - /** - * This function is called when the session handler - * has session data to save, which usually happens - * at the end of your script - * - * Has to be overwritten by each container class - * - * @param string $id ID of the session - * @param mixed $data The data associated with a given session ID - * - * @access public - * @return bool - */ - function write($id, $data) - { - return true; - } - - /** - * This function is called when a session is destroyed. - * It is responsible for deleting the session and cleaning things up. - * - * Has to be overwritten by each container class - * - * @param string $id ID of the session - * - * @access public - * @return bool - */ - function destroy($id) - { - return true; - } - - /** - * This function copies session data of specified id to specified table - * - * Has to be overwritten by each container class - * - * @param string $targetTable Table to replicate data to - * @param string $id ID of the session - * - * @access public - * @return bool - */ - function replicate($targetTable, $id = null) - { - return true; - } - - /** - * This function is responsible for garbage collection. - * In the case of session handling, it is responsible - * for deleting old, stale sessions that are hanging around. - * The session handler will call this every now and then. - * - * Has to be overwritten by each container class - * - * @param integer $maxlifetime Maximum lifetime - * - * @access public - * @return bool - */ - function gc($maxlifetime) - { - return true; - } - - /** - * Set session save handler - * - * @access public - * @return void - */ - function set() - { - $GLOBALS['HTTP_Session_Container'] =& $this; - session_module_name('user'); - session_set_save_handler('HTTP_Session_Open', - 'HTTP_Session_Close', - 'HTTP_Session_Read', - 'HTTP_Session_Write', - 'HTTP_Session_Destroy', - 'HTTP_Session_GC'); - } - - /** - * Destructor for compatibility with PHP >= 5.0.5 - * - * @access private - * @return void - */ - function __destruct() - { - $GLOBALS['HTTP_Session_Container'] =& $this; - session_write_close(); - } -} - -// Delegate function calls to the object's methods -/** @ignore */ -function HTTP_Session_Open($save_path, $session_name) -{ - return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->open($save_path, $session_name) - : false; -} -/** @ignore */ -function HTTP_Session_Close() -{ - return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->close() - : false; -} -/** @ignore */ -function HTTP_Session_Read($id) -{ - return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->read($id) - : false; -} -/** @ignore */ -function HTTP_Session_Write($id, $data) -{ - return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->write($id, $data) - : false; -} -/** @ignore */ -function HTTP_Session_Destroy($id) -{ - return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->destroy($id) - : false; -} -/** @ignore */ -function HTTP_Session_GC($maxlifetime) -{ - return (isset($GLOBALS['HTTP_Session_Container'])) ? $GLOBALS['HTTP_Session_Container']->gc($maxlifetime) - : false; -} -?> \ No newline at end of file diff --git a/libraries/HTTP_Session/Session/Container/DB.php b/libraries/HTTP_Session/Session/Container/DB.php deleted file mode 100644 index 3b6007310afca2e438d00db6d92bbee451cc61f7..0000000000000000000000000000000000000000 --- a/libraries/HTTP_Session/Session/Container/DB.php +++ /dev/null @@ -1,364 +0,0 @@ -<?php - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Database container for session data - * - * PEAR::DB database container - * - * PHP version 4 - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @category HTTP - * @package HTTP_Session - * @author Alexander Radivanovich <info@wwwlab.net> - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: DB.php,v 1.7 2007/07/14 12:11:54 troehr Exp $ - * @link http://pear.php.net/package/HTTP_Session - * @since File available since Release 0.4.0 - */ - -require_once 'HTTP/Session/Container.php'; -require_once 'DB.php'; - -/** - * Database container for session data - * - * Create the following table to store session data - * <code> - * CREATE TABLE `sessiondata` ( - * `id` CHAR(32) NOT NULL, - * `expiry` INT UNSIGNED NOT NULL DEFAULT 0, - * `data` TEXT NOT NULL, - * PRIMARY KEY (`id`) - * ); - * </code> - * - * @category HTTP - * @package HTTP_Session - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTTP_Session - * @since Class available since Release 0.4.0 - */ -class HTTP_Session_Container_DB extends HTTP_Session_Container -{ - /** - * DB connection object - * - * @var object DB - * @access private - */ - var $db = null; - - /** - * Session data cache id - * - * @var mixed - * @access private - */ - var $crc = false; - - /** - * Constrtuctor method - * - * $options is an array with the options.<br> - * The options are: - * <ul> - * <li>'dsn' - The DSN string</li> - * <li>'table' - Table with session data, default is 'sessiondata'</li> - * <li>'autooptimize' - Boolean, 'true' to optimize - * the table on garbage collection, default is 'false'.</li> - * </ul> - * - * @param array $options Options - * - * @access public - * @return object - */ - function HTTP_Session_Container_DB($options) - { - $this->_setDefaults(); - if (is_array($options)) { - $this->_parseOptions($options); - } else { - $this->options['dsn'] = $options; - } - } - - /** - * Connect to database by using the given DSN string - * - * @param string $dsn DSN string - * - * @access private - * @return mixed Object on error, otherwise bool - */ - function _connect($dsn) - { - if (is_string($dsn) || is_array($dsn)) { - $this->db = DB::connect($dsn); - } else if (is_object($dsn) && is_a($dsn, "db_common")) { - $this->db = $dsn; - } else if (is_object($dsn) && DB::isError($dsn)) { - return new DB_Error($dsn->code, PEAR_ERROR_DIE); - } else { - return new PEAR_Error("The given dsn was not valid in file " . __FILE__ - . " at line " . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - - } - - if (DB::isError($this->db)) { - return new DB_Error($this->db->code, PEAR_ERROR_DIE); - } - - return true; - } - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['dsn'] = null; - $this->options['table'] = 'sessiondata'; - $this->options['autooptimize'] = false; - } - - /** - * Establish connection to a database - * - * @param string $save_path Save path - * @param string $session_name Session name - * - * @return bool - */ - function open($save_path, $session_name) - { - if (DB::isError($this->_connect($this->options['dsn']))) { - return false; - } else { - return true; - } - } - - /** - * Free resources - * - * @return void - */ - function close() - { - return true; - } - - /** - * Read session data - * - * @param string $id Session id - * - * @return void - */ - function read($id) - { - $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d", - $this->options['table'], - $this->db->quoteSmart(md5($id)), - time()); - $result = $this->db->getOne($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - $this->crc = strlen($result) . crc32($result); - return $result; - } - - /** - * Write session data - * - * @param string $id Session id - * @param mixed $data Data - * - * @return bool - */ - function write($id, $data) - { - if ((false !== $this->crc) && - ($this->crc === strlen($data) . crc32($data))) { - // $_SESSION hasn't been touched, no need to update the blob column - $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s", - $this->options['table'], - time() + ini_get('session.gc_maxlifetime'), - $this->db->quoteSmart(md5($id))); - } else { - // Check if table row already exists - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", - $this->options['table'], - $this->db->quoteSmart(md5($id))); - $result = $this->db->getOne($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - if (0 == intval($result)) { - // Insert new row into table - $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)", - $this->options['table'], - $this->db->quoteSmart(md5($id)), - time() + ini_get('session.gc_maxlifetime'), - $this->db->quoteSmart($data)); - } else { - // Update existing row - $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s", - $this->options['table'], - time() + ini_get('session.gc_maxlifetime'), - $this->db->quoteSmart($data), - $this->db->quoteSmart(md5($id))); - } - } - $result = $this->db->query($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Destroy session data - * - * @param string $id Session id - * - * @return void - */ - function destroy($id) - { - $query = sprintf("DELETE FROM %s WHERE id = %s", - $this->options['table'], - $this->db->quoteSmart(md5($id))); - $result = $this->db->query($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Replicate session data to table specified in option 'replicateBeforeDestroy' - * - * @param string $targetTable Table to replicate to - * @param string $id Id of record to replicate - * - * @access private - * @return bool - */ - function replicate($targetTable, $id = null) - { - if (is_null($id)) { - $id = HTTP_Session::id(); - } - - // Check if table row already exists - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", - $targetTable, - $this->db->quoteSmart(md5($id))); - $result = $this->db->getOne($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - // Insert new row into dest table - if (0 == intval($result)) { - $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s", - $targetTable, - $this->options['table'], - $this->db->quoteSmart(md5($id))); - - } else { - // Update existing row - $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s", - $targetTable, - $this->options['table'], - $this->db->quoteSmart(md5($id))); - } - - $result = $this->db->query($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Garbage collection - * - * @param int $maxlifetime Maximum lifetime - * - * @return bool - */ - function gc($maxlifetime) - { - $query = sprintf("DELETE FROM %s WHERE expiry < %d", - $this->options['table'], - time()); - $result = $this->db->query($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - if ($this->options['autooptimize']) { - switch($this->db->phptype) { - case 'mysql': - $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); - break; - case 'pgsql': - $query = sprintf("VACUUM %s", $this->options['table']); - break; - default: - $query = null; - break; - } - if (isset($query)) { - $result = $this->db->query($query); - if (DB::isError($result)) { - new DB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - } - } - - return true; - } -} -?> \ No newline at end of file diff --git a/libraries/HTTP_Session/Session/Container/MDB.php b/libraries/HTTP_Session/Session/Container/MDB.php deleted file mode 100644 index 2a8f54c79697fda569fdb74c217e01200ae0686c..0000000000000000000000000000000000000000 --- a/libraries/HTTP_Session/Session/Container/MDB.php +++ /dev/null @@ -1,364 +0,0 @@ -<?php - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Database container for session data - * - * PEAR::MDB database container - * - * PHP version 4 - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @category HTTP - * @package HTTP_Session - * @author Alexander Radivanovich <info@wwwlab.net> - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: MDB.php,v 1.5 2007/07/14 12:11:55 troehr Exp $ - * @link http://pear.php.net/package/HTTP_Session - * @since File available since Release 0.5.0 - */ - -require_once 'HTTP/Session/Container.php'; -require_once 'MDB.php'; - -/** - * Database container for session data - * - * Create the following table to store session data - * <code> - * CREATE TABLE `sessiondata` ( - * `id` CHAR(32) NOT NULL, - * `expiry` INT UNSIGNED NOT NULL DEFAULT 0, - * `data` TEXT NOT NULL, - * PRIMARY KEY (`id`) - * ); - * </code> - * - * @category HTTP - * @package HTTP_Session - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTTP_Session - * @since Class available since Release 0.4.0 - */ -class HTTP_Session_Container_MDB extends HTTP_Session_Container -{ - - /** - * MDB connection object - * - * @var object MDB - * @access private - */ - var $db = null; - - /** - * Session data cache id - * - * @var mixed - * @access private - */ - var $crc = false; - - /** - * Constructor method - * - * $options is an array with the options.<br> - * The options are: - * <ul> - * <li>'dsn' - The DSN string</li> - * <li>'table' - Table with session data, default is 'sessiondata'</li> - * <li>'autooptimize' - Boolean, 'true' to optimize - * the table on garbage collection, default is 'false'.</li> - * </ul> - * - * @param array $options Options - * - * @access public - * @return object - */ - function HTTP_Session_Container_MDB($options) - { - $this->_setDefaults(); - if (is_array($options)) { - $this->_parseOptions($options); - } else { - $this->options['dsn'] = $options; - } - } - - /** - * Connect to database by using the given DSN string - * - * @param string $dsn DSN string - * - * @access private - * @return mixed Object on error, otherwise bool - */ - function _connect($dsn) - { - if (is_string($dsn) || is_array($dsn)) { - $this->db = MDB::connect($dsn); - } else if (is_object($dsn) && is_a($dsn, 'mdb_common')) { - $this->db = $dsn; - } else if (is_object($dsn) && MDB::isError($dsn)) { - return new MDB_Error($dsn->code, PEAR_ERROR_DIE); - } else { - return new PEAR_Error("The given dsn was not valid in file " . __FILE__ - . " at line " . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - - } - - if (MDB::isError($this->db)) { - return new MDB_Error($this->db->code, PEAR_ERROR_DIE); - } - - return true; - } - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['dsn'] = null; - $this->options['table'] = 'sessiondata'; - $this->options['autooptimize'] = false; - } - - /** - * Establish connection to a database - * - * @param string $save_path Save path - * @param string $session_name Session name - * - * @return bool - */ - function open($save_path, $session_name) - { - if (MDB::isError($this->_connect($this->options['dsn']))) { - return false; - } else { - return true; - } - } - - /** - * Free resources - * - * @return bool - */ - function close() - { - return true; - } - - /** - * Read session data - * - * @param string $id Session id - * - * @return mixed - */ - function read($id) - { - $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d", - $this->options['table'], - $this->db->getTextValue(md5($id)), - time()); - $result = $this->db->getOne($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - $this->crc = strlen($result) . crc32($result); - return $result; - } - - /** - * Write session data - * - * @param string $id Session id - * @param mixed $data Data - * - * @return bool - */ - function write($id, $data) - { - if ((false !== $this->crc) && - ($this->crc === strlen($data) . crc32($data))) { - // $_SESSION hasn't been touched, no need to update the blob column - $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s", - $this->options['table'], - time() + ini_get('session.gc_maxlifetime'), - $this->db->getTextValue(md5($id))); - } else { - // Check if table row already exists - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", - $this->options['table'], - $this->db->getTextValue(md5($id))); - $result = $this->db->getOne($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - if (0 == intval($result)) { - // Insert new row into table - $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)", - $this->options['table'], - $this->db->getTextValue(md5($id)), - time() + ini_get('session.gc_maxlifetime'), - $this->db->getTextValue($data)); - } else { - // Update existing row - $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s", - $this->options['table'], - time() + ini_get('session.gc_maxlifetime'), - $this->db->getTextValue($data), - $this->db->getTextValue(md5($id))); - } - } - $result = $this->db->query($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Destroy session data - * - * @param string $id Session id - * - * @return bool - */ - function destroy($id) - { - $query = sprintf("DELETE FROM %s WHERE id = %s", - $this->options['table'], - $this->db->getTextValue(md5($id))); - $result = $this->db->query($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Replicate session data to table specified in option 'replicateBeforeDestroy' - * - * @param string $targetTable Table to replicate to - * @param string $id Id of record to replicate - * - * @access private - * @return bool - */ - function replicate($targetTable, $id = null) - { - if (is_null($id)) { - $id = HTTP_Session::id(); - } - - // Check if table row already exists - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", - $targetTable, - $this->db->getTextValue(md5($id))); - $result = $this->db->getOne($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - // Insert new row into dest table - if (0 == intval($result)) { - $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s", - $targetTable, - $this->options['table'], - $this->db->getTextValue(md5($id))); - } else { - // Update existing row - $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s", - $targetTable, - $this->options['table'], - $this->db->getTextValue(md5($id))); - } - - $result = $this->db->query($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Garbage collection - * - * @param int $maxlifetime Maximum lifetime - * - * @return bool - */ - function gc($maxlifetime) - { - $query = sprintf("DELETE FROM %s WHERE expiry < %d", - $this->options['table'], - time()); - $result = $this->db->query($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - if ($this->options['autooptimize']) { - switch($this->db->phptype) { - case 'mysql': - $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); - break; - case 'pgsql': - $query = sprintf("VACUUM %s", $this->options['table']); - break; - default: - $query = null; - break; - } - if (isset($query)) { - $result = $this->db->query($query); - if (MDB::isError($result)) { - new MDB_Error($result->code, PEAR_ERROR_DIE); - return false; - } - } - } - - return true; - } -} -?> \ No newline at end of file diff --git a/libraries/HTTP_Session/Session/Container/MDB2.php b/libraries/HTTP_Session/Session/Container/MDB2.php deleted file mode 100644 index e36616ba5d23bca18e9932e1d0326e670c1c15c1..0000000000000000000000000000000000000000 --- a/libraries/HTTP_Session/Session/Container/MDB2.php +++ /dev/null @@ -1,364 +0,0 @@ -<?php - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Database container for session data - * - * PEAR::MDB2 database container - * - * PHP version 4 - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @category HTTP - * @package HTTP_Session - * @author Alexander Radivanovich <info@wwwlab.net> - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: MDB2.php,v 1.5 2007/07/14 12:11:55 troehr Exp $ - * @link http://pear.php.net/package/HTTP_Session - * @since File available since Release 0.5.0 - */ - -require_once 'HTTP/Session/Container.php'; -require_once 'MDB2.php'; - -/** - * Database container for session data - * - * Create the following table to store session data - * <code> - * CREATE TABLE `sessiondata` ( - * `id` CHAR(32) NOT NULL, - * `expiry` INT UNSIGNED NOT NULL DEFAULT 0, - * `data` TEXT NOT NULL, - * PRIMARY KEY (`id`) - * ); - * </code> - * - * @category HTTP - * @package HTTP_Session - * @author David Costa <gurugeek@php.net> - * @author Michael Metz <pear.metz@speedpartner.de> - * @author Stefan Neufeind <pear.neufeind@speedpartner.de> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2005 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTTP_Session - * @since Class available since Release 0.5.0 - */ -class HTTP_Session_Container_MDB2 extends HTTP_Session_Container -{ - /** - * MDB2 connection object - * - * @var object MDB2 - * @access private - */ - var $db = null; - - /** - * Session data cache id - * - * @var mixed - * @access private - */ - var $crc = false; - - /** - * Constructor method - * - * $options is an array with the options.<br> - * The options are: - * <ul> - * <li>'dsn' - The DSN string</li> - * <li>'table' - Table with session data, default is 'sessiondata'</li> - * <li>'autooptimize' - Boolean, 'true' to optimize - * the table on garbage collection, default is 'false'.</li> - * </ul> - * - * @param array $options Options - * - * @access public - * @return void - */ - function HTTP_Session_Container_MDB2($options) - { - $this->_setDefaults(); - if (is_array($options)) { - $this->_parseOptions($options); - } else { - $this->options['dsn'] = $options; - } - } - - /** - * Connect to database by using the given DSN string - * - * @param string $dsn DSN string - * - * @access private - * @return mixed Object on error, otherwise bool - */ - function _connect($dsn) - { - if (is_string($dsn) || is_array($dsn)) { - $this->db = MDB2::connect($dsn); - } else if (is_object($dsn) && is_a($dsn, 'MDB2_Driver_Common')) { - $this->db = $dsn; - } else if (is_object($dsn) && MDB2::isError($dsn)) { - return $dsn; - } else { - return new PEAR_Error("The given dsn was not valid in file " . __FILE__ - . " at line " . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - - } - - if (MDB2::isError($this->db)) { - return new MDB2_Error($this->db->code, PEAR_ERROR_DIE); - } - - return true; - } - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['dsn'] = null; - $this->options['table'] = 'sessiondata'; - $this->options['autooptimize'] = false; - } - - /** - * Establish connection to a database - * - * @param string $save_path Save path - * @param string $session_name Session name - * - * @return bool - */ - function open($save_path, $session_name) - { - if (MDB2::isError($this->_connect($this->options['dsn']))) { - return false; - } else { - return true; - } - } - - /** - * Free resources - * - * @return bool - */ - function close() - { - return true; - } - - /** - * Read session data - * - * @param string $id Session id - * - * @return mixed - */ - function read($id) - { - $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d", - $this->options['table'], - $this->db->quote(md5($id), 'text'), - time()); - $result = $this->db->queryOne($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - $this->crc = strlen($result) . crc32($result); - return $result; - } - - /** - * Write session data - * - * @param string $id Session id - * @param mixed $data Data - * - * @return bool - */ - function write($id, $data) - { - if ((false !== $this->crc) && - ($this->crc === strlen($data) . crc32($data))) { - // $_SESSION hasn't been touched, no need to update the blob column - $query = sprintf("UPDATE %s SET expiry = %d WHERE id = %s", - $this->options['table'], - time() + ini_get('session.gc_maxlifetime'), - $this->db->quote(md5($id), 'text')); - } else { - // Check if table row already exists - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", - $this->options['table'], - $this->db->quote(md5($id), 'text')); - $result = $this->db->queryOne($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - if (0 == intval($result)) { - // Insert new row into table - $query = sprintf("INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)", - $this->options['table'], - $this->db->quote(md5($id), 'text'), - time() + ini_get('session.gc_maxlifetime'), - $this->db->quote($data, 'text')); - } else { - // Update existing row - $query = sprintf("UPDATE %s SET expiry = %d, data = %s WHERE id = %s", - $this->options['table'], - time() + ini_get('session.gc_maxlifetime'), - $this->db->quote($data, 'text'), - $this->db->quote(md5($id), 'text')); - } - } - $result = $this->db->query($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Destroy session data - * - * @param string $id Session id - * - * @return bool - */ - function destroy($id) - { - $query = sprintf("DELETE FROM %s WHERE id = %s", - $this->options['table'], - $this->db->quote(md5($id), 'text')); - $result = $this->db->query($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Replicate session data to table specified in option 'replicateBeforeDestroy' - * - * @param string $targetTable Table to replicate to - * @param string $id Id of record to replicate - * - * @access private - * @return bool - */ - function replicate($targetTable, $id = null) - { - if (is_null($id)) { - $id = HTTP_Session::id(); - } - - // Check if table row already exists - $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", - $targetTable, - $this->db->quote(md5($id), 'text')); - $result = $this->db->queryOne($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - - // Insert new row into dest table - if (0 == intval($result)) { - $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s", - $targetTable, - $this->options['table'], - $this->db->quote(md5($id), 'text')); - - } else { - // Update existing row - $query = sprintf("UPDATE %s dst, %s src SET dst.expiry = src.expiry, dst.data = src.data WHERE dst.id = src.id AND src.id = %s", - $targetTable, - $this->options['table'], - $this->db->quote(md5($id), 'text')); - } - - $result = $this->db->query($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - - return true; - } - - /** - * Garbage collection - * - * @param int $maxlifetime Maximum lifetime - * - * @return bool - */ - function gc($maxlifetime) - { - $query = sprintf("DELETE FROM %s WHERE expiry < %d", - $this->options['table'], - time()); - $result = $this->db->query($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - if ($this->options['autooptimize']) { - switch($this->db->phptype) { - case 'mysql': - $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); - break; - case 'pgsql': - $query = sprintf("VACUUM %s", $this->options['table']); - break; - default: - $query = null; - break; - } - if (isset($query)) { - $result = $this->db->query($query); - if (MDB2::isError($result)) { - $this->db->raiseError($result->code, PEAR_ERROR_DIE); - return false; - } - } - } - - return true; - } -} -?> \ No newline at end of file diff --git a/libraries/HTTP_Session/Session/Container/Memcache.php b/libraries/HTTP_Session/Session/Container/Memcache.php deleted file mode 100644 index d2889ffcea97476cd791460b314556301031c41d..0000000000000000000000000000000000000000 --- a/libraries/HTTP_Session/Session/Container/Memcache.php +++ /dev/null @@ -1,202 +0,0 @@ -<?php - -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Database container for session data - * - * Memcache database container - * - * PHP version 4 - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @category HTTP - * @package HTTP_Session - * @author Chad Wagner <chad.wagner@gmail.com> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2007 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: Memcache.php,v 1.3 2007/07/14 12:11:55 troehr Exp $ - * @link http://pear.php.net/package/HTTP_Session - * @since File available since Release 0.5.6 - */ - -require_once 'HTTP/Session/Container.php'; - -/** - * Database container for session data - * - * @category HTTP - * @package HTTP_Session - * @author Chad Wagner <chad.wagner@gmail.com> - * @author Torsten Roehr <torsten.roehr@gmx.de> - * @copyright 1997-2007 The PHP Group - * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTTP_Session - * @since Class available since Release 0.5.6 - */ -class HTTP_Session_Container_Memcache extends HTTP_Session_Container -{ - /** - * Memcache connection object - * - * @var object Memcache - * @access private - */ - var $mc; - - /** - * Constructor method - * - * $options is an array with the options.<br> - * The options are: - * <ul> - * <li>'memcache' - Memcache object - * <li>'prefix' - Key prefix, default is 'sessiondata:'</li> - * </ul> - * - * @param array $options Options - * - * @access public - * @return object - */ - function HTTP_Session_Container_Memcache($options) - { - $this->_setDefaults(); - - if (is_array($options)) { - $this->_parseOptions($options); - } - } - - /** - * Connect to database by using the given DSN string - * - * @param string $mc Memcache object - * - * @access private - * @return mixed Object on error, otherwise bool - */ - function _connect($mc) - { - if (is_object($mc) && is_a($mc, 'Memcache')) { - $this->mc = $mc; - - } else { - - return new PEAR_Error('The given memcache object was not valid in file ' - . __FILE__ . ' at line ' . __LINE__, - 41, - PEAR_ERROR_RETURN, - null, - null - ); - } - - return true; - } - - /** - * Set some default options - * - * @access private - * @return void - */ - function _setDefaults() - { - $this->options['prefix'] = 'sessiondata:'; - $this->options['memcache'] = null; - } - - /** - * Establish connection to a database - * - * @param string $save_path Save path - * @param string $session_name Session name - * - * @access public - * @return mixed Object on error, otherwise bool - */ - function open($save_path, $session_name) - { - return $this->_connect($this->options['memcache']); - } - - /** - * Free resources - * - * @access public - * @return bool - */ - function close() - { - return true; - } - - /** - * Read session data - * - * @param string $id Session id - * - * @access public - * @return mixed - */ - function read($id) - { - $result = $this->mc->get($this->options['prefix'] . $id); - return $result; - } - - /** - * Write session data - * - * @param string $id Session id - * @param mixed $data Session data - * - * @access public - * @return bool - */ - function write($id, $data) - { - $this->mc->set($this->options['prefix'] . $id, - $data, - MEMCACHE_COMPRESSED, - time() + ini_get('session.gc_maxlifetime')); - - return true; - } - - /** - * Destroy session data - * - * @param string $id Session id - * - * @access public - * @return bool - */ - function destroy($id) - { - $this->mc->delete($this->options['prefix'] . $id); - return true; - } - - /** - * Garbage collection - * - * @param int $maxlifetime Maximum lifetime - * - * @access public - * @return bool - */ - function gc($maxlifetime) - { - return true; - } -} -?> \ No newline at end of file diff --git a/libraries/HTTP_Session2/HTTP/Session2.php b/libraries/HTTP_Session2/HTTP/Session2.php new file mode 100644 index 0000000000000000000000000000000000000000..3f677447312478abc5163e4330999fed7d4a8cf4 --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2.php @@ -0,0 +1,760 @@ +<?php +/** + * +-----------------------------------------------------------------------+ + * | Copyright (c) 2004, Tony Bibbs | + * | All rights reserved. | + * | | + * | Redistribution and use in source and binary forms, with or without | + * | modification, are permitted provided that the following conditions | + * | are met: | + * | | + * | o Redistributions of source code must retain the above copyright | + * | notice, this list of conditions and the following disclaimer. | + * | o Redistributions in binary form must reproduce the above copyright | + * | notice, this list of conditions and the following disclaimer in the | + * | documentation and/or other materials provided with the distribution.| + * | o The names of the authors may not be used to endorse or promote | + * | products derived from this software without specific prior written | + * | permission. | + * | | + * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | + * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | + * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | + * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | + * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | + * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | + * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | + * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | + * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | + * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | + * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | + * | | + * +-----------------------------------------------------------------------+ + * | Author: Tony Bibbs <tony@geeklog.net> | + * +-----------------------------------------------------------------------+ + * + * PHP version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivaniovich <info@wwwlab.net> + * @author Tony Bibbs <tony@geeklog.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: Session2.php 267739 2008-10-25 16:54:23Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + */ + +/** + * HTTP_Session2_Exception + */ +require_once 'Session2/Exception.php'; + +/** + * Class for managing HTTP sessions + * + * Provides access to session-state values as well as session-level + * settings and lifetime management methods. + * Based on the standart PHP session handling mechanism + * it provides for you more advanced features such as + * database container, idle and expire timeouts, etc. + * + * Expample 1: + * + * <code> + * // Setting some options and detecting of a new session + * HTTP_Session2::useCookies(false); + * HTTP_Session2::start('MySessionID'); + * HTTP_Session2::set('variable', 'The string'); + * if (HTTP_Session2::isNew()) { + * echo 'new session was created with the current request'; + * $visitors++; // Increase visitors count + * } + * + * //HTTP_Session2::regenerateId(); + * </code> + * + * Example 2: + * + * <code> + * // Using database container + * HTTP_Session2::setContainer('DB'); + * HTTP_Session2::start(); + * </code> + * + * Example 3: + * + * <code> + * // Setting timeouts + * HTTP_Session2::start(); + * HTTP_Session2::setExpire(time() + 60 * 60); // expires in one hour + * HTTP_Session2::setIdle(10 * 60); // idles in ten minutes + * if (HTTP_Session2::isExpired()) { + * // expired + * echo('Your session is expired!'); + * HTTP_Session2::destroy(); + * } + * if (HTTP_Session2::isIdle()) { + * // idle + * echo('You've been idle for too long!'); + * HTTP_Session2::destroy(); + * } + * HTTP_Session2::updateIdle(); + * </code> + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivaniovich <info@wwwlab.net> + * @author Tony Bibbs <tony@geeklog.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + */ +class HTTP_Session2 +{ + /** + * @const STARTED - The session was started with the current request + */ + const STARTED = 1; + + /** + * @const CONTINUE - No new session was started with the current request + */ + const CONTINUED = 2; + + /** + * @const ERR_UNKNOWN_CONTAINER - Container not found. + */ + const ERR_UNKNOWN_CONTAINER = 667; + + /** + * @const ERR_SYSTEM_PERM - System permissions not sufficient. + * E.g. Not enough permissions to override ini-settings. + */ + const ERR_SYSTEM_PERM = 668; + + /** + * @const ERR_SYSTEM_PRECONDITION - Precondition failed. E.g. error occured and + * HTTP_Session2 can't start up, etc.. + */ + const ERR_SYSTEM_PRECONDITION = 669; + + /** + * @const ERR_NOT_IMPLEMENTED Feature is not yet Implement in the container. + */ + const ERR_NOT_IMPLEMENTED = 670; + + /** + * Container instance + */ + public static $container; + + /** + * Sets user-defined session storage functions + * + * Sets the user-defined session storage functions which are used + * for storing and retrieving data associated with a session. + * This is most useful when a storage method other than + * those supplied by PHP sessions is preferred. + * i.e. Storing the session data in a local database. + * + * @param string $container Name of the container (e.g. DB, MDB, ...). + * @param array $container_options Options, most likely an array. + * + * @return void + * @see session_set_save_handler() + */ + static function setContainer($container, $container_options = null) + { + $container_class = 'HTTP_Session2_Container_' . $container; + $container_classfile = 'HTTP/Session2/Container/' . $container . '.php'; + + if (!class_exists($container_class)) { + include_once $container_classfile; + } + if (!class_exists($container_class)) { + throw new HTTP_Session2_Exception( + "Container class, $container_class, does not exist", + self::ERR_UNKNOWN_CONTAINER); + } + self::$container = new $container_class($container_options); + + self::$container->set(); + } + + /** + * Initializes session data + * + * Creates a session (or resumes the current one + * based on the session id being passed + * via a GET variable or a cookie). + * You can provide your own name and/or id for a session. + * + * @param string $name Name of a session, default is 'SessionID' + * @param string $id Id of a session which will be used + * only when the session is new + * + * @return void + * @see session_name() + * @see session_id() + * @see session_start() + */ + public static function start($name = 'SessionID', $id = null) + { + self::name($name); + if (is_null(self::detectID())) { + if ($id) { + self::id($id); + } else { + self::id(uniqid(dechex(rand()))); + } + } + session_start(); + if (!isset($_SESSION['__HTTP_Session2_Info'])) { + $_SESSION['__HTTP_Session2_Info'] = self::STARTED; + } else { + $_SESSION['__HTTP_Session2_Info'] = self::CONTINUED; + } + } + + /** + * Writes session data and ends session + * + * Session data is usually stored after your script + * terminated without the need to call HTTP_Session2::stop(), + * but as session data is locked to prevent concurrent + * writes only one script may operate on a session at any time. + * When using framesets together with sessions you will + * experience the frames loading one by one due to this + * locking. You can reduce the time needed to load all the + * frames by ending the session as soon as all changes + * to session variables are done. + * + * @return void + * @see session_write_close() + */ + public static function pause() + { + session_write_close(); + } + + /** + * Frees all session variables and destroys all data + * registered to a session + * + * This method resets the $_SESSION variable and + * destroys all of the data associated + * with the current session in its storage (file or DB). + * It forces new session to be started after this method + * is called. It does not unset the session cookie. + * + * @return void + * @see session_unset() + * @see session_destroy() + */ + public static function destroy() + { + session_unset(); + session_destroy(); + } + + /** + * Free all session variables + * + * @todo TODO Save expire and idle timestamps? + * @return void + */ + public static function clear() + { + $info = $_SESSION['__HTTP_Session2_Info']; + + session_unset(); + + $_SESSION['__HTTP_Session2_Info'] = $info; + } + + /** + * Tries to find any session id in $_GET, $_POST or $_COOKIE + * + * @return string Session ID (if exists) or null + */ + public static function detectID() + { + if (self::useCookies()) { + if (isset($_COOKIE[self::name()])) { + return $_COOKIE[self::name()]; + } + } else { + if (isset($_GET[self::name()])) { + return $_GET[self::name()]; + } + if (isset($_POST[self::name()])) { + return $_POST[self::name()]; + } + } + return null; + } + + /** + * Sets new name of a session + * + * @param string $name New name of a sesion + * + * @return string Previous name of a session + * @see session_name() + */ + public static function name($name = null) + { + if (isset($name)) { + return session_name($name); + } + return session_name(); + } + + /** + * Sets new ID of a session + * + * @param string $id New ID of a sesion + * + * @return string Previous ID of a session + * @see session_id() + */ + public static function id($id = null) + { + if (isset($id)) { + return session_id($id); + } + return session_id(); + } + + /** + * Sets the maximum expire time + * + * @param integer $time Time in seconds + * @param bool $add Add time to current expire time or not + * + * @return void + */ + public static function setExpire($time, $add = false) + { + if ($add && isset($_SESSION['__HTTP_Session2_Expire'])) { + $_SESSION['__HTTP_Session2_Expire'] += $time; + } else { + $_SESSION['__HTTP_Session2_Expire'] = $time; + } + if (!isset($_SESSION['__HTTP_Session2_Expire_TS'])) { + $_SESSION['__HTTP_Session2_Expire_TS'] = time(); + } + } + + /** + * Sets the maximum idle time + * + * Sets the time-out period allowed + * between requests before the session-state + * provider terminates the session. + * + * @param integer $time Time in seconds + * @param bool $add Add time to current maximum idle time or not + * + * @return void + */ + public static function setIdle($time, $add = false) + { + if ($add && isset($_SESSION['__HTTP_Session2_Idle'])) { + $_SESSION['__HTTP_Session2_Idle'] += $time; + } else { + $_SESSION['__HTTP_Session2_Idle'] = $time; + } + if (!isset($_SESSION['__HTTP_Session2_Idle_TS'])) { + $_SESSION['__HTTP_Session2_Idle_TS'] = time(); + } + } + + /** + * Returns the time up to the session is valid + * + * @return integer Time when the session idles + */ + public static function sessionValidThru() + { + if ( + !isset($_SESSION['__HTTP_Session2_Idle_TS']) + || !isset($_SESSION['__HTTP_Session2_Idle'])) { + return 0; + } + return $_SESSION['__HTTP_Session2_Idle_TS'] + + $_SESSION['__HTTP_Session2_Idle']; + } + + /** + * Check if session is expired + * + * @return boolean + */ + public static function isExpired() + { + if ( + isset($_SESSION['__HTTP_Session2_Expire']) + && $_SESSION['__HTTP_Session2_Expire'] > 0 + && isset($_SESSION['__HTTP_Session2_Expire_TS']) + && + ( + $_SESSION['__HTTP_Session2_Expire_TS'] + + $_SESSION['__HTTP_Session2_Expire'] + ) <= time()) { + return true; + } + return false; + } + + /** + * Check if session is idle + * + * @return boolean Obvious + */ + public static function isIdle() + { + if ( + isset($_SESSION['__HTTP_Session2_Idle']) + && $_SESSION['__HTTP_Session2_Idle'] > 0 + && isset($_SESSION['__HTTP_Session2_Idle_TS']) + && ( + $_SESSION['__HTTP_Session2_Idle_TS'] + + $_SESSION['__HTTP_Session2_Idle'] + ) <= time()) { + return true; + } + return false; + } + + /** + * Updates the idletime + * + * @return void + */ + public static function updateIdle() + { + if (isset($_SESSION['__HTTP_Session2_Idle_TS'])) { + $_SESSION['__HTTP_Session2_Idle_TS'] = time(); + } + } + + /** + * If optional parameter is specified it indicates whether the module will + * use cookies to store the session id on the client side in a cookie. + * + * By default this cookie will be deleted when the browser is closed! + * + * It will throw an Exception if it's not able to set the session.use_cookie + * property. + * + * It returns the previous value of this property. + * + * @param boolean $useCookies If specified it will replace the previous value of + * this property. By default 'null', which doesn't + * change any setting on your system. If you supply a + * parameter, please supply 'boolean'. + * + * @return boolean The previous value of the property + * + * @throws HTTP_Session2_Exception If ini_set() fails! + * @see session_set_cookie_params() + * @link http://php.net/manual/en/function.session-set-cookie-params.php + */ + public static function useCookies($useCookies = null) + { + $return = false; + if (ini_get('session.use_cookies') == '1') { + $return = true; + } + if ($useCookies !== null) { + if ($useCookies === true) { + $status = ini_set('session.use_cookies', 1); + } else { + $status = ini_set('session.use_cookies', 0); + } + if ($status === false) { + $msg = "Could not set 'session.use_cookies'. Please check your "; + $msg .= 'permissions to override php.ini-settings. E.g. a possible '; + $msg .= 'php_admin_value setting or blocked ini_set() calls '; + throw new HTTP_Session2_Exception($msg, self::ERR_SYSTEM_PERM); + } + } + return $return; + } + + /** + * Gets a value indicating whether the session + * was created with the current request + * + * You MUST call this method only after you have started + * the session with the HTTP_Session2::start() method. + * + * @return boolean true when the session was created with the current request + * false otherwise + * + * @see self::start() + * @uses self::STARTED + */ + public static function isNew() + { + // The best way to check if a session is new is to check + // for existence of a session data storage + // with the current session id, but this is impossible + // with the default PHP module wich is 'files'. + // So we need to emulate it. + return !isset($_SESSION['__HTTP_Session2_Info']) || + $_SESSION['__HTTP_Session2_Info'] == self::STARTED; + } + + /** + * Register variable with the current session + * + * @param string $name Name of a global variable + * + * @return void + * @see session_register() + */ + public static function register($name) + { + session_register($name); + } + + /** + * Unregister a variable from the current session + * + * @param string $name Name of a global variable + * + * @return void + * @see session_unregister() + */ + public static function unregister($name) + { + session_unregister($name); + } + + /** + * Returns session variable + * + * @param string $name Name of a variable + * @param mixed $default Default value of a variable if not set + * + * @return mixed Value of a variable + */ + public static function &get($name, $default = null) + { + if (!isset($_SESSION[$name]) && isset($default)) { + $_SESSION[$name] = $default; + } + return $_SESSION[$name]; + } + + /** + * Sets session variable + * + * @param string $name Name of a variable + * @param mixed $value Value of a variable + * + * @return mixed Old value of a variable + */ + public static function set($name, $value) + { + $return = (isset($_SESSION[$name])) ? $_SESSION[$name] : null; + if (null === $value) { + unset($_SESSION[$name]); + } else { + $_SESSION[$name] = $value; + } + return $return; + } + + /** + * Returns local variable of a script + * + * Two scripts can have local variables with the same names + * + * @param string $name Name of a variable + * @param mixed $default Default value of a variable if not set + * + * @return mixed Value of a local variable + */ + static function &getLocal($name, $default = null) + { + $local = md5(self::localName()); + if (!is_array($_SESSION[$local])) { + $_SESSION[$local] = array(); + } + if (!isset($_SESSION[$local][$name]) && isset($default)) { + $_SESSION[$local][$name] = $default; + } + return $_SESSION[$local][$name]; + } + + /** + * Sets local variable of a script. + * Two scripts can have local variables with the same names. + * + * @param string $name Name of a local variable + * @param mixed $value Value of a local variable + * + * @return mixed Old value of a local variable + */ + static function setLocal($name, $value) + { + $local = md5(self::localName()); + if (!is_array($_SESSION[$local])) { + $_SESSION[$local] = array(); + } + $return = $_SESSION[$local][$name]; + if (null === $value) { + unset($_SESSION[$local][$name]); + } else { + $_SESSION[$local][$name] = $value; + } + return $return; + } + + /** + * set the usage of transparent SID + * + * @param boolean $useTransSID Flag to use transparent SID + * + * @return boolean + */ + static function useTransSID($useTransSID = false) + { + $return = ini_get('session.use_trans_sid') ? true : false; + if ($useTransSID === false) { + ini_set('session.use_trans_sid', $useTransSID ? 1 : 0); + } + return $return; + } + + /** + * Sets new local name + * + * @param string $name New local name + * + * @return string Previous local name + */ + static function localName($name = null) + { + $return = ''; + if (isset($GLOBALS['__HTTP_Session2_Localname'])) { + $return .= $GLOBALS['__HTTP_Session2_Localname']; + } + if (!empty($name)) { + $GLOBALS['__HTTP_Session2_Localname'] = $name; + } + return $return; + } + + /** + * init + * + * @return void + */ + static function init() + { + // Disable auto-start of a sesion + ini_set('session.auto_start', 0); + + // Set local name equal to the current script name + self::localName($_SERVER['SCRIPT_NAME']); + } + + /** + * Regenrates session id + * + * If session_regenerate_id() is not available emulates its functionality + * + * @param boolean $deleteOldSessionData Whether to delete data of old session + * + * @return boolean + */ + public static function regenerateId($deleteOldSessionData = false) + { + if (function_exists('session_regenerate_id')) { + return session_regenerate_id($deleteOldSessionData); + + // emulate session_regenerate_id() + } else { + + do { + $newId = uniqid(dechex(rand())); + } while ($newId === session_id()); + + if ($deleteOldSessionData) { + session_unset(); + } + + session_id($newId); + + return true; + } + } + + /** + * This function copies session data of specified id to specified table + * + * @param string $target Target to replicate to + * @param string $id Id of record to replicate + * + * @return boolean + */ + public static function replicate($target, $id = null) + { + return self::$container->replicate($target, $id); + } + + /** + * If optional parameter is specified it determines the number of seconds + * after which session data will be seen as 'garbage' and cleaned up + * + * It returns the previous value of this property + * + * @param int $gcMaxLifetime If specified it will replace the previous value of + * this property, and must be integer. + * + * @return boolean The previous value of the property + */ + public static function setGcMaxLifetime($gcMaxLifetime = null) + { + $return = ini_get('session.gc_maxlifetime'); + if (isset($gcMaxLifetime) && is_int($gcMaxLifetime) && $gcMaxLifetime >= 1) { + ini_set('session.gc_maxlifetime', $gcMaxLifetime); + } + return $return; + } + + /** + * If optional parameter is specified it determines the + * probability that the gc (garbage collection) routine is started + * and session data is cleaned up + * + * It returns the previous value of this property + * + * @param int $gcProbability If specified it will replace the previous value of + * this property. + * + * @return boolean The previous value of the property + */ + public static function setGcProbability($gcProbability = null) + { + $return = ini_get('session.gc_probability'); + if (isset($gcProbability) && + is_int($gcProbability) && + $gcProbability >= 1 && + $gcProbability <= 100) { + ini_set('session.gc_probability', $gcProbability); + } + return $return; + } +} + +/** + * init {@link HTTP_Session2} + * + * @see HTTP_Session2::init() + */ +HTTP_Session2::init(); diff --git a/libraries/HTTP_Session2/HTTP/Session2/Container.php b/libraries/HTTP_Session2/HTTP/Session2/Container.php new file mode 100644 index 0000000000000000000000000000000000000000..a3c9ef8a806b18e914217b4f87d63f0bd263fc32 --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2/Container.php @@ -0,0 +1,138 @@ +<?php +/** + * +-----------------------------------------------------------------------+ + * | Copyright (c) 2004, Tony Bibbs | + * | All rights reserved. | + * | | + * | Redistribution and use in source and binary forms, with or without | + * | modification, are permitted provided that the following conditions | + * | are met: | + * | | + * | o Redistributions of source code must retain the above copyright | + * | notice, this list of conditions and the following disclaimer. | + * | o Redistributions in binary form must reproduce the above copyright | + * | notice, this list of conditions and the following disclaimer in the | + * | documentation and/or other materials provided with the distribution.| + * | o The names of the authors may not be used to endorse or promote | + * | products derived from this software without specific prior written | + * | permission. | + * | | + * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | + * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | + * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | + * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | + * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | + * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | + * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | + * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | + * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | + * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | + * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | + * | | + * +-----------------------------------------------------------------------+ + * | Author: Alexander Radivanovich <info@wwwlab.net> | + * | Tony Bibbs <tony@geeklog.net> | + * +-----------------------------------------------------------------------+ + * + * PHP version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivaniovich <info@wwwlab.net> + * @author Tony Bibbs <tony@geeklog.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: Container.php 295734 2010-03-02 13:25:15Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + */ + +/** + * HTTP_Session2_Container_Interface + */ +require_once 'HTTP/Session2/Container/Interface.php'; + +/** + * Container class for storing session data data + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivaniovich <info@wwwlab.net> + * @author Tony Bibbs <tony@geeklog.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + */ +abstract class HTTP_Session2_Container implements HTTP_Session2_Container_Interface +{ + /** + * Additional options for the container object + * + * @var array + */ + protected $options = array(); + + /** + * Constrtuctor method + * + * @param array $options Additional options for the container object + * + * @return void + */ + public function __construct($options = null) + { + $this->setDefaults(); + if (is_array($options)) { + $this->parseOptions($options); + } + } + + /** + * Call session_write_close() in destructor for compatibility with PHP >= 5.0.5 + * + * @return void + */ + public function __destruct() + { + session_write_close(); + } + + /** + * Set some default options + * + * @return void + */ + protected function setDefaults() + { + } + + /** + * Parse options passed to the container class + * + * @param array $options Options + * + * @return void + */ + protected function parseOptions($options) + { + foreach ($options as $option => $value) { + if (in_array($option, array_keys($this->options))) { + $this->options[$option] = $value; + } + } + } + + /** + * Set session save handler + * + * @return void + */ + public function set() + { + session_module_name('user'); + session_set_save_handler(array($this, 'open'), + array($this, 'close'), + array($this, 'read'), + array($this, 'write'), + array($this, 'destroy'), + array($this, 'gc')); + } +} \ No newline at end of file diff --git a/libraries/HTTP_Session2/HTTP/Session2/Container/DB.php b/libraries/HTTP_Session2/HTTP/Session2/Container/DB.php new file mode 100644 index 0000000000000000000000000000000000000000..bb2b5e26deb94febcc04dd9d7d1371643c315f3e --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2/Container/DB.php @@ -0,0 +1,382 @@ +<?php +/** + * +-----------------------------------------------------------------------+ + * | Copyright (c) 2002, Alexander Radivanovich | + * | All rights reserved. | + * | | + * | Redistribution and use in source and binary forms, with or without | + * | modification, are permitted provided that the following conditions | + * | are met: | + * | | + * | o Redistributions of source code must retain the above copyright | + * | notice, this list of conditions and the following disclaimer. | + * | o Redistributions in binary form must reproduce the above copyright | + * | notice, this list of conditions and the following disclaimer in the | + * | documentation and/or other materials provided with the distribution.| + * | o The names of the authors may not be used to endorse or promote | + * | products derived from this software without specific prior written | + * | permission. | + * | | + * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | + * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | + * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | + * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | + * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | + * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | + * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | + * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | + * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | + * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | + * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | + * | | + * +-----------------------------------------------------------------------+ + * | Author: Alexander Radivanovich <info@wwwlab.net> | + * +-----------------------------------------------------------------------+ + * + * PHP Version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivanovich <info@wwwlab.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: DB.php 266493 2008-09-18 16:58:29Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + * @deprecated This driver/container is deprecated from 0.9.0 + */ + +/** + * HTTP/Session2/Container.php + * @ignore + */ +require_once 'HTTP/Session2/Container.php'; + +/** + * HTTP/Session2/Exception.php + * + * @todo Implement HTTP_Session2_Containter_DB_Exception + */ +require_once 'HTTP/Session2/Exception.php'; + +/** + * DB.php + * @ignore + */ +require_once 'DB.php'; + +/** + * Database container for session data + * + * Create the following table to store session data + * <code> + * CREATE TABLE `sessiondata` ( + * `id` CHAR(32) NOT NULL, + * `expiry` INT UNSIGNED NOT NULL DEFAULT 0, + * `data` TEXT NOT NULL, + * PRIMARY KEY (`id`) + * ); + * </code> + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivanovich <info@wwwlab.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + * @deprecated This driver/container is deprecated from 0.9.0 + */ +class HTTP_Session2_Container_DB extends HTTP_Session2_Container +{ + + /** + * DB connection object + * + * @var object DB + */ + private $_db = null; + + /** + * Session data cache id + * + * @var mixed + */ + private $_crc = false; + + /** + * Constrtuctor method + * + * $options is an array with the options.<br> + * The options are: + * <ul> + * <li>'dsn' - The DSN string</li> + * <li>'table' - Table with session data, default is 'sessiondata'</li> + * <li>'autooptimize' - Boolean, 'true' to optimize + * the table on garbage collection, default is 'false'.</li> + * </ul> + * + * @param array $options The options + * + * @return void + */ + public function __construct($options) + { + parent::__construct($options); + } + + /** + * Connect to database by using the given DSN string + * + * @param string $dsn DSN string + * + * @return boolean + * @throws HTTP_Session2_Exception An exception?! + */ + protected function connect($dsn) + { + if (is_string($dsn)) { + $this->_db = DB::connect($dsn); + } else if (is_object($dsn) && is_a($dsn, 'db_common')) { + $this->_db = $dsn; + } else if (DB::isError($dsn)) { + throw new HTTP_Session2_Exception($dsn->getMessage(), $dsn->getCode()); + } else { + $msg = "The given dsn was not valid in file "; + $msg .= __FILE__ . " at line " . __LINE__; + throw new HTTP_Session2_Exception($msg, + HTTP_Session2::ERR_SYSTEM_PRECONDITION); + } + return true; + } + + /** + * Set some default options + * + * @return void + */ + protected function setDefaults() + { + $this->options['dsn'] = null; + $this->options['table'] = 'sessiondata'; + $this->options['autooptimize'] = false; + } + + /** + * Establish connection to a database + * + * @param string $save_path The path to save/write sessions. + * @param string $session_name The session name. + * + * @return boolean + * @uses self::connect(); + * @uses self::$options + */ + public function open($save_path, $session_name) + { + return $this->connect($this->options['dsn']); + } + + /** + * Free resources + * + * @return boolean + */ + public function close() + { + return true; + } + + /** + * Read session data + * + * @param string $id The Id! + * + * @return mixed + * @throws HTTP_Session2_Exception An exception!? + */ + public function read($id) + { + $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d", + $this->options['table'], + $this->_db->quote(md5($id)), + time()); + + $result = $this->_db->getOne($query); + if (DB::isError($result)) { + throw new HTTP_Session2_Exception($result->getMessage(), + $result->getCode()); + } + $this->_crc = strlen($result) . crc32($result); + return $result; + } + + /** + * Write session data + * + * @param string $id The id. + * @param string $data The data. + * + * @return boolean + * @todo Remove sprintf(), they are expensive. + */ + public function write($id, $data) + { + if ((false !== $this->_crc) + && ($this->_crc === strlen($data) . crc32($data))) { + /* $_SESSION hasn't been touched, no need to update the blob column */ + $query = "UPDATE %s SET expiry = %d WHERE id = %s AND expiry >= %d"; + $query = sprintf($query, + $this->options['table'], + time() + ini_get('session.gc_maxlifetime'), + $this->_db->quote(md5($id)), + time()); + } else { + /* Check if table row already exists */ + $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = '%s'", + $this->options['table'], + md5($id)); + + $result = $this->_db->getOne($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + if (0 == intval($result)) { + /* Insert new row into table */ + $query = "INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)"; + $query = sprintf($query, + $this->options['table'], + $this->_db->quote(md5($id)), + time() + ini_get('session.gc_maxlifetime'), + $this->_db->quote($data)); + } else { + /* Update existing row */ + $query = "UPDATE %s SET expiry = %d, data = %s"; + $query .= " WHERE id = %s AND expiry >= %d"; + $query = sprintf($query, + $this->options['table'], + time() + ini_get('session.gc_maxlifetime'), + $this->_db->quote($data), + $this->_db->quote(md5($id)), + time()); + } + } + $result = $this->_db->query($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + return true; + } + + /** + * Destroy session data + * + * @param string $id The id. + * + * @return boolean + */ + public function destroy($id) + { + $query = sprintf("DELETE FROM %s WHERE id = %s", + $this->options['table'], + $this->_db->quote(md5($id))); + + $result = $this->_db->query($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + return true; + } + + /** + * Garbage collection + * + * @param int $maxlifetime The session's maximum lifetime. + * + * @return boolean + * @todo Find out why the DB is not used for garbage collection. + */ + public function gc($maxlifetime) + { + $query = sprintf("DELETE FROM %s WHERE expiry < %d", + $this->options['table'], + time()); + + $result = $this->_db->query($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + + if ($this->options['autooptimize']) { + switch($this->_db->type) { + case 'mysql': + $query = sprintf("OPTIMIZE TABLE %s", $this->options['table']); + break; + case 'pgsql': + $query = sprintf("VACUUM %s", $this->options['table']); + break; + default: + $query = null; + break; + } + if (isset($query)) { + $result = $this->_db->query($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + } + } + return true; + } + + /** + * Replicate session data to specified target + * + * @param string $target Target to replicate to + * @param string $id Id of record to replicate, + * if not specified current session id will be used + * + * @return boolean + */ + public function replicate($target, $id = null) + { + if (is_null($id)) { + $id = HTTP_Session2::id(); + } + + // Check if table row already exists + $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = %s", + $target, + $this->_db->quoteSmart(md5($id))); + $result = $this->_db->getOne($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + + // Insert new row into target table + if (0 == intval($result)) { + $query = "INSERT INTO $target SELECT * FROM"; + $query .= " " . $this->options['table']; + $query .= " WHERE id = " . $this->_db->quoteSmart(md5($id)); + } else { + // Update existing row + $query = "UPDATE $target dst,"; + $query .= " " . $this->options['table']; + $query .= " src SET dst.expiry = src.expiry,"; + $query .= " dst.data = src.data"; + $query .= " WHERE dst.id = src.id"; + $query .= " AND src.id = " . $this->_db->quoteSmart(md5($id)); + } + + $result = $this->_db->query($query); + if (DB::isError($result)) { + new DB_Error($result->code, PEAR_ERROR_DIE); + return false; + } + + return true; + } +} diff --git a/libraries/HTTP_Session2/HTTP/Session2/Container/Interface.php b/libraries/HTTP_Session2/HTTP/Session2/Container/Interface.php new file mode 100644 index 0000000000000000000000000000000000000000..e528617d7b5993f00374d8a79a32887c90862de5 --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2/Container/Interface.php @@ -0,0 +1,123 @@ +<?php +/** + * +-----------------------------------------------------------------------+ + * | Copyright (c) 2004, Tony Bibbs | + * | All rights reserved. | + * | | + * | Redistribution and use in source and binary forms, with or without | + * | modification, are permitted provided that the following conditions | + * | are met: | + * | | + * | o Redistributions of source code must retain the above copyright | + * | notice, this list of conditions and the following disclaimer. | + * | o Redistributions in binary form must reproduce the above copyright | + * | notice, this list of conditions and the following disclaimer in the | + * | documentation and/or other materials provided with the distribution.| + * | o The names of the authors may not be used to endorse or promote | + * | products derived from this software without specific prior written | + * | permission. | + * | | + * | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | + * | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | + * | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | + * | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | + * | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | + * | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | + * | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | + * | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | + * | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | + * | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | + * | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | + * | | + * +-----------------------------------------------------------------------+ + * | Author: Alexander Radivanovich <info@wwwlab.net> | + * | Tony Bibbs <tony@geeklog.net> | + * +-----------------------------------------------------------------------+ + * + * PHP Version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivaniovich <info@wwwlab.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: Interface.php 267742 2008-10-25 17:01:14Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + */ + +/** + * Container class for storing session data data + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivaniovich <info@wwwlab.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + */ +interface HTTP_Session2_Container_Interface +{ + /** + * open + * + * @param string $save_path Path to save sessions in. + * @param string $session_name Name of the session. + * + * @return void + */ + public function open($save_path, $session_name); + + /** + * close + * + * @return void + */ + public function close(); + + /** + * read + * + * @param string $id The session ID. + * + * @return void + */ + public function read($id); + + /** + * write + * + * @param string $id The session ID. + * @param string $data The data to save/write. + * + * @return void + */ + public function write($id, $data); + + /** + * destroy + * + * @param string $id The session ID. + * + * @return void + */ + public function destroy($id); + + /** + * gc + * + * @param int $maxlifetime The session's maximum lifetime. + * + * @return void + */ + public function gc($maxlifetime); + + /** + * Replicate session data to specified target + * + * @param string $target Target to replicate to + * @param string $id Id of record to replicate, + * if not specified current session id will be used + * + * @return boolean + */ + public function replicate($target, $id = null); +} diff --git a/libraries/HTTP_Session2/HTTP/Session2/Container/MDB2.php b/libraries/HTTP_Session2/HTTP/Session2/Container/MDB2.php new file mode 100644 index 0000000000000000000000000000000000000000..e2482414d6760bd7692b7ce3bce529ae1ba4efe0 --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2/Container/MDB2.php @@ -0,0 +1,358 @@ +<?php +/** + * HTTP_Session2_Container_MDB2 + * + * PHP Version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Till Klampaeckel <till@php.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: MDB2.php 267741 2008-10-25 17:00:06Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + */ + +/** + * HTTP/Session2/Container.php + * @ignore + */ +require_once 'HTTP/Session2/Container.php'; + +/** + * HTTP/Session2/Exception.php + */ +require_once 'HTTP/Session2/Exception.php'; + +/** + * MDB2.php + * @ignore + */ +require_once 'MDB2.php'; + +/** + * Database container for session data + * + * Create the following table to store session data + * <code> + * CREATE TABLE `sessiondata` ( + * `id` CHAR(32) NOT NULL, + * `expiry` INT UNSIGNED NOT NULL DEFAULT 0, + * `data` TEXT NOT NULL, + * PRIMARY KEY (`id`) + * ); + * </code> + * + * @category HTTP + * @package HTTP_Session2 + * @author Alexander Radivanovich <info@wwwlab.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + * @uses MDB2 + * @uses MDB2_Driver_* + */ +class HTTP_Session2_Container_MDB2 extends HTTP_Session2_Container +{ + + /** + * MDB2 connection object + * + * @var object DB + */ + protected $db = null; + + /** + * Session data cache id + * + * @var mixed + */ + protected $crc = false; + + /** + * Constrtuctor method + * + * $options is an array with the options.<br> + * The options are: + * <ul> + * <li>'dsn' - The DSN string</li> + * <li>'table' - Table with session data, default is 'sessiondata'</li> + * <li>'autooptimize' - Boolean, 'true' to optimize + * the table on garbage collection, default is 'false'.</li> + * </ul> + * + * @param array $options The options + * + * @return object + */ + public function __construct($options) + { + parent::__construct($options); + } + + /** + * Connect to database by using the given DSN string + * + * @param mixed $dsn DSN string or MDB2 object + * + * @return boolean + * @throws HTTP_Session2_Exception An exception?! + */ + protected function connect($dsn) + { + // pseudo singleton approach + if (is_object($this->db)) { + return true; + } + if (is_string($dsn) || is_array($dsn)) { + if (MDB2::isError($this->db = MDB2::connect($dsn))) { + throw new HTTP_Session2_Exception($this->db->getDebugInfo(), + $this->db->getCode()); + } + } else if (is_object($dsn) && ($dsn instanceof MDB2_Driver_Common)) { + $this->db = $dsn; + } else if (MDB2::isError($dsn)) { + throw new HTTP_Session2_Exception($dsn->getDebugInfo(), + $dsn->getCode()); + } else { + $msg = "The given dsn was not valid in file "; + $msg .= __FILE__ . " at line " . __LINE__; + throw new HTTP_Session2_Exception($msg, + HTTP_Session2::ERR_SYSTEM_PRECONDITION); + } + if (MDB2::isError($this->db)) { + throw new HTTP_Session2_Exception($this->db->getMessage(), + $this->db->getCode()); + } + return true; + } + + /** + * Set some default options + * + * @return void + */ + protected function setDefaults() + { + $this->options['dsn'] = null; + $this->options['table'] = 'sessiondata'; + $this->options['autooptimize'] = false; + } + + /** + * Establish connection to a database + * + * @param string $save_path The path to save/write sessions. + * @param string $session_name The session name. + * + * @return boolean + * @uses self::connect(); + * @uses self::$options + */ + public function open($save_path, $session_name) + { + return $this->connect($this->options['dsn']); + } + + /** + * Free resources + * + * @return boolean + */ + public function close() + { + if (is_object($this->db)) { + $this->db->disconnect(); + } + return true; + } + + /** + * Read session data + * + * @param string $id The Id! + * + * @return mixed + * @throws HTTP_Session2_Exception An exception!? + * @todo Get rid off sprintf() + */ + public function read($id) + { + $query = sprintf("SELECT data FROM %s WHERE id = %s AND expiry >= %d", + $this->options['table'], + $this->db->quote(md5($id)), + time()); + + $result = $this->db->queryOne($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getMessage(), + $result->getCode()); + } + $this->crc = strlen($result) . crc32($result); + return $result; + } + + /** + * Write session data + * + * @param string $id The id. + * @param string $data The data. + * + * @return boolean + * @todo Remove sprintf(), they are expensive. + */ + public function write($id, $data) + { + if ((false !== $this->crc) + && ($this->crc === strlen($data) . crc32($data))) { + /* $_SESSION hasn't been touched, no need to update the blob column */ + $query = "UPDATE %s SET expiry = %d WHERE id = %s AND expiry >= %d"; + $query = sprintf($query, + $this->options['table'], + time() + ini_get('session.gc_maxlifetime'), + $this->db->quote(md5($id)), + time()); + } else { + /* Check if table row already exists */ + $query = sprintf("SELECT COUNT(id) FROM %s WHERE id = '%s'", + $this->options['table'], + md5($id)); + + $result = $this->db->queryOne($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getUserInfo(), + $result->getCode()); + } + if (0 == intval($result)) { + /* Insert new row into table */ + $query = "INSERT INTO %s (id, expiry, data) VALUES (%s, %d, %s)"; + $query = sprintf($query, + $this->options['table'], + $this->db->quote(md5($id)), + time() + ini_get('session.gc_maxlifetime'), + $this->db->quote($data)); + } else { + /* Update existing row */ + $query = "UPDATE %s SET expiry = %d, data = %s"; + $query .= " WHERE id = %s AND expiry >= %d"; + $query = sprintf($query, + $this->options['table'], + time() + ini_get('session.gc_maxlifetime'), + $this->db->quote($data), + $this->db->quote(md5($id)), + time()); + } + } + $result = $this->db->query($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getUserInfo(), + $result->getCode()); + } + return true; + } + + /** + * Destroy session data + * + * @param string $id The id. + * + * @return boolean + * @throws HTTP_Session2_Exception An exception containing MDB2 data. + */ + public function destroy($id) + { + $query = sprintf("DELETE FROM %s WHERE id = %s", + $this->options['table'], + $this->db->quote(md5($id))); + + $result = $this->db->query($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception ($result->getMessage(), + $result->getCode()); + } + return true; + } + + /** + * Garbage collection + * + * Currently supported are mysql, mysqli and pgsql. + * + * @param int $maxlifetime The session's maximum lifetime. + * + * @return boolean + * @throws HTTP_Session2_Exception An exception that contains MDB2 data. + * @todo Fix database-specific garbage collection. + */ + public function gc($maxlifetime) + { + $query = sprintf("DELETE FROM %s WHERE expiry < %d", + $this->options['table'], + time()); + + $result = $this->db->query($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getMessage(), + $result->getCode()); + } + + if ($this->options['autooptimize']) { + $this->db->loadModule('Manager'); + $result = $this->db->vacuum($this->options['table']); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getMessage(), + $result->getCode()); + } + } + return true; + } + + /** + * Replicate session data to specified target + * + * @param string $target The target (table) to replicate to. + * @param string $id Id of record to replicate, + * if not specified current session id will be used + * + * @return boolean + * @throws HTTP_Session2_Exception To carry any MDB2 related error out. + */ + public function replicate($target, $id = null) + { + if ($id === null) { + $id = HTTP_Session2::id(); + } + + // Check if table row already exists + $query = "SELECT COUNT(id) FROM $target"; + $query .= " WHERE id = " . $this->db->quote(md5($id), 'text'); + $result = $this->db->queryOne($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getDebugInfo(), + $result->getCode()); + } + + // Insert new row into dest table + if (0 == intval($result)) { + $query = sprintf("INSERT INTO %s SELECT * FROM %s WHERE id = %s", + $target, + $this->options['table'], + $this->db->quote(md5($id), 'text')); + + } else { + // Update existing row + $query = "UPDATE $target dst, " . $this->options['table']; + $query .= " src SET dst.expiry = src.expiry,"; + $query .= " dst.data = src.data"; + $query .= " WHERE dst.id = src.id"; + $query .= " AND src.id = " . $this->db->quote(md5($id), 'text'); + } + + $result = $this->db->query($query); + if (MDB2::isError($result)) { + throw new HTTP_Session2_Exception($result->getDebugInfo(), + $result->getCode()); + } + + return true; + } +} diff --git a/libraries/HTTP_Session2/HTTP/Session2/Container/Memcache.php b/libraries/HTTP_Session2/HTTP/Session2/Container/Memcache.php new file mode 100644 index 0000000000000000000000000000000000000000..d6a7feab763c4aa74bd5aa1b0d4a1d3cd406b250 --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2/Container/Memcache.php @@ -0,0 +1,190 @@ +<?php +/** + * HTTP_Session2_Container_Memcache + * + * PHP Version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Chad Wagner <chad.wagner@gmail.com> + * @author Torsten Roehr <torsten.roehr@gmx.de> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: Memcache.php 267740 2008-10-25 16:57:41Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + */ + +/** + * HTTP_Session2_Container + */ +require_once 'HTTP/Session2/Container.php'; + +/** + * HTTP_Session2_Exception + */ +require_once 'HTTP/Session2/Exception.php'; + +/** + * Memcache container for session data + * + * @category HTTP + * @package HTTP_Session2 + * @author Chad Wagner <chad.wagner@gmail.com> + * @author Torsten Roehr <torsten.roehr@gmx.de> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + * @since 0.6.2 + */ +class HTTP_Session2_Container_Memcache extends HTTP_Session2_Container +{ + /** + * Memcache connection object + * + * @var object Memcache + */ + protected $mc; + + /** + * Constructor method + * + * $options is an array with the options.<br> + * The options are: + * <ul> + * <li>'memcache' - Memcache object + * <li>'prefix' - Key prefix, default is 'sessiondata:'</li> + * </ul> + * + * @param array $options Options + * + * @return object + */ + public function __construct($options) + { + parent::__construct($options); + } + + /** + * Connect using the given Memcache object. + * + * @param Memcache $mc A Memcache instance. + * + * @return boolean + * @throws HTTP_Session2_Exception + */ + protected function connect($mc) + { + if ($mc instanceof Memcache) { + $this->mc = $mc; + return true; + } + throw new HTTP_Session2_Exception( + 'The given memcache object was not valid in file ' + . __FILE__ . ' at line ' . __LINE__, + HTTP_Session2::ERR_SYSTEM_PRECONDITION); + } + + /** + * Set some default options + * + * @return void + */ + protected function setDefaults() + { + $this->options['prefix'] = 'sessiondata:'; + $this->options['memcache'] = null; + } + + /** + * Establish connection to a database + * + * @param string $save_path Save path + * @param string $session_name Session name + * + * @return boolean + */ + public function open($save_path, $session_name) + { + return $this->connect($this->options['memcache']); + } + + /** + * Free resources + * + * @return boolean + */ + public function close() + { + return true; + } + /** + * Read session data + * + * @param string $id Session id + * + * @return mixed + */ + public function read($id) + { + return $this->mc->get($this->options['prefix'] . $id); + } + + /** + * Write session data + * + * @param string $id Session id + * @param mixed $data Session data + * + * @return boolean + */ + public function write($id, $data) + { + $this->mc->set($this->options['prefix'] . $id, + $data, + MEMCACHE_COMPRESSED, + time() + ini_get('session.gc_maxlifetime')); + + return true; + } + + /** + * Destroy session data + * + * @param string $id Session id + * + * @return boolean + */ + public function destroy($id) + { + $this->mc->delete($this->options['prefix'] . $id); + return true; + } + + /** + * Garbage collection + * + * @param int $maxlifetime Maximum lifetime + * + * @return boolean + */ + public function gc($maxlifetime) + { + return true; + } + + /** + * Replicate session data to specified target + * + * @param string $target Target to replicate to + * @param string $id Id of record to replicate, + * if not specified current session id will be used + * + * @return boolean + */ + public function replicate($target, $id = null) + { + $msg = 'The replicate feature is not available yet'; + $msg .= ' for the Memcache container.'; + + throw new HTTP_Session2_Exception($msg, HTTP_Session2::ERR_NOT_IMPLEMENTED); + } +} diff --git a/libraries/HTTP_Session2/HTTP/Session2/Exception.php b/libraries/HTTP_Session2/HTTP/Session2/Exception.php new file mode 100644 index 0000000000000000000000000000000000000000..b64399bbb19bb4709cc2a66ba30593f33fd5952d --- /dev/null +++ b/libraries/HTTP_Session2/HTTP/Session2/Exception.php @@ -0,0 +1,110 @@ +<?php +/** + * HTTP_Session2_Exception + * + * Base exception class for HTTP_Session2 + * + * Copyright (c) 2007, Till Klampaeckel + * + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of PEAR nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * PHP version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Till Klampaeckel <till@php.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version CVS: $Id: Exception.php 266531 2008-09-19 13:12:58Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + */ + +/** + * PEAR/Exception.php + * @ignore + */ +require_once 'vtlib/thirdparty/network/PEAR.php'; + +/** + * HTTP_Session2_Exception + * + * PHP version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @author Till Klampaeckel <till@php.net> + * @license http://www.opensource.org/licenses/bsd-license.php The BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + */ +class HTTP_Session2_Exception extends PEAR_Exception +{ + /** + * @var array $exceptionStack To add an exception, when we re-throw. + */ + protected $exceptionStack = array(); + + /** + * __construct + * + * @param string $message An error message. + * @param mixed $code An error code. + * @param mixed $exception The previous exception, when we re-throw [optional] + * + * @uses parent::__construct() + * @uses self::$exceptionStack + */ + public function __construct($message, $code = null, $exception = null) + { + if ($exception !== null) { + array_push($this->exceptionStack, $exception); + } + parent::__construct($message, $code); + } + + /** + * __toString() implementation for lazy coders like me :) + * + * @return string + * @uses parent::$message + * @uses parent::$code + */ + public function __toString() + { + return "{$this->message} Code: {$this->code}"; + } + + /** + * Return all stacked exceptions + * + * @return array + * @uses self::$exceptionStack + */ + public function getExceptionStack() + { + return $this->exceptionStack; + } +} diff --git a/libraries/HTTP_Session2/docs/HTTP_Session2_Example.php b/libraries/HTTP_Session2/docs/HTTP_Session2_Example.php new file mode 100644 index 0000000000000000000000000000000000000000..8f2b59d17b0e51dc8b5497774f47c58d9fa88eb6 --- /dev/null +++ b/libraries/HTTP_Session2/docs/HTTP_Session2_Example.php @@ -0,0 +1,144 @@ +<?php +// +// +-----------------------------------------------------------------------+ +// | Copyright (c) 2002, Alexander Radivanovich | +// | All rights reserved. | +// | | +// | Redistribution and use in source and binary forms, with or without | +// | modification, are permitted provided that the following conditions | +// | are met: | +// | | +// | o Redistributions of source code must retain the above copyright | +// | notice, this list of conditions and the following disclaimer. | +// | o Redistributions in binary form must reproduce the above copyright | +// | notice, this list of conditions and the following disclaimer in the | +// | documentation and/or other materials provided with the distribution.| +// | o The names of the authors may not be used to endorse or promote | +// | products derived from this software without specific prior written | +// | permission. | +// | | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | +// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | +// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | +// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | +// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | +// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | +// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | +// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | +// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | +// | | +// +-----------------------------------------------------------------------+ +// | Author: Alexander Radivanovich <info@wwwlab.net> | +// +-----------------------------------------------------------------------+ +// + +//ob_start(); //-- For easy debugging --// + +require_once 'PEAR.php'; +require_once 'HTTP/Session2.php'; + +ini_set('error_reporting', E_ALL); +ini_set('display_errors', 1); +//PEAR::setErrorHandling(PEAR_ERROR_DIE); + +/* +HTTP_Session2::setContainer( + 'DB', + array( + 'dsn' => 'mysql://root@localhost/database', + 'table' => 'sessiondata' + ) +); +*/ +HTTP_Session2::useCookies(true); +HTTP_Session2::start('SessionID', uniqid('MyID')); + +?> +<html> +<head> +<style> +body, td { + font-family: Verdana, Arial, sans-serif; + font-size: 11px; +} +A:link { color:#003399; text-decoration: none; } +A:visited { color:#6699CC; text-decoration: none; } +A:hover { text-decoration: underline; } +</style> +<title>HTTP Session</title> +</head> +<body style="margin: 5px;"> +<?php + +/* +if (!isset($variable)) { + $variable = 0; + echo("The variable wasn't previously set<br>\n"); +} else { + $variable++; + echo("Yes, it was set already<br>\n"); +} +*/ + +switch (@$_GET['action']) { + case 'setvariable': + HTTP_Session2::set('variable', 'Test string'); + //HTTP_Session2::register('variable'); + break; + case 'unsetvariable': + HTTP_Session2::set('variable', null); + //HTTP_Session2::unregister('variable'); + break; + case 'clearsession': + HTTP_Session2::clear(); + break; + case 'destroysession': + HTTP_Session2::destroy(); + break; +} + +HTTP_Session2::setExpire(60); +HTTP_Session2::setIdle(5); + +//echo("session_is_registered('variable'): <b>'" . (session_is_registered('variable') ? "<span style='color: red;'>yes</span>" : "no") . "'</b><br>\n"); +//echo("isset(\$GLOBALS['variable']): <b>'" . (isset($GLOBALS['variable']) ? "<span style='color: red;'>yes</span>" : "no") . "'</b><br>\n"); + +echo("------------------------------------------------------------------<br>\n"); +echo("Session name: <b>'" . HTTP_Session2::name() . "'</b><br>\n"); +echo("Session id: <b>'" . HTTP_Session2::id() . "'</b><br>\n"); +echo("Is new session: <b>'" . (HTTP_Session2::isNew() ? "<span style='color: red;'>yes</span>" : "no") . "'</b><br>\n"); +echo("Is expired: <b>'" . (HTTP_Session2::isExpired() ? "<span style='color: red;'>yes</span>" : "no") . "'</b><br>\n"); +echo("Is idle: <b>'" . (HTTP_Session2::isIdle() ? "<span style='color: red;'>yes</span>" : "no") . "'</b><br>\n"); +//echo("Variable: <b>'" . HTTP_Session2::get('variable') . "'</b><br>\n"); +echo("Session valid thru: <b>'" . (HTTP_Session2::sessionValidThru() - time()) . "'</b><br>\n"); +echo("------------------------------------------------------------------<br>\n"); + +if (HTTP_Session2::isNew()) { + //HTTP_Session2::set('var', 'value'); + //HTTP_Session2::setLocal('localvar', 'localvalue'); + //blah blah blah +} + +?> +<div style="background-color: #F0F0F0; padding: 15px; margin: 5px;"> +<pre> +$_SESSION: +<?php +var_dump($_SESSION); +?> +</pre> +</div> +<?php + +HTTP_Session2::updateIdle(); + +?> +<p><a href="<?php echo $_SERVER['SCRIPT_NAME'] ?>?action=setvariable">Set variable</a></p> +<p><a href="<?php echo $_SERVER['SCRIPT_NAME'] ?>?action=unsetvariable">Unset variable</a></p> +<p><a href="<?php echo $_SERVER['SCRIPT_NAME'] ?>?action=destroysession">Destroy session</a></p> +<p><a href="<?php echo $_SERVER['SCRIPT_NAME'] ?>?action=clearsession">Clear session data</a></p> +<p><a href="<?php echo $_SERVER['SCRIPT_NAME'] ?>">Reload page</a></p> +</body> +</html> diff --git a/libraries/HTTP_Session2/docs/sessiondata.sql b/libraries/HTTP_Session2/docs/sessiondata.sql new file mode 100644 index 0000000000000000000000000000000000000000..f2997cf8fa8fdcbae4ec2d62b592354cbaaf8e2a --- /dev/null +++ b/libraries/HTTP_Session2/docs/sessiondata.sql @@ -0,0 +1,7 @@ +CREATE TABLE `sessiondata` ( + `id` varchar(32) NOT NULL default '', + `expiry` int(10) unsigned NOT NULL default '0', + `data` text NOT NULL, + PRIMARY KEY (`id`) +) TYPE=MyISAM; + diff --git a/libraries/HTTP_Session2/tests/AllTests.php b/libraries/HTTP_Session2/tests/AllTests.php new file mode 100644 index 0000000000000000000000000000000000000000..d5a5b1be401732e731f9bdd05e297e4284386298 --- /dev/null +++ b/libraries/HTTP_Session2/tests/AllTests.php @@ -0,0 +1,131 @@ +<?php +/** + * Master Unit Test Suite file for HTTP_Session2 + * + * This top-level test suite file organizes + * all class test suite files, + * so that the full suite can be run + * by PhpUnit or via "pear run-tests -u". + * + * PHP version 5 + * + * @category HTTP + * @package HTTP_Session2 + * @subpackage UnitTesting + * @author Chuck Burgess <ashnazg@php.net> + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: AllTests.php 266495 2008-09-18 17:31:48Z till $ + * @link http://pear.php.net/package/HTTP_Session2 + * @since 0.8.0 + */ + + +/** + * Check PHP version... PhpUnit v3+ requires at least PHP v5.1.4 + */ +if (version_compare(PHP_VERSION, "5.1.4") < 0) { + // Cannnot run test suites + echo 'Cannot run test suite via PhpUnit... requires at least PHP v5.1.4.' . PHP_EOL; + echo 'Use "pear run-tests -p HTTP_Session2" to run the PHPT tests directly.' . PHP_EOL +; + exit(1); +} + + +/** + * Derive the "main" method name + * @internal PhpUnit would have to rename PHPUnit_MAIN_METHOD to PHPUNIT_MAIN_METHOD + * to make this usage meet the PEAR CS... we cannot rename it here. + */ +if (!defined('PHPUnit_MAIN_METHOD')) { + define('PHPUnit_MAIN_METHOD', 'HTTP_Session2_AllTests::main'); +} + + +/* + * Files needed by PhpUnit + */ +require_once 'PHPUnit/Framework.php'; +require_once 'PHPUnit/TextUI/TestRunner.php'; +require_once 'PHPUnit/Extensions/PhptTestSuite.php'; + +/* + * You must add each additional class-level test suite file here + */ +// there are no PhpUnit test files... only PHPTs.. so nothing is listed here + +/** + * directory where PHPT tests are located + */ +define('HTTP_Session2_DIR_PHPT', dirname(__FILE__)); + +/** + * Master Unit Test Suite class for HTTP_Session2 + * + * This top-level test suite class organizes + * all class test suite files, + * so that the full suite can be run + * by PhpUnit or via "pear run-tests -up HTTP_Session2". + * + * @category XML + * @package HTTP_Session2 + * @subpackage UnitTesting + * @author Chuck Burgess <ashnazg@php.net> + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTTP_Session2 + * @since 0.8.0 + */ +class HTTP_Session2_AllTests +{ + + /** + * Launches the TextUI test runner + * + * @return void + * @uses PHPUnit_TextUI_TestRunner + */ + public static function main() + { + PHPUnit_TextUI_TestRunner::run(self::suite()); + } + + + /** + * Adds all class test suites into the master suite + * + * @return PHPUnit_Framework_TestSuite a master test suite + * containing all class test suites + * @uses PHPUnit_Framework_TestSuite + */ + public static function suite() + { + $suite = new PHPUnit_Framework_TestSuite( + 'HTTP_Session2 Full Suite of Unit Tests'); + + /* + * You must add each additional class-level test suite name here + */ + // there are no PhpUnit test files... only PHPTs.. so nothing is listed here + + /* + * add PHPT tests + */ + $phpt = new PHPUnit_Extensions_PhptTestSuite(HTTP_Session2_DIR_PHPT); + $suite->addTestSuite($phpt); + + return $suite; + } +} + +/** + * Call the main method if this file is executed directly + * @internal PhpUnit would have to rename PHPUnit_MAIN_METHOD to PHPUNIT_MAIN_METHOD + * to make this usage meet the PEAR CS... we cannot rename it here. + */ +if (PHPUnit_MAIN_METHOD == 'HTTP_Session2_AllTests::main') { + HTTP_Session2_AllTests::main(); +} + +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ +?> diff --git a/libraries/HTTP_Session2/tests/functions.php b/libraries/HTTP_Session2/tests/functions.php new file mode 100644 index 0000000000000000000000000000000000000000..d23c89417d8d3ef13f464097e703180b41de81dd --- /dev/null +++ b/libraries/HTTP_Session2/tests/functions.php @@ -0,0 +1,37 @@ +<?php +/** + * Recursively delete a directory + * + * @param string $dir Directory name + * @param boolean $deleteRootToo Delete specified top-level directory as well + * @link http://de2.php.net/manual/en/function.unlink.php#87045 + * @author John Hassal + */ +function unlinkRecursive($dir, $deleteRootToo = false) +{ + if (!is_dir($dir)) { + return; + } + + if (!$dh = opendir($dir)) { + return; + } + while (false !== ($obj = readdir($dh))) { + if ($obj == '.' || $obj == '..') { + continue; + } + + if (file_exists($dir . '/' . $obj)) { + if (!@unlink($dir . '/' . $obj)) { + unlinkRecursive($dir.'/'.$obj, true); + } + } + } + closedir($dh); + + if ($deleteRootToo) { + @rmdir($dir); + } + return; +} +?> diff --git a/libraries/HTTP_Session2/tests/test-session-doctrine.phpt b/libraries/HTTP_Session2/tests/test-session-doctrine.phpt new file mode 100644 index 0000000000000000000000000000000000000000..53915c0a9dcedcd3d71cbba270ae42cb35979cf8 --- /dev/null +++ b/libraries/HTTP_Session2/tests/test-session-doctrine.phpt @@ -0,0 +1,96 @@ +--TEST-- +HTTP_Session2 with phpDoctrine container (and sqlite) write and read +--SKIPIF-- +<?php +$skip = true; +if ($skip === true) { + die('Skip This is an incomplete test.'); +} +if (!extension_loaded('pdo')) { + die('Skip This test needs pdo, please make sure it\'s loaded.'); +} +if (!extension_loaded('pdo_sqlite')) { + die('Skip This test needs pdo_sqlite, please make sure it\'s loaded.'); +} +include_once 'Doctrine/lib/Doctrine.php'; +if (!class_exists('Doctrine')) { + die('Skip This test needs phpDoctrine, please make sure it\'s installed.'); +} +?> +--FILE-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +$_db = $_tmp . '/test-doctrine.db'; + +require_once 'HTTP/Session2.php'; + +/** + * This is a hack. + * + * @param string $_db Path to the db. + * + * @return void + */ +function createDB($db) +{ + require_once 'Doctrine/lib/Doctrine.php'; + spl_autoload_register(array('Doctrine', 'autoload')); + + try { + $db = Doctrine_Manager::connection("sqlite:///$db"); + $path = '@include_path@/HTTP/Session2/Container/Doctrine'; + + if (strstr($path, '@include_path@')) { // for from VCS + $path = str_replace( + '@include_path@', + realpath(dirname(__FILE__) . '/../'), + $path + ); + } + $sql = Doctrine::generateSqlFromModels($path); + $db->execute($sql); + } catch (Doctrine_Exception $e) { + if (!strstr($e->getMessage(), 'already exists')) { + die("createDB sql error: {$e->getMessage()} ({$e->getCode()})"); + } + } +} + +if (!file_exists($_tmp)) { + mkdir($_tmp); +} +createDB($_db); + +try { + HTTP_Session2::useCookies(false); + HTTP_Session2::setContainer('Doctrine', + array('dsn' => "sqlite:///{$_db}", + 'table' => 'sessiondata')); + + HTTP_Session2::start('testSession'); + HTTP_Session2::id('sessionTest'); + + $nCount = 0; + while (++$nCount <= 2) { + $_var = HTTP_Session2::get('test', 'bar'); + if ($_var == 'bar') { + var_dump("Setting.."); + HTTP_Session2::set('test', 'foobar'); + } else { + var_dump("Retrieving.."); + var_dump(HTTP_Session2::get('test')); + } + } +} catch (Exception $e) { + die($e->getMessage()); +} +--CLEAN-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +include dirname(__FILE__) . '/functions.php'; +unlinkRecursive($_tmp); +--EXPECT-- +string(9) "Setting.." +string(12) "Retrieving.." +string(6) "foobar" + diff --git a/libraries/HTTP_Session2/tests/test-session-mdb2.phpt b/libraries/HTTP_Session2/tests/test-session-mdb2.phpt new file mode 100644 index 0000000000000000000000000000000000000000..91bdd16436bf28d161285d2a043f9936364148cb --- /dev/null +++ b/libraries/HTTP_Session2/tests/test-session-mdb2.phpt @@ -0,0 +1,90 @@ +--TEST-- +HTTP_Session2 with MDB2 container (and sqlite) write and read +--SKIPIF-- +<?php +if ( + false === @include_once 'MDB2.php' + || false === @include_once 'MDB2/Driver/sqlite.php' +) { + die('skip Please install MDB2 (and its SQLite driver) to run this test.'); +} +if (!extension_loaded('sqlite')) { + die('skip Please install the sqlite extension to run this test.'); +} +?> +--FILE-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +$_db = $_tmp . '/test.db'; + +require_once 'MDB2.php'; +require_once 'HTTP/Session2.php'; + +/** + * This is a hack. + * + * @param string $_db Path to the db. + * + * @return void + */ +function createDB($db) +{ + if (!file_exists($db)) { + if ($db = sqlite_open($db, "0666", $sqliteerror)) { + // create table + $sql = 'CREATE TABLE "sessiondata" ('; + $sql .= '"id" VARCHAR(32) NOT NULL,'; + $sql .= '"expiry" INT UNSIGNED NOT NULL DEFAULT 0,'; + $sql .= '"data" TEXT NOT NULL,'; + $sql .= 'PRIMARY KEY ("id")'; + $sql .= ');'; + + sqlite_query($db, $sql); + sqlite_close($db); + } else { + die($sqliteerror); + } + } +} + +if (!file_exists($_tmp)) { + mkdir($_tmp); +} +createDB($_db); + +try { + HTTP_Session2::useCookies(false); + HTTP_Session2::setContainer('MDB2', + array('dsn' => "sqlite:///{$_db}", + 'table' => 'sessiondata')); + + HTTP_Session2::start('testSession'); + HTTP_Session2::id('sessionTest'); + + $nCount = 0; + while (++$nCount <= 2) { + $_var = HTTP_Session2::get('test', 'bar'); + if ($_var == 'bar') { + var_dump("Setting.."); + HTTP_Session2::set('test', 'foobar'); + } else { + var_dump("Retrieving.."); + var_dump(HTTP_Session2::get('test')); + } + } +} catch (HTTP_Session2_Exception $e) { + die($e->getMessage()); +} +--CLEAN-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +$_db = $_tmp . '/test.db'; +unlink($_db); + +include dirname(__FILE__) . '/functions.php'; +unlinkRecursive($_tmp, true); + +--EXPECT-- +string(9) "Setting.." +string(12) "Retrieving.." +string(6) "foobar" diff --git a/libraries/HTTP_Session2/tests/test-session.phpt b/libraries/HTTP_Session2/tests/test-session.phpt new file mode 100644 index 0000000000000000000000000000000000000000..34eba76021b05cf0736c9de5f48f1308e728d25e --- /dev/null +++ b/libraries/HTTP_Session2/tests/test-session.phpt @@ -0,0 +1,37 @@ +--TEST-- +Vanilla testing session write and read +--FILE-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +$_id = 1234; + +if (!file_exists($_tmp)) { + mkdir($_tmp); +} +ini_set('session.save_path', $_tmp); +session_id($_id); + +session_start(); + +$nCount = 0; +while(++$nCount <= 2) { + if (!isset($_SESSION['test'])) { + var_dump("Setting.."); + $_SESSION['test'] = 'foobar'; + } else { + var_dump("Retrieving.."); + var_dump($_SESSION['test']); + } +} +--CLEAN-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +$_id = 1234; + +unlink($_tmp . '/' . 'sess_' . $_id); +rmdir($_tmp); +--EXPECT-- +string(9) "Setting.." +string(12) "Retrieving.." +string(6) "foobar" + diff --git a/libraries/HTTP_Session2/tests/test-session2.phpt b/libraries/HTTP_Session2/tests/test-session2.phpt new file mode 100644 index 0000000000000000000000000000000000000000..a21cb54854fcd0f0a03382465f0160514b7b4381 --- /dev/null +++ b/libraries/HTTP_Session2/tests/test-session2.phpt @@ -0,0 +1,39 @@ +--TEST-- +HTTP_Session2 testing session write and read (file-only) +--FILE-- +<?php +$_tmp = dirname(__FILE__) . '/tmp'; +$_id = 1234; + +require_once 'HTTP/Session2.php'; + +if (!file_exists($_tmp)) { + mkdir($_tmp); +} +ini_set('session.save_path', $_tmp); + +HTTP_Session2::useCookies(false); +HTTP_Session2::start('testSession'); +HTTP_Session2::id($_id); + +$nCount = 0; +while(++$nCount <= 2) { + $_var = HTTP_Session2::get('test', 'bar'); + if ($_var == 'bar') { + var_dump("Setting.."); + HTTP_Session2::set('test', 'foobar'); + } else { + var_dump("Retrieving.."); + var_dump(HTTP_Session2::get('test')); + } +} +--CLEAN-- +<?php +include dirname(__FILE__) . '/functions.php'; +$_tmp = dirname(__FILE__) . '/tmp'; +unlinkRecursive($_tmp, true); +--EXPECT-- +string(9) "Setting.." +string(12) "Retrieving.." +string(6) "foobar" + diff --git a/vtlib/thirdparty/network/PEAR.php b/vtlib/thirdparty/network/PEAR.php index 4c24c6006a398f8f8ade714a87e67db58b9c7619..45665a575526e07c154a4902dced3c49625ecd17 100644 --- a/vtlib/thirdparty/network/PEAR.php +++ b/vtlib/thirdparty/network/PEAR.php @@ -1115,4 +1115,460 @@ class PEAR_Error * c-basic-offset: 4 * End: */ + +/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ +/** + * PEAR_Exception + * + * PHP version 5 + * + * @category PEAR + * @package PEAR_Exception + * @author Tomas V. V. Cox <cox@idecnet.com> + * @author Hans Lellelid <hans@velum.net> + * @author Bertrand Mansion <bmansion@mamasam.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @link http://pear.php.net/package/PEAR_Exception + * @since File available since Release 1.0.0 + */ + + +/** + * Base PEAR_Exception Class + * + * 1) Features: + * + * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) + * - Definable triggers, shot when exceptions occur + * - Pretty and informative error messages + * - Added more context info available (like class, method or cause) + * - cause can be a PEAR_Exception or an array of mixed + * PEAR_Exceptions/PEAR_ErrorStack warnings + * - callbacks for specific exception classes and their children + * + * 2) Ideas: + * + * - Maybe a way to define a 'template' for the output + * + * 3) Inherited properties from PHP Exception Class: + * + * protected $message + * protected $code + * protected $line + * protected $file + * private $trace + * + * 4) Inherited methods from PHP Exception Class: + * + * __clone + * __construct + * getMessage + * getCode + * getFile + * getLine + * getTraceSafe + * getTraceSafeAsString + * __toString + * + * 5) Usage example + * + * <code> + * require_once 'PEAR/Exception.php'; + * + * class Test { + * function foo() { + * throw new PEAR_Exception('Error Message', ERROR_CODE); + * } + * } + * + * function myLogger($pear_exception) { + * echo $pear_exception->getMessage(); + * } + * // each time a exception is thrown the 'myLogger' will be called + * // (its use is completely optional) + * PEAR_Exception::addObserver('myLogger'); + * $test = new Test; + * try { + * $test->foo(); + * } catch (PEAR_Exception $e) { + * print $e; + * } + * </code> + * + * @category PEAR + * @package PEAR_Exception + * @author Tomas V.V.Cox <cox@idecnet.com> + * @author Hans Lellelid <hans@velum.net> + * @author Bertrand Mansion <bmansion@mamasam.com> + * @author Greg Beaver <cellog@php.net> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.0.0 + * @link http://pear.php.net/package/PEAR_Exception + * @since Class available since Release 1.0.0 + */ +class PEAR_Exception extends Exception +{ + const OBSERVER_PRINT = -2; + const OBSERVER_TRIGGER = -4; + const OBSERVER_DIE = -8; + protected $cause; + private static $_observers = array(); + private static $_uniqueid = 0; + private $_trace; + + /** + * Supported signatures: + * - PEAR_Exception(string $message); + * - PEAR_Exception(string $message, int $code); + * - PEAR_Exception(string $message, Exception $cause); + * - PEAR_Exception(string $message, Exception $cause, int $code); + * - PEAR_Exception(string $message, PEAR_Error $cause); + * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); + * - PEAR_Exception(string $message, array $causes); + * - PEAR_Exception(string $message, array $causes, int $code); + * + * @param string $message exception message + * @param int|Exception|PEAR_Error|array|null $p2 exception cause + * @param int|null $p3 exception code or null + */ + public function __construct($message, $p2 = null, $p3 = null) + { + if (is_int($p2)) { + $code = $p2; + $this->cause = null; + } elseif (is_object($p2) || is_array($p2)) { + // using is_object allows both Exception and PEAR_Error + if (is_object($p2) && !($p2 instanceof Exception)) { + if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { + throw new PEAR_Exception( + 'exception cause must be Exception, ' . + 'array, or PEAR_Error' + ); + } + } + $code = $p3; + if (is_array($p2) && isset($p2['message'])) { + // fix potential problem of passing in a single warning + $p2 = array($p2); + } + $this->cause = $p2; + } else { + $code = null; + $this->cause = null; + } + parent::__construct($message, $code); + $this->signal(); + } + + /** + * Add an exception observer + * + * @param mixed $callback - A valid php callback, see php func is_callable() + * - A PEAR_Exception::OBSERVER_* constant + * - An array(const PEAR_Exception::OBSERVER_*, + * mixed $options) + * @param string $label The name of the observer. Use this if you want + * to remove it later with removeObserver() + * + * @return void + */ + public static function addObserver($callback, $label = 'default') + { + self::$_observers[$label] = $callback; + } + + /** + * Remove an exception observer + * + * @param string $label Name of the observer + * + * @return void + */ + public static function removeObserver($label = 'default') + { + unset(self::$_observers[$label]); + } + + /** + * Generate a unique ID for an observer + * + * @return int unique identifier for an observer + */ + public static function getUniqueId() + { + return self::$_uniqueid++; + } + + /** + * Send a signal to all observers + * + * @return void + */ + protected function signal() + { + foreach (self::$_observers as $func) { + if (is_callable($func)) { + call_user_func($func, $this); + continue; + } + settype($func, 'array'); + switch ($func[0]) { + case self::OBSERVER_PRINT : + $f = (isset($func[1])) ? $func[1] : '%s'; + printf($f, $this->getMessage()); + break; + case self::OBSERVER_TRIGGER : + $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; + trigger_error($this->getMessage(), $f); + break; + case self::OBSERVER_DIE : + $f = (isset($func[1])) ? $func[1] : '%s'; + die(printf($f, $this->getMessage())); + break; + default: + trigger_error('invalid observer type', E_USER_WARNING); + } + } + } + + /** + * Return specific error information that can be used for more detailed + * error messages or translation. + * + * This method may be overridden in child exception classes in order + * to add functionality not present in PEAR_Exception and is a placeholder + * to define API + * + * The returned array must be an associative array of parameter => value like so: + * <pre> + * array('name' => $name, 'context' => array(...)) + * </pre> + * + * @return array + */ + public function getErrorData() + { + return array(); + } + + /** + * Returns the exception that caused this exception to be thrown + * + * @return Exception|array The context of the exception + */ + public function getCause() + { + return $this->cause; + } + + /** + * Function must be public to call on caused exceptions + * + * @param array $causes Array that gets filled. + * + * @return void + */ + public function getCauseMessage(&$causes) + { + $trace = $this->getTraceSafe(); + $cause = array('class' => get_class($this), + 'message' => $this->message, + 'file' => 'unknown', + 'line' => 'unknown'); + if (isset($trace[0])) { + if (isset($trace[0]['file'])) { + $cause['file'] = $trace[0]['file']; + $cause['line'] = $trace[0]['line']; + } + } + $causes[] = $cause; + if ($this->cause instanceof PEAR_Exception) { + $this->cause->getCauseMessage($causes); + } elseif ($this->cause instanceof Exception) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => $this->cause->getFile(), + 'line' => $this->cause->getLine()); + } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($this->cause)) { + foreach ($this->cause as $cause) { + if ($cause instanceof PEAR_Exception) { + $cause->getCauseMessage($causes); + } elseif ($cause instanceof Exception) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => $cause->getFile(), + 'line' => $cause->getLine()); + } elseif (class_exists('PEAR_Error') + && $cause instanceof PEAR_Error + ) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($cause) && isset($cause['message'])) { + // PEAR_ErrorStack warning + $causes[] = array( + 'class' => $cause['package'], + 'message' => $cause['message'], + 'file' => isset($cause['context']['file']) ? + $cause['context']['file'] : + 'unknown', + 'line' => isset($cause['context']['line']) ? + $cause['context']['line'] : + 'unknown', + ); + } + } + } + } + + /** + * Build a backtrace and return it + * + * @return array Backtrace + */ + public function getTraceSafe() + { + if (!isset($this->_trace)) { + $this->_trace = $this->getTrace(); + if (empty($this->_trace)) { + $backtrace = debug_backtrace(); + $this->_trace = array($backtrace[count($backtrace)-1]); + } + } + return $this->_trace; + } + + /** + * Gets the first class of the backtrace + * + * @return string Class name + */ + public function getErrorClass() + { + $trace = $this->getTraceSafe(); + return $trace[0]['class']; + } + + /** + * Gets the first method of the backtrace + * + * @return string Method/function name + */ + public function getErrorMethod() + { + $trace = $this->getTraceSafe(); + return $trace[0]['function']; + } + + /** + * Converts the exception to a string (HTML or plain text) + * + * @return string String representation + * + * @see toHtml() + * @see toText() + */ + public function __toString() + { + if (isset($_SERVER['REQUEST_URI'])) { + return $this->toHtml(); + } + return $this->toText(); + } + + /** + * Generates a HTML representation of the exception + * + * @return string HTML code + */ + public function toHtml() + { + $trace = $this->getTraceSafe(); + $causes = array(); + $this->getCauseMessage($causes); + $html = '<table style="border: 1px" cellspacing="0">' . "\n"; + foreach ($causes as $i => $cause) { + $html .= '<tr><td colspan="3" style="background: #ff9999">' + . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: ' + . htmlspecialchars($cause['message']) + . ' in <b>' . $cause['file'] . '</b> ' + . 'on line <b>' . $cause['line'] . '</b>' + . "</td></tr>\n"; + } + $html .= '<tr><td colspan="3" style="background-color: #aaaaaa; text-align: center; font-weight: bold;">Exception trace</td></tr>' . "\n" + . '<tr><td style="text-align: center; background: #cccccc; width:20px; font-weight: bold;">#</td>' + . '<td style="text-align: center; background: #cccccc; font-weight: bold;">Function</td>' + . '<td style="text-align: center; background: #cccccc; font-weight: bold;">Location</td></tr>' . "\n"; + + foreach ($trace as $k => $v) { + $html .= '<tr><td style="text-align: center;">' . $k . '</td>' + . '<td>'; + if (!empty($v['class'])) { + $html .= $v['class'] . $v['type']; + } + $html .= $v['function']; + $args = array(); + if (!empty($v['args'])) { + foreach ($v['args'] as $arg) { + if (is_null($arg)) { + $args[] = 'null'; + } else if (is_array($arg)) { + $args[] = 'Array'; + } else if (is_object($arg)) { + $args[] = 'Object('.get_class($arg).')'; + } else if (is_bool($arg)) { + $args[] = $arg ? 'true' : 'false'; + } else if (is_int($arg) || is_double($arg)) { + $args[] = $arg; + } else { + $arg = (string)$arg; + $str = htmlspecialchars(substr($arg, 0, 16)); + if (strlen($arg) > 16) { + $str .= '…'; + } + $args[] = "'" . $str . "'"; + } + } + } + $html .= '(' . implode(', ', $args) . ')' + . '</td>' + . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown') + . ':' . (isset($v['line']) ? $v['line'] : 'unknown') + . '</td></tr>' . "\n"; + } + $html .= '<tr><td style="text-align: center;">' . ($k+1) . '</td>' + . '<td>{main}</td>' + . '<td> </td></tr>' . "\n" + . '</table>'; + return $html; + } + + /** + * Generates text representation of the exception and stack trace + * + * @return string + */ + public function toText() + { + $causes = array(); + $this->getCauseMessage($causes); + $causeMsg = ''; + foreach ($causes as $i => $cause) { + $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' + . $cause['message'] . ' in ' . $cause['file'] + . ' on line ' . $cause['line'] . "\n"; + } + return $causeMsg . $this->getTraceAsString(); + } +} + ?>