PageRenderTime 106ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/app/classes/Zend/Session/Storage/AbstractSessionArrayStorage.php

https://gitlab.com/jalon/doadoronline
PHP | 487 lines | 236 code | 58 blank | 193 comment | 38 complexity | b20cdba996c644ee58ccf64a18c4374d MD5 | raw file
  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 ArrayIterator;
  11. use IteratorAggregate;
  12. use Zend\Session\Exception;
  13. /**
  14. * Session storage in $_SESSION
  15. *
  16. * Replaces the $_SESSION superglobal with an ArrayObject that allows for
  17. * property access, metadata storage, locking, and immutability.
  18. */
  19. abstract class AbstractSessionArrayStorage implements
  20. IteratorAggregate,
  21. StorageInterface,
  22. StorageInitializationInterface
  23. {
  24. /**
  25. * Constructor
  26. *
  27. * @param array|null $input
  28. */
  29. public function __construct($input = null)
  30. {
  31. // this is here for B.C.
  32. $this->init($input);
  33. }
  34. /**
  35. * Initialize Storage
  36. *
  37. * @param array $input
  38. * @return void
  39. */
  40. public function init($input = null)
  41. {
  42. if ((null === $input) && isset($_SESSION)) {
  43. $input = $_SESSION;
  44. if (is_object($input) && !$_SESSION instanceof \ArrayObject) {
  45. $input = (array) $input;
  46. }
  47. } elseif (null === $input) {
  48. $input = array();
  49. }
  50. $_SESSION = $input;
  51. $this->setRequestAccessTime(microtime(true));
  52. }
  53. /**
  54. * Get Offset
  55. *
  56. * @param mixed $key
  57. * @return mixed
  58. */
  59. public function __get($key)
  60. {
  61. return $this->offsetGet($key);
  62. }
  63. /**
  64. * Set Offset
  65. *
  66. * @param mixed $key
  67. * @param mixed $value
  68. * @return void
  69. */
  70. public function __set($key, $value)
  71. {
  72. return $this->offsetSet($key, $value);
  73. }
  74. /**
  75. * Isset Offset
  76. *
  77. * @param mixed $key
  78. * @return bool
  79. */
  80. public function __isset($key)
  81. {
  82. return $this->offsetExists($key);
  83. }
  84. /**
  85. * Unset Offset
  86. *
  87. * @param mixed $key
  88. * @return void
  89. */
  90. public function __unset($key)
  91. {
  92. return $this->offsetUnset($key);
  93. }
  94. /**
  95. * Destructor
  96. *
  97. * @return void
  98. */
  99. public function __destruct()
  100. {
  101. return ;
  102. }
  103. /**
  104. * Offset Exists
  105. *
  106. * @param mixed $key
  107. * @return bool
  108. */
  109. public function offsetExists($key)
  110. {
  111. return isset($_SESSION[$key]);
  112. }
  113. /**
  114. * Offset Get
  115. *
  116. * @param mixed $key
  117. * @return mixed
  118. */
  119. public function offsetGet($key)
  120. {
  121. if (isset($_SESSION[$key])) {
  122. return $_SESSION[$key];
  123. }
  124. return null;
  125. }
  126. /**
  127. * Offset Set
  128. *
  129. * @param mixed $key
  130. * @param mixed $value
  131. * @return void
  132. */
  133. public function offsetSet($key, $value)
  134. {
  135. $_SESSION[$key] = $value;
  136. }
  137. /**
  138. * Offset Unset
  139. *
  140. * @param mixed $key
  141. * @return void
  142. */
  143. public function offsetUnset($key)
  144. {
  145. unset($_SESSION[$key]);
  146. }
  147. /**
  148. * Count
  149. *
  150. * @return int
  151. */
  152. public function count()
  153. {
  154. return count($_SESSION);
  155. }
  156. /**
  157. * Seralize
  158. *
  159. * @return string
  160. */
  161. public function serialize()
  162. {
  163. return serialize($_SESSION);
  164. }
  165. /**
  166. * Unserialize
  167. *
  168. * @param string $session
  169. * @return mixed
  170. */
  171. public function unserialize($session)
  172. {
  173. return unserialize($session);
  174. }
  175. /**
  176. * Get Iterator
  177. *
  178. * @return ArrayIterator
  179. */
  180. public function getIterator()
  181. {
  182. return new ArrayIterator($_SESSION);
  183. }
  184. /**
  185. * Load session object from an existing array
  186. *
  187. * Ensures $_SESSION is set to an instance of the object when complete.
  188. *
  189. * @param array $array
  190. * @return SessionStorage
  191. */
  192. public function fromArray(array $array)
  193. {
  194. $ts = $this->getRequestAccessTime();
  195. $_SESSION = $array;
  196. $this->setRequestAccessTime($ts);
  197. return $this;
  198. }
  199. /**
  200. * Mark object as isImmutable
  201. *
  202. * @return SessionStorage
  203. */
  204. public function markImmutable()
  205. {
  206. $_SESSION['_IMMUTABLE'] = true;
  207. return $this;
  208. }
  209. /**
  210. * Determine if this object is isImmutable
  211. *
  212. * @return bool
  213. */
  214. public function isImmutable()
  215. {
  216. return (isset($_SESSION['_IMMUTABLE']) && $_SESSION['_IMMUTABLE']);
  217. }
  218. /**
  219. * Lock this storage instance, or a key within it
  220. *
  221. * @param null|int|string $key
  222. * @return ArrayStorage
  223. */
  224. public function lock($key = null)
  225. {
  226. if (null === $key) {
  227. $this->setMetadata('_READONLY', true);
  228. return $this;
  229. }
  230. if (isset($_SESSION[$key])) {
  231. $this->setMetadata('_LOCKS', array($key => true));
  232. }
  233. return $this;
  234. }
  235. /**
  236. * Is the object or key marked as locked?
  237. *
  238. * @param null|int|string $key
  239. * @return bool
  240. */
  241. public function isLocked($key = null)
  242. {
  243. if ($this->isImmutable()) {
  244. // isImmutable trumps all
  245. return true;
  246. }
  247. if (null === $key) {
  248. // testing for global lock
  249. return $this->getMetadata('_READONLY');
  250. }
  251. $locks = $this->getMetadata('_LOCKS');
  252. $readOnly = $this->getMetadata('_READONLY');
  253. if ($readOnly && !$locks) {
  254. // global lock in play; all keys are locked
  255. return true;
  256. }
  257. if ($readOnly && $locks) {
  258. return array_key_exists($key, $locks);
  259. }
  260. // test for individual locks
  261. if (!$locks) {
  262. return false;
  263. }
  264. return array_key_exists($key, $locks);
  265. }
  266. /**
  267. * Unlock an object or key marked as locked
  268. *
  269. * @param null|int|string $key
  270. * @return ArrayStorage
  271. */
  272. public function unlock($key = null)
  273. {
  274. if (null === $key) {
  275. // Unlock everything
  276. $this->setMetadata('_READONLY', false);
  277. $this->setMetadata('_LOCKS', false);
  278. return $this;
  279. }
  280. $locks = $this->getMetadata('_LOCKS');
  281. if (!$locks) {
  282. if (!$this->getMetadata('_READONLY')) {
  283. return $this;
  284. }
  285. $array = $this->toArray();
  286. $keys = array_keys($array);
  287. $locks = array_flip($keys);
  288. unset($array, $keys);
  289. }
  290. if (array_key_exists($key, $locks)) {
  291. unset($locks[$key]);
  292. $this->setMetadata('_LOCKS', $locks, true);
  293. }
  294. return $this;
  295. }
  296. /**
  297. * Set storage metadata
  298. *
  299. * Metadata is used to store information about the data being stored in the
  300. * object. Some example use cases include:
  301. * - Setting expiry data
  302. * - Maintaining access counts
  303. * - localizing session storage
  304. * - etc.
  305. *
  306. * @param string $key
  307. * @param mixed $value
  308. * @param bool $overwriteArray Whether to overwrite or merge array values; by default, merges
  309. * @return ArrayStorage
  310. * @throws Exception\RuntimeException
  311. */
  312. public function setMetadata($key, $value, $overwriteArray = false)
  313. {
  314. if ($this->isImmutable()) {
  315. throw new Exception\RuntimeException(sprintf(
  316. 'Cannot set key "%s" as storage is marked isImmutable', $key
  317. ));
  318. }
  319. if (!isset($_SESSION['__ZF'])) {
  320. $_SESSION['__ZF'] = array();
  321. }
  322. if (isset($_SESSION['__ZF'][$key]) && is_array($value)) {
  323. if ($overwriteArray) {
  324. $_SESSION['__ZF'][$key] = $value;
  325. } else {
  326. $_SESSION['__ZF'][$key] = array_replace_recursive($_SESSION['__ZF'][$key], $value);
  327. }
  328. } else {
  329. if ((null === $value) && isset($_SESSION['__ZF'][$key])) {
  330. $array = $_SESSION['__ZF'];
  331. unset($array[$key]);
  332. $_SESSION['__ZF'] = $array;
  333. unset($array);
  334. } elseif (null !== $value) {
  335. $_SESSION['__ZF'][$key] = $value;
  336. }
  337. }
  338. return $this;
  339. }
  340. /**
  341. * Retrieve metadata for the storage object or a specific metadata key
  342. *
  343. * Returns false if no metadata stored, or no metadata exists for the given
  344. * key.
  345. *
  346. * @param null|int|string $key
  347. * @return mixed
  348. */
  349. public function getMetadata($key = null)
  350. {
  351. if (!isset($_SESSION['__ZF'])) {
  352. return false;
  353. }
  354. if (null === $key) {
  355. return $_SESSION['__ZF'];
  356. }
  357. if (!array_key_exists($key, $_SESSION['__ZF'])) {
  358. return false;
  359. }
  360. return $_SESSION['__ZF'][$key];
  361. }
  362. /**
  363. * Clear the storage object or a subkey of the object
  364. *
  365. * @param null|int|string $key
  366. * @return ArrayStorage
  367. * @throws Exception\RuntimeException
  368. */
  369. public function clear($key = null)
  370. {
  371. if ($this->isImmutable()) {
  372. throw new Exception\RuntimeException('Cannot clear storage as it is marked immutable');
  373. }
  374. if (null === $key) {
  375. $this->fromArray(array());
  376. return $this;
  377. }
  378. if (!isset($_SESSION[$key])) {
  379. return $this;
  380. }
  381. // Clear key data
  382. unset($_SESSION[$key]);
  383. // Clear key metadata
  384. $this->setMetadata($key, null)
  385. ->unlock($key);
  386. return $this;
  387. }
  388. /**
  389. * Retrieve the request access time
  390. *
  391. * @return float
  392. */
  393. public function getRequestAccessTime()
  394. {
  395. return $this->getMetadata('_REQUEST_ACCESS_TIME');
  396. }
  397. /**
  398. * Set the request access time
  399. *
  400. * @param float $time
  401. * @return ArrayStorage
  402. */
  403. protected function setRequestAccessTime($time)
  404. {
  405. $this->setMetadata('_REQUEST_ACCESS_TIME', $time);
  406. return $this;
  407. }
  408. /**
  409. * Cast the object to an array
  410. *
  411. * @param bool $metaData Whether to include metadata
  412. * @return array
  413. */
  414. public function toArray($metaData = false)
  415. {
  416. if (isset($_SESSION)) {
  417. $values = $_SESSION;
  418. } else {
  419. $values = array();
  420. }
  421. if ($metaData) {
  422. return $values;
  423. }
  424. if (isset($values['__ZF'])) {
  425. unset($values['__ZF']);
  426. }
  427. return $values;
  428. }
  429. }