PageRenderTime 63ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Session/Store.php

https://gitlab.com/techniconline/kmc
PHP | 672 lines | 281 code | 93 blank | 298 comment | 9 complexity | 32413357714984eea64785ad4644ab1c MD5 | raw file
  1. <?php namespace Illuminate\Session;
  2. use SessionHandlerInterface;
  3. use InvalidArgumentException;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
  6. use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
  7. class Store implements SessionInterface
  8. {
  9. /**
  10. * The session ID.
  11. *
  12. * @var string
  13. */
  14. protected $id;
  15. /**
  16. * The session name.
  17. *
  18. * @var string
  19. */
  20. protected $name;
  21. /**
  22. * The session attributes.
  23. *
  24. * @var array
  25. */
  26. protected $attributes = array();
  27. /**
  28. * The session bags.
  29. *
  30. * @var array
  31. */
  32. protected $bags = array();
  33. /**
  34. * The meta-data bag instance.
  35. *
  36. * @var \Symfony\Component\HttpFoundation\Session\Storage\MetadataBag
  37. */
  38. protected $metaBag;
  39. /**
  40. * Local copies of the session bag data.
  41. *
  42. * @var array
  43. */
  44. protected $bagData = array();
  45. /**
  46. * The session handler implementation.
  47. *
  48. * @var \SessionHandlerInterface
  49. */
  50. protected $handler;
  51. /**
  52. * Session store started status.
  53. *
  54. * @var bool
  55. */
  56. protected $started = false;
  57. /**
  58. * Create a new session instance.
  59. *
  60. * @param string $name
  61. * @param \SessionHandlerInterface $handler
  62. * @param string|null $id
  63. * @return void
  64. */
  65. public function __construct($name, SessionHandlerInterface $handler, $id = null)
  66. {
  67. $this->setId($id);
  68. $this->name = $name;
  69. $this->handler = $handler;
  70. $this->metaBag = new MetadataBag;
  71. }
  72. /**
  73. * {@inheritdoc}
  74. */
  75. public function start()
  76. {
  77. $this->loadSession();
  78. if (!$this->has('_token')) $this->regenerateToken();
  79. return $this->started = true;
  80. }
  81. /**
  82. * Load the session data from the handler.
  83. *
  84. * @return void
  85. */
  86. protected function loadSession()
  87. {
  88. $this->attributes = array_merge($this->attributes, $this->readFromHandler());
  89. foreach (array_merge($this->bags, array($this->metaBag)) as $bag) {
  90. $this->initializeLocalBag($bag);
  91. $bag->initialize($this->bagData[$bag->getStorageKey()]);
  92. }
  93. }
  94. /**
  95. * Read the session data from the handler.
  96. *
  97. * @return array
  98. */
  99. protected function readFromHandler()
  100. {
  101. $data = $this->handler->read($this->getId());
  102. if ($data) {
  103. $data = @unserialize($this->prepareForUnserialize($data));
  104. if ($data !== false) return $data;
  105. }
  106. return [];
  107. }
  108. /**
  109. * Prepare the raw string data from the session for unserialization.
  110. *
  111. * @param string $data
  112. * @return string
  113. */
  114. protected function prepareForUnserialize($data)
  115. {
  116. return $data;
  117. }
  118. /**
  119. * Initialize a bag in storage if it doesn't exist.
  120. *
  121. * @param \Symfony\Component\HttpFoundation\Session\SessionBagInterface $bag
  122. * @return void
  123. */
  124. protected function initializeLocalBag($bag)
  125. {
  126. $this->bagData[$bag->getStorageKey()] = $this->pull($bag->getStorageKey(), []);
  127. }
  128. /**
  129. * {@inheritdoc}
  130. */
  131. public function getId()
  132. {
  133. return $this->id;
  134. }
  135. /**
  136. * {@inheritdoc}
  137. */
  138. public function setId($id)
  139. {
  140. if (!$this->isValidId($id)) {
  141. $id = $this->generateSessionId();
  142. }
  143. $this->id = $id;
  144. }
  145. /**
  146. * Determine if this is a valid session ID.
  147. *
  148. * @param string $id
  149. * @return bool
  150. */
  151. public function isValidId($id)
  152. {
  153. return is_string($id) && preg_match('/^[a-f0-9]{40}$/', $id);
  154. }
  155. /**
  156. * Get a new, random session ID.
  157. *
  158. * @return string
  159. */
  160. protected function generateSessionId()
  161. {
  162. return sha1(uniqid('', true) . str_random(25) . microtime(true));
  163. }
  164. /**
  165. * {@inheritdoc}
  166. */
  167. public function getName()
  168. {
  169. return $this->name;
  170. }
  171. /**
  172. * {@inheritdoc}
  173. */
  174. public function setName($name)
  175. {
  176. $this->name = $name;
  177. }
  178. /**
  179. * {@inheritdoc}
  180. */
  181. public function invalidate($lifetime = null)
  182. {
  183. $this->clear();
  184. return $this->migrate(true, $lifetime);
  185. }
  186. /**
  187. * {@inheritdoc}
  188. */
  189. public function migrate($destroy = false, $lifetime = null)
  190. {
  191. if ($destroy) $this->handler->destroy($this->getId());
  192. $this->setExists(false);
  193. $this->id = $this->generateSessionId();
  194. return true;
  195. }
  196. /**
  197. * Generate a new session identifier.
  198. *
  199. * @param bool $destroy
  200. * @return bool
  201. */
  202. public function regenerate($destroy = false)
  203. {
  204. return $this->migrate($destroy);
  205. }
  206. /**
  207. * {@inheritdoc}
  208. */
  209. public function save()
  210. {
  211. $this->addBagDataToSession();
  212. $this->ageFlashData();
  213. $this->handler->write($this->getId(), $this->prepareForStorage(serialize($this->attributes)));
  214. $this->started = false;
  215. }
  216. /**
  217. * Prepare the serialized session data for storage.
  218. *
  219. * @param string $data
  220. * @return string
  221. */
  222. protected function prepareForStorage($data)
  223. {
  224. return $data;
  225. }
  226. /**
  227. * Merge all of the bag data into the session.
  228. *
  229. * @return void
  230. */
  231. protected function addBagDataToSession()
  232. {
  233. foreach (array_merge($this->bags, array($this->metaBag)) as $bag) {
  234. $this->put($bag->getStorageKey(), $this->bagData[$bag->getStorageKey()]);
  235. }
  236. }
  237. /**
  238. * Age the flash data for the session.
  239. *
  240. * @return void
  241. */
  242. public function ageFlashData()
  243. {
  244. foreach ($this->get('flash.old', array()) as $old) {
  245. $this->forget($old);
  246. }
  247. $this->put('flash.old', $this->get('flash.new', array()));
  248. $this->put('flash.new', array());
  249. }
  250. /**
  251. * {@inheritdoc}
  252. */
  253. public function has($name)
  254. {
  255. return !is_null($this->get($name));
  256. }
  257. /**
  258. * {@inheritdoc}
  259. */
  260. public function get($name, $default = null)
  261. {
  262. return array_get($this->attributes, $name, $default);
  263. }
  264. /**
  265. * Get the value of a given key and then forget it.
  266. *
  267. * @param string $key
  268. * @param string $default
  269. * @return mixed
  270. */
  271. public function pull($key, $default = null)
  272. {
  273. return array_pull($this->attributes, $key, $default);
  274. }
  275. /**
  276. * Determine if the session contains old input.
  277. *
  278. * @param string $key
  279. * @return bool
  280. */
  281. public function hasOldInput($key = null)
  282. {
  283. $old = $this->getOldInput($key);
  284. return is_null($key) ? count($old) > 0 : !is_null($old);
  285. }
  286. /**
  287. * Get the requested item from the flashed input array.
  288. *
  289. * @param string $key
  290. * @param mixed $default
  291. * @return mixed
  292. */
  293. public function getOldInput($key = null, $default = null)
  294. {
  295. $input = $this->get('_old_input', array());
  296. // Input that is flashed to the session can be easily retrieved by the
  297. // developer, making repopulating old forms and the like much more
  298. // convenient, since the request's previous input is available.
  299. return array_get($input, $key, $default);
  300. }
  301. /**
  302. * {@inheritdoc}
  303. */
  304. public function set($name, $value)
  305. {
  306. array_set($this->attributes, $name, $value);
  307. }
  308. /**
  309. * Put a key / value pair or array of key / value pairs in the session.
  310. *
  311. * @param string|array $key
  312. * @param mixed|null $value
  313. * @return void
  314. */
  315. public function put($key, $value = null)
  316. {
  317. if (!is_array($key)) $key = array($key => $value);
  318. foreach ($key as $arrayKey => $arrayValue) {
  319. $this->set($arrayKey, $arrayValue);
  320. }
  321. }
  322. /**
  323. * Push a value onto a session array.
  324. *
  325. * @param string $key
  326. * @param mixed $value
  327. * @return void
  328. */
  329. public function push($key, $value)
  330. {
  331. $array = $this->get($key, array());
  332. $array[] = $value;
  333. $this->put($key, $array);
  334. }
  335. /**
  336. * Flash a key / value pair to the session.
  337. *
  338. * @param string $key
  339. * @param mixed $value
  340. * @return void
  341. */
  342. public function flash($key, $value)
  343. {
  344. $this->put($key, $value);
  345. $this->push('flash.new', $key);
  346. $this->removeFromOldFlashData(array($key));
  347. }
  348. /**
  349. * Flash an input array to the session.
  350. *
  351. * @param array $value
  352. * @return void
  353. */
  354. public function flashInput(array $value)
  355. {
  356. $this->flash('_old_input', $value);
  357. }
  358. /**
  359. * Reflash all of the session flash data.
  360. *
  361. * @return void
  362. */
  363. public function reflash()
  364. {
  365. $this->mergeNewFlashes($this->get('flash.old', array()));
  366. $this->put('flash.old', array());
  367. }
  368. /**
  369. * Reflash a subset of the current flash data.
  370. *
  371. * @param array|mixed $keys
  372. * @return void
  373. */
  374. public function keep($keys = null)
  375. {
  376. $keys = is_array($keys) ? $keys : func_get_args();
  377. $this->mergeNewFlashes($keys);
  378. $this->removeFromOldFlashData($keys);
  379. }
  380. /**
  381. * Merge new flash keys into the new flash array.
  382. *
  383. * @param array $keys
  384. * @return void
  385. */
  386. protected function mergeNewFlashes(array $keys)
  387. {
  388. $values = array_unique(array_merge($this->get('flash.new', array()), $keys));
  389. $this->put('flash.new', $values);
  390. }
  391. /**
  392. * Remove the given keys from the old flash data.
  393. *
  394. * @param array $keys
  395. * @return void
  396. */
  397. protected function removeFromOldFlashData(array $keys)
  398. {
  399. $this->put('flash.old', array_diff($this->get('flash.old', array()), $keys));
  400. }
  401. /**
  402. * {@inheritdoc}
  403. */
  404. public function all()
  405. {
  406. return $this->attributes;
  407. }
  408. /**
  409. * {@inheritdoc}
  410. */
  411. public function replace(array $attributes)
  412. {
  413. $this->put($attributes);
  414. }
  415. /**
  416. * {@inheritdoc}
  417. */
  418. public function remove($name)
  419. {
  420. return array_pull($this->attributes, $name);
  421. }
  422. /**
  423. * Remove an item from the session.
  424. *
  425. * @param string $key
  426. * @return void
  427. */
  428. public function forget($key)
  429. {
  430. array_forget($this->attributes, $key);
  431. }
  432. /**
  433. * {@inheritdoc}
  434. */
  435. public function clear()
  436. {
  437. $this->attributes = array();
  438. foreach ($this->bags as $bag) {
  439. $bag->clear();
  440. }
  441. }
  442. /**
  443. * Remove all of the items from the session.
  444. *
  445. * @return void
  446. */
  447. public function flush()
  448. {
  449. $this->clear();
  450. }
  451. /**
  452. * {@inheritdoc}
  453. */
  454. public function isStarted()
  455. {
  456. return $this->started;
  457. }
  458. /**
  459. * {@inheritdoc}
  460. */
  461. public function registerBag(SessionBagInterface $bag)
  462. {
  463. $this->bags[$bag->getStorageKey()] = $bag;
  464. }
  465. /**
  466. * {@inheritdoc}
  467. */
  468. public function getBag($name)
  469. {
  470. return array_get($this->bags, $name, function () {
  471. throw new InvalidArgumentException("Bag not registered.");
  472. });
  473. }
  474. /**
  475. * {@inheritdoc}
  476. */
  477. public function getMetadataBag()
  478. {
  479. return $this->metaBag;
  480. }
  481. /**
  482. * Get the raw bag data array for a given bag.
  483. *
  484. * @param string $name
  485. * @return array
  486. */
  487. public function getBagData($name)
  488. {
  489. return array_get($this->bagData, $name, array());
  490. }
  491. /**
  492. * Get the CSRF token value.
  493. *
  494. * @return string
  495. */
  496. public function token()
  497. {
  498. return $this->get('_token');
  499. }
  500. /**
  501. * Get the CSRF token value.
  502. *
  503. * @return string
  504. */
  505. public function getToken()
  506. {
  507. return $this->token();
  508. }
  509. /**
  510. * Regenerate the CSRF token value.
  511. *
  512. * @return void
  513. */
  514. public function regenerateToken()
  515. {
  516. $this->put('_token', str_random(40));
  517. }
  518. /**
  519. * Get the previous URL from the session.
  520. *
  521. * @return string|null
  522. */
  523. public function previousUrl()
  524. {
  525. return $this->get('_previous.url');
  526. }
  527. /**
  528. * Set the "previous" URL in the session.
  529. *
  530. * @param string $url
  531. * @return void
  532. */
  533. public function setPreviousUrl($url)
  534. {
  535. return $this->put('_previous.url', $url);
  536. }
  537. /**
  538. * Set the existence of the session on the handler if applicable.
  539. *
  540. * @param bool $value
  541. * @return void
  542. */
  543. public function setExists($value)
  544. {
  545. if ($this->handler instanceof ExistenceAwareInterface) {
  546. $this->handler->setExists($value);
  547. }
  548. }
  549. /**
  550. * Get the underlying session handler implementation.
  551. *
  552. * @return \SessionHandlerInterface
  553. */
  554. public function getHandler()
  555. {
  556. return $this->handler;
  557. }
  558. /**
  559. * Determine if the session handler needs a request.
  560. *
  561. * @return bool
  562. */
  563. public function handlerNeedsRequest()
  564. {
  565. return $this->handler instanceof CookieSessionHandler;
  566. }
  567. /**
  568. * Set the request on the handler instance.
  569. *
  570. * @param \Symfony\Component\HttpFoundation\Request $request
  571. * @return void
  572. */
  573. public function setRequestOnHandler(Request $request)
  574. {
  575. if ($this->handlerNeedsRequest()) {
  576. $this->handler->setRequest($request);
  577. }
  578. }
  579. }