--- /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-2009 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 singleton instance.
+ *
+ * @var array
+ */
+ static protected $_instance = array();
+
+ /**
+ * 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;
+
+ /**
+ * Returns a reference to the global Horde_SessionObjects object, only
+ * creating it if it doesn't already exist.
+ *
+ * This method must be invoked as:
+ * $objectstore = Horde_SessionObjects::singleton();
+ *
+ * @return Horde_SessionObjects The Horde_SessionObjects instance.
+ */
+ static public function singleton($params = array())
+ {
+ ksort($params);
+ $sig = md5($params);
+
+ if (!isset(self::$_instance[$sig])) {
+ self::$_instance[$sig] = new Horde_SessionObjects($params);
+ }
+
+ return self::$_instance[$sig];
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $params The parameter array.
+ * <pre>
+ * Optional Parameters:
+ * 'name' -- The name of the session variable to store the objects in.
+ * 'size' -- The maximum size of the (non-prunable) object store.
+ * </pre>
+ */
+ protected function __construct($params = array())
+ {
+ if (isset($params['name'])) {
+ $this->_name = $params['name'];
+ }
+
+ if (isset($params['size']) && is_int($params['size'])) {
+ $this->_size = $params['size'];
+ }
+ }
+
+ /**
+ * Destructor.
+ */
+ public function __destruct()
+ {
+ /* Prune old entries. */
+ if (isset($_SESSION[$this->_name]['__prune']) &&
+ ($_SESSION[$this->_name]['__prune'] > $this->_size)) {
+ $pruneList = array();
+ foreach ($_SESSION[$this->_name] as $key => $val) {
+ if ($val['prune']) {
+ $pruneList[] = $key;
+ }
+ }
+
+ $pruneOids = array_slice($pruneList, 0, $_SESSION[$this->_name]['__prune'] - $this->_size);
+ foreach ($pruneOids as $val) {
+ unset($_SESSION[$this->_name][$val]);
+ }
+ $_SESSION[$this->_name]['__prune'] -= count($pruneOids);
+ }
+ }
+
+ /**
+ * 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[] = SERIALIZE_BASIC;
+ }
+ if (Horde_Serialize::hasCapability(SERIALIZE_LZF)) {
+ $modes[] = 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(SERIALIZE_LZF)) {
+ $modes[] = SERIALIZE_LZF;
+ }
+ $object = Horde_Serialize::unserialize($_SESSION[$this->_name][$oid]['data'], array_merge($modes, array(SERIALIZE_BASIC)));
+ if (is_a($object, 'PEAR_Error')) {
+ $this->setPruneFlag($oid, true);
+ $object = false;
+ }
+ }
+
+ return $object;
+ }
+
+ /**
+ * Sets the prune flag on a store object.
+ *
+ * @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'];
+ }
+ }
+
+ /**
+ * 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>* 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>Horde_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>