PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

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