* Attempts to return a concrete Horde_SessionHandler instance based on
* $driver.
*
- * @param string $driver The type of concrete subclass to return.
+ * @param string $driver The type of concrete subclass to return
+ * (case-insensitive).
* @param array $params A hash containing any additional configuration or
* connection parameters a subclass might need.
*
*/
static public function factory($driver, $params = array())
{
- $driver = basename($driver);
+ $driver = basename(strtolower($driver));
$persistent_params = array();
if ($driver == 'memcached') {
$params = array();
}
- $class = 'Horde_SessionHandler_' . $driver;
+ $class = 'Horde_SessionHandler_' . ucfirst($driver);
if (class_exists($class)) {
if (empty($params)) {
return new $class(array_merge($params, $persistent_params));
}
- throw new Horde_Exception('Class definition of ' . $class . ' not found.');
+ throw new Horde_Exception('Driver "' . $driver . '" not found.');
}
/**
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler:: implementation for LDAP directories.
+ *
+ * Required parameters:<pre>
+ * 'hostspec' - (string) The hostname of the ldap server.
+ * 'port' - (integer) The port number of the ldap server.
+ * 'dn' - (string) The bind DN.
+ * 'password' - (string) The bind password.
+ * </pre>
+ *
+ * This code is adapted from the comments at
+ * http://www.php.net/session-set-save-handler.
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_Ldap extends Horde_SessionHandler
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var resource
+ */
+ protected $_conn;
+
+ /**
+ * Open the backend.
+ *
+ * @param string $save_path The path to the session object.
+ * @param string $session_name The name of the session.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _open($save_path = null, $session_name = null)
+ {
+ $this->_conn = @ldap_connect($this->_params['hostspec'], $this->_params['port']);
+
+ // Set protocol version if necessary.
+ if (isset($this->_params['version'])) {
+ if (!@ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION, $this->_params['version'])) {
+ throw new Horde_Exception(sprintf('Set LDAP protocol version to %d failed: [%d] %s', $this->_params['version'], ldap_errno($conn), ldap_error($conn)));
+ }
+ }
+
+ if (!@ldap_bind($this->_conn, $this->_params['dn'], $this->_params['password'])) {
+ throw new Horde_Exception('Could not bind to LDAP server.');
+ }
+ }
+
+ /**
+ * Close the backend.
+ */
+ protected function _close()
+ {
+ if (!@ldap_close($this->_conn)) {
+ throw new Horde_Exception('Could not unbind from LDAP server.');
+ }
+ }
+
+ /**
+ * Read the data for a particular session identifier from the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ $sr = @ldap_search($this->_conn, $this->_params['dn'], "(cn=$id)");
+ $info = @ldap_get_entries($this->_conn, $sr);
+ return ($info['count'] > 0) ? $info[0]['session'][0] : '';
+ }
+
+ /**
+ * Write session data to the backend.
+ *
+ * @param string $id The session identifier.
+ * @param string $session_data The session data.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ protected function _write($id, $session_data)
+ {
+ $update = array('objectClass' => array('phpsession', 'top'),
+ 'session' => $session_data);
+ $dn = "cn=$id," . $this->_params['dn'];
+ @ldap_delete($this->_conn, $dn);
+ return @ldap_add($this->_conn, $dn, $update);
+ }
+
+ /**
+ * Destroy the data for a particular session identifier in the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function destroy($id)
+ {
+ $dn = "cn=$id," . $this->_params['dn'];
+ return @ldap_delete($this->_conn, $dn);
+ }
+
+ /**
+ * Garbage collect stale sessions from the backend.
+ *
+ * @param integer $maxlifetime The maximum age of a session.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function gc($maxlifetime = 300)
+ {
+ $sr = @ldap_search($this->_conn, $this->_params['dn'],
+ '(objectClass=phpsession)', array('+', 'cn'));
+ $info = @ldap_get_entries($this->_conn, $sr);
+ if ($info['count'] > 0) {
+ for ($i = 0; $i < $info['count']; $i++) {
+ $id = $info[$i]['cn'][0];
+ $dn = "cn=$id," . $this->_params['dn'];
+ $ldapstamp = $info[$i]['modifytimestamp'][0];
+ $year = substr($ldapstamp, 0, 4);
+ $month = substr($ldapstamp, 4, 2);
+ $day = substr($ldapstamp, 6, 2);
+ $hour = substr($ldapstamp, 8, 2);
+ $minute = substr($ldapstamp, 10, 2);
+ $modified = gmmktime($hour, $minute, 0, $month, $day, $year);
+ if (time() - $modified >= $maxlifetime) {
+ @ldap_delete($this->_conn, $dn);
+ }
+ }
+ }
+
+ return true;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler:: implementation for memcache.
+ *
+ * NOTE FOR WINDOWS USERS w/PHP 4: Due to limitations in PHP 4, you should not
+ * use the memcache driver. Either upgrade to PHP 5 or use a different
+ * session handler.
+ *
+ * Optional parameters:<pre>
+ * 'persistent_driver' - (string) If set, uses this backend to store session
+ * data persistently.
+ * 'persistent_params' - (array) If using a persistent backend, the params
+ * to use for the persistent backend.
+ * 'track' - (boolean) Track active sessions?
+ * 'track_lifetime' - (integer) The number of seconds after which tracked
+ * sessions will be treated as expired.
+ * </pre>
+ *
+ * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Rong-En Fan <rafan@infor.org>
+ * @author Michael Slusarz <slusarz@curecanti.org>
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_Memcache extends Horde_SessionHandler
+{
+ /**
+ * Horde_Memcache object.
+ *
+ * @var Horde_Memcache
+ */
+ protected $_memcache;
+
+ /**
+ * Current session ID.
+ *
+ * @var string
+ */
+ protected $_id;
+
+ /**
+ * Persistent backend driver.
+ *
+ * @var Horde_SessionHandler
+ */
+ protected $_persistent;
+
+ /**
+ * Do read-only get?
+ *
+ * @var boolean
+ */
+ protected $_readonly = false;
+
+ /**
+ * The ID used for session tracking.
+ *
+ * @var string
+ */
+ protected $_trackID = 'horde_memcache_sessions_track';
+
+ /**
+ * Constructor.
+ *
+ * @param array $params A hash containing connection parameters.
+ *
+ * @throws Horde_Exception
+ */
+ protected function __construct($params = array())
+ {
+ if (!empty($params['persistent_driver'])) {
+ try {
+ $this->_persistent = &self::singleton($params['persistent_driver'], empty($params['persistent_params']) ? null : $params['persistent_params']);
+ } catch (Horde_Exception $e) {
+ throw new Horde_Exception('Horde is unable to correctly start the persistent session handler.');
+ }
+ }
+
+ parent::__construct($params);
+
+ // If using a persistent backend, don't track sessions in memcache
+ if (isset($this->_persistent)) {
+ $this->_params['track'] = false;
+ }
+
+ if (empty($this->_params['track_lifetime'])) {
+ $this->_params['track_lifetime'] = ini_get('session.gc_maxlifetime');
+ }
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ if (!empty($this->_params['track']) && (rand(0, 999) == 0)) {
+ $this->_trackGC();
+ }
+
+ parent::__destruct();
+ }
+
+ /**
+ * Open the backend.
+ *
+ * @param string $save_path The path to the session object.
+ * @param string $session_name The name of the session.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _open($save_path = null, $session_name = null)
+ {
+ $this->_memcache = &Horde_Memcache::singleton();
+ if (is_a($this->_memcache, 'PEAR_Error')) {
+ throw new Horde_Exception($this->_memcache);
+ }
+
+ if (isset($this->_persistent)) {
+ if (!$this->_persistent->open($save_path, $session_name)) {
+ throw new Horde_Exception('Could not open persistent backend.');
+ }
+ }
+ }
+
+ /**
+ * Close the backend.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _close()
+ {
+ if (isset($this->_id)) {
+ $this->_memcache->unlock($this->_id);
+ }
+ if (isset($this->_persistent)) {
+ $this->_persistent->close();
+ }
+ }
+
+ /**
+ * Read the data for a particular session identifier.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ if (!$this->_readonly) {
+ $this->_memcache->lock($id);
+ }
+ $result = $this->_memcache->get($id);
+
+ if ($result === false) {
+ if (!$this->_readonly) {
+ $this->_memcache->unlock($id);
+ }
+
+ if (isset($this->_persistent)) {
+ $result = $this->_persistent->read($id);
+ }
+
+ if ($result === false) {
+ Horde::logMessage('Error retrieving session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return false;
+ }
+
+ $this->_persistent->write($id, $session_data);
+ }
+
+ if (!$this->_readonly) {
+ $this->_id = $id;
+ }
+
+ Horde::logMessage('Read session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return $result;
+ }
+
+ /**
+ * Write session data to the backend.
+ *
+ * @param string $id The session identifier.
+ * @param string $session_data The session data.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ protected function _write($id, $session_data)
+ {
+ if (!empty($this->_params['track'])) {
+ // Do a replace - the only time it should fail is if we are
+ // writing a session for the first time. If that is the case,
+ // update the session tracker.
+ $res = $this->_memcache->replace($id, $session_data);
+ $track = !$res;
+ } else {
+ $res = $track = false;
+ }
+
+ if (!$res &&
+ !$this->_memcache->set($id, $session_data)) {
+ Horde::logMessage('Error writing session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ if (isset($this->_persistent)) {
+ $result = $this->_persistent->write($id, $session_data);
+ }
+
+ if ($track) {
+ $this->_memcache->lock($this->_trackID);
+ $ids = $this->_memcache->get($this->_trackID);
+ if ($ids === false) {
+ $ids = array();
+ }
+
+ $ids[$id] = time();
+ $this->_memcache->set($this->_trackID, $ids);
+ $this->_memcache->unlock($this->_trackID);
+ }
+
+ Horde::logMessage('Wrote session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return true;
+ }
+
+ /**
+ * Destroy the data for a particular session identifier.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function destroy($id)
+ {
+ $result = $this->_memcache->delete($id);
+ $this->_memcache->unlock($id);
+
+ if ($result !== false &&
+ isset($this->_persistent)) {
+ $result = $this->_persistent->destroy($id);
+ }
+
+ if ($result !== false) {
+ Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return false;
+ }
+
+ if (!empty($this->_params['track'])) {
+ $this->_memcache->lock($this->_trackID);
+ $ids = $this->_memcache->get($this->_trackID);
+ if ($ids !== false) {
+ unset($ids[$id]);
+ $this->_memcache->set($this->_trackID, $ids);
+ }
+ $this->_memcache->unlock($this->_trackID);
+ }
+
+ Horde::logMessage('Deleted session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+ return true;
+ }
+
+ /**
+ * Garbage collect stale sessions from the backend.
+ *
+ * @param integer $maxlifetime The maximum age of a session.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function gc($maxlifetime = 300)
+ {
+ $result = true;
+
+ if (isset($this->_persistent)) {
+ $result = $this->_persistent->gc($maxlifetime);
+ }
+
+ // Memcache does its own garbage collection.
+ return $result;
+ }
+
+ /**
+ * Get a list of (possibly) valid session identifiers.
+ *
+ * @return array A list of session identifiers.
+ * @throws Horde_Exception
+ */
+ public function getSessionIDs()
+ {
+ if (isset($this->_persistent)) {
+ return $this->_persistent->getSessionIDs();
+ }
+
+ try {
+ $this->_open();
+
+ if (empty($this->_params['track'])) {
+ throw new Horde_Exception(_("Memcache session tracking not enabled."));
+ }
+ } catch (Horde_Exception $e) {
+ if (isset($this->_persistent)) {
+ return $this->_persistent->getSessionIDs();
+ }
+ throw $e;
+ }
+
+ $this->_trackGC();
+
+ $ids = $this->_memcache->get($this->_trackID);
+ return ($ids === false) ? array() : array_keys($ids);
+ }
+
+ /**
+ * Get session data read-only.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _readOnly($id)
+ {
+ $this->_readonly = true;
+ $result = $this->_memcache->get($id);
+ $this->_readonly = false;
+ return $result;
+ }
+
+ /**
+ * Do garbage collection for session tracking information.
+ */
+ protected function _trackGC()
+ {
+ $this->_memcache->lock($this->_trackID);
+ $ids = $this->_memcache->get($this->_trackID);
+ if (empty($ids)) {
+ $this->_memcache->unlock($this->_trackID);
+ return;
+ }
+
+ $tstamp = time() - $this->_params['track_lifetime'];
+ $alter = false;
+
+ foreach ($ids as $key => $val) {
+ if ($tstamp > $val) {
+ unset($ids[$key]);
+ $alter = true;
+ }
+ }
+
+ if ($alter) {
+ $this->_memcache->set($this->_trackID, $ids);
+ }
+
+ $this->_memcache->unlock($this->_trackID);
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler:: implementation for MySQL (native).
+ *
+ * Required parameters:<pre>
+ * 'hostspec' - (string) The hostname of the database server.
+ * 'protocol' - (string) The communication protocol ('tcp', 'unix', etc.).
+ * 'username' - (string) The username with which to connect to the
+ * database.
+ * 'password' - (string) The password associated with 'username'.
+ * 'database' - (string) The name of the database.
+ * 'table' - (string) The name of the sessiondata table in 'database'.
+ * 'rowlocking' - (boolean) Whether to use row-level locking and
+ * transactions (InnoDB) or table-level locking (MyISAM).
+ * </pre>
+ *
+ * Required for some configurations:<pre>
+ * 'port' - (integer) The port on which to connect to the database.
+ * </pre>
+ *
+ * Optional parameters:<pre>
+ * 'persistent' - (boolean) Use persistent DB connections?
+ * </pre>
+ *
+ * The table structure can be found in:
+ * horde/scripts/sql/horde_sessionhandler.sql.
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Mike Cochrame <mike@graftonhall.co.nz>
+ * @author Chuck Hagenbuch <chuck@horde.org>
+ * @author Jan Schneider <jan@horde.org>
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_Mysql extends Horde_SessionHandler
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var resource
+ */
+ protected $_db;
+
+ /**
+ * Attempts to open a connection to the SQL server.
+ *
+ * @param string $save_path The path to the session object.
+ * @param string $session_name The name of the session.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _open($save_path = null, $session_name = null)
+ {
+ Horde::assertDriverConfig($this->_params, 'sessionhandler',
+ array('hostspec', 'username', 'database'),
+ 'session handler MySQL');
+
+ if (empty($this->_params['password'])) {
+ $this->_params['password'] = '';
+ }
+
+ if (empty($this->_params['table'])) {
+ $this->_params['table'] = 'horde_sessionhandler';
+ }
+
+ $connect = empty($this->_params['persistent'])
+ ? 'mysql_connect'
+ : 'mysql_pconnect';
+
+ if (!$this->_db = @$connect($this->_params['hostspec'] . (!empty($this->_params['port']) ? ':' . $this->_params['port'] : ''),
+ $this->_params['username'],
+ $this->_params['password'])) {
+ throw new Horde_Exception('Could not connect to database for SQL Horde_SessionHandler.');
+ }
+
+ if (!@mysql_select_db($this->_params['database'], $this->_db)) {
+ throw new Horde_Exception(sprintf('Could not connect to database %s for SQL Horde_SessionHandler.', $this->_params['database']));
+ }
+ }
+
+ /**
+ * Close the backend.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _close()
+ {
+ /* Disconnect from database. */
+ if (!@mysql_close($this->_db)) {
+ throw new Horde_Exception('Could not disconnect from database.');
+ }
+ }
+
+ /**
+ * Read the data for a particular session identifier from the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ /* Select db */
+ if (!@mysql_select_db($this->_params['database'], $this->_db)) {
+ return '';
+ }
+
+ $query = sprintf('SELECT session_data FROM %s WHERE session_id = %s',
+ $this->_params['table'],
+ $this->_quote($id));
+
+ if (!empty($this->_params['rowlocking'])) {
+ /* Start a transaction. */
+ $result = @mysql_query('START TRANSACTION', $this->_db);
+ $query .= ' FOR UPDATE';
+ } else {
+ $result = @mysql_query('LOCK TABLES ' . $this->_params['table'] . ' WRITE', $this->_db);
+ }
+ if (!$result) {
+ return '';
+ }
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Mysql::_read(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = @mysql_query($query, $this->_db);
+ if (!$result) {
+ Horde::logMessage('Error retrieving session data (id = ' . $id . '): ' . mysql_error($this->_db), __FILE__, __LINE__, PEAR_LOG_ERR);
+ return '';
+ }
+
+ return @mysql_result($result, 0, 0);
+ }
+
+ /**
+ * Write session data to the backend.
+ *
+ * @param string $id The session identifier.
+ * @param string $session_data The session data.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ protected function _write($id, $session_data)
+ {
+ /* Select db */
+ if (!@mysql_select_db($this->_params['database'], $this->_db)) {
+ return '';
+ }
+
+ /* Build the SQL query. */
+ $query = sprintf('REPLACE INTO %s (session_id, session_data, session_lastmodified)' .
+ ' VALUES (%s, %s, %s)',
+ $this->_params['table'],
+ $this->_quote($id),
+ $this->_quote($session_data),
+ time());
+
+ $result = @mysql_query($query, $this->_db);
+ if (!$result) {
+ $error = mysql_error($this->_db);
+ }
+ if (empty($this->_params['rowlocking'])) {
+ @mysql_query('UNLOCK TABLES ' . $this->_params['table'], $this->_db);
+ }
+ if (!$result) {
+ @mysql_query('ROLLBACK', $this->_db);
+ Horde::logMessage('Error writing session data: ' . $error, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ @mysql_query('COMMIT', $this->_db);
+
+ return true;
+ }
+
+ /**
+ * Destroy the data for a particular session identifier in the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function destroy($id)
+ {
+ /* Select db */
+ if (!@mysql_select_db($this->_params['database'], $this->_db)) {
+ return '';
+ }
+
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_id = %s',
+ $this->_params['table'], $this->_quote($id));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Mysql::destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = @mysql_query($query, $this->_db);
+ if (!$result) {
+ $error = mysql_error($this->_db);
+ }
+ if (empty($this->_params['rowlocking'])) {
+ @mysql_query('UNLOCK TABLES ' . $this->_params['table'], $this->_db);
+ }
+ if (!$result) {
+ @mysql_query('ROLLBACK', $this->_db);
+ Horde::logMessage('Failed to delete session (id = ' . $id . '): ' . $error, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ @mysql_query('COMMIT', $this->_db);
+
+ return true;
+ }
+
+ /**
+ * Garbage collect stale sessions from the backend.
+ *
+ * @param integer $maxlifetime The maximum age of a session.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function gc($maxlifetime = 300)
+ {
+ /* Select db */
+ if (!@mysql_select_db($this->_params['database'], $this->_db)) {
+ return '';
+ }
+
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s',
+ $this->_params['table'], (int)(time() - $maxlifetime));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Mysql::gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = @mysql_query($query, $this->_db);
+ if (!$result) {
+ Horde::logMessage('Error garbage collecting old sessions: ' . mysql_error($this->_db), __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ return @mysql_affected_rows($this->_db);
+ }
+
+ /**
+ * Get a list of the valid session identifiers.
+ *
+ * @return array A list of valid session identifiers.
+ * @throws Horde_Exception
+ */
+ public function getSessionIDs()
+ {
+ /* Make sure we have a valid database connection. */
+ $this->_open();
+
+ $query = sprintf('SELECT session_id FROM %s' .
+ ' WHERE session_lastmodified >= %s',
+ $this->_params['table'],
+ time() - ini_get('session.gc_maxlifetime'));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Mysql::getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = @mysql_query($query, $this->_db);
+ if (!$result) {
+ throw new Horde_Exception('Error getting session IDs: ' . mysql_error($this->_db));
+ }
+
+ $sessions = array();
+
+ while ($row = mysql_fetch_row($result)) {
+ $sessions[] = $row[0];
+ }
+
+ return $sessions;
+ }
+
+ /**
+ * Escape a mysql string.
+ *
+ * @param string $value The string to quote.
+ *
+ * @return string The quoted string.
+ */
+ protected function _quote($value)
+ {
+ switch (strtolower(gettype($value))) {
+ case 'null':
+ return 'NULL';
+
+ case 'integer':
+ return $value;
+
+ case 'string':
+ default:
+ return "'" . @mysql_real_escape_string($value, $this->_db) . "'";
+ }
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler:: implementation for PHP's built-in session handler.
+ *
+ * Required parameters:<pre>
+ * None.</pre>
+ *
+ * Optional parameters:<pre>
+ * None.</pre>
+ *
+ * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Matt Selsky <selsky@columbia.edu>
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_None extends Horde_SessionHandler
+{
+ /**
+ * Read the data for a particular session identifier from the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ $file = session_save_path() . DIRECTORY_SEPARATOR . 'sess_' . $id;
+ $session_data = @file_get_contents($file);
+ if ($session_data === false) {
+ Horde::logMessage('Unable to read file: ' . $file, __FILE__, __LINE__, PEAR_LOG_ERR);
+ $session_data = '';
+ }
+
+ return $session_data;
+ }
+
+ /**
+ * Get a list of the valid session identifiers.
+ *
+ * @return array A list of valid session identifiers.
+ */
+ public function getSessionIDs()
+ {
+ $sessions = array();
+
+ $path = session_save_path();
+ $d = @dir(empty($path) ? Util::getTempDir() : $path);
+ if (!$d) {
+ return $sessions;
+ }
+
+ while (($entry = $d->read()) !== false) {
+ /* Make sure we're dealing with files that start with
+ * sess_. */
+ if (is_file($d->path . DIRECTORY_SEPARATOR . $entry) &&
+ !strncmp($entry, 'sess_', strlen('sess_'))) {
+ $sessions[] = substr($entry, strlen('sess_'));
+ }
+ }
+
+ return $sessions;
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler:: implementation for Oracle 8i (native).
+ *
+ * Required parameters:<pre>
+ * 'hostspec' - (string) The hostname of the database server.
+ * 'username' - (string) The username with which to connect to the database.
+ * 'password' - (string) The password associated with 'username'.
+ * 'database' - (string) The name of the database.
+ * 'table' - (string) The name of the sessiondata table in 'database'.
+ * </pre>
+ *
+ * Required for some configurations:<pre>
+ * 'port' - (integer) The port on which to connect to the database.
+ * </pre>
+ *
+ * Optional parameters:<pre>
+ * 'persistent' - (boolean) Use persistent DB connections?
+ * </pre>
+
+ * The table structure can be found in:
+ * horde/scripts/sql/horde_sessionhandler.oci8.sql.
+ *
+ * Copyright 2003-2009 Liam Hoekenga <liamr@umich.edu>
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Liam Hoekenga <liamr@umich.edu>
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_Oci8 extends Horde_SessionHandler
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var resource
+ */
+ protected $_db;
+
+ /**
+ * Attempts to open a connection to the SQL server.
+ *
+ * @param string $save_path The path to the session object.
+ * @param string $session_name The name of the session.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _open($save_path = false, $session_name = false)
+ {
+ Horde::assertDriverConfig($this->_params, 'sessionhandler',
+ array('hostspec', 'username', 'password'),
+ 'session handler Oracle');
+
+ if (!isset($this->_params['table'])) {
+ $this->_params['table'] = 'horde_sessionhandler';
+ }
+
+ if (function_exists('oci_connect')) {
+ $connect = empty($this->_params['persistent'])
+ ? 'oci_connect'
+ : 'oci_pconnect';
+ } else {
+ $connect = empty($this->_params['persistent'])
+ ? 'OCILogon'
+ : 'OCIPLogon';
+ }
+
+ if (!is_resource($this->_db = @$connect($this->_params['username'],
+ $this->_params['password'],
+ $this->_params['hostspec']))) {
+ throw new Horde_Exception('Could not connect to database for SQL Horde_SessionHandler.');
+ }
+ }
+
+ /**
+ * Close the backend.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _close()
+ {
+ if (!OCILogOff($this->_db)) {
+ throw new Horde_Exception('Could not disconnect from databse.');
+ }
+ }
+
+ /**
+ * Read the data for a particular session identifier from the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ $select_query = sprintf('SELECT session_data FROM %s WHERE session_id = %s FOR UPDATE',
+ $this->_params['table'], $this->_quote($id));
+
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Oci8::_read(): query = "%s"', $select_query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $select_statement = OCIParse($this->_db, $select_query);
+ OCIExecute($select_statement, OCI_DEFAULT);
+ if (OCIFetchInto($select_statement, $result)) {
+ $value = $result[0]->load();
+ } else {
+ $value = '';
+ }
+
+ OCIFreeStatement($select_statement);
+
+ return $value;
+ }
+
+ /**
+ * Write session data to the backend.
+ *
+ * @param string $id The session identifier.
+ * @param string $session_data The session data.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ protected function _write($id, $session_data)
+ {
+ $select_query = sprintf('SELECT session_data FROM %s WHERE session_id = %s FOR UPDATE',
+ $this->_params['table'], $this->_quote($id));
+
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Oci8::_write(): query = "%s"', $select_query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $select_statement = OCIParse($this->_db, $select_query);
+ OCIExecute($select_statement, OCI_DEFAULT);
+ if (OCIFetchInto($select_statement, $result)) {
+ /* Discard the existing LOB contents. */
+ if (!$result[0]->truncate()) {
+ OCIRollback($this->_db);
+ return false;
+ }
+
+ /* Save the session data. */
+ if ($result[0]->save($session_data)) {
+ OCICommit($this->_db);
+ OCIFreeStatement($select_statement);
+ } else {
+ OCIRollback($this->_db);
+ return false;
+ }
+ } else {
+ $insert_query = sprintf('INSERT INTO %s (session_id, session_lastmodified, session_data) VALUES (%s, %s, EMPTY_BLOB()) RETURNING session_data INTO :blob',
+ $this->_params['table'],
+ $this->_quote($id),
+ $this->_quote(time()));
+
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Oci8::_read(): query = "%s"', $insert_query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $insert_statement = OCIParse($this->_db, $insert_query);
+ $lob = OCINewDescriptor($this->_db);
+ OCIBindByName($insert_statement, ':blob', $lob, -1, SQLT_BLOB);
+ OCIExecute($insert_statement, OCI_DEFAULT);
+ if (!$lob->save($session_data)) {
+ OCIRollback($this->_db);
+ return false;
+ }
+ OCICommit($this->_db);
+ OCIFreeStatement($insert_statement);
+ }
+
+ return true;
+ }
+
+ /**
+ * Destroy the data for a particular session identifier in the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function destroy($id)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_id = %s',
+ $this->_params['table'], $this->_quote($id));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Oci8::destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $statement = OCIParse($this->_db, $query);
+ $result = OCIExecute($statement);
+ if (!$result) {
+ OCIFreeStatement($statement);
+ Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ OCIFreeStatement($statement);
+
+ return true;
+ }
+
+ /**
+ * Garbage collect stale sessions from the backend.
+ *
+ * @param integer $maxlifetime The maximum age of a session.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function gc($maxlifetime = 1)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s',
+ $this->_params['table'], $this->_quote(time() - $maxlifetime));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Oci8::gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $statement = OCIParse($this->_db, $query);
+ $result = OCIExecute($statement);
+ if (!$result) {
+ OCIFreeStatement($statement);
+ Horde::logMessage('Error garbage collecting old sessions', __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ OCIFreeStatement($statement);
+
+ return true;
+ }
+
+ /**
+ * Get a list of the valid session identifiers.
+ *
+ * @return array A list of valid session identifiers.
+ * @throws Horde_Exception
+ */
+ public function getSessionIDs()
+ {
+ /* Make sure we have a valid database connection. */
+ $this->open();
+
+ /* Session timeout, don't rely on garbage collection */
+ $query = sprintf('SELECT session_id FROM %s ' .
+ 'WHERE session_lastmodified >= %s',
+ $this->_params['table'],
+ time() - ini_get('session.gc_maxlifetime'));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Oci8::getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute query */
+ $statement = OCIParse($this->_db, $query);
+ OCIExecute($statement);
+
+ $sessions = array();
+ while (OCIFetchInto($statement, $row)) {
+ $sessions[] = $row[0];
+ }
+
+ OCIFreeStatement($statement);
+
+ return $sessions;
+ }
+
+ /**
+ * Escape a string for insertion. Stolen from PEAR::DB.
+ *
+ * @param string $value The string to quote.
+ *
+ * @return string The quoted string.
+ */
+ protected function _quote($value)
+ {
+ return is_null($value)
+ ? 'NULL'
+ : "'" . str_replace("'", "''", $value) . "'";
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler implementation for PostgreSQL (native).
+ *
+ * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * Required parameters:<pre>
+ * 'database' - (string) The name of the database.
+ * 'password' - (string) The password associated with 'username'.
+ * 'protocol' - (string) The communication protocol ('tcp', 'unix').
+ * 'username' - (string) The username with which to connect to the database.
+ *
+ * Required for some configurations (i.e. 'protocol' = 'tcp'):<pre>
+ * 'hostspec' - (string) The hostname of the database server.
+ * 'port' - (integer) The port on which to connect to the database.
+ * </pre>
+ *
+ * Optional parameters:<pre>
+ * 'persistent' - (boolean) Use persistent DB connections?
+ * Default: NO
+ * 'table' - (string) The name of the sessiondata table in 'database'.
+ * Default: 'horde_sessionhandler'</pre>
+ * </pre>
+
+ * The table structure can be found in:
+ * horde/scripts/sql/horde_sessionhandler.pgsql.sql.
+ *
+ * Contributors:<pre>
+ * Jason Carlson Return an empty string on failed reads
+ * pat@pcprogrammer.com Perform update in a single transaction
+ * Jonathan Crompton Lock row for life of session</pre>
+ *
+ * @author Jon Parise <jon@csh.rit.edu>
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_Pgsql extends Horde_SessionHandler
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var resource
+ */
+ protected $_db;
+
+ /**
+ * Attempts to open a connection to the SQL server.
+ *
+ * @param string $save_path The path to the session object.
+ * @param string $session_name The name of the session.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _open($save_path = null, $session_name = null)
+ {
+ Horde::assertDriverConfig($this->_params, 'sessionhandler',
+ array('hostspec', 'username', 'database', 'password'),
+ 'session handler pgsql');
+
+ if (empty($this->_params['table'])) {
+ $this->_params['table'] = 'horde_sessionhandler';
+ }
+
+ $connect = empty($this->_params['persistent']) ?
+ 'pg_connect' :'pg_pconnect';
+
+ $paramstr = '';
+ if (isset($this->_params['protocol']) &&
+ $this->_params['protocol'] == 'tcp') {
+ $paramstr .= ' host=' . $this->_params['hostspec'];
+ if (isset($this->_params['port'])) {
+ $paramstr .= ' port=' . $this->_params['port'];
+ }
+ }
+ $paramstr .= ' dbname=' . $this->_params['database'] .
+ ' user=' . $this->_params['username'] .
+ ' password=' . $this->_params['password'];
+
+ if (!$this->_db = @$connect($paramstr)) {
+ throw new Horde_Exception(sprintf('Could not connect to database %s for SQL Horde_SessionHandler.', $this->_params['database']));
+ }
+ }
+
+ /**
+ * Close the backend.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _close()
+ {
+ /* Disconnect from database. */
+ if (!@pg_close($this->_db)) {
+ throw new Horde_Exception('Cound not disconnect from database.');
+ }
+ }
+
+ /**
+ * Read the data for a particular session identifier from the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ @pg_query($this->_db, 'BEGIN;');
+
+ $query = sprintf('SELECT session_data FROM %s WHERE session_id = %s ' .
+ 'FOR UPDATE;',
+ $this->_params['table'],
+ $this->_quote($id));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Pgsql::' . '_read(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = @pg_query($this->_db, $query);
+ $data = pg_fetch_result($result, 0, 'session_data');
+ pg_free_result($result);
+
+ return pack('H*', $data);
+ }
+
+ /**
+ * Write session data to the backend.
+ *
+ * @param string $id The session identifier.
+ * @param string $session_data The session data.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ protected function _write($id, $session_data)
+ {
+ $query = sprintf('SELECT session_data FROM %s WHERE session_id = %s ' .
+ 'FOR UPDATE',
+ $this->_params['table'],
+ $this->_quote($id));
+ $result = @pg_query($this->_db, $query);
+ $rows = pg_num_rows($result);
+ pg_free_result($result);
+
+ if ($rows == 0) {
+ $query = sprintf('INSERT INTO %s (session_id, ' .
+ 'session_lastmodified, session_data) ' .
+ 'VALUES (%s, %s, %s);',
+ $this->_params['table'],
+ $this->_quote($id),
+ time(),
+ $this->_quote(bin2hex($session_data)));
+ } else {
+ $query = sprintf('UPDATE %s SET session_lastmodified = %s, ' .
+ 'session_data = %s WHERE session_id = %s;',
+ $this->_params['table'],
+ time(),
+ $this->_quote(bin2hex($session_data)),
+ $this->_quote($id));
+ }
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Pgsql::' . '_write(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ $result = @pg_query($this->_db, $query);
+ $rows = pg_affected_rows($result);
+ pg_free_result($result);
+
+ @pg_query($this->_db, 'COMMIT;');
+
+ if ($rows != 1) {
+ Horde::logMessage('Error writing session data', __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Destroy the data for a particular session identifier in the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function destroy($id)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_id = %s;',
+ $this->_params['table'], $this->_quote($id));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Pgsql::' . 'destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = @pg_query($this->_db, $query);
+
+ @pg_query($this->_db, 'COMMIT;');
+
+ if (!$result) {
+ pg_free_result($result);
+ Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ pg_free_result($result);
+ return true;
+ }
+
+ /**
+ * Garbage collect stale sessions from the backend.
+ *
+ * @param integer $maxlifetime The maximum age of a session.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function gc($maxlifetime = 300)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s',
+ $this->_params['table'],
+ $this->_quote(time() - $maxlifetime));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Pgsql::' . 'gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = @pg_query($this->_db, $query);
+ if (!$result) {
+ Horde::logMessage('Error garbage collecting old sessions', __FILE__, __LINE__, PEAR_LOG_ERR);
+ }
+
+ pg_free_result($result);
+
+ return $result;
+ }
+
+ /**
+ * Get a list of the valid session identifiers.
+ *
+ * @return array A list of valid session identifiers.
+ * @throws Horde_Exception
+ */
+ public function getSessionIDs()
+ {
+ /* Make sure we have a valid database connection. */
+ $this->_open();
+
+ /* Build the SQL query. */
+ $query = sprintf('SELECT session_id FROM %s ' .
+ 'WHERE session_lastmodified >= %s',
+ $this->_params['table'],
+ time() - ini_get('session.gc_maxlifetime'));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Pgsql::' . 'getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = @pg_query($this->_db, $query);
+ if (!$result) {
+ pg_free_result($result);
+ throw new Horde_Exception('Error getting session IDs');
+ }
+
+ $sessions = array();
+ while ($row = pg_fetch_row($result)) {
+ $sessions[] = $row[0];
+ }
+
+ pg_free_result($result);
+
+ return $sessions;
+ }
+
+ /**
+ * Escape a string for insertion into the database.
+ *
+ * @param string $value The string to quote.
+ *
+ * @return string The quoted string.
+ */
+ protected function _quote($value)
+ {
+ return "'" . addslashes($value) . "'";
+ }
+
+}
--- /dev/null
+<?php
+/**
+ * Horde_SessionHandler implementation for PHP's PEAR database abstraction
+ * layer.
+ *
+ * Required parameters:<pre>
+ * 'phptype' - (string) The database type (e.g. 'pgsql', 'mysql', etc.).
+ * 'hostspec' - (string) The hostname of the database server.
+ * 'protocol' - (string) The communication protocol ('tcp', 'unix', etc.).
+ * 'username' - (string) The username with which to connect to the database.
+ * 'password' - (string) The password associated with 'username'.
+ * 'database' - (string) The name of the database.
+ * 'options' - (array) Additional options to pass to the database.
+ * 'tty' - (string) The TTY on which to connect to the database.
+ * 'port' - (integer) The port on which to connect to the database.
+ * </pre>
+ *
+ * Optional parameters:<pre>
+ * 'table' - (string) The name of the sessiondata table in 'database'.
+ * 'persistent' - (boolean) Use persistent DB connections?
+ * </pre>
+ *
+ * Optional values when using separate reading and writing servers, for example
+ * in replication settings:<pre>
+ * 'splitread' - (boolean) Whether to implement the separation or not.
+ * 'read' - (array) Array containing the parameters which are
+ * different for the writer database connection, currently
+ * supports only 'hostspec' and 'port' parameters.
+ * </pre>
+ *
+ * The table structure can be found in:
+ * horde/scripts/sql/horde_sessionhandler.sql.
+ *
+ * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @package Horde_SessionHandler
+ */
+class Horde_SessionHandler_Sql extends Horde_SessionHandler
+{
+ /**
+ * Handle for the current database connection.
+ *
+ * @var DB
+ */
+ protected $_db;
+
+ /**
+ * Handle for the current database connection, used for writing. Defaults
+ * to the same handle as $_db if a separate write database is not required.
+ *
+ * @var DB
+ */
+ protected $_write_db;
+
+ /**
+ * Attempts to open a connection to the SQL server.
+ *
+ * @param string $save_path The path to the session object.
+ * @param string $session_name The name of the session.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _open($save_path = null, $session_name = null)
+ {
+ Horde::assertDriverConfig($this->_params, 'sessionhandler',
+ array('phptype'),
+ 'session handler SQL');
+
+ if (!isset($this->_params['database'])) {
+ $this->_params['database'] = '';
+ }
+ if (!isset($this->_params['username'])) {
+ $this->_params['username'] = '';
+ }
+ if (!isset($this->_params['hostspec'])) {
+ $this->_params['hostspec'] = '';
+ }
+ if (empty($this->_params['table'])) {
+ $this->_params['table'] = 'horde_sessionhandler';
+ }
+
+ /* Connect to the SQL server using the supplied parameters. */
+ $this->_write_db = &DB::connect($this->_params,
+ array('persistent' => !empty($this->_params['persistent']),
+ 'ssl' => !empty($this->_params['ssl'])));
+ if (is_a($this->_write_db, 'PEAR_Error')) {
+ throw new Horde_Exception($this->_write_db);
+ }
+
+ $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+
+ /* Check if we need to set up the read DB connection
+ * seperately. */
+ if (!empty($this->_params['splitread'])) {
+ $params = array_merge($this->_params, $this->_params['read']);
+ $this->_db = &DB::connect($params,
+ array('persistent' => !empty($params['persistent']),
+ 'ssl' => !empty($this->_params['ssl'])));
+ if (is_a($this->_db, 'PEAR_Error')) {
+ throw new Horde_Exception($this->_db);
+ }
+ $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
+ } else {
+ /* Default to the same DB handle for reads. */
+ $this->_db =& $this->_write_db;
+ }
+ }
+
+ /**
+ * Close the backend.
+ *
+ * @throws Horde_Exception
+ */
+ protected function _close()
+ {
+ /* Close any open transactions. */
+ $this->_db->commit();
+ $this->_db->autoCommit(true);
+ $this->_write_db->commit();
+ $this->_write_db->autoCommit(true);
+
+ @$this->_write_db->disconnect();
+ @$this->_db->disconnect();
+ }
+
+ /**
+ * Read the data for a particular session identifier from the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return string The session data.
+ */
+ protected function _read($id)
+ {
+ /* Begin a transaction. */
+ $result = $this->_write_db->autocommit(false);
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return '';
+ }
+
+ /* Execute the query. */
+ $result = Horde_SQL::readBlob($this->_write_db, $this->_params['table'], 'session_data', array('session_id' => $id));
+
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return '';
+ }
+
+ return $result;
+ }
+
+ /**
+ * Write session data to the backend.
+ *
+ * @param string $id The session identifier.
+ * @param string $session_data The session data.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ protected function _write($id, $session_data)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('SELECT session_id FROM %s WHERE session_id = ?',
+ $this->_params['table']);
+ $values = array($id);
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Sql::write(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = $this->_write_db->getOne($query, $values);
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ if ($result) {
+ $result = Horde_SQL::updateBlob($this->_write_db, $this->_params['table'], 'session_data',
+ $session_data, array('session_id' => $id),
+ array('session_lastmodified' => time()));
+ } else {
+ $result = Horde_SQL::insertBlob($this->_write_db, $this->_params['table'], 'session_data',
+ $session_data, array('session_id' => $id,
+ 'session_lastmodified' => time()));
+ }
+
+ if (is_a($result, 'PEAR_Error')) {
+ $this->_write_db->rollback();
+ $this->_write_db->autoCommit(true);
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ $result = $this->_write_db->commit();
+ if (is_a($result, 'PEAR_Error')) {
+ $this->_write_db->autoCommit(true);
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ $this->_write_db->autoCommit(true);
+ return true;
+ }
+
+ /**
+ * Destroy the data for a particular session identifier in the backend.
+ *
+ * @param string $id The session identifier.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function destroy($id)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_id = ?',
+ $this->_params['table']);
+ $values = array($id);
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Sql::destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = $this->_write_db->query($query, $values);
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ $result = $this->_write_db->commit();
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Garbage collect stale sessions from the backend.
+ *
+ * @param integer $maxlifetime The maximum age of a session.
+ *
+ * @return boolean True on success, false otherwise.
+ */
+ public function gc($maxlifetime = 300)
+ {
+ /* Build the SQL query. */
+ $query = sprintf('DELETE FROM %s WHERE session_lastmodified < ?',
+ $this->_params['table']);
+ $values = array(time() - $maxlifetime);
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Sql::gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = $this->_write_db->query($query, $values);
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get a list of the valid session identifiers.
+ *
+ * @return array A list of valid session identifiers.
+ * @throws Horde_Exception
+ */
+ public function getSessionIDs()
+ {
+ $this->open();
+
+ /* Build the SQL query. */
+ $query = 'SELECT session_id FROM ' . $this->_params['table'] .
+ ' WHERE session_lastmodified => ?';
+ $values = array(time() - ini_get('session.gc_maxlifetime'));
+
+ /* Log the query at a DEBUG log level. */
+ Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_Sql::getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+ /* Execute the query. */
+ $result = $this->_db->getCol($query, 0, $values);
+ if (is_a($result, 'PEAR_Error')) {
+ Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+ return false;
+ }
+
+ return $result;
+ }
+
+}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler:: implementation for LDAP directories.
- *
- * Required parameters:<pre>
- * 'hostspec' - (string) The hostname of the ldap server.
- * 'port' - (integer) The port number of the ldap server.
- * 'dn' - (string) The bind DN.
- * 'password' - (string) The bind password.
- * </pre>
- *
- * This code is adapted from the comments at
- * http://www.php.net/session-set-save-handler.
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_ldap extends Horde_SessionHandler
-{
- /**
- * Handle for the current database connection.
- *
- * @var resource
- */
- protected $_conn;
-
- /**
- * Open the backend.
- *
- * @param string $save_path The path to the session object.
- * @param string $session_name The name of the session.
- *
- * @throws Horde_Exception
- */
- protected function _open($save_path = null, $session_name = null)
- {
- $this->_conn = @ldap_connect($this->_params['hostspec'], $this->_params['port']);
-
- // Set protocol version if necessary.
- if (isset($this->_params['version'])) {
- if (!@ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION, $this->_params['version'])) {
- throw new Horde_Exception(sprintf('Set LDAP protocol version to %d failed: [%d] %s', $this->_params['version'], ldap_errno($conn), ldap_error($conn)));
- }
- }
-
- if (!@ldap_bind($this->_conn, $this->_params['dn'], $this->_params['password'])) {
- throw new Horde_Exception('Could not bind to LDAP server.');
- }
- }
-
- /**
- * Close the backend.
- */
- protected function _close()
- {
- if (!@ldap_close($this->_conn)) {
- throw new Horde_Exception('Could not unbind from LDAP server.');
- }
- }
-
- /**
- * Read the data for a particular session identifier from the backend.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- $sr = @ldap_search($this->_conn, $this->_params['dn'], "(cn=$id)");
- $info = @ldap_get_entries($this->_conn, $sr);
- return ($info['count'] > 0) ? $info[0]['session'][0] : '';
- }
-
- /**
- * Write session data to the backend.
- *
- * @param string $id The session identifier.
- * @param string $session_data The session data.
- *
- * @return boolean True on success, false otherwise.
- */
- protected function _write($id, $session_data)
- {
- $update = array('objectClass' => array('phpsession', 'top'),
- 'session' => $session_data);
- $dn = "cn=$id," . $this->_params['dn'];
- @ldap_delete($this->_conn, $dn);
- return @ldap_add($this->_conn, $dn, $update);
- }
-
- /**
- * Destroy the data for a particular session identifier in the backend.
- *
- * @param string $id The session identifier.
- *
- * @return boolean True on success, false otherwise.
- */
- public function destroy($id)
- {
- $dn = "cn=$id," . $this->_params['dn'];
- return @ldap_delete($this->_conn, $dn);
- }
-
- /**
- * Garbage collect stale sessions from the backend.
- *
- * @param integer $maxlifetime The maximum age of a session.
- *
- * @return boolean True on success, false otherwise.
- */
- public function gc($maxlifetime = 300)
- {
- $sr = @ldap_search($this->_conn, $this->_params['dn'],
- '(objectClass=phpsession)', array('+', 'cn'));
- $info = @ldap_get_entries($this->_conn, $sr);
- if ($info['count'] > 0) {
- for ($i = 0; $i < $info['count']; $i++) {
- $id = $info[$i]['cn'][0];
- $dn = "cn=$id," . $this->_params['dn'];
- $ldapstamp = $info[$i]['modifytimestamp'][0];
- $year = substr($ldapstamp, 0, 4);
- $month = substr($ldapstamp, 4, 2);
- $day = substr($ldapstamp, 6, 2);
- $hour = substr($ldapstamp, 8, 2);
- $minute = substr($ldapstamp, 10, 2);
- $modified = gmmktime($hour, $minute, 0, $month, $day, $year);
- if (time() - $modified >= $maxlifetime) {
- @ldap_delete($this->_conn, $dn);
- }
- }
- }
-
- return true;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler:: implementation for memcache.
- *
- * NOTE FOR WINDOWS USERS w/PHP 4: Due to limitations in PHP 4, you should not
- * use the memcache driver. Either upgrade to PHP 5 or use a different
- * session handler.
- *
- * Optional parameters:<pre>
- * 'persistent_driver' - (string) If set, uses this backend to store session
- * data persistently.
- * 'persistent_params' - (array) If using a persistent backend, the params
- * to use for the persistent backend.
- * 'track' - (boolean) Track active sessions?
- * 'track_lifetime' - (integer) The number of seconds after which tracked
- * sessions will be treated as expired.
- * </pre>
- *
- * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Rong-En Fan <rafan@infor.org>
- * @author Michael Slusarz <slusarz@curecanti.org>
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_memcache extends Horde_SessionHandler
-{
- /**
- * Horde_Memcache object.
- *
- * @var Horde_Memcache
- */
- protected $_memcache;
-
- /**
- * Current session ID.
- *
- * @var string
- */
- protected $_id;
-
- /**
- * Persistent backend driver.
- *
- * @var Horde_SessionHandler
- */
- protected $_persistent;
-
- /**
- * Do read-only get?
- *
- * @var boolean
- */
- protected $_readonly = false;
-
- /**
- * The ID used for session tracking.
- *
- * @var string
- */
- protected $_trackID = 'horde_memcache_sessions_track';
-
- /**
- * Constructor.
- *
- * @param array $params A hash containing connection parameters.
- *
- * @throws Horde_Exception
- */
- protected function __construct($params = array())
- {
- if (!empty($params['persistent_driver'])) {
- try {
- $this->_persistent = &self::singleton($params['persistent_driver'], empty($params['persistent_params']) ? null : $params['persistent_params']);
- } catch (Horde_Exception $e) {
- throw new Horde_Exception('Horde is unable to correctly start the persistent session handler.');
- }
- }
-
- parent::__construct($params);
-
- // If using a persistent backend, don't track sessions in memcache
- if (isset($this->_persistent)) {
- $this->_params['track'] = false;
- }
-
- if (empty($this->_params['track_lifetime'])) {
- $this->_params['track_lifetime'] = ini_get('session.gc_maxlifetime');
- }
- }
-
- /**
- * Destructor.
- */
- public function __destruct()
- {
- if (!empty($this->_params['track']) && (rand(0, 999) == 0)) {
- $this->_trackGC();
- }
-
- parent::__destruct();
- }
-
- /**
- * Open the backend.
- *
- * @param string $save_path The path to the session object.
- * @param string $session_name The name of the session.
- *
- * @throws Horde_Exception
- */
- protected function _open($save_path = null, $session_name = null)
- {
- $this->_memcache = &Horde_Memcache::singleton();
- if (is_a($this->_memcache, 'PEAR_Error')) {
- throw new Horde_Exception($this->_memcache);
- }
-
- if (isset($this->_persistent)) {
- if (!$this->_persistent->open($save_path, $session_name)) {
- throw new Horde_Exception('Could not open persistent backend.');
- }
- }
- }
-
- /**
- * Close the backend.
- *
- * @throws Horde_Exception
- */
- protected function _close()
- {
- if (isset($this->_id)) {
- $this->_memcache->unlock($this->_id);
- }
- if (isset($this->_persistent)) {
- $this->_persistent->close();
- }
- }
-
- /**
- * Read the data for a particular session identifier.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- if (!$this->_readonly) {
- $this->_memcache->lock($id);
- }
- $result = $this->_memcache->get($id);
-
- if ($result === false) {
- if (!$this->_readonly) {
- $this->_memcache->unlock($id);
- }
-
- if (isset($this->_persistent)) {
- $result = $this->_persistent->read($id);
- }
-
- if ($result === false) {
- Horde::logMessage('Error retrieving session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- return false;
- }
-
- $this->_persistent->write($id, $session_data);
- }
-
- if (!$this->_readonly) {
- $this->_id = $id;
- }
-
- Horde::logMessage('Read session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- return $result;
- }
-
- /**
- * Write session data to the backend.
- *
- * @param string $id The session identifier.
- * @param string $session_data The session data.
- *
- * @return boolean True on success, false otherwise.
- */
- protected function _write($id, $session_data)
- {
- if (!empty($this->_params['track'])) {
- // Do a replace - the only time it should fail is if we are
- // writing a session for the first time. If that is the case,
- // update the session tracker.
- $res = $this->_memcache->replace($id, $session_data);
- $track = !$res;
- } else {
- $res = $track = false;
- }
-
- if (!$res &&
- !$this->_memcache->set($id, $session_data)) {
- Horde::logMessage('Error writing session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- if (isset($this->_persistent)) {
- $result = $this->_persistent->write($id, $session_data);
- }
-
- if ($track) {
- $this->_memcache->lock($this->_trackID);
- $ids = $this->_memcache->get($this->_trackID);
- if ($ids === false) {
- $ids = array();
- }
-
- $ids[$id] = time();
- $this->_memcache->set($this->_trackID, $ids);
- $this->_memcache->unlock($this->_trackID);
- }
-
- Horde::logMessage('Wrote session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- return true;
- }
-
- /**
- * Destroy the data for a particular session identifier.
- *
- * @param string $id The session identifier.
- *
- * @return boolean True on success, false otherwise.
- */
- public function destroy($id)
- {
- $result = $this->_memcache->delete($id);
- $this->_memcache->unlock($id);
-
- if ($result !== false &&
- isset($this->_persistent)) {
- $result = $this->_persistent->destroy($id);
- }
-
- if ($result !== false) {
- Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- return false;
- }
-
- if (!empty($this->_params['track'])) {
- $this->_memcache->lock($this->_trackID);
- $ids = $this->_memcache->get($this->_trackID);
- if ($ids !== false) {
- unset($ids[$id]);
- $this->_memcache->set($this->_trackID, $ids);
- }
- $this->_memcache->unlock($this->_trackID);
- }
-
- Horde::logMessage('Deleted session data (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
- return true;
- }
-
- /**
- * Garbage collect stale sessions from the backend.
- *
- * @param integer $maxlifetime The maximum age of a session.
- *
- * @return boolean True on success, false otherwise.
- */
- public function gc($maxlifetime = 300)
- {
- $result = true;
-
- if (isset($this->_persistent)) {
- $result = $this->_persistent->gc($maxlifetime);
- }
-
- // Memcache does its own garbage collection.
- return $result;
- }
-
- /**
- * Get a list of (possibly) valid session identifiers.
- *
- * @return array A list of session identifiers.
- * @throws Horde_Exception
- */
- public function getSessionIDs()
- {
- if (isset($this->_persistent)) {
- return $this->_persistent->getSessionIDs();
- }
-
- try {
- $this->_open();
-
- if (empty($this->_params['track'])) {
- throw new Horde_Exception(_("Memcache session tracking not enabled."));
- }
- } catch (Horde_Exception $e) {
- if (isset($this->_persistent)) {
- return $this->_persistent->getSessionIDs();
- }
- throw $e;
- }
-
- $this->_trackGC();
-
- $ids = $this->_memcache->get($this->_trackID);
- return ($ids === false) ? array() : array_keys($ids);
- }
-
- /**
- * Get session data read-only.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _readOnly($id)
- {
- $this->_readonly = true;
- $result = $this->_memcache->get($id);
- $this->_readonly = false;
- return $result;
- }
-
- /**
- * Do garbage collection for session tracking information.
- */
- protected function _trackGC()
- {
- $this->_memcache->lock($this->_trackID);
- $ids = $this->_memcache->get($this->_trackID);
- if (empty($ids)) {
- $this->_memcache->unlock($this->_trackID);
- return;
- }
-
- $tstamp = time() - $this->_params['track_lifetime'];
- $alter = false;
-
- foreach ($ids as $key => $val) {
- if ($tstamp > $val) {
- unset($ids[$key]);
- $alter = true;
- }
- }
-
- if ($alter) {
- $this->_memcache->set($this->_trackID, $ids);
- }
-
- $this->_memcache->unlock($this->_trackID);
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler:: implementation for MySQL (native).
- *
- * Required parameters:<pre>
- * 'hostspec' - (string) The hostname of the database server.
- * 'protocol' - (string) The communication protocol ('tcp', 'unix', etc.).
- * 'username' - (string) The username with which to connect to the
- * database.
- * 'password' - (string) The password associated with 'username'.
- * 'database' - (string) The name of the database.
- * 'table' - (string) The name of the sessiondata table in 'database'.
- * 'rowlocking' - (boolean) Whether to use row-level locking and
- * transactions (InnoDB) or table-level locking (MyISAM).
- * </pre>
- *
- * Required for some configurations:<pre>
- * 'port' - (integer) The port on which to connect to the database.
- * </pre>
- *
- * Optional parameters:<pre>
- * 'persistent' - (boolean) Use persistent DB connections?
- * </pre>
- *
- * The table structure can be found in:
- * horde/scripts/sql/horde_sessionhandler.sql.
- *
- * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Mike Cochrame <mike@graftonhall.co.nz>
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @author Jan Schneider <jan@horde.org>
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_mysql extends Horde_SessionHandler
-{
- /**
- * Handle for the current database connection.
- *
- * @var resource
- */
- protected $_db;
-
- /**
- * Attempts to open a connection to the SQL server.
- *
- * @param string $save_path The path to the session object.
- * @param string $session_name The name of the session.
- *
- * @throws Horde_Exception
- */
- protected function _open($save_path = null, $session_name = null)
- {
- Horde::assertDriverConfig($this->_params, 'sessionhandler',
- array('hostspec', 'username', 'database'),
- 'session handler MySQL');
-
- if (empty($this->_params['password'])) {
- $this->_params['password'] = '';
- }
-
- if (empty($this->_params['table'])) {
- $this->_params['table'] = 'horde_sessionhandler';
- }
-
- $connect = empty($this->_params['persistent'])
- ? 'mysql_connect'
- : 'mysql_pconnect';
-
- if (!$this->_db = @$connect($this->_params['hostspec'] . (!empty($this->_params['port']) ? ':' . $this->_params['port'] : ''),
- $this->_params['username'],
- $this->_params['password'])) {
- throw new Horde_Exception('Could not connect to database for SQL Horde_SessionHandler.');
- }
-
- if (!@mysql_select_db($this->_params['database'], $this->_db)) {
- throw new Horde_Exception(sprintf('Could not connect to database %s for SQL Horde_SessionHandler.', $this->_params['database']));
- }
- }
-
- /**
- * Close the backend.
- *
- * @throws Horde_Exception
- */
- protected function _close()
- {
- /* Disconnect from database. */
- if (!@mysql_close($this->_db)) {
- throw new Horde_Exception('Could not disconnect from database.');
- }
- }
-
- /**
- * Read the data for a particular session identifier from the backend.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- /* Select db */
- if (!@mysql_select_db($this->_params['database'], $this->_db)) {
- return '';
- }
-
- $query = sprintf('SELECT session_data FROM %s WHERE session_id = %s',
- $this->_params['table'],
- $this->_quote($id));
-
- if (!empty($this->_params['rowlocking'])) {
- /* Start a transaction. */
- $result = @mysql_query('START TRANSACTION', $this->_db);
- $query .= ' FOR UPDATE';
- } else {
- $result = @mysql_query('LOCK TABLES ' . $this->_params['table'] . ' WRITE', $this->_db);
- }
- if (!$result) {
- return '';
- }
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_mysql::_read(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $result = @mysql_query($query, $this->_db);
- if (!$result) {
- Horde::logMessage('Error retrieving session data (id = ' . $id . '): ' . mysql_error($this->_db), __FILE__, __LINE__, PEAR_LOG_ERR);
- return '';
- }
-
- return @mysql_result($result, 0, 0);
- }
-
- /**
- * Write session data to the backend.
- *
- * @param string $id The session identifier.
- * @param string $session_data The session data.
- *
- * @return boolean True on success, false otherwise.
- */
- protected function _write($id, $session_data)
- {
- /* Select db */
- if (!@mysql_select_db($this->_params['database'], $this->_db)) {
- return '';
- }
-
- /* Build the SQL query. */
- $query = sprintf('REPLACE INTO %s (session_id, session_data, session_lastmodified)' .
- ' VALUES (%s, %s, %s)',
- $this->_params['table'],
- $this->_quote($id),
- $this->_quote($session_data),
- time());
-
- $result = @mysql_query($query, $this->_db);
- if (!$result) {
- $error = mysql_error($this->_db);
- }
- if (empty($this->_params['rowlocking'])) {
- @mysql_query('UNLOCK TABLES ' . $this->_params['table'], $this->_db);
- }
- if (!$result) {
- @mysql_query('ROLLBACK', $this->_db);
- Horde::logMessage('Error writing session data: ' . $error, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- @mysql_query('COMMIT', $this->_db);
-
- return true;
- }
-
- /**
- * Destroy the data for a particular session identifier in the backend.
- *
- * @param string $id The session identifier.
- *
- * @return boolean True on success, false otherwise.
- */
- public function destroy($id)
- {
- /* Select db */
- if (!@mysql_select_db($this->_params['database'], $this->_db)) {
- return '';
- }
-
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_id = %s',
- $this->_params['table'], $this->_quote($id));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_mysql::destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = @mysql_query($query, $this->_db);
- if (!$result) {
- $error = mysql_error($this->_db);
- }
- if (empty($this->_params['rowlocking'])) {
- @mysql_query('UNLOCK TABLES ' . $this->_params['table'], $this->_db);
- }
- if (!$result) {
- @mysql_query('ROLLBACK', $this->_db);
- Horde::logMessage('Failed to delete session (id = ' . $id . '): ' . $error, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- @mysql_query('COMMIT', $this->_db);
-
- return true;
- }
-
- /**
- * Garbage collect stale sessions from the backend.
- *
- * @param integer $maxlifetime The maximum age of a session.
- *
- * @return boolean True on success, false otherwise.
- */
- public function gc($maxlifetime = 300)
- {
- /* Select db */
- if (!@mysql_select_db($this->_params['database'], $this->_db)) {
- return '';
- }
-
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s',
- $this->_params['table'], (int)(time() - $maxlifetime));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_mysql::gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = @mysql_query($query, $this->_db);
- if (!$result) {
- Horde::logMessage('Error garbage collecting old sessions: ' . mysql_error($this->_db), __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- return @mysql_affected_rows($this->_db);
- }
-
- /**
- * Get a list of the valid session identifiers.
- *
- * @return array A list of valid session identifiers.
- * @throws Horde_Exception
- */
- public function getSessionIDs()
- {
- /* Make sure we have a valid database connection. */
- $this->_open();
-
- $query = sprintf('SELECT session_id FROM %s' .
- ' WHERE session_lastmodified >= %s',
- $this->_params['table'],
- time() - ini_get('session.gc_maxlifetime'));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_mysql::getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $result = @mysql_query($query, $this->_db);
- if (!$result) {
- throw new Horde_Exception('Error getting session IDs: ' . mysql_error($this->_db));
- }
-
- $sessions = array();
-
- while ($row = mysql_fetch_row($result)) {
- $sessions[] = $row[0];
- }
-
- return $sessions;
- }
-
- /**
- * Escape a mysql string.
- *
- * @param string $value The string to quote.
- *
- * @return string The quoted string.
- */
- protected function _quote($value)
- {
- switch (strtolower(gettype($value))) {
- case 'null':
- return 'NULL';
-
- case 'integer':
- return $value;
-
- case 'string':
- default:
- return "'" . @mysql_real_escape_string($value, $this->_db) . "'";
- }
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler implementation for PHP's built-in session handler.
- *
- * Required parameters:<pre>
- * None.</pre>
- *
- * Optional parameters:<pre>
- * None.</pre>
- *
- * Copyright 2005-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Matt Selsky <selsky@columbia.edu>
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_none extends Horde_SessionHandler
-{
- /**
- * Read the data for a particular session identifier from the backend.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- $file = session_save_path() . DIRECTORY_SEPARATOR . 'sess_' . $id;
- $session_data = @file_get_contents($file);
- if ($session_data === false) {
- Horde::logMessage('Unable to read file: ' . $file, __FILE__, __LINE__, PEAR_LOG_ERR);
- $session_data = '';
- }
-
- return $session_data;
- }
-
- /**
- * Get a list of the valid session identifiers.
- *
- * @return array A list of valid session identifiers.
- */
- public function getSessionIDs()
- {
- $sessions = array();
-
- $path = session_save_path();
- $d = @dir(empty($path) ? Util::getTempDir() : $path);
- if (!$d) {
- return $sessions;
- }
-
- while (($entry = $d->read()) !== false) {
- /* Make sure we're dealing with files that start with
- * sess_. */
- if (is_file($d->path . DIRECTORY_SEPARATOR . $entry) &&
- !strncmp($entry, 'sess_', strlen('sess_'))) {
- $sessions[] = substr($entry, strlen('sess_'));
- }
- }
-
- return $sessions;
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler:: implementation for Oracle 8i (native).
- *
- * Required parameters:<pre>
- * 'hostspec' - (string) The hostname of the database server.
- * 'username' - (string) The username with which to connect to the database.
- * 'password' - (string) The password associated with 'username'.
- * 'database' - (string) The name of the database.
- * 'table' - (string) The name of the sessiondata table in 'database'.
- * </pre>
- *
- * Required for some configurations:<pre>
- * 'port' - (integer) The port on which to connect to the database.
- * </pre>
- *
- * Optional parameters:<pre>
- * 'persistent' - (boolean) Use persistent DB connections?
- * </pre>
-
- * The table structure can be found in:
- * horde/scripts/sql/horde_sessionhandler.oci8.sql.
- *
- * Copyright 2003-2009 Liam Hoekenga <liamr@umich.edu>
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Liam Hoekenga <liamr@umich.edu>
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_oci8 extends Horde_SessionHandler
-{
- /**
- * Handle for the current database connection.
- *
- * @var resource
- */
- protected $_db;
-
- /**
- * Attempts to open a connection to the SQL server.
- *
- * @param string $save_path The path to the session object.
- * @param string $session_name The name of the session.
- *
- * @throws Horde_Exception
- */
- protected function _open($save_path = false, $session_name = false)
- {
- Horde::assertDriverConfig($this->_params, 'sessionhandler',
- array('hostspec', 'username', 'password'),
- 'session handler Oracle');
-
- if (!isset($this->_params['table'])) {
- $this->_params['table'] = 'horde_sessionhandler';
- }
-
- if (function_exists('oci_connect')) {
- $connect = empty($this->_params['persistent'])
- ? 'oci_connect'
- : 'oci_pconnect';
- } else {
- $connect = empty($this->_params['persistent'])
- ? 'OCILogon'
- : 'OCIPLogon';
- }
-
- if (!is_resource($this->_db = @$connect($this->_params['username'],
- $this->_params['password'],
- $this->_params['hostspec']))) {
- throw new Horde_Exception('Could not connect to database for SQL Horde_SessionHandler.');
- }
- }
-
- /**
- * Close the backend.
- *
- * @throws Horde_Exception
- */
- protected function _close()
- {
- if (!OCILogOff($this->_db)) {
- throw new Horde_Exception('Could not disconnect from databse.');
- }
- }
-
- /**
- * Read the data for a particular session identifier from the backend.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- $select_query = sprintf('SELECT session_data FROM %s WHERE session_id = %s FOR UPDATE',
- $this->_params['table'], $this->_quote($id));
-
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_oci8::_read(): query = "%s"', $select_query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $select_statement = OCIParse($this->_db, $select_query);
- OCIExecute($select_statement, OCI_DEFAULT);
- if (OCIFetchInto($select_statement, $result)) {
- $value = $result[0]->load();
- } else {
- $value = '';
- }
-
- OCIFreeStatement($select_statement);
-
- return $value;
- }
-
- /**
- * Write session data to the backend.
- *
- * @param string $id The session identifier.
- * @param string $session_data The session data.
- *
- * @return boolean True on success, false otherwise.
- */
- protected function _write($id, $session_data)
- {
- $select_query = sprintf('SELECT session_data FROM %s WHERE session_id = %s FOR UPDATE',
- $this->_params['table'], $this->_quote($id));
-
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_oci8::_write(): query = "%s"', $select_query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $select_statement = OCIParse($this->_db, $select_query);
- OCIExecute($select_statement, OCI_DEFAULT);
- if (OCIFetchInto($select_statement, $result)) {
- /* Discard the existing LOB contents. */
- if (!$result[0]->truncate()) {
- OCIRollback($this->_db);
- return false;
- }
-
- /* Save the session data. */
- if ($result[0]->save($session_data)) {
- OCICommit($this->_db);
- OCIFreeStatement($select_statement);
- } else {
- OCIRollback($this->_db);
- return false;
- }
- } else {
- $insert_query = sprintf('INSERT INTO %s (session_id, session_lastmodified, session_data) VALUES (%s, %s, EMPTY_BLOB()) RETURNING session_data INTO :blob',
- $this->_params['table'],
- $this->_quote($id),
- $this->_quote(time()));
-
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_oci8::_read(): query = "%s"', $insert_query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $insert_statement = OCIParse($this->_db, $insert_query);
- $lob = OCINewDescriptor($this->_db);
- OCIBindByName($insert_statement, ':blob', $lob, -1, SQLT_BLOB);
- OCIExecute($insert_statement, OCI_DEFAULT);
- if (!$lob->save($session_data)) {
- OCIRollback($this->_db);
- return false;
- }
- OCICommit($this->_db);
- OCIFreeStatement($insert_statement);
- }
-
- return true;
- }
-
- /**
- * Destroy the data for a particular session identifier in the backend.
- *
- * @param string $id The session identifier.
- *
- * @return boolean True on success, false otherwise.
- */
- public function destroy($id)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_id = %s',
- $this->_params['table'], $this->_quote($id));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_oci8::destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $statement = OCIParse($this->_db, $query);
- $result = OCIExecute($statement);
- if (!$result) {
- OCIFreeStatement($statement);
- Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- OCIFreeStatement($statement);
-
- return true;
- }
-
- /**
- * Garbage collect stale sessions from the backend.
- *
- * @param integer $maxlifetime The maximum age of a session.
- *
- * @return boolean True on success, false otherwise.
- */
- public function gc($maxlifetime = 1)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s',
- $this->_params['table'], $this->_quote(time() - $maxlifetime));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_oci8::gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $statement = OCIParse($this->_db, $query);
- $result = OCIExecute($statement);
- if (!$result) {
- OCIFreeStatement($statement);
- Horde::logMessage('Error garbage collecting old sessions', __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- OCIFreeStatement($statement);
-
- return true;
- }
-
- /**
- * Get a list of the valid session identifiers.
- *
- * @return array A list of valid session identifiers.
- * @throws Horde_Exception
- */
- public function getSessionIDs()
- {
- /* Make sure we have a valid database connection. */
- $this->open();
-
- /* Session timeout, don't rely on garbage collection */
- $query = sprintf('SELECT session_id FROM %s ' .
- 'WHERE session_lastmodified >= %s',
- $this->_params['table'],
- time() - ini_get('session.gc_maxlifetime'));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_oci8::getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute query */
- $statement = OCIParse($this->_db, $query);
- OCIExecute($statement);
-
- $sessions = array();
- while (OCIFetchInto($statement, $row)) {
- $sessions[] = $row[0];
- }
-
- OCIFreeStatement($statement);
-
- return $sessions;
- }
-
- /**
- * Escape a string for insertion. Stolen from PEAR::DB.
- *
- * @param string $value The string to quote.
- *
- * @return string The quoted string.
- */
- protected function _quote($value)
- {
- return is_null($value)
- ? 'NULL'
- : "'" . str_replace("'", "''", $value) . "'";
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler implementation for PostgreSQL (native).
- *
- * Copyright 1999-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * Required parameters:<pre>
- * 'database' - (string) The name of the database.
- * 'password' - (string) The password associated with 'username'.
- * 'protocol' - (string) The communication protocol ('tcp', 'unix').
- * 'username' - (string) The username with which to connect to the database.
- *
- * Required for some configurations (i.e. 'protocol' = 'tcp'):<pre>
- * 'hostspec' - (string) The hostname of the database server.
- * 'port' - (integer) The port on which to connect to the database.
- * </pre>
- *
- * Optional parameters:<pre>
- * 'persistent' - (boolean) Use persistent DB connections?
- * Default: NO
- * 'table' - (string) The name of the sessiondata table in 'database'.
- * Default: 'horde_sessionhandler'</pre>
- * </pre>
-
- * The table structure can be found in:
- * horde/scripts/sql/horde_sessionhandler.pgsql.sql.
- *
- * Contributors:<pre>
- * Jason Carlson Return an empty string on failed reads
- * pat@pcprogrammer.com Perform update in a single transaction
- * Jonathan Crompton Lock row for life of session</pre>
- *
- * @author Jon Parise <jon@csh.rit.edu>
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_pgsql extends Horde_SessionHandler
-{
- /**
- * Handle for the current database connection.
- *
- * @var resource
- */
- protected $_db;
-
- /**
- * Attempts to open a connection to the SQL server.
- *
- * @param string $save_path The path to the session object.
- * @param string $session_name The name of the session.
- *
- * @throws Horde_Exception
- */
- protected function _open($save_path = null, $session_name = null)
- {
- Horde::assertDriverConfig($this->_params, 'sessionhandler',
- array('hostspec', 'username', 'database', 'password'),
- 'session handler pgsql');
-
- if (empty($this->_params['table'])) {
- $this->_params['table'] = 'horde_sessionhandler';
- }
-
- $connect = empty($this->_params['persistent']) ?
- 'pg_connect' :'pg_pconnect';
-
- $paramstr = '';
- if (isset($this->_params['protocol']) &&
- $this->_params['protocol'] == 'tcp') {
- $paramstr .= ' host=' . $this->_params['hostspec'];
- if (isset($this->_params['port'])) {
- $paramstr .= ' port=' . $this->_params['port'];
- }
- }
- $paramstr .= ' dbname=' . $this->_params['database'] .
- ' user=' . $this->_params['username'] .
- ' password=' . $this->_params['password'];
-
- if (!$this->_db = @$connect($paramstr)) {
- throw new Horde_Exception(sprintf('Could not connect to database %s for SQL Horde_SessionHandler.', $this->_params['database']));
- }
- }
-
- /**
- * Close the backend.
- *
- * @throws Horde_Exception
- */
- protected function _close()
- {
- /* Disconnect from database. */
- if (!@pg_close($this->_db)) {
- throw new Horde_Exception('Cound not disconnect from database.');
- }
- }
-
- /**
- * Read the data for a particular session identifier from the backend.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- @pg_query($this->_db, 'BEGIN;');
-
- $query = sprintf('SELECT session_data FROM %s WHERE session_id = %s ' .
- 'FOR UPDATE;',
- $this->_params['table'],
- $this->_quote($id));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_pgsql::' . '_read(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $result = @pg_query($this->_db, $query);
- $data = pg_fetch_result($result, 0, 'session_data');
- pg_free_result($result);
-
- return pack('H*', $data);
- }
-
- /**
- * Write session data to the backend.
- *
- * @param string $id The session identifier.
- * @param string $session_data The session data.
- *
- * @return boolean True on success, false otherwise.
- */
- protected function _write($id, $session_data)
- {
- $query = sprintf('SELECT session_data FROM %s WHERE session_id = %s ' .
- 'FOR UPDATE',
- $this->_params['table'],
- $this->_quote($id));
- $result = @pg_query($this->_db, $query);
- $rows = pg_num_rows($result);
- pg_free_result($result);
-
- if ($rows == 0) {
- $query = sprintf('INSERT INTO %s (session_id, ' .
- 'session_lastmodified, session_data) ' .
- 'VALUES (%s, %s, %s);',
- $this->_params['table'],
- $this->_quote($id),
- time(),
- $this->_quote(bin2hex($session_data)));
- } else {
- $query = sprintf('UPDATE %s SET session_lastmodified = %s, ' .
- 'session_data = %s WHERE session_id = %s;',
- $this->_params['table'],
- time(),
- $this->_quote(bin2hex($session_data)),
- $this->_quote($id));
- }
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_pgsql::' . '_write(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- $result = @pg_query($this->_db, $query);
- $rows = pg_affected_rows($result);
- pg_free_result($result);
-
- @pg_query($this->_db, 'COMMIT;');
-
- if ($rows != 1) {
- Horde::logMessage('Error writing session data', __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- return true;
- }
-
- /**
- * Destroy the data for a particular session identifier in the backend.
- *
- * @param string $id The session identifier.
- *
- * @return boolean True on success, false otherwise.
- */
- public function destroy($id)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_id = %s;',
- $this->_params['table'], $this->_quote($id));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_pgsql::' . 'destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = @pg_query($this->_db, $query);
-
- @pg_query($this->_db, 'COMMIT;');
-
- if (!$result) {
- pg_free_result($result);
- Horde::logMessage('Failed to delete session (id = ' . $id . ')', __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- pg_free_result($result);
- return true;
- }
-
- /**
- * Garbage collect stale sessions from the backend.
- *
- * @param integer $maxlifetime The maximum age of a session.
- *
- * @return boolean True on success, false otherwise.
- */
- public function gc($maxlifetime = 300)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s',
- $this->_params['table'],
- $this->_quote(time() - $maxlifetime));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_pgsql::' . 'gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = @pg_query($this->_db, $query);
- if (!$result) {
- Horde::logMessage('Error garbage collecting old sessions', __FILE__, __LINE__, PEAR_LOG_ERR);
- }
-
- pg_free_result($result);
-
- return $result;
- }
-
- /**
- * Get a list of the valid session identifiers.
- *
- * @return array A list of valid session identifiers.
- * @throws Horde_Exception
- */
- public function getSessionIDs()
- {
- /* Make sure we have a valid database connection. */
- $this->_open();
-
- /* Build the SQL query. */
- $query = sprintf('SELECT session_id FROM %s ' .
- 'WHERE session_lastmodified >= %s',
- $this->_params['table'],
- time() - ini_get('session.gc_maxlifetime'));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_pgsql::' . 'getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = @pg_query($this->_db, $query);
- if (!$result) {
- pg_free_result($result);
- throw new Horde_Exception('Error getting session IDs');
- }
-
- $sessions = array();
- while ($row = pg_fetch_row($result)) {
- $sessions[] = $row[0];
- }
-
- pg_free_result($result);
-
- return $sessions;
- }
-
- /**
- * Escape a string for insertion into the database.
- *
- * @param string $value The string to quote.
- *
- * @return string The quoted string.
- */
- protected function _quote($value)
- {
- return "'" . addslashes($value) . "'";
- }
-
-}
+++ /dev/null
-<?php
-/**
- * Horde_SessionHandler implementation for PHP's PEAR database abstraction
- * layer.
- *
- * Required parameters:<pre>
- * 'phptype' - (string) The database type (e.g. 'pgsql', 'mysql', etc.).
- * 'hostspec' - (string) The hostname of the database server.
- * 'protocol' - (string) The communication protocol ('tcp', 'unix', etc.).
- * 'username' - (string) The username with which to connect to the database.
- * 'password' - (string) The password associated with 'username'.
- * 'database' - (string) The name of the database.
- * 'options' - (array) Additional options to pass to the database.
- * 'tty' - (string) The TTY on which to connect to the database.
- * 'port' - (integer) The port on which to connect to the database.
- * </pre>
- *
- * Optional parameters:<pre>
- * 'table' - (string) The name of the sessiondata table in 'database'.
- * 'persistent' - (boolean) Use persistent DB connections?
- * </pre>
- *
- * Optional values when using separate reading and writing servers, for example
- * in replication settings:<pre>
- * 'splitread' - (boolean) Whether to implement the separation or not.
- * 'read' - (array) Array containing the parameters which are
- * different for the writer database connection, currently
- * supports only 'hostspec' and 'port' parameters.
- * </pre>
- *
- * The table structure can be found in:
- * horde/scripts/sql/horde_sessionhandler.sql.
- *
- * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Mike Cochrane <mike@graftonhall.co.nz>
- * @package Horde_SessionHandler
- */
-class Horde_SessionHandler_sql extends Horde_SessionHandler
-{
- /**
- * Handle for the current database connection.
- *
- * @var DB
- */
- protected $_db;
-
- /**
- * Handle for the current database connection, used for writing. Defaults
- * to the same handle as $_db if a separate write database is not required.
- *
- * @var DB
- */
- protected $_write_db;
-
- /**
- * Attempts to open a connection to the SQL server.
- *
- * @param string $save_path The path to the session object.
- * @param string $session_name The name of the session.
- *
- * @throws Horde_Exception
- */
- protected function _open($save_path = null, $session_name = null)
- {
- Horde::assertDriverConfig($this->_params, 'sessionhandler',
- array('phptype'),
- 'session handler SQL');
-
- if (!isset($this->_params['database'])) {
- $this->_params['database'] = '';
- }
- if (!isset($this->_params['username'])) {
- $this->_params['username'] = '';
- }
- if (!isset($this->_params['hostspec'])) {
- $this->_params['hostspec'] = '';
- }
- if (empty($this->_params['table'])) {
- $this->_params['table'] = 'horde_sessionhandler';
- }
-
- /* Connect to the SQL server using the supplied parameters. */
- $this->_write_db = &DB::connect($this->_params,
- array('persistent' => !empty($this->_params['persistent']),
- 'ssl' => !empty($this->_params['ssl'])));
- if (is_a($this->_write_db, 'PEAR_Error')) {
- throw new Horde_Exception($this->_write_db);
- }
-
- $this->_write_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
-
- /* Check if we need to set up the read DB connection
- * seperately. */
- if (!empty($this->_params['splitread'])) {
- $params = array_merge($this->_params, $this->_params['read']);
- $this->_db = &DB::connect($params,
- array('persistent' => !empty($params['persistent']),
- 'ssl' => !empty($this->_params['ssl'])));
- if (is_a($this->_db, 'PEAR_Error')) {
- throw new Horde_Exception($this->_db);
- }
- $this->_db->setOption('portability', DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
- } else {
- /* Default to the same DB handle for reads. */
- $this->_db =& $this->_write_db;
- }
- }
-
- /**
- * Close the backend.
- *
- * @throws Horde_Exception
- */
- protected function _close()
- {
- /* Close any open transactions. */
- $this->_db->commit();
- $this->_db->autoCommit(true);
- $this->_write_db->commit();
- $this->_write_db->autoCommit(true);
-
- @$this->_write_db->disconnect();
- @$this->_db->disconnect();
- }
-
- /**
- * Read the data for a particular session identifier from the backend.
- *
- * @param string $id The session identifier.
- *
- * @return string The session data.
- */
- protected function _read($id)
- {
- /* Begin a transaction. */
- $result = $this->_write_db->autocommit(false);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return '';
- }
-
- /* Execute the query. */
- $result = Horde_SQL::readBlob($this->_write_db, $this->_params['table'], 'session_data', array('session_id' => $id));
-
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return '';
- }
-
- return $result;
- }
-
- /**
- * Write session data to the backend.
- *
- * @param string $id The session identifier.
- * @param string $session_data The session data.
- *
- * @return boolean True on success, false otherwise.
- */
- protected function _write($id, $session_data)
- {
- /* Build the SQL query. */
- $query = sprintf('SELECT session_id FROM %s WHERE session_id = ?',
- $this->_params['table']);
- $values = array($id);
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_sql::write(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = $this->_write_db->getOne($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- if ($result) {
- $result = Horde_SQL::updateBlob($this->_write_db, $this->_params['table'], 'session_data',
- $session_data, array('session_id' => $id),
- array('session_lastmodified' => time()));
- } else {
- $result = Horde_SQL::insertBlob($this->_write_db, $this->_params['table'], 'session_data',
- $session_data, array('session_id' => $id,
- 'session_lastmodified' => time()));
- }
-
- if (is_a($result, 'PEAR_Error')) {
- $this->_write_db->rollback();
- $this->_write_db->autoCommit(true);
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- $result = $this->_write_db->commit();
- if (is_a($result, 'PEAR_Error')) {
- $this->_write_db->autoCommit(true);
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- $this->_write_db->autoCommit(true);
- return true;
- }
-
- /**
- * Destroy the data for a particular session identifier in the backend.
- *
- * @param string $id The session identifier.
- *
- * @return boolean True on success, false otherwise.
- */
- public function destroy($id)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_id = ?',
- $this->_params['table']);
- $values = array($id);
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_sql::destroy(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- $result = $this->_write_db->commit();
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- return true;
- }
-
- /**
- * Garbage collect stale sessions from the backend.
- *
- * @param integer $maxlifetime The maximum age of a session.
- *
- * @return boolean True on success, false otherwise.
- */
- public function gc($maxlifetime = 300)
- {
- /* Build the SQL query. */
- $query = sprintf('DELETE FROM %s WHERE session_lastmodified < ?',
- $this->_params['table']);
- $values = array(time() - $maxlifetime);
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_sql::gc(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = $this->_write_db->query($query, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- return true;
- }
-
- /**
- * Get a list of the valid session identifiers.
- *
- * @return array A list of valid session identifiers.
- * @throws Horde_Exception
- */
- public function getSessionIDs()
- {
- $this->open();
-
- /* Build the SQL query. */
- $query = 'SELECT session_id FROM ' . $this->_params['table'] .
- ' WHERE session_lastmodified => ?';
- $values = array(time() - ini_get('session.gc_maxlifetime'));
-
- /* Log the query at a DEBUG log level. */
- Horde::logMessage(sprintf('SQL Query by Horde_SessionHandler_sql::getSessionIDs(): query = "%s"', $query), __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
- /* Execute the query. */
- $result = $this->_db->getCol($query, 0, $values);
- if (is_a($result, 'PEAR_Error')) {
- Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
- return false;
- }
-
- return $result;
- }
-
-}
<dir name="lib">
<dir name="Horde">
<dir name="SessionHandler">
- <file name="ldap.php" role="php" />
- <file name="memcache.php" role="php" />
- <file name="mysql.php" role="php" />
- <file name="none.php" role="php" />
- <file name="oci8.php" role="php" />
- <file name="pgsql.php" role="php" />
- <file name="sql.php" role="php" />
+ <file name="Ldap.php" role="php" />
+ <file name="Memcache.php" role="php" />
+ <file name="Mysql.php" role="php" />
+ <file name="None.php" role="php" />
+ <file name="Oci8.php" role="php" />
+ <file name="Pgsql.php" role="php" />
+ <file name="Sql.php" role="php" />
</dir> <!-- /lib/Horde/SessionHandler -->
<file name="SessionHandler.php" role="php" />
</dir> <!-- /lib/Horde -->
</dependencies>
<phprelease>
<filelist>
- <install name="lib/Horde/SessionHandler/ldap.php" as="Horde/SessionHandler/ldap.php" />
- <install name="lib/Horde/SessionHandler/memcache.php" as="Horde/SessionHandler/memcache.php" />
- <install name="lib/Horde/SessionHandler/mysql.php" as="Horde/SessionHandler/mysql.php" />
- <install name="lib/Horde/SessionHandler/none.php" as="Horde/SessionHandler/none.php" />
- <install name="lib/Horde/SessionHandler/oci8.php" as="Horde/SessionHandler/pgsql.php" />
- <install name="lib/Horde/SessionHandler/sql.php" as="Horde/SessionHandler/sql.php" />
+ <install name="lib/Horde/SessionHandler/Ldap.php" as="Horde/SessionHandler/Ldap.php" />
+ <install name="lib/Horde/SessionHandler/Memcache.php" as="Horde/SessionHandler/Memcache.php" />
+ <install name="lib/Horde/SessionHandler/Mysql.php" as="Horde/SessionHandler/Mysql.php" />
+ <install name="lib/Horde/SessionHandler/None.php" as="Horde/SessionHandler/None.php" />
+ <install name="lib/Horde/SessionHandler/Oci8.php" as="Horde/SessionHandler/Pgsql.php" />
+ <install name="lib/Horde/SessionHandler/Sql.php" as="Horde/SessionHandler/Sql.php" />
<install name="lib/Horde/SessionHandler.php" as="Horde/SessionHandler.php" />
<install name="scripts/Horde/SessionHandler/horde-active-sessions.php" as="scripts/horde-active-sessions.php" />
</filelist>