PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/horde-3.3.13/lib/Horde/SessionObjects.php

#
PHP | 277 lines | 129 code | 24 blank | 124 comment | 23 complexity | 0140f0dc0be701d33f8bd3fcbfa9f364 MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /**
  3. * The Horde_SessionObjects:: class provides a way for storing data
  4. * (usually, but not necessarily, objects) in the current user's
  5. * session.
  6. *
  7. * $Horde: framework/SessionObjects/SessionObjects.php,v 1.6.12.12 2009/01/06 15:23:35 jan Exp $
  8. *
  9. * Copyright 2003-2009 The Horde Project (http://www.horde.org/)
  10. *
  11. * See the enclosed file COPYING for license information (LGPL). If youq
  12. * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  13. *
  14. * @author Chuck Hagenbuch <chuck@horde.org>
  15. * @since Horde 1.3
  16. * @package Horde_SessionObjects
  17. */
  18. class Horde_SessionObjects {
  19. /**
  20. * The list of oids to prune at the end of a request.
  21. *
  22. * @var array
  23. */
  24. var $_pruneList = null;
  25. /**
  26. * The name of the store.
  27. *
  28. * @var string
  29. */
  30. var $_name = 'horde_session_objects';
  31. /**
  32. * Allow store() to overwrite current objects?
  33. *
  34. * @var boolean
  35. */
  36. var $_overwrite = false;
  37. /**
  38. * The maximum number of objects that the store should hold.
  39. *
  40. * @var integer
  41. */
  42. var $_size = 20;
  43. /**
  44. * Serialized cache item.
  45. *
  46. * @var string
  47. */
  48. var $_sdata = null;
  49. /**
  50. * Returns a reference to the global Horde_SessionObjects object,
  51. * only creating it if it doesn't already exist.
  52. *
  53. * This method must be invoked as:
  54. * $objectstore = &Horde_SessionObjects::singleton();
  55. *
  56. * @return Horde_SessionObjects The Horde_SessionObjects instance.
  57. */
  58. function &singleton()
  59. {
  60. static $object;
  61. if (!isset($object)) {
  62. $object = new Horde_SessionObjects();
  63. }
  64. return $object;
  65. }
  66. /**
  67. * Constructor.
  68. *
  69. * @param array $params The parameter array.
  70. * <pre>
  71. * Optional Parameters:
  72. * 'name' -- The name of the session variable to store the objects in.
  73. * 'size' -- The maximum size of the (non-prunable) object store.
  74. * </pre>
  75. */
  76. function Horde_SessionObjects($params = array())
  77. {
  78. if (isset($params['name'])) {
  79. $this->_name = $params['name'];
  80. }
  81. if (isset($params['size']) && is_int($params['size'])) {
  82. $this->_size = $params['size'];
  83. }
  84. }
  85. /**
  86. * Wrapper around store that will return the oid instead.
  87. *
  88. * @see store
  89. *
  90. * @param mixed $data The data to store in the session store.
  91. * @param boolean $prune If false, this object will not be pruned from the
  92. * store if the maximum store size is exceeded.
  93. *
  94. * @return string The MD5 string representing the object's ID.
  95. */
  96. function storeOid($data, $prune = true)
  97. {
  98. $this->_sdata = true;
  99. $oid = $this->oid($data);
  100. $this->store($oid, $data, $prune);
  101. $this->_sdata = null;
  102. return $oid;
  103. }
  104. /**
  105. * Attempts to store an object in the session store.
  106. *
  107. * @param string $oid Object ID used as the storage key.
  108. * @param mixed $data The data to store in the session store.
  109. * @param boolean $prune If false, this object will not be pruned from the
  110. * store if the maximum store size is exceeded.
  111. *
  112. * @return boolean True on success, false on failure.
  113. */
  114. function store($oid, $data, $prune = true)
  115. {
  116. if (!isset($_SESSION[$this->_name])) {
  117. $_SESSION[$this->_name] = array('__prune' => 0);
  118. }
  119. $ptr = &$_SESSION[$this->_name];
  120. if ($this->_overwrite || !isset($ptr[$oid])) {
  121. require_once 'Horde/Serialize.php';
  122. $modes = array();
  123. if (!is_null($this->_sdata)) {
  124. $data = $this->_sdata;
  125. } else {
  126. $modes[] = SERIALIZE_BASIC;
  127. }
  128. if (Horde_Serialize::hasCapability(SERIALIZE_LZF)) {
  129. $modes[] = SERIALIZE_LZF;
  130. }
  131. $ptr[$oid] = array(
  132. 'data' => ((empty($modes)) ? $data : Horde_Serialize::serialize($data, $modes)),
  133. 'prune' => $prune
  134. );
  135. if ($prune) {
  136. ++$ptr['__prune'];
  137. }
  138. }
  139. /* Check for prunable Oids. */
  140. $this->_pruneOids();
  141. return true;
  142. }
  143. /**
  144. * Overwrites a current element in the object store.
  145. *
  146. * @param string $oid Object ID used as the storage key.
  147. * @param mixed $data The data to store in the session store.
  148. * @param boolean $prune If false, this object will not be pruned from the
  149. * store if the maximum store size is exceeded.
  150. *
  151. * @return boolean True on success, false on failure.
  152. */
  153. function overwrite($oid, $data, $prune = true)
  154. {
  155. $this->_overwrite = true;
  156. $success = $this->store($oid, $data, $prune);
  157. $this->_overwrite = false;
  158. return $success;
  159. }
  160. /**
  161. * Attempts to retrive an object from the store.
  162. *
  163. * @param string $oid Object ID to query.
  164. * @param enum $type NOT USED
  165. * @param integer $val NOT USED
  166. *
  167. * @return mixed The requested object, or false on failure.
  168. */
  169. function &query($oid, $type = null, $val = null)
  170. {
  171. if (!isset($_SESSION[$this->_name]) ||
  172. (is_null($oid) || !isset($_SESSION[$this->_name][$oid]))) {
  173. $object = false;
  174. } else {
  175. require_once 'Horde/Serialize.php';
  176. $modes = array();
  177. if (Horde_Serialize::hasCapability(SERIALIZE_LZF)) {
  178. $modes[] = SERIALIZE_LZF;
  179. }
  180. $object = Horde_Serialize::unserialize($_SESSION[$this->_name][$oid]['data'], array_merge($modes, array(SERIALIZE_BASIC)));
  181. if (is_a($object, 'PEAR_Error')) {
  182. $this->setPruneFlag($oid, true);
  183. $object = false;
  184. }
  185. }
  186. return $object;
  187. }
  188. /**
  189. * Sets the prune flag on a store object.
  190. *
  191. * @param string $oid The object ID.
  192. * @param boolean $prune True to allow pruning, false for no pruning.
  193. */
  194. function setPruneFlag($oid, $prune)
  195. {
  196. if (!isset($_SESSION[$this->_name])) {
  197. return;
  198. }
  199. $ptr = &$_SESSION[$this->_name];
  200. if (isset($ptr[$oid]) && ($ptr[$oid]['prune'] != $prune)) {
  201. $ptr[$oid]['prune'] = $prune;
  202. ($prune) ? ++$ptr['__prune'] : --$ptr['__prune'];
  203. }
  204. }
  205. /**
  206. * Generates an OID for an object.
  207. *
  208. * @param mixed $data The data to store in the store.
  209. *
  210. * @return string $oid An object ID to use as the storage key.
  211. */
  212. function oid($data)
  213. {
  214. $data = serialize($data);
  215. $oid = md5($data);
  216. if ($this->_sdata === true) {
  217. $this->_sdata = $data;
  218. }
  219. return $oid;
  220. }
  221. /**
  222. * Generate the list of prunable oids.
  223. *
  224. * @access private
  225. */
  226. function _pruneOids()
  227. {
  228. if (is_null($this->_pruneList) &&
  229. isset($_SESSION[$this->_name]['__prune']) &&
  230. ($_SESSION[$this->_name]['__prune'] > $this->_size)) {
  231. $this->_pruneList = array();
  232. foreach ($_SESSION[$this->_name] as $key => $val) {
  233. if ($val['prune']) {
  234. $this->_pruneList[] = $key;
  235. }
  236. }
  237. register_shutdown_function(array(&$this, '_prune'));
  238. }
  239. }
  240. /**
  241. * Prune old store entries at request shutdown.
  242. *
  243. * @access private
  244. */
  245. function _prune()
  246. {
  247. $pruneOids = array_slice($this->_pruneList, 0, $_SESSION[$this->_name]['__prune'] - $this->_size);
  248. foreach ($pruneOids as $val) {
  249. unset($_SESSION[$this->_name][$val]);
  250. }
  251. $_SESSION[$this->_name]['__prune'] -= count($pruneOids);
  252. }
  253. }