PageRenderTime 23ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/monica/monica/vendor/zendframework/zendframework/library/Zend/Session/Storage/ArrayStorage.php

https://bitbucket.org/alexandretaz/maniac_divers
PHP | 348 lines | 175 code | 35 blank | 138 comment | 30 complexity | 33325cb00f19a53436c2f7892f70492a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Session\Storage;
  10. use ArrayObject;
  11. use Zend\Session\Exception;
  12. /**
  13. * Array session storage
  14. *
  15. * Defines an ArrayObject interface for accessing session storage, with options
  16. * for setting metadata, locking, and marking as isImmutable.
  17. */
  18. class ArrayStorage extends ArrayObject implements StorageInterface
  19. {
  20. /**
  21. * Is storage marked isImmutable?
  22. * @var bool
  23. */
  24. protected $isImmutable = false;
  25. /**
  26. * Constructor
  27. *
  28. * Instantiates storage as an ArrayObject, allowing property access.
  29. * Also sets the initial request access time.
  30. *
  31. * @param array $input
  32. * @param int $flags
  33. * @param string $iteratorClass
  34. */
  35. public function __construct(
  36. $input = array(),
  37. $flags = ArrayObject::ARRAY_AS_PROPS,
  38. $iteratorClass = '\\ArrayIterator'
  39. ) {
  40. parent::__construct($input, $flags, $iteratorClass);
  41. $this->setRequestAccessTime(microtime(true));
  42. }
  43. /**
  44. * Set the request access time
  45. *
  46. * @param float $time
  47. * @return ArrayStorage
  48. */
  49. protected function setRequestAccessTime($time)
  50. {
  51. $this->setMetadata('_REQUEST_ACCESS_TIME', $time);
  52. return $this;
  53. }
  54. /**
  55. * Retrieve the request access time
  56. *
  57. * @return float
  58. */
  59. public function getRequestAccessTime()
  60. {
  61. return $this->getMetadata('_REQUEST_ACCESS_TIME');
  62. }
  63. /**
  64. * Set a value in the storage object
  65. *
  66. * If the object is marked as isImmutable, or the object or key is marked as
  67. * locked, raises an exception.
  68. *
  69. * @param string $key
  70. * @param mixed $value
  71. * @return void
  72. */
  73. /**
  74. * @param mixed $key
  75. * @param mixed $value
  76. * @throws Exception\RuntimeException
  77. */
  78. public function offsetSet($key, $value)
  79. {
  80. if ($this->isImmutable()) {
  81. throw new Exception\RuntimeException(sprintf(
  82. 'Cannot set key "%s" as storage is marked isImmutable', $key
  83. ));
  84. }
  85. if ($this->isLocked($key)) {
  86. throw new Exception\RuntimeException(sprintf(
  87. 'Cannot set key "%s" due to locking', $key
  88. ));
  89. }
  90. parent::offsetSet($key, $value);
  91. }
  92. /**
  93. * Lock this storage instance, or a key within it
  94. *
  95. * @param null|int|string $key
  96. * @return ArrayStorage
  97. */
  98. public function lock($key = null)
  99. {
  100. if (null === $key) {
  101. $this->setMetadata('_READONLY', true);
  102. return $this;
  103. }
  104. if (isset($this[$key])) {
  105. $this->setMetadata('_LOCKS', array($key => true));
  106. }
  107. return $this;
  108. }
  109. /**
  110. * Is the object or key marked as locked?
  111. *
  112. * @param null|int|string $key
  113. * @return bool
  114. */
  115. public function isLocked($key = null)
  116. {
  117. if ($this->isImmutable()) {
  118. // isImmutable trumps all
  119. return true;
  120. }
  121. if (null === $key) {
  122. // testing for global lock
  123. return $this->getMetadata('_READONLY');
  124. }
  125. $locks = $this->getMetadata('_LOCKS');
  126. $readOnly = $this->getMetadata('_READONLY');
  127. if ($readOnly && !$locks) {
  128. // global lock in play; all keys are locked
  129. return true;
  130. } elseif ($readOnly && $locks) {
  131. return array_key_exists($key, $locks);
  132. }
  133. // test for individual locks
  134. if (!$locks) {
  135. return false;
  136. }
  137. return array_key_exists($key, $locks);
  138. }
  139. /**
  140. * Unlock an object or key marked as locked
  141. *
  142. * @param null|int|string $key
  143. * @return ArrayStorage
  144. */
  145. public function unlock($key = null)
  146. {
  147. if (null === $key) {
  148. // Unlock everything
  149. $this->setMetadata('_READONLY', false);
  150. $this->setMetadata('_LOCKS', false);
  151. return $this;
  152. }
  153. $locks = $this->getMetadata('_LOCKS');
  154. if (!$locks) {
  155. if (!$this->getMetadata('_READONLY')) {
  156. return $this;
  157. }
  158. $array = $this->toArray();
  159. $keys = array_keys($array);
  160. $locks = array_flip($keys);
  161. unset($array, $keys);
  162. }
  163. if (array_key_exists($key, $locks)) {
  164. unset($locks[$key]);
  165. $this->setMetadata('_LOCKS', $locks, true);
  166. }
  167. return $this;
  168. }
  169. /**
  170. * Mark the storage container as isImmutable
  171. *
  172. * @return ArrayStorage
  173. */
  174. public function markImmutable()
  175. {
  176. $this->isImmutable = true;
  177. return $this;
  178. }
  179. /**
  180. * Is the storage container marked as isImmutable?
  181. *
  182. * @return bool
  183. */
  184. public function isImmutable()
  185. {
  186. return $this->isImmutable;
  187. }
  188. /**
  189. * Set storage metadata
  190. *
  191. * Metadata is used to store information about the data being stored in the
  192. * object. Some example use cases include:
  193. * - Setting expiry data
  194. * - Maintaining access counts
  195. * - localizing session storage
  196. * - etc.
  197. *
  198. * @param string $key
  199. * @param mixed $value
  200. * @param bool $overwriteArray Whether to overwrite or merge array values; by default, merges
  201. * @return ArrayStorage
  202. * @throws Exception\RuntimeException
  203. */
  204. public function setMetadata($key, $value, $overwriteArray = false)
  205. {
  206. if ($this->isImmutable) {
  207. throw new Exception\RuntimeException(sprintf(
  208. 'Cannot set key "%s" as storage is marked isImmutable', $key
  209. ));
  210. }
  211. if (!isset($this['__ZF'])) {
  212. $this['__ZF'] = array();
  213. }
  214. if (isset($this['__ZF'][$key]) && is_array($value)) {
  215. if ($overwriteArray) {
  216. $this['__ZF'][$key] = $value;
  217. } else {
  218. $this['__ZF'][$key] = array_replace_recursive($this['__ZF'][$key], $value);
  219. }
  220. } else {
  221. if ((null === $value) && isset($this['__ZF'][$key])) {
  222. // unset($this['__ZF'][$key]) led to "indirect modification...
  223. // has no effect" errors, so explicitly pulling array and
  224. // unsetting key.
  225. $array = $this['__ZF'];
  226. unset($array[$key]);
  227. $this['__ZF'] = $array;
  228. unset($array);
  229. } elseif (null !== $value) {
  230. $this['__ZF'][$key] = $value;
  231. }
  232. }
  233. return $this;
  234. }
  235. /**
  236. * Retrieve metadata for the storage object or a specific metadata key
  237. *
  238. * Returns false if no metadata stored, or no metadata exists for the given
  239. * key.
  240. *
  241. * @param null|int|string $key
  242. * @return mixed
  243. */
  244. public function getMetadata($key = null)
  245. {
  246. if (!isset($this['__ZF'])) {
  247. return false;
  248. }
  249. if (null === $key) {
  250. return $this['__ZF'];
  251. }
  252. if (!array_key_exists($key, $this['__ZF'])) {
  253. return false;
  254. }
  255. return $this['__ZF'][$key];
  256. }
  257. /**
  258. * Clear the storage object or a subkey of the object
  259. *
  260. * @param null|int|string $key
  261. * @return ArrayStorage
  262. * @throws Exception\RuntimeException
  263. */
  264. public function clear($key = null)
  265. {
  266. if ($this->isImmutable()) {
  267. throw new Exception\RuntimeException('Cannot clear storage as it is marked immutable');
  268. }
  269. if (null === $key) {
  270. $this->fromArray(array());
  271. return $this;
  272. }
  273. if (!isset($this[$key])) {
  274. return $this;
  275. }
  276. // Clear key data
  277. unset($this[$key]);
  278. // Clear key metadata
  279. $this->setMetadata($key, null)
  280. ->unlock($key);
  281. return $this;
  282. }
  283. /**
  284. * Load the storage from another array
  285. *
  286. * Overwrites any data that was previously set.
  287. *
  288. * @param array $array
  289. * @return ArrayStorage
  290. */
  291. public function fromArray(array $array)
  292. {
  293. $ts = $this->getRequestAccessTime();
  294. $this->exchangeArray($array);
  295. $this->setRequestAccessTime($ts);
  296. return $this;
  297. }
  298. /**
  299. * Cast the object to an array
  300. *
  301. * Returns data only, no metadata.
  302. *
  303. * @return array
  304. */
  305. public function toArray()
  306. {
  307. $values = $this->getArrayCopy();
  308. if (isset($values['__ZF'])) {
  309. unset($values['__ZF']);
  310. }
  311. return $values;
  312. }
  313. }