{
public function create(Horde_Injector $injector)
{
- $group = null;
- if (!empty($GLOBALS['conf']['group']['cache'])) {
- $session = new Horde_SessionObjects();
- $group = $session->query('horde_group');
- }
+ $group = empty($GLOBALS['conf']['group']['cache'])
+ ? null
+ : $GLOBALS['session']->retrieve('horde_group');
if (!$group) {
$driver = $GLOBALS['conf']['group']['driver'];
}
if (!empty($GLOBALS['conf']['share']['cache'])) {
- $cache_sig = 'horde_share_' . $app . '_' . $driver . '1';
- $ob = $this->_injector->getInstance('Horde_SessionObjects')->query($cache_sig);
+ $cache_sig = 'horde_share/' . $app . '/' . $driver . '1';
+ $ob = $GLOBALS['session']->retrieve($cache_sig);
}
if (empty($ob)) {
*/
public function shutdown($sig, $share)
{
- $this->_injector->getInstance('Horde_SessionObjects')->overwrite($sig, $share, false);
+ $GLOBALS['session']->store($share, false, $sig);
}
}
*/
class Horde_Session implements ArrayAccess
{
+ /* Class constants. */
+ const DATA = '_d';
+ const PRUNE = '_p';
+ const SERIALIZED = '_s';
+
+ /**
+ * Maximum size of the pruneable data store.
+ *
+ * @var integer
+ */
+ public $maxStore = 20;
+
/**
* The session handler object.
*
session_start();
/* Create internal data arrays. */
- if (!isset($_SESSION['_s'])) {
+ if (!isset($_SESSION[self::SERIALIZED])) {
/* Is this key serialized? */
- $_SESSION['_s'] = array();
+ $_SESSION[self::SERIALIZED] = array();
}
}
}
$this->_cleansession = true;
}
+ /* Session object storage. */
+
+ /**
+ * Store an arbitrary piece of data in the session.
+ * Equivalent to: $this[self::DATA . ':' . $id] = $value;
+ *
+ * @param mixed $data Data to save.
+ * @param boolean $prune Is data pruneable?
+ * @param string $id ID to use (otherwise, is autogenerated).
+ *
+ * @return string The session storage id (used to get session data).
+ */
+ public function store($data, $prune = true, $id = null)
+ {
+ if (is_null($id)) {
+ $id = strval(new Horde_Support_Randomid());
+ } else {
+ $offset = $this->_parseOffset($id);
+ $id = $offset->name;
+ }
+
+ $full_id = self::DATA . ':' . $id;
+ $this->_offsetSet($this->_parseOffset($full_id), $data);
+
+ if ($prune) {
+ $ptr = &$_SESSION[self::PRUNE];
+ unset($ptr[$id]);
+ $ptr[$id] = 1;
+ if (count($ptr) > $this->maxStore) {
+ array_shift($ptr);
+ }
+ }
+
+ return $full_id;
+ }
+
+ /**
+ * Retrieve data from the session data store (created via store()).
+ * Equivalent to: $value = $this[self::DATA . ':' . $id];
+ *
+ * @param string $id The session data ID.
+ *
+ * @return mixed The session data value.
+ */
+ public function retrieve($id)
+ {
+ $id = trim($id);
+
+ if (strpos($id, self::DATA) !== 0) {
+ $id = self::DATA . ':' . $id;
+ }
+
+ return $this[$id];
+ }
+
+ /**
+ * Purge data from the session data store (created via store()).
+ * Equivalent to: unset($this[self::DATA . ':' . $id]);
+ *
+ * @param string $id The session data ID.
+ */
+ public function purge($id)
+ {
+ $id = trim($id);
+
+ if (strpos($id, self::DATA) !== 0) {
+ $id = self::DATA . ':' . $id;
+ }
+
+ unset($this[$id]);
+ }
+
/* ArrayAccess methods. */
/**
$data = $_SESSION[$ob->app][$ob->name];
- if (!isset($_SESSION['_s'][$ob->key])) {
+ if (!isset($_SESSION[self::SERIALIZED][$ob->key])) {
return $data;
}
$data = lzf_decompress($data);
}
- return ($_SESSION['_s'][$ob->key] == 's')
+ return ($_SESSION[self::SERIALIZED][$ob->key] == 's')
? @unserialize($data)
: json_decode($data, true);
}
{
$ob = $this->_parseOffset($offset);
+ if ($ob->app == self::DATA) {
+ $this->store($value, false, $ob->name);
+ } else {
+ $this->_offsetSet($ob, $value);
+ }
+ }
+
+ /**
+ * TODO
+ */
+ private function _offsetSet($ob, $value)
+ {
/* Each particular piece of session data is generally not used on any
* given page load. Thus, for arrays ans objects, it is beneficial to
* always convert to string representations so that the object/array
if ($this->_lzf) {
$value = lzf_compress($value);
}
- $_SESSION['_s'][$ob->key] = 's';
+ $_SESSION[self::SERIALIZED][$ob->key] = 's';
} elseif (is_array($value)) {
$value = json_encode($value);
if ($this->_lzf) {
$value = lzf_compress($value);
}
- $_SESSION['_s'][$ob->key] = 'j';
+ $_SESSION[self::SERIALIZED][$ob->key] = 'j';
}
$_SESSION[$ob->app][$ob->name] = $value;
if (isset($_SESSION[$ob->app])) {
if (!strlen($ob->key)) {
foreach (array_keys($_SESSION[$ob->app]) as $key) {
- unset($_SESSION['_s'][$key]);
+ unset($_SESSION[self::SERIALIZED][$key]);
}
unset($_SESSION[$ob->app]);
} elseif (isset($_SESSION[$ob->app][$ob->name])) {
- unset($_SESSION[$ob->app][$ob->name], $_SESSION['_s'][$ob->key]);
+ unset(
+ $_SESSION[$ob->app][$ob->name],
+ $_SESSION[self::PRUNE][$ob->key],
+ $_SESSION[self::SERIALIZED][$ob->key]
+ );
}
}
}
*/
public function shutdown()
{
- $GLOBALS['injector']->getInstance('Horde_SessionObjects')->overwrite('horde_group', $this, false);
+ // TODO: Mve to core.
+ $GLOBALS['session']->store($this, false, 'horde_group');
}
/**
<name>Log</name>
<channel>pear.horde.org</channel>
</package>
- <package>
- <name>SessionObjects</name>
- <channel>pear.horde.org</channel>
- </package>
</optional>
</dependencies>
<phprelease>
<min>0.1.0</min>
</package>
<package>
- <name>Horde_SessionObjects</name>
- <channel>pear.horde.org</channel>
- </package>
- <package>
<name>Horde_MIME</name>
<channel>pear.horde.org</channel>
</package>
+++ /dev/null
-<?php
-/**
- * The Horde_SessionObjects:: class provides a way for storing data
- * (usually, but not necessarily, objects) in the current user's
- * session.
- *
- * Copyright 2003-2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If youq
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author Chuck Hagenbuch <chuck@horde.org>
- * @package Horde_SessionObjects
- * @category Horde
- */
-class Horde_SessionObjects
-{
- /**
- * The name of the store.
- *
- * @var string
- */
- protected $_name = 'horde_session_objects';
-
- /**
- * Allow store() to overwrite current objects?
- *
- * @var boolean
- */
- protected $_overwrite = false;
-
- /**
- * The maximum number of objects that the store should hold.
- *
- * @var integer
- */
- protected $_size = 20;
-
- /**
- * Serialized cache item.
- *
- * @var string
- */
- protected $_sdata = null;
-
- /**
- * Constructor.
- *
- * @param array $params Optional parameters:
- * <pre>
- * 'name' - (string) The name of the session variable to store the objects
- * in.
- * 'size' - (integer) The maximum size of the (non-prunable) object store.
- * </pre>
- */
- public function __construct($params = array())
- {
- if (isset($params['name'])) {
- $this->_name = $params['name'];
- }
-
- if (isset($params['size']) && is_int($params['size'])) {
- $this->_size = $params['size'];
- }
-
- register_shutdown_function(array($this, 'shutdown'));
- }
-
- /**
- * Tasks to run on shutdown.
- */
- public function shutdown()
- {
- /* Prune old entries. */
- if (isset($_SESSION[$this->_name]['__prune']) &&
- ($_SESSION[$this->_name]['__prune'] > $this->_size)) {
- $pruneList = array();
- $prune_count = $_SESSION[$this->_name]['__prune'] - $this->_size;
-
- foreach ($_SESSION[$this->_name] as $key => $val) {
- if ($val['prune']) {
- $pruneList[] = $key;
- if (!--$prune_count) {
- break;
- }
- }
- }
-
- $this->prune($pruneList);
- }
- }
-
- /**
- * Wrapper around store that will return the oid instead.
- *
- * @see Horde_SessionObjects::store()
- *
- * @param mixed $data The data to store in the session store.
- * @param boolean $prune If false, this object will not be pruned from the
- * store if the maximum store size is exceeded.
- *
- * @return string The MD5 string representing the object's ID.
- */
- public function storeOid($data, $prune = true)
- {
- $this->_sdata = true;
- $oid = $this->oid($data);
- $this->store($oid, $data, $prune);
- $this->_sdata = null;
- return $oid;
- }
-
- /**
- * Attempts to store an object in the session store.
- *
- * @param string $oid Object ID used as the storage key.
- * @param mixed $data The data to store in the session store.
- * @param boolean $prune If false, this object will not be pruned from the
- * store if the maximum store size is exceeded.
- *
- * @return boolean True on success.
- */
- public function store($oid, $data, $prune = true)
- {
- if (!isset($_SESSION[$this->_name])) {
- $_SESSION[$this->_name] = array('__prune' => 0);
- }
- $ptr = &$_SESSION[$this->_name];
-
- if ($this->_overwrite || !isset($ptr[$oid])) {
- $modes = array();
- if (!is_null($this->_sdata)) {
- $data = $this->_sdata;
- } else {
- $modes[] = Horde_Serialize::BASIC;
- }
- if (Horde_Serialize::hasCapability(Horde_Serialize::LZF)) {
- $modes[] = Horde_Serialize::LZF;
- }
- $ptr[$oid] = array(
- 'data' => ((empty($modes)) ? $data : Horde_Serialize::serialize($data, $modes)),
- 'prune' => $prune
- );
-
- if ($prune) {
- ++$ptr['__prune'];
- }
- }
-
- return true;
- }
-
- /**
- * Overwrites a current element in the object store.
- *
- * @param string $oid Object ID used as the storage key.
- * @param mixed $data The data to store in the session store.
- * @param boolean $prune If false, this object will not be pruned from the
- * store if the maximum store size is exceeded.
- *
- * @return boolean True on success, false on failure.
- */
- public function overwrite($oid, $data, $prune = true)
- {
- $this->_overwrite = true;
- $success = $this->store($oid, $data, $prune);
- $this->_overwrite = false;
- return $success;
- }
-
- /**
- * Attempts to retrive an object from the store.
- *
- * @param string $oid Object ID to query.
- * @param enum $type NOT USED
- * @param integer $val NOT USED
- *
- * @return mixed The requested object, or false on failure.
- */
- public function query($oid, $type = null, $val = null)
- {
- if (!isset($_SESSION[$this->_name]) ||
- (is_null($oid) || !isset($_SESSION[$this->_name][$oid]))) {
- $object = false;
- } else {
- $modes = array();
- if (Horde_Serialize::hasCapability(Horde_Serialize::LZF)) {
- $modes[] = Horde_Serialize::LZF;
- }
- $object = Horde_Serialize::unserialize($_SESSION[$this->_name][$oid]['data'], array_merge($modes, array(Horde_Serialize::BASIC)));
- if (is_a($object, 'PEAR_Error')) {
- $this->setPruneFlag($oid, true);
- $object = false;
- }
- }
-
- return $object;
- }
-
- /**
- * Sets the prune flag on a store object. The object will be pruned
- * when the maximum storage size is reached.
- *
- * @param string $oid The object ID.
- * @param boolean $prune True to allow pruning, false for no pruning.
- */
- public function setPruneFlag($oid, $prune)
- {
- if (!isset($_SESSION[$this->_name])) {
- return;
- }
-
- $ptr = &$_SESSION[$this->_name];
- if (isset($ptr[$oid]) && ($ptr[$oid]['prune'] != $prune)) {
- $ptr[$oid]['prune'] = $prune;
- ($prune) ? ++$ptr['__prune'] : --$ptr['__prune'];
- }
- }
-
- /**
- * Immediately prune an object.
- *
- * @param mixed $oid The object ID or an array of object IDs.
- */
- public function prune($oid)
- {
- if (!isset($_SESSION[$this->_name])) {
- return;
- }
-
- if (!is_array($oid)) {
- $oid = array($oid);
- }
-
- $prune_count = 0;
-
- foreach ($oid as $val) {
- if (isset($_SESSION[$this->_name][$val])) {
- ++$prune_count;
- unset($_SESSION[$this->_name][$val]);
- }
- }
-
- $_SESSION[$this->_name]['__prune'] -= $prune_count;
- }
-
- /**
- * Generates an OID for an object.
- *
- * @param mixed $data The data to store in the store.
- *
- * @return string $oid An object ID to use as the storage key.
- */
- public function oid($data)
- {
- $data = serialize($data);
- $oid = md5($data);
- if ($this->_sdata === true) {
- $this->_sdata = $data;
- }
- return $oid;
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
-http://pear.php.net/dtd/tasks-1.0.xsd
-http://pear.php.net/dtd/package-2.0
-http://pear.php.net/dtd/package-2.0.xsd">
- <name>SessionObjects</name>
- <channel>pear.horde.org</channel>
- <summary>Horde Session Storage API</summary>
- <description>The Horde_SessionObjects:: class provides a way for storing
- data (usually, but not necessarily, objects) in the current user's
- session.
- </description>
- <lead>
- <name>Chuck Hagenbuch</name>
- <user>chuck</user>
- <email>chuck@horde.org</email>
- <active>yes</active>
- </lead>
- <date>2009-02-12</date>
- <version>
- <release>0.1.0</release>
- <api>0.1.0</api>
- </version>
- <stability>
- <release>beta</release>
- <api>beta</api>
- </stability>
- <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>* Remove singleton().
- * Added prune() function.
- * Initial Horde 4 package</notes>
- <contents>
- <dir name="/">
- <dir name="lib">
- <dir name="Horde">
- <file name="SessionObjects.php" role="php" />
- </dir> <!-- /lib/Horde -->
- </dir> <!-- /lib -->
- </dir> <!-- / -->
- </contents>
- <dependencies>
- <required>
- <php>
- <min>5.2.0</min>
- </php>
- <pearinstaller>
- <min>1.5.0</min>
- </pearinstaller>
- <package>
- <name>Horde_Framework</name>
- <channel>pear.horde.org</channel>
- </package>
- <package>
- <name>Serialize</name>
- <channel>pear.horde.org</channel>
- </package>
- </required>
- <optional>
- <package>
- <name>lzf</name>
- <channel>pecl.php.net</channel>
- </package>
- </optional>
- </dependencies>
- <phprelease>
- <filelist>
- <install name="lib/Horde/SessionObjects.php" as="Horde/SessionObjects.php" />
- </filelist>
- </phprelease>
- <changelog>
- <release>
- <date>2007-10-10</date>
- <time>23:17:00</time>
- <version>
- <release>0.0.3</release>
- <api>0.0.3</api>
- </version>
- <stability>
- <release>alpha</release>
- <api>alpha</api>
- </stability>
- <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>Added support for lzf compression; don't serialize same data twice
- </notes>
- </release>
- <release>
- <version>
- <release>0.0.2</release>
- <api>0.0.2</api>
- </version>
- <stability>
- <release>alpha</release>
- <api>alpha</api>
- </stability>
- <date>2006-05-08</date>
- <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>Converted to package.xml 2.0 for pear.horde.org
- </notes>
- </release>
- <release>
- <version>
- <release>0.0.1</release>
- <api>0.0.1</api>
- </version>
- <stability>
- <release>alpha</release>
- <api>alpha</api>
- </stability>
- <date>2003-07-05</date>
- <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
- <notes>Initial release as a PEAR package
- </notes>
- </release>
- </changelog>
-</package>
*/
public function reloadWindow($reload)
{
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
- $href = $cacheSess->query($reload);
- $cacheSess->prune($reload);
+ global $session;
+
+ $href = $session[$reload];
+ unset($session[$reload]);
echo Horde::wrapInlineScript(array(
'opener.focus();'.
'opener.location.href="' . $href . '";',
*/
public function reloadWindow($reload)
{
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
- $href = $cacheSess->query($reload);
- $cacheSess->prune($reload);
+ global $session;
+
+ $href = $session[$reload];
+ unset($session[$reload]);
echo Horde::wrapInlineScript(array(
'opener.focus();',
'opener.location.href="' . $href . '";',
if (empty($cacheid)) {
$cacheid = strval(new Horde_Support_Randomid());
} elseif (!isset($this->_instances[$cacheid])) {
- $obs = $this->_injector->getInstance('Horde_SessionObjects');
- $this->_instances[$cacheid] = $obs->query($cacheid);
+ $this->_instances[$cacheid] = $GLOBALS['session']->retrieve($cacheid);
}
if (empty($this->_instances[$cacheid])) {
*/
public function shutdown()
{
- $cache = $GLOBALS['session']['imp:compose_cache:array'];
+ global $session;
+
+ $cache = $session['imp:compose_cache:array'];
$changed = false;
- $obs = $this->_injector->getInstance('Horde_SessionObjects');
foreach ($this->_instances as $key => $val) {
switch ($val->changed) {
case 'changed':
$val->changed = '';
- $obs->overwrite($key, $val, false);
+ $session->store($val, false, $key);
$cache[$key] = 1;
$changed = true;
break;
case 'deleted':
- $obs->prune($key);
unset($cache[$key]);
+ $session->purge($key);
$changed = true;
break;
}
), 'dom');
if ($GLOBALS['session']['imp:file_upload']) {
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
Horde::addInlineScript(array(
- '$("import_pgp_personal").observe("click", function(e) { ' . Horde::popupJs($pgp_url, array('params' => array('actionID' => 'import_personal_public_key', 'reload' => $cacheSess->storeOid($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
+ '$("import_pgp_personal").observe("click", function(e) { ' . Horde::popupJs($pgp_url, array('params' => array('actionID' => 'import_personal_public_key', 'reload' => $GLOBALS['session']->store($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
), 'dom');
}
$t->set('can_import', true);
$t->set('no_source', !$GLOBALS['prefs']->getValue('add_source'));
if (!$t->get('no_source')) {
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
$t->set('import_pubkey-help', Horde_Help::link('imp', 'pgp-import-pubkey'));
Horde::addInlineScript(array(
- '$("import_pgp_public").observe("click", function(e) { ' . Horde::popupJs($pgp_url, array('params' => array('actionID' => 'import_public_key', 'reload' => $cacheSess->storeOid($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
+ '$("import_pgp_public").observe("click", function(e) { ' . Horde::popupJs($pgp_url, array('params' => array('actionID' => 'import_public_key', 'reload' => $GLOBALS['session']->store($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
), 'dom');
}
}
'$("delete_smime_personal").observe("click", function(e) { if (!window.confirm(' . Horde_Serialize::serialize(_("Are you sure you want to delete your keypair? (This is NOT recommended!)"), Horde_Serialize::JSON, 'UTF-8') . ')) { e.stop(); } })'
), 'dom');
} elseif ($GLOBALS['session']['imp:file_upload']) {
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
$t->set('import-cert-help', Horde_Help::link('imp', 'smime-import-personal-certs'));
Horde::addInlineScript(array(
- '$("import_smime_personal").observe("click", function(e) { ' . Horde::popupJs($smime_url, array('params' => array('actionID' => 'import_personal_public_key', 'reload' => $cacheSess->storeOid($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
+ '$("import_smime_personal").observe("click", function(e) { ' . Horde::popupJs($smime_url, array('params' => array('actionID' => 'import_personal_public_key', 'reload' => $GLOBALS['session']->store($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
), 'dom');
}
}
$t->set('can_import', true);
$t->set('no_source', !$GLOBALS['prefs']->getValue('add_source'));
if (!$t->get('no_source')) {
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
$t->set('import_pubkey-help', Horde_Help::link('imp', 'smime-import-pubkey'));
Horde::addInlineScript(array(
- '$("import_smime_public").observe("click", function(e) { ' . Horde::popupJs($smime_url, array('params' => array('actionID' => 'import_public_key', 'reload' => $cacheSess->storeOid($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
+ '$("import_smime_public").observe("click", function(e) { ' . Horde::popupJs($smime_url, array('params' => array('actionID' => 'import_public_key', 'reload' => $GLOBALS['session']->store($ui->selfUrl()->setRaw(true), false)), 'height' => 275, 'width' => 750, 'urlencode' => true)) . '; e.stop(); })'
), 'dom');
}
}
*/
public function shutdown()
{
- $cache = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
-
/* Store the current objects. */
foreach ($this->_cache as $key => $val) {
- if (!$val['mod'] && isset($_SESSION['ingo']['storage'][$key])) {
- continue;
- }
- if (isset($_SESSION['ingo']['storage'][$key])) {
- $cache->setPruneFlag($_SESSION['ingo']['storage'][$key], true);
+ if ($val['mod'] || !isset($_SESSION['ingo']['storage'][$key])) {
+ $_SESSION['ingo']['storage'][$key] = $GLOBALS['session']->store($val['ob'], false);
}
- $_SESSION['ingo']['storage'][$key] = $cache->storeOid($val['ob'], false);
}
}
/* Don't cache if using shares. */
if ($cache && empty($GLOBALS['ingo_shares'])) {
if (!isset($this->_cache[$field])) {
- $this->_cache[$field] = array('mod' => false);
- if (isset($_SESSION['ingo']['storage'][$field])) {
- $cacheSess = $GLOBALS['injector']->getInstance('Horde_SessionObjects');
- $this->_cache[$field]['ob'] = $cacheSess->query($_SESSION['ingo']['storage'][$field]);
- } else {
- $this->_cache[$field]['ob'] = $this->_retrieve($field, $readonly);
- }
+ $this->_cache[$field] = array(
+ 'mod' => false,
+ 'ob' => isset($_SESSION['ingo']['storage'][$field])
+ ? $GLOBALS['session'][$_SESSION['ingo']['storage'][$field]]
+ : $this->_retrieve($field, $readonly)
+ );
}
$ob = $this->_cache[$field]['ob'];
} else {