PageRenderTime 53ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

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

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