driver.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <?php namespace Laravel\Session;
  2. use Laravel\Str;
  3. use Laravel\Input;
  4. use Laravel\Cookie;
  5. abstract class Driver {
  6. /**
  7. * The session payload, which contains the session ID, data and last activity timestamp.
  8. *
  9. * @var array
  10. */
  11. public $session = array();
  12. /**
  13. * Load the session for a given session ID.
  14. *
  15. * The session will be checked for validity and necessary data. For example, if the session
  16. * does not have a CSRF token, a token will be generated for the session.
  17. *
  18. * If the session has expired, a new, empty session will be generated.
  19. *
  20. * @param string $id
  21. * @param int $lifetime
  22. * @return void
  23. */
  24. public function start($id, $lifetime)
  25. {
  26. $this->session = ( ! is_null($id)) ? $this->load($id) : null;
  27. if (is_null($this->session) or (time() - $this->session['last_activity']) > ($lifetime * 60))
  28. {
  29. $this->session = array('id' => Str::random(40), 'data' => array());
  30. }
  31. if ( ! $this->has('csrf_token')) $this->put('csrf_token', Str::random(16));
  32. $this->session['last_activity'] = time();
  33. }
  34. /**
  35. * Load a session by ID.
  36. *
  37. * The session will be retrieved from persistant storage and returned as an array.
  38. * The array contains the session ID, last activity UNIX timestamp, and session data.
  39. *
  40. * @param string $id
  41. * @return array
  42. */
  43. abstract protected function load($id);
  44. /**
  45. * Delete the session from persistant storage.
  46. *
  47. * @return void
  48. */
  49. abstract protected function delete();
  50. /**
  51. * Save the session to persistant storage.
  52. *
  53. * @return void
  54. */
  55. abstract protected function save();
  56. /**
  57. * Determine if the session or flash data contains an item.
  58. *
  59. * @param string $key
  60. * @return bool
  61. */
  62. public function has($key)
  63. {
  64. return ( ! is_null($this->get($key)));
  65. }
  66. /**
  67. * Get an item from the session.
  68. *
  69. * A default value may also be specified, and will be returned in the requested
  70. * item does not exist in the session.
  71. *
  72. * @param string $key
  73. * @param mixed $default
  74. * @return mixed
  75. */
  76. public function get($key, $default = null)
  77. {
  78. foreach (array($key, ':old:'.$key, ':new:'.$key) as $possibility)
  79. {
  80. if (array_key_exists($possibility, $this->session['data'])) return $this->session['data'][$possibility];
  81. }
  82. return ($default instanceof \Closure) ? call_user_func($default) : $default;
  83. }
  84. /**
  85. * Write an item to the session.
  86. *
  87. * @param string $key
  88. * @param mixed $value
  89. * @return Driver
  90. */
  91. public function put($key, $value)
  92. {
  93. $this->session['data'][$key] = $value;
  94. return $this;
  95. }
  96. /**
  97. * Write an item to the session flash data.
  98. *
  99. * Flash data only exists for the next request. After that, it will be removed from
  100. * the session. Flash data is useful for temporary status or welcome messages.
  101. *
  102. * @param string $key
  103. * @param mixed $value
  104. * @return Driver
  105. */
  106. public function flash($key, $value)
  107. {
  108. $this->put(':new:'.$key, $value);
  109. return $this;
  110. }
  111. /**
  112. * Remove an item from the session.
  113. *
  114. * @param string $key
  115. * @return Driver
  116. */
  117. public function forget($key)
  118. {
  119. unset($this->session['data'][$key]);
  120. }
  121. /**
  122. * Remove all items from the session.
  123. *
  124. * @return void
  125. */
  126. public function flush()
  127. {
  128. $this->session['data'] = array();
  129. }
  130. /**
  131. * Regenerate the session ID.
  132. *
  133. * @return void
  134. */
  135. public function regenerate()
  136. {
  137. $this->delete();
  138. $this->session['id'] = Str::random(40);
  139. }
  140. /**
  141. * Close the session.
  142. *
  143. * The session will be stored in persistant storage and the session cookie will be
  144. * session cookie will be sent to the browser.
  145. *
  146. * The input of the current request will also be flashed to the session so it is
  147. * available for the next request via the "old" method on the input class.
  148. *
  149. * @param Laravel\Input $input
  150. * @param array $config
  151. * @return void
  152. */
  153. public function close(Input $input, $config)
  154. {
  155. $this->flash('laravel_old_input', $input->get())->age();
  156. $this->save();
  157. $this->write_cookie($input->cookies, $config);
  158. if ($this instanceof Sweeper and mt_rand(1, 100) <= 2)
  159. {
  160. $this->sweep(time() - ($config['lifetime'] * 60));
  161. }
  162. }
  163. /**
  164. * Age the session flash data.
  165. *
  166. * To age the data, we will forget all of the old keys and then rewrite the newly
  167. * flashed items to have old keys, which will be available for the next request.
  168. *
  169. * @return void
  170. */
  171. protected function age()
  172. {
  173. foreach ($this->session['data'] as $key => $value)
  174. {
  175. if (strpos($key, ':old:') === 0) $this->forget($key);
  176. }
  177. $session = $this->session['data'];
  178. $this->session['data'] = array_combine(str_replace(':new:', ':old:', array_keys($session)), array_values($session));
  179. }
  180. /**
  181. * Write the session cookie.
  182. *
  183. * All of the session cookie configuration options are stored in the session
  184. * configuration file. The cookie will only be written if the headers have not
  185. * already been sent to the browser.
  186. *
  187. * @param Laravel\Cookie $cookie
  188. * @param array $config
  189. * @return void
  190. */
  191. protected function write_cookie(Cookie $cookies, $config)
  192. {
  193. if ( ! headers_sent())
  194. {
  195. extract($config);
  196. $minutes = ($expire_on_close) ? 0 : $lifetime;
  197. $cookies->put('laravel_session', $this->session['id'], $minutes, $path, $domain, $https, $http_only);
  198. }
  199. }
  200. /**
  201. * Magic Method for retrieving items from the session.
  202. */
  203. public function __get($key)
  204. {
  205. return $this->get($key);
  206. }
  207. /**
  208. * Magic Method for writings items to the session.
  209. */
  210. public function __set($key, $value)
  211. {
  212. $this->put($key, $value);
  213. }
  214. }