PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/Zend/Session/Namespace.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 529 lines | 210 code | 76 blank | 243 comment | 47 complexity | 76bddc151801bea02ef10bfa0baf5399 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Session
  17. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: Namespace.php 20096 2010-01-06 02:05:09Z bkarwin $
  20. * @since Preview Release 0.2
  21. */
  22. /**
  23. * @see Zend_Session
  24. */
  25. #require_once 'Zend/Session.php';
  26. /**
  27. * @see Zend_Session_Abstract
  28. */
  29. #require_once 'Zend/Session/Abstract.php';
  30. /**
  31. * Zend_Session_Namespace
  32. *
  33. * @category Zend
  34. * @package Zend_Session
  35. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  36. * @license http://framework.zend.com/license/new-bsd New BSD License
  37. */
  38. class Zend_Session_Namespace extends Zend_Session_Abstract implements IteratorAggregate
  39. {
  40. /**
  41. * used as option to constructor to prevent additional instances to the same namespace
  42. */
  43. const SINGLE_INSTANCE = true;
  44. /**
  45. * Namespace - which namespace this instance of zend-session is saving-to/getting-from
  46. *
  47. * @var string
  48. */
  49. protected $_namespace = "Default";
  50. /**
  51. * Namespace locking mechanism
  52. *
  53. * @var array
  54. */
  55. protected static $_namespaceLocks = array();
  56. /**
  57. * Single instance namespace array to ensure data security.
  58. *
  59. * @var array
  60. */
  61. protected static $_singleInstances = array();
  62. /**
  63. * resetSingleInstance()
  64. *
  65. * @param string $namespaceName
  66. * @return null
  67. */
  68. public static function resetSingleInstance($namespaceName = null)
  69. {
  70. if ($namespaceName != null) {
  71. if (array_key_exists($namespaceName, self::$_singleInstances)) {
  72. unset(self::$_singleInstances[$namespaceName]);
  73. }
  74. return;
  75. }
  76. self::$_singleInstances = array();
  77. return;
  78. }
  79. /**
  80. * __construct() - Returns an instance object bound to a particular, isolated section
  81. * of the session, identified by $namespace name (defaulting to 'Default').
  82. * The optional argument $singleInstance will prevent construction of additional
  83. * instance objects acting as accessors to this $namespace.
  84. *
  85. * @param string $namespace - programmatic name of the requested namespace
  86. * @param bool $singleInstance - prevent creation of additional accessor instance objects for this namespace
  87. * @return void
  88. */
  89. public function __construct($namespace = 'Default', $singleInstance = false)
  90. {
  91. if ($namespace === '') {
  92. /**
  93. * @see Zend_Session_Exception
  94. */
  95. #require_once 'Zend/Session/Exception.php';
  96. throw new Zend_Session_Exception('Session namespace must be a non-empty string.');
  97. }
  98. if ($namespace[0] == "_") {
  99. /**
  100. * @see Zend_Session_Exception
  101. */
  102. #require_once 'Zend/Session/Exception.php';
  103. throw new Zend_Session_Exception('Session namespace must not start with an underscore.');
  104. }
  105. if (preg_match('#(^[0-9])#i', $namespace[0])) {
  106. /**
  107. * @see Zend_Session_Exception
  108. */
  109. #require_once 'Zend/Session/Exception.php';
  110. throw new Zend_Session_Exception('Session namespace must not start with a number.');
  111. }
  112. if (isset(self::$_singleInstances[$namespace])) {
  113. /**
  114. * @see Zend_Session_Exception
  115. */
  116. #require_once 'Zend/Session/Exception.php';
  117. throw new Zend_Session_Exception("A session namespace object already exists for this namespace ('$namespace'), and no additional accessors (session namespace objects) for this namespace are permitted.");
  118. }
  119. if ($singleInstance === true) {
  120. self::$_singleInstances[$namespace] = true;
  121. }
  122. $this->_namespace = $namespace;
  123. // Process metadata specific only to this namespace.
  124. Zend_Session::start(true); // attempt auto-start (throws exception if strict option set)
  125. if (self::$_readable === false) {
  126. /**
  127. * @see Zend_Session_Exception
  128. */
  129. #require_once 'Zend/Session/Exception.php';
  130. throw new Zend_Session_Exception(self::_THROW_NOT_READABLE_MSG);
  131. }
  132. if (!isset($_SESSION['__ZF'])) {
  133. return; // no further processing needed
  134. }
  135. // do not allow write access to namespaces, after stop() or writeClose()
  136. if (parent::$_writable === true) {
  137. if (isset($_SESSION['__ZF'][$namespace])) {
  138. // Expire Namespace by Namespace Hop (ENNH)
  139. if (isset($_SESSION['__ZF'][$namespace]['ENNH'])) {
  140. $_SESSION['__ZF'][$namespace]['ENNH']--;
  141. if ($_SESSION['__ZF'][$namespace]['ENNH'] === 0) {
  142. if (isset($_SESSION[$namespace])) {
  143. self::$_expiringData[$namespace] = $_SESSION[$namespace];
  144. unset($_SESSION[$namespace]);
  145. }
  146. unset($_SESSION['__ZF'][$namespace]);
  147. }
  148. }
  149. // Expire Namespace Variables by Namespace Hop (ENVNH)
  150. if (isset($_SESSION['__ZF'][$namespace]['ENVNH'])) {
  151. foreach ($_SESSION['__ZF'][$namespace]['ENVNH'] as $variable => $hops) {
  152. $_SESSION['__ZF'][$namespace]['ENVNH'][$variable]--;
  153. if ($_SESSION['__ZF'][$namespace]['ENVNH'][$variable] === 0) {
  154. if (isset($_SESSION[$namespace][$variable])) {
  155. self::$_expiringData[$namespace][$variable] = $_SESSION[$namespace][$variable];
  156. unset($_SESSION[$namespace][$variable]);
  157. }
  158. unset($_SESSION['__ZF'][$namespace]['ENVNH'][$variable]);
  159. }
  160. }
  161. if(empty($_SESSION['__ZF'][$namespace]['ENVNH'])) {
  162. unset($_SESSION['__ZF'][$namespace]['ENVNH']);
  163. }
  164. }
  165. }
  166. if (empty($_SESSION['__ZF'][$namespace])) {
  167. unset($_SESSION['__ZF'][$namespace]);
  168. }
  169. if (empty($_SESSION['__ZF'])) {
  170. unset($_SESSION['__ZF']);
  171. }
  172. }
  173. }
  174. /**
  175. * getIterator() - return an iteratable object for use in foreach and the like,
  176. * this completes the IteratorAggregate interface
  177. *
  178. * @return ArrayObject - iteratable container of the namespace contents
  179. */
  180. public function getIterator()
  181. {
  182. return new ArrayObject(parent::_namespaceGetAll($this->_namespace));
  183. }
  184. /**
  185. * lock() - mark a session/namespace as readonly
  186. *
  187. * @return void
  188. */
  189. public function lock()
  190. {
  191. self::$_namespaceLocks[$this->_namespace] = true;
  192. }
  193. /**
  194. * unlock() - unmark a session/namespace to enable read & write
  195. *
  196. * @return void
  197. */
  198. public function unlock()
  199. {
  200. unset(self::$_namespaceLocks[$this->_namespace]);
  201. }
  202. /**
  203. * unlockAll() - unmark all session/namespaces to enable read & write
  204. *
  205. * @return void
  206. */
  207. public static function unlockAll()
  208. {
  209. self::$_namespaceLocks = array();
  210. }
  211. /**
  212. * isLocked() - return lock status, true if, and only if, read-only
  213. *
  214. * @return bool
  215. */
  216. public function isLocked()
  217. {
  218. return isset(self::$_namespaceLocks[$this->_namespace]);
  219. }
  220. /**
  221. * unsetAll() - unset all variables in this namespace
  222. *
  223. * @return true
  224. */
  225. public function unsetAll()
  226. {
  227. return parent::_namespaceUnset($this->_namespace);
  228. }
  229. /**
  230. * __get() - method to get a variable in this object's current namespace
  231. *
  232. * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace
  233. * @return mixed
  234. */
  235. public function & __get($name)
  236. {
  237. if ($name === '') {
  238. /**
  239. * @see Zend_Session_Exception
  240. */
  241. #require_once 'Zend/Session/Exception.php';
  242. throw new Zend_Session_Exception("The '$name' key must be a non-empty string");
  243. }
  244. return parent::_namespaceGet($this->_namespace, $name);
  245. }
  246. /**
  247. * __set() - method to set a variable/value in this object's namespace
  248. *
  249. * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace
  250. * @param mixed $value - value in the <key,value> pair to assign to the $name key
  251. * @throws Zend_Session_Exception
  252. * @return true
  253. */
  254. public function __set($name, $value)
  255. {
  256. if (isset(self::$_namespaceLocks[$this->_namespace])) {
  257. /**
  258. * @see Zend_Session_Exception
  259. */
  260. #require_once 'Zend/Session/Exception.php';
  261. throw new Zend_Session_Exception('This session/namespace has been marked as read-only.');
  262. }
  263. if ($name === '') {
  264. /**
  265. * @see Zend_Session_Exception
  266. */
  267. #require_once 'Zend/Session/Exception.php';
  268. throw new Zend_Session_Exception("The '$name' key must be a non-empty string");
  269. }
  270. if (parent::$_writable === false) {
  271. /**
  272. * @see Zend_Session_Exception
  273. */
  274. #require_once 'Zend/Session/Exception.php';
  275. throw new Zend_Session_Exception(parent::_THROW_NOT_WRITABLE_MSG);
  276. }
  277. $name = (string) $name;
  278. $_SESSION[$this->_namespace][$name] = $value;
  279. }
  280. /**
  281. * apply() - enables applying user-selected function, such as array_merge() to the namespace
  282. * Parameters following the $callback argument are passed to the callback function.
  283. * Caveat: ignores members expiring now.
  284. *
  285. * Example:
  286. * $namespace->apply('array_merge', array('tree' => 'apple', 'fruit' => 'peach'), array('flower' => 'rose'));
  287. * $namespace->apply('count');
  288. *
  289. * @param string|array $callback - callback function
  290. */
  291. public function apply($callback)
  292. {
  293. $arg_list = func_get_args();
  294. $arg_list[0] = $_SESSION[$this->_namespace];
  295. return call_user_func_array($callback, $arg_list);
  296. }
  297. /**
  298. * applySet() - enables applying user-selected function, and sets entire namespace to the result
  299. * Result of $callback must be an array.
  300. * Parameters following the $callback argument are passed to the callback function.
  301. * Caveat: ignores members expiring now.
  302. *
  303. * Example:
  304. * $namespace->applySet('array_merge', array('tree' => 'apple', 'fruit' => 'peach'), array('flower' => 'rose'));
  305. *
  306. * @param string|array $callback - callback function
  307. */
  308. public function applySet($callback)
  309. {
  310. $arg_list = func_get_args();
  311. $arg_list[0] = $_SESSION[$this->_namespace];
  312. $result = call_user_func_array($callback, $arg_list);
  313. if (!is_array($result)) {
  314. /**
  315. * @see Zend_Session_Exception
  316. */
  317. #require_once 'Zend/Session/Exception.php';
  318. throw new Zend_Session_Exception('Result must be an array. Got: ' . gettype($result));
  319. }
  320. $_SESSION[$this->_namespace] = $result;
  321. return $result;
  322. }
  323. /**
  324. * __isset() - determine if a variable in this object's namespace is set
  325. *
  326. * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace
  327. * @return bool
  328. */
  329. public function __isset($name)
  330. {
  331. if ($name === '') {
  332. /**
  333. * @see Zend_Session_Exception
  334. */
  335. #require_once 'Zend/Session/Exception.php';
  336. throw new Zend_Session_Exception("The '$name' key must be a non-empty string");
  337. }
  338. return parent::_namespaceIsset($this->_namespace, $name);
  339. }
  340. /**
  341. * __unset() - unset a variable in this object's namespace.
  342. *
  343. * @param string $name - programmatic name of a key, in a <key,value> pair in the current namespace
  344. * @return true
  345. */
  346. public function __unset($name)
  347. {
  348. if ($name === '') {
  349. /**
  350. * @see Zend_Session_Exception
  351. */
  352. #require_once 'Zend/Session/Exception.php';
  353. throw new Zend_Session_Exception("The '$name' key must be a non-empty string");
  354. }
  355. return parent::_namespaceUnset($this->_namespace, $name);
  356. }
  357. /**
  358. * setExpirationSeconds() - expire the namespace, or specific variables after a specified
  359. * number of seconds
  360. *
  361. * @param int $seconds - expires in this many seconds
  362. * @param mixed $variables - OPTIONAL list of variables to expire (defaults to all)
  363. * @throws Zend_Session_Exception
  364. * @return void
  365. */
  366. public function setExpirationSeconds($seconds, $variables = null)
  367. {
  368. if (parent::$_writable === false) {
  369. /**
  370. * @see Zend_Session_Exception
  371. */
  372. #require_once 'Zend/Session/Exception.php';
  373. throw new Zend_Session_Exception(parent::_THROW_NOT_WRITABLE_MSG);
  374. }
  375. if ($seconds <= 0) {
  376. /**
  377. * @see Zend_Session_Exception
  378. */
  379. #require_once 'Zend/Session/Exception.php';
  380. throw new Zend_Session_Exception('Seconds must be positive.');
  381. }
  382. if ($variables === null) {
  383. // apply expiration to entire namespace
  384. $_SESSION['__ZF'][$this->_namespace]['ENT'] = time() + $seconds;
  385. } else {
  386. if (is_string($variables)) {
  387. $variables = array($variables);
  388. }
  389. foreach ($variables as $variable) {
  390. if (!empty($variable)) {
  391. $_SESSION['__ZF'][$this->_namespace]['ENVT'][$variable] = time() + $seconds;
  392. }
  393. }
  394. }
  395. }
  396. /**
  397. * setExpirationHops() - expire the namespace, or specific variables after a specified
  398. * number of page hops
  399. *
  400. * @param int $hops - how many "hops" (number of subsequent requests) before expiring
  401. * @param mixed $variables - OPTIONAL list of variables to expire (defaults to all)
  402. * @param boolean $hopCountOnUsageOnly - OPTIONAL if set, only count a hop/request if this namespace is used
  403. * @throws Zend_Session_Exception
  404. * @return void
  405. */
  406. public function setExpirationHops($hops, $variables = null, $hopCountOnUsageOnly = false)
  407. {
  408. if (parent::$_writable === false) {
  409. /**
  410. * @see Zend_Session_Exception
  411. */
  412. #require_once 'Zend/Session/Exception.php';
  413. throw new Zend_Session_Exception(parent::_THROW_NOT_WRITABLE_MSG);
  414. }
  415. if ($hops <= 0) {
  416. /**
  417. * @see Zend_Session_Exception
  418. */
  419. #require_once 'Zend/Session/Exception.php';
  420. throw new Zend_Session_Exception('Hops must be positive number.');
  421. }
  422. if ($variables === null) {
  423. // apply expiration to entire namespace
  424. if ($hopCountOnUsageOnly === false) {
  425. $_SESSION['__ZF'][$this->_namespace]['ENGH'] = $hops;
  426. } else {
  427. $_SESSION['__ZF'][$this->_namespace]['ENNH'] = $hops;
  428. }
  429. } else {
  430. if (is_string($variables)) {
  431. $variables = array($variables);
  432. }
  433. foreach ($variables as $variable) {
  434. if (!empty($variable)) {
  435. if ($hopCountOnUsageOnly === false) {
  436. $_SESSION['__ZF'][$this->_namespace]['ENVGH'][$variable] = $hops;
  437. } else {
  438. $_SESSION['__ZF'][$this->_namespace]['ENVNH'][$variable] = $hops;
  439. }
  440. }
  441. }
  442. }
  443. }
  444. /**
  445. * Returns the namespace name
  446. *
  447. * @return string
  448. */
  449. public function getNamespace()
  450. {
  451. return $this->_namespace;
  452. }
  453. }