PageRenderTime 21ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

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