driver = $driver; } /** * Load the session for the current request. * * @param string $id * @return void */ public function load($id) { if ( ! is_null($id)) $this->session = $this->driver->load($id); // If the session doesn't exist or is invalid, we will create a new session // array and mark the session as being non-existent. Some drivers, such as // the database driver, need to know whether the session exists in storage // so they can know whether to "insert" or "update" the session. if (is_null($this->session) or $this->invalid()) { $this->exists = false; $this->session = array('id' => Str::random(40), 'data' => array( ':new:' => array(), ':old:' => array(), )); } // A CSRF token is stored in every session. The token is used by the Form // class and the "csrf" filter to protect the application from cross-site // request forgery attacks. The token is simply a long, random string // which should be posted with each request. if ( ! $this->has('csrf_token')) { $this->put('csrf_token', Str::random(40)); } } /** * Deteremine if the session payload instance is valid. * * The session is considered valid if it exists and has not expired. * * @return bool */ protected function invalid() { $lifetime = Config::$items['session']['lifetime']; return (time() - $this->session['last_activity']) > ($lifetime * 60); } /** * Determine if session handling has been started for the request. * * @return bool */ public function started() { return is_array($this->session); } /** * Determine if the session or flash data contains an item. * * @param string $key * @return bool */ public function has($key) { return ( ! is_null($this->get($key))); } /** * Get an item from the session. * * The session flash data will also be checked for the requested item. * * * // Get an item from the session * $name = Session::get('name'); * * // Return a default value if the item doesn't exist * $name = Session::get('name', 'Taylor'); * * * @param string $key * @param mixed $default * @return mixed */ public function get($key, $default = null) { if (isset($this->session['data'][$key])) { return $this->session['data'][$key]; } elseif (isset($this->session['data'][':new:'][$key])) { return $this->session['data'][':new:'][$key]; } elseif (isset($this->session['data'][':old:'][$key])) { return $this->session['data'][':old:'][$key]; } return ($default instanceof Closure) ? call_user_func($default) : $default; } /** * Write an item to the session. * * @param string $key * @param mixed $value * @return void */ public function put($key, $value) { Arr::set($this->session['data'], $key, $value); } /** * Write an item to the session flash data. * * Flash data only exists for the next request to the application, and is * useful for storing temporary data such as error or status messages. * * @param string $key * @param mixed $value * @return void */ public function flash($key, $value) { Arr::set($this->session['data'][':new:'], $key, $value); } /** * Keep the session flash data from expiring at the end of the request. * * @return void */ public function reflash() { $old = $this->session['data'][':old:']; $this->session['data'][':new:'] = array_merge($this->session['data'][':new:'], $old); } /** * Keep a session flash item from expiring at the end of the request. * * @param string|array $key * @return void */ public function keep($keys) { foreach ((array) $keys as $key) { $this->flash($key, $this->get($key)); } } /** * Remove an item from the session data. * * @param string $key * @return void */ public function forget($key) { Arr::forget($this->session['data'], $key); } /** * Remove all of the items from the session. * * @return void */ public function flush() { $this->session['data'] = array(); } /** * Assign a new, random ID to the session. * * @return void */ public function regenerate() { $this->session['id'] = Str::random(40); $this->exists = false; } /** * Get the CSRF token that is stored in the session data. * * @return string */ public function token() { return $this->get('csrf_token'); } /** * Store the session payload in storage. * * @return void */ public function save() { $this->session['last_activity'] = time(); $this->age(); $config = Config::$items['session']; $this->driver->save($this->session, $config, $this->exists); $this->cookie(); // Some session drivers implement the Sweeper interface, meaning that they // must clean up expired sessions manually. If the driver is a sweeper, we // need to determine if garbage collection should be run for the request. // Since garbage collection can be expensive, the probability of it // occuring is controlled by the "sweepage" configuration option. $sweepage = $config['sweepage']; if ($this->driver instanceof Sweeper and (mt_rand(1, $sweepage[1]) <= $sweepage[0])) { $this->driver->sweep(time() - ($config['lifetime'] * 60)); } } /** * Age the session flash data. * * Session flash data is only available during the request in which it * was flashed, and the request after that. To "age" the data, we will * remove all of the :old: items and re-address the new items. * * @return void */ protected function age() { $this->session['data'][':old:'] = $this->session['data'][':new:']; $this->session['data'][':new:'] = array(); } /** * Send the session ID cookie to the browser. * * @return void */ protected function cookie() { $config = Config::$items['session']; extract($config, EXTR_SKIP); $minutes = ( ! $expire_on_close) ? $lifetime : 0; Cookie::put($cookie, $this->session['id'], $minutes, $path, $domain, $secure); } }