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

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

https://gitlab.com/Marwein/tnjobs
PHP | 699 lines | 298 code | 95 blank | 306 comment | 12 complexity | 0892815226994a62c94c51846e51a818 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. return ! is_null($this->get($name));
  266. }
  267. /**
  268. * {@inheritdoc}
  269. */
  270. public function get($name, $default = null)
  271. {
  272. return Arr::get($this->attributes, $name, $default);
  273. }
  274. /**
  275. * Get the value of a given key and then forget it.
  276. *
  277. * @param string $key
  278. * @param string $default
  279. * @return mixed
  280. */
  281. public function pull($key, $default = null)
  282. {
  283. return Arr::pull($this->attributes, $key, $default);
  284. }
  285. /**
  286. * Determine if the session contains old input.
  287. *
  288. * @param string $key
  289. * @return bool
  290. */
  291. public function hasOldInput($key = null)
  292. {
  293. $old = $this->getOldInput($key);
  294. return is_null($key) ? count($old) > 0 : ! is_null($old);
  295. }
  296. /**
  297. * Get the requested item from the flashed input array.
  298. *
  299. * @param string $key
  300. * @param mixed $default
  301. * @return mixed
  302. */
  303. public function getOldInput($key = null, $default = null)
  304. {
  305. $input = $this->get('_old_input', []);
  306. // Input that is flashed to the session can be easily retrieved by the
  307. // developer, making repopulating old forms and the like much more
  308. // convenient, since the request's previous input is available.
  309. return Arr::get($input, $key, $default);
  310. }
  311. /**
  312. * {@inheritdoc}
  313. */
  314. public function set($name, $value)
  315. {
  316. Arr::set($this->attributes, $name, $value);
  317. }
  318. /**
  319. * Put a key / value pair or array of key / value pairs in the session.
  320. *
  321. * @param string|array $key
  322. * @param mixed $value
  323. * @return void
  324. */
  325. public function put($key, $value = null)
  326. {
  327. if (! is_array($key)) {
  328. $key = [$key => $value];
  329. }
  330. foreach ($key as $arrayKey => $arrayValue) {
  331. $this->set($arrayKey, $arrayValue);
  332. }
  333. }
  334. /**
  335. * Push a value onto a session array.
  336. *
  337. * @param string $key
  338. * @param mixed $value
  339. * @return void
  340. */
  341. public function push($key, $value)
  342. {
  343. $array = $this->get($key, []);
  344. $array[] = $value;
  345. $this->put($key, $array);
  346. }
  347. /**
  348. * Flash a key / value pair to the session.
  349. *
  350. * @param string $key
  351. * @param mixed $value
  352. * @return void
  353. */
  354. public function flash($key, $value)
  355. {
  356. $this->put($key, $value);
  357. $this->push('flash.new', $key);
  358. $this->removeFromOldFlashData([$key]);
  359. }
  360. /**
  361. * Flash a key / value pair to the session
  362. * for immediate use.
  363. *
  364. * @param string $key
  365. * @param mixed $value
  366. * @return void
  367. */
  368. public function now($key, $value)
  369. {
  370. $this->put($key, $value);
  371. $this->push('flash.old', $key);
  372. }
  373. /**
  374. * Flash an input array to the session.
  375. *
  376. * @param array $value
  377. * @return void
  378. */
  379. public function flashInput(array $value)
  380. {
  381. $this->flash('_old_input', $value);
  382. }
  383. /**
  384. * Reflash all of the session flash data.
  385. *
  386. * @return void
  387. */
  388. public function reflash()
  389. {
  390. $this->mergeNewFlashes($this->get('flash.old', []));
  391. $this->put('flash.old', []);
  392. }
  393. /**
  394. * Reflash a subset of the current flash data.
  395. *
  396. * @param array|mixed $keys
  397. * @return void
  398. */
  399. public function keep($keys = null)
  400. {
  401. $keys = is_array($keys) ? $keys : func_get_args();
  402. $this->mergeNewFlashes($keys);
  403. $this->removeFromOldFlashData($keys);
  404. }
  405. /**
  406. * Merge new flash keys into the new flash array.
  407. *
  408. * @param array $keys
  409. * @return void
  410. */
  411. protected function mergeNewFlashes(array $keys)
  412. {
  413. $values = array_unique(array_merge($this->get('flash.new', []), $keys));
  414. $this->put('flash.new', $values);
  415. }
  416. /**
  417. * Remove the given keys from the old flash data.
  418. *
  419. * @param array $keys
  420. * @return void
  421. */
  422. protected function removeFromOldFlashData(array $keys)
  423. {
  424. $this->put('flash.old', array_diff($this->get('flash.old', []), $keys));
  425. }
  426. /**
  427. * {@inheritdoc}
  428. */
  429. public function all()
  430. {
  431. return $this->attributes;
  432. }
  433. /**
  434. * {@inheritdoc}
  435. */
  436. public function replace(array $attributes)
  437. {
  438. $this->put($attributes);
  439. }
  440. /**
  441. * {@inheritdoc}
  442. */
  443. public function remove($name)
  444. {
  445. return Arr::pull($this->attributes, $name);
  446. }
  447. /**
  448. * Remove one or many items from the session.
  449. *
  450. * @param string|array $keys
  451. * @return void
  452. */
  453. public function forget($keys)
  454. {
  455. Arr::forget($this->attributes, $keys);
  456. }
  457. /**
  458. * {@inheritdoc}
  459. */
  460. public function clear()
  461. {
  462. $this->attributes = [];
  463. foreach ($this->bags as $bag) {
  464. $bag->clear();
  465. }
  466. }
  467. /**
  468. * Remove all of the items from the session.
  469. *
  470. * @return void
  471. */
  472. public function flush()
  473. {
  474. $this->clear();
  475. }
  476. /**
  477. * {@inheritdoc}
  478. */
  479. public function isStarted()
  480. {
  481. return $this->started;
  482. }
  483. /**
  484. * {@inheritdoc}
  485. */
  486. public function registerBag(SessionBagInterface $bag)
  487. {
  488. $this->bags[$bag->getStorageKey()] = $bag;
  489. }
  490. /**
  491. * {@inheritdoc}
  492. */
  493. public function getBag($name)
  494. {
  495. return Arr::get($this->bags, $name, function () {
  496. throw new InvalidArgumentException('Bag not registered.');
  497. });
  498. }
  499. /**
  500. * {@inheritdoc}
  501. */
  502. public function getMetadataBag()
  503. {
  504. return $this->metaBag;
  505. }
  506. /**
  507. * Get the raw bag data array for a given bag.
  508. *
  509. * @param string $name
  510. * @return array
  511. */
  512. public function getBagData($name)
  513. {
  514. return Arr::get($this->bagData, $name, []);
  515. }
  516. /**
  517. * Get the CSRF token value.
  518. *
  519. * @return string
  520. */
  521. public function token()
  522. {
  523. return $this->get('_token');
  524. }
  525. /**
  526. * Get the CSRF token value.
  527. *
  528. * @return string
  529. */
  530. public function getToken()
  531. {
  532. return $this->token();
  533. }
  534. /**
  535. * Regenerate the CSRF token value.
  536. *
  537. * @return void
  538. */
  539. public function regenerateToken()
  540. {
  541. $this->put('_token', Str::random(40));
  542. }
  543. /**
  544. * Get the previous URL from the session.
  545. *
  546. * @return string|null
  547. */
  548. public function previousUrl()
  549. {
  550. return $this->get('_previous.url');
  551. }
  552. /**
  553. * Set the "previous" URL in the session.
  554. *
  555. * @param string $url
  556. * @return void
  557. */
  558. public function setPreviousUrl($url)
  559. {
  560. return $this->put('_previous.url', $url);
  561. }
  562. /**
  563. * Set the existence of the session on the handler if applicable.
  564. *
  565. * @param bool $value
  566. * @return void
  567. */
  568. public function setExists($value)
  569. {
  570. if ($this->handler instanceof ExistenceAwareInterface) {
  571. $this->handler->setExists($value);
  572. }
  573. }
  574. /**
  575. * Get the underlying session handler implementation.
  576. *
  577. * @return \SessionHandlerInterface
  578. */
  579. public function getHandler()
  580. {
  581. return $this->handler;
  582. }
  583. /**
  584. * Determine if the session handler needs a request.
  585. *
  586. * @return bool
  587. */
  588. public function handlerNeedsRequest()
  589. {
  590. return $this->handler instanceof CookieSessionHandler;
  591. }
  592. /**
  593. * Set the request on the handler instance.
  594. *
  595. * @param \Symfony\Component\HttpFoundation\Request $request
  596. * @return void
  597. */
  598. public function setRequestOnHandler(Request $request)
  599. {
  600. if ($this->handlerNeedsRequest()) {
  601. $this->handler->setRequest($request);
  602. }
  603. }
  604. }