PageRenderTime 656ms CodeModel.GetById 169ms app.highlight 254ms RepoModel.GetById 147ms app.codeStats 0ms

/system/classes/Kohana/Session.php

https://bitbucket.org/chrispiechowicz/zepto
PHP | 505 lines | 191 code | 59 blank | 255 comment | 14 complexity | b6374139e23179479a0e9e306c5af257 MD5 | raw file
  1<?php defined('SYSPATH') OR die('No direct script access.');
  2/**
  3 * Base session class.
  4 *
  5 * @package    Kohana
  6 * @category   Session
  7 * @author     Kohana Team
  8 * @copyright  (c) 2008-2012 Kohana Team
  9 * @license    http://kohanaframework.org/license
 10 */
 11abstract class Kohana_Session {
 12
 13	/**
 14	 * @var  string  default session adapter
 15	 */
 16	public static $default = 'native';
 17
 18	/**
 19	 * @var  array  session instances
 20	 */
 21	public static $instances = array();
 22
 23	/**
 24	 * Creates a singleton session of the given type. Some session types
 25	 * (native, database) also support restarting a session by passing a
 26	 * session id as the second parameter.
 27	 *
 28	 *     $session = Session::instance();
 29	 *
 30	 * [!!] [Session::write] will automatically be called when the request ends.
 31	 *
 32	 * @param   string  $type   type of session (native, cookie, etc)
 33	 * @param   string  $id     session identifier
 34	 * @return  Session
 35	 * @uses    Kohana::$config
 36	 */
 37	public static function instance($type = NULL, $id = NULL)
 38	{
 39		if ($type === NULL)
 40		{
 41			// Use the default type
 42			$type = Session::$default;
 43		}
 44
 45		if ( ! isset(Session::$instances[$type]))
 46		{
 47			// Load the configuration for this type
 48			$config = Kohana::$config->load('session')->get($type);
 49
 50			// Set the session class name
 51			$class = 'Session_'.ucfirst($type);
 52
 53			// Create a new session instance
 54			Session::$instances[$type] = $session = new $class($config, $id);
 55
 56			// Write the session at shutdown
 57			register_shutdown_function(array($session, 'write'));
 58		}
 59
 60		return Session::$instances[$type];
 61	}
 62
 63	/**
 64	 * @var  string  cookie name
 65	 */
 66	protected $_name = 'session';
 67
 68	/**
 69	 * @var  int  cookie lifetime
 70	 */
 71	protected $_lifetime = 0;
 72
 73	/**
 74	 * @var  bool  encrypt session data?
 75	 */
 76	protected $_encrypted = FALSE;
 77
 78	/**
 79	 * @var  array  session data
 80	 */
 81	protected $_data = array();
 82
 83	/**
 84	 * @var  bool  session destroyed?
 85	 */
 86	protected $_destroyed = FALSE;
 87
 88	/**
 89	 * Overloads the name, lifetime, and encrypted session settings.
 90	 *
 91	 * [!!] Sessions can only be created using the [Session::instance] method.
 92	 *
 93	 * @param   array   $config configuration
 94	 * @param   string  $id     session id
 95	 * @return  void
 96	 * @uses    Session::read
 97	 */
 98	public function __construct(array $config = NULL, $id = NULL)
 99	{
100		if (isset($config['name']))
101		{
102			// Cookie name to store the session id in
103			$this->_name = (string) $config['name'];
104		}
105
106		if (isset($config['lifetime']))
107		{
108			// Cookie lifetime
109			$this->_lifetime = (int) $config['lifetime'];
110		}
111
112		if (isset($config['encrypted']))
113		{
114			if ($config['encrypted'] === TRUE)
115			{
116				// Use the default Encrypt instance
117				$config['encrypted'] = 'default';
118			}
119
120			// Enable or disable encryption of data
121			$this->_encrypted = $config['encrypted'];
122		}
123
124		// Load the session
125		$this->read($id);
126	}
127
128	/**
129	 * Session object is rendered to a serialized string. If encryption is
130	 * enabled, the session will be encrypted. If not, the output string will
131	 * be encoded.
132	 *
133	 *     echo $session;
134	 *
135	 * @return  string
136	 * @uses    Encrypt::encode
137	 */
138	public function __toString()
139	{
140		// Serialize the data array
141		$data = $this->_serialize($this->_data);
142
143		if ($this->_encrypted)
144		{
145			// Encrypt the data using the default key
146			$data = Encrypt::instance($this->_encrypted)->encode($data);
147		}
148		else
149		{
150			// Encode the data
151			$data = $this->_encode($data);
152		}
153
154		return $data;
155	}
156
157	/**
158	 * Returns the current session array. The returned array can also be
159	 * assigned by reference.
160	 *
161	 *     // Get a copy of the current session data
162	 *     $data = $session->as_array();
163	 *
164	 *     // Assign by reference for modification
165	 *     $data =& $session->as_array();
166	 *
167	 * @return  array
168	 */
169	public function & as_array()
170	{
171		return $this->_data;
172	}
173
174	/**
175	 * Get the current session id, if the session supports it.
176	 *
177	 *     $id = $session->id();
178	 *
179	 * [!!] Not all session types have ids.
180	 *
181	 * @return  string
182	 * @since   3.0.8
183	 */
184	public function id()
185	{
186		return NULL;
187	}
188
189	/**
190	 * Get the current session cookie name.
191	 *
192	 *     $name = $session->name();
193	 *
194	 * @return  string
195	 * @since   3.0.8
196	 */
197	public function name()
198	{
199		return $this->_name;
200	}
201
202	/**
203	 * Get a variable from the session array.
204	 *
205	 *     $foo = $session->get('foo');
206	 *
207	 * @param   string  $key        variable name
208	 * @param   mixed   $default    default value to return
209	 * @return  mixed
210	 */
211	public function get($key, $default = NULL)
212	{
213		return array_key_exists($key, $this->_data) ? $this->_data[$key] : $default;
214	}
215
216	/**
217	 * Get and delete a variable from the session array.
218	 *
219	 *     $bar = $session->get_once('bar');
220	 *
221	 * @param   string  $key        variable name
222	 * @param   mixed   $default    default value to return
223	 * @return  mixed
224	 */
225	public function get_once($key, $default = NULL)
226	{
227		$value = $this->get($key, $default);
228
229		unset($this->_data[$key]);
230
231		return $value;
232	}
233
234	/**
235	 * Set a variable in the session array.
236	 *
237	 *     $session->set('foo', 'bar');
238	 *
239	 * @param   string  $key    variable name
240	 * @param   mixed   $value  value
241	 * @return  $this
242	 */
243	public function set($key, $value)
244	{
245		$this->_data[$key] = $value;
246
247		return $this;
248	}
249
250	/**
251	 * Set a variable by reference.
252	 *
253	 *     $session->bind('foo', $foo);
254	 *
255	 * @param   string  $key    variable name
256	 * @param   mixed   $value  referenced value
257	 * @return  $this
258	 */
259	public function bind($key, & $value)
260	{
261		$this->_data[$key] =& $value;
262
263		return $this;
264	}
265
266	/**
267	 * Removes a variable in the session array.
268	 *
269	 *     $session->delete('foo');
270	 *
271	 * @param   string  $key,...    variable name
272	 * @return  $this
273	 */
274	public function delete($key)
275	{
276		$args = func_get_args();
277
278		foreach ($args as $key)
279		{
280			unset($this->_data[$key]);
281		}
282
283		return $this;
284	}
285
286	/**
287	 * Loads existing session data.
288	 *
289	 *     $session->read();
290	 *
291	 * @param   string  $id session id
292	 * @return  void
293	 */
294	public function read($id = NULL)
295	{
296		$data = NULL;
297
298		try
299		{
300			if (is_string($data = $this->_read($id)))
301			{
302				if ($this->_encrypted)
303				{
304					// Decrypt the data using the default key
305					$data = Encrypt::instance($this->_encrypted)->decode($data);
306				}
307				else
308				{
309					// Decode the data
310					$data = $this->_decode($data);
311				}
312
313				// Unserialize the data
314				$data = $this->_unserialize($data);
315			}
316			else
317			{
318				// Ignore these, session is valid, likely no data though.
319			}
320		}
321		catch (Exception $e)
322		{
323			// Error reading the session, usually a corrupt session.
324			throw new Session_Exception('Error reading session data.', NULL, Session_Exception::SESSION_CORRUPT);
325		}
326
327		if (is_array($data))
328		{
329			// Load the data locally
330			$this->_data = $data;
331		}
332	}
333
334	/**
335	 * Generates a new session id and returns it.
336	 *
337	 *     $id = $session->regenerate();
338	 *
339	 * @return  string
340	 */
341	public function regenerate()
342	{
343		return $this->_regenerate();
344	}
345
346	/**
347	 * Sets the last_active timestamp and saves the session.
348	 *
349	 *     $session->write();
350	 *
351	 * [!!] Any errors that occur during session writing will be logged,
352	 * but not displayed, because sessions are written after output has
353	 * been sent.
354	 *
355	 * @return  boolean
356	 * @uses    Kohana::$log
357	 */
358	public function write()
359	{
360		if (headers_sent() OR $this->_destroyed)
361		{
362			// Session cannot be written when the headers are sent or when
363			// the session has been destroyed
364			return FALSE;
365		}
366
367		// Set the last active timestamp
368		$this->_data['last_active'] = time();
369
370		try
371		{
372			return $this->_write();
373		}
374		catch (Exception $e)
375		{
376			// Log & ignore all errors when a write fails
377			Kohana::$log->add(Log::ERROR, Kohana_Exception::text($e))->write();
378
379			return FALSE;
380		}
381	}
382
383	/**
384	 * Completely destroy the current session.
385	 *
386	 *     $success = $session->destroy();
387	 *
388	 * @return  boolean
389	 */
390	public function destroy()
391	{
392		if ($this->_destroyed === FALSE)
393		{
394			if ($this->_destroyed = $this->_destroy())
395			{
396				// The session has been destroyed, clear all data
397				$this->_data = array();
398			}
399		}
400
401		return $this->_destroyed;
402	}
403
404	/**
405	 * Restart the session.
406	 *
407	 *     $success = $session->restart();
408	 *
409	 * @return  boolean
410	 */
411	public function restart()
412	{
413		if ($this->_destroyed === FALSE)
414		{
415			// Wipe out the current session.
416			$this->destroy();
417		}
418
419		// Allow the new session to be saved
420		$this->_destroyed = FALSE;
421
422		return $this->_restart();
423	}
424
425	/**
426	 * Serializes the session data.
427	 *
428	 * @param   array  $data  data
429	 * @return  string
430	 */
431	protected function _serialize($data)
432	{
433		return serialize($data);
434	}
435
436	/**
437	 * Unserializes the session data.
438	 *
439	 * @param   string  $data  data
440	 * @return  array
441	 */
442	protected function _unserialize($data)
443	{
444		return unserialize($data);
445	}
446
447	/**
448	 * Encodes the session data using [base64_encode].
449	 *
450	 * @param   string  $data  data
451	 * @return  string
452	 */
453	protected function _encode($data)
454	{
455		return base64_encode($data);
456	}
457
458	/**
459	 * Decodes the session data using [base64_decode].
460	 *
461	 * @param   string  $data  data
462	 * @return  string
463	 */
464	protected function _decode($data)
465	{
466		return base64_decode($data);
467	}
468
469	/**
470	 * Loads the raw session data string and returns it.
471	 *
472	 * @param   string  $id session id
473	 * @return  string
474	 */
475	abstract protected function _read($id = NULL);
476
477	/**
478	 * Generate a new session id and return it.
479	 *
480	 * @return  string
481	 */
482	abstract protected function _regenerate();
483
484	/**
485	 * Writes the current session.
486	 *
487	 * @return  boolean
488	 */
489	abstract protected function _write();
490
491	/**
492	 * Destroys the current session.
493	 *
494	 * @return  boolean
495	 */
496	abstract protected function _destroy();
497
498	/**
499	 * Restarts the current session.
500	 *
501	 * @return  boolean
502	 */
503	abstract protected function _restart();
504
505} // End Session