blob: b6c862daea3a92243b8645fce5723f19a5a1c472 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Darren Hillc4e266b2011-08-30 15:40:27 -04002/**
3 * CodeIgniter
4 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +03005 * An open source application development framework for PHP 5.2.4 or newer
6 *
7 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
Darren Hillc4e266b2011-08-30 15:40:27 -040018 *
19 * @package CodeIgniter
Andrey Andreev9ffcee62012-09-05 16:25:16 +030020 * @author EllisLab Dev Team
Andrey Andreevc5536aa2012-11-01 17:33:58 +020021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Andrey Andreev9ffcee62012-09-05 16:25:16 +030022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Darren Hillc4e266b2011-08-30 15:40:27 -040023 * @link http://codeigniter.com
24 * @since Version 2.0
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Darren Hillc4e266b2011-08-30 15:40:27 -040028
Darren Hillc4e266b2011-08-30 15:40:27 -040029/**
Andrey Andreev9ffcee62012-09-05 16:25:16 +030030 * CodeIgniter Session Class
Darren Hillc4e266b2011-08-30 15:40:27 -040031 *
32 * The user interface defined by EllisLabs, now with puggable drivers to manage different storage mechanisms.
dchill420e884082012-08-11 20:10:17 -040033 * By default, the cookie session driver will load, but the 'sess_driver' config/param item (see above) can be
34 * used to specify the 'native' driver, or any other you might create.
Darren Hillc4e266b2011-08-30 15:40:27 -040035 * Once loaded, this driver setup is a drop-in replacement for the former CI_Session library, taking its place as the
36 * 'session' member of the global controller framework (e.g.: $CI->session or $this->session).
37 * In keeping with the CI_Driver methodology, multiple drivers may be loaded, although this might be a bit confusing.
Darren Hill5073a372011-08-31 13:54:19 -040038 * The CI_Session library class keeps track of the most recently loaded driver as "current" to call for driver methods.
Darren Hillc4e266b2011-08-30 15:40:27 -040039 * Ideally, one driver is loaded and all calls go directly through the main library interface. However, any methods
40 * called through the specific driver will switch the "current" driver to itself before invoking the library method
41 * (which will then call back into the driver for low-level operations). So, alternation between two drivers can be
42 * achieved by specifying which driver to use for each call (e.g.: $this->session->native->set_userdata('foo', 'bar');
43 * $this->session->cookie->userdata('foo'); $this->session->native->unset_userdata('foo');). Notice in the previous
44 * example that the _native_ userdata value 'foo' would be set to 'bar', which would NOT be returned by the call for
45 * the _cookie_ userdata 'foo', nor would the _cookie_ value be unset by the call to unset the _native_ 'foo' value.
46 *
47 * @package CodeIgniter
48 * @subpackage Libraries
49 * @category Sessions
Andrey Andreev9ffcee62012-09-05 16:25:16 +030050 * @author EllisLab Dev Team
Darren Hillc4e266b2011-08-30 15:40:27 -040051 * @link http://codeigniter.com/user_guide/libraries/sessions.html
52 */
Darren Hilla2ae6572011-09-01 07:36:26 -040053class CI_Session extends CI_Driver_Library {
Andrey Andreev9ffcee62012-09-05 16:25:16 +030054
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020055 /**
56 * Initialization parameters
57 *
58 * @var array
59 */
Darren Hillc4e266b2011-08-30 15:40:27 -040060 public $params = array();
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020061
62 /**
63 * Current driver in use
64 *
65 * @var string
66 */
Andrey Andreev9ffcee62012-09-05 16:25:16 +030067 protected $current = NULL;
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020068
69 /**
70 * User data
71 *
72 * @var array
73 */
Darren Hilla2ae6572011-09-01 07:36:26 -040074 protected $userdata = array();
Darren Hillc4e266b2011-08-30 15:40:27 -040075
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020076 // ------------------------------------------------------------------------
77
Darren Hillc4e266b2011-08-30 15:40:27 -040078 const FLASHDATA_KEY = 'flash';
79 const FLASHDATA_NEW = ':new:';
80 const FLASHDATA_OLD = ':old:';
81 const FLASHDATA_EXP = ':exp:';
82 const EXPIRATION_KEY = '__expirations';
83 const TEMP_EXP_DEF = 300;
84
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020085 // ------------------------------------------------------------------------
86
Darren Hillc4e266b2011-08-30 15:40:27 -040087 /**
Darren Hill5073a372011-08-31 13:54:19 -040088 * CI_Session constructor
Darren Hillc4e266b2011-08-30 15:40:27 -040089 *
90 * The constructor loads the configured driver ('sess_driver' in config.php or as a parameter), running
91 * routines in its constructor, and manages flashdata aging.
92 *
Darren Hill5073a372011-08-31 13:54:19 -040093 * @param array Configuration parameters
Andrey Andreev2e3e2302012-10-09 15:52:34 +030094 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -040095 */
96 public function __construct(array $params = array())
97 {
Andrey Andreev2e3e2302012-10-09 15:52:34 +030098 $CI =& get_instance();
99
100 // No sessions under CLI
101 if ($CI->input->is_cli_request())
102 {
103 return;
104 }
105
Darren Hill5073a372011-08-31 13:54:19 -0400106 log_message('debug', 'CI_Session Class Initialized');
Darren Hillc4e266b2011-08-30 15:40:27 -0400107
108 // Get valid drivers list
dchill4226429202012-07-31 10:55:07 -0400109 $this->valid_drivers = array(
dchill426262d052012-11-24 18:41:13 -0500110 'native',
111 'cookie'
dchill4226429202012-07-31 10:55:07 -0400112 );
Darren Hillc4e266b2011-08-30 15:40:27 -0400113 $key = 'sess_valid_drivers';
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300114 $drivers = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
Darren Hillc4e266b2011-08-30 15:40:27 -0400115 if ($drivers)
116 {
Darren Hillc4e266b2011-08-30 15:40:27 -0400117 // Add driver names to valid list
dchill426262d052012-11-24 18:41:13 -0500118 foreach ((array) $drivers as $driver)
Darren Hillc4e266b2011-08-30 15:40:27 -0400119 {
dchill4277ee3fd2012-07-24 11:50:01 -0400120 if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers)))
Darren Hillc4e266b2011-08-30 15:40:27 -0400121 {
122 $this->valid_drivers[] = $driver;
123 }
124 }
125 }
126
127 // Get driver to load
128 $key = 'sess_driver';
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300129 $driver = isset($params[$key]) ? $params[$key] : $CI->config->item($key);
130 if ( ! $driver)
131 {
132 $driver = 'cookie';
133 }
134
dchill426262d052012-11-24 18:41:13 -0500135 if ( ! in_array(strtolower($driver), array_map('strtolower', $this->valid_drivers)))
Darren Hillc4e266b2011-08-30 15:40:27 -0400136 {
dchill426262d052012-11-24 18:41:13 -0500137 $this->valid_drivers[] = $driver;
Darren Hillc4e266b2011-08-30 15:40:27 -0400138 }
139
140 // Save a copy of parameters in case drivers need access
141 $this->params = $params;
142
143 // Load driver and get array reference
144 $this->load_driver($driver);
Darren Hillc4e266b2011-08-30 15:40:27 -0400145
146 // Delete 'old' flashdata (from last request)
147 $this->_flashdata_sweep();
148
149 // Mark all new flashdata as old (data will be deleted before next request)
150 $this->_flashdata_mark();
151
152 // Delete expired tempdata
153 $this->_tempdata_sweep();
154
Darren Hill5073a372011-08-31 13:54:19 -0400155 log_message('debug', 'CI_Session routines successfully run');
Darren Hillc4e266b2011-08-30 15:40:27 -0400156 }
157
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300158 // ------------------------------------------------------------------------
159
Darren Hillc4e266b2011-08-30 15:40:27 -0400160 /**
161 * Loads session storage driver
162 *
Darren Hill5073a372011-08-31 13:54:19 -0400163 * @param string Driver classname
164 * @return object Loaded driver object
Darren Hillc4e266b2011-08-30 15:40:27 -0400165 */
166 public function load_driver($driver)
167 {
dchill4226429202012-07-31 10:55:07 -0400168 // Save reference to most recently loaded driver as library default and sync userdata
Darren Hillc4e266b2011-08-30 15:40:27 -0400169 $this->current = parent::load_driver($driver);
dchill42b1855372012-07-31 09:32:23 -0400170 $this->userdata =& $this->current->get_userdata();
Darren Hillc4e266b2011-08-30 15:40:27 -0400171 return $this->current;
172 }
173
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300174 // ------------------------------------------------------------------------
175
Darren Hillc4e266b2011-08-30 15:40:27 -0400176 /**
177 * Select default session storage driver
178 *
dchill426262d052012-11-24 18:41:13 -0500179 * @param string Driver name
Darren Hill5073a372011-08-31 13:54:19 -0400180 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400181 */
182 public function select_driver($driver)
183 {
184 // Validate driver name
dchill426262d052012-11-24 18:41:13 -0500185 $prefix = (string) get_instance()->config->item('subclass_prefix');
186 $child = strtolower(str_replace(array('CI_', $prefix, $this->lib_name.'_'), '', $driver));
187 if (in_array($child, array_map('strtolower', $this->valid_drivers)))
Darren Hillc4e266b2011-08-30 15:40:27 -0400188 {
dchill42b1855372012-07-31 09:32:23 -0400189 // See if driver is loaded
dchill42b1855372012-07-31 09:32:23 -0400190 if (isset($this->$child))
Darren Hillc4e266b2011-08-30 15:40:27 -0400191 {
dchill42aee92652012-08-26 21:45:35 -0400192 // See if driver is already current
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300193 if ($this->$child !== $this->current)
194 {
dchill42aee92652012-08-26 21:45:35 -0400195 // Make driver current and sync userdata
196 $this->current = $this->$child;
197 $this->userdata =& $this->current->get_userdata();
198 }
Darren Hillc4e266b2011-08-30 15:40:27 -0400199 }
200 else
201 {
dchill4226429202012-07-31 10:55:07 -0400202 // Load new driver
dchill42aee92652012-08-26 21:45:35 -0400203 $this->load_driver($child);
Darren Hillc4e266b2011-08-30 15:40:27 -0400204 }
205 }
206 }
207
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300208 // ------------------------------------------------------------------------
209
Darren Hillc4e266b2011-08-30 15:40:27 -0400210 /**
211 * Destroy the current session
212 *
Darren Hill5073a372011-08-31 13:54:19 -0400213 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400214 */
215 public function sess_destroy()
216 {
217 // Just call destroy on driver
218 $this->current->sess_destroy();
219 }
220
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300221 // ------------------------------------------------------------------------
222
Darren Hillc4e266b2011-08-30 15:40:27 -0400223 /**
224 * Regenerate the current session
225 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300226 * @param bool Destroy session data flag (default: false)
Darren Hill5073a372011-08-31 13:54:19 -0400227 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400228 */
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300229 public function sess_regenerate($destroy = FALSE)
Darren Hillc4e266b2011-08-30 15:40:27 -0400230 {
dchill4226429202012-07-31 10:55:07 -0400231 // Call regenerate on driver and resync userdata
Darren Hillc4e266b2011-08-30 15:40:27 -0400232 $this->current->sess_regenerate($destroy);
dchill4226429202012-07-31 10:55:07 -0400233 $this->userdata =& $this->current->get_userdata();
Darren Hillc4e266b2011-08-30 15:40:27 -0400234 }
235
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300236 // ------------------------------------------------------------------------
237
Darren Hillc4e266b2011-08-30 15:40:27 -0400238 /**
239 * Fetch a specific item from the session array
240 *
Darren Hill5073a372011-08-31 13:54:19 -0400241 * @param string Item key
dchill42c5872252012-07-30 14:53:11 -0400242 * @return string Item value or NULL if not found
Darren Hillc4e266b2011-08-30 15:40:27 -0400243 */
244 public function userdata($item)
245 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300246 return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
Darren Hillc4e266b2011-08-30 15:40:27 -0400247 }
248
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300249 // ------------------------------------------------------------------------
250
Darren Hillc4e266b2011-08-30 15:40:27 -0400251 /**
252 * Fetch all session data
253 *
254 * @return array User data array
255 */
256 public function all_userdata()
257 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300258 return isset($this->userdata) ? $this->userdata : NULL;
Darren Hillc4e266b2011-08-30 15:40:27 -0400259 }
260
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300261 // ------------------------------------------------------------------------
262
Darren Hillc4e266b2011-08-30 15:40:27 -0400263 /**
dchill42c5079de2012-07-23 10:53:47 -0400264 * Fetch all flashdata
265 *
vkeranov3bb40292012-10-27 18:47:26 +0300266 * @return array Flash data array
dchill42c5079de2012-07-23 10:53:47 -0400267 */
268 public function all_flashdata()
269 {
270 $out = array();
271
272 // loop through all userdata
273 foreach ($this->all_userdata() as $key => $val)
274 {
dchill42c5872252012-07-30 14:53:11 -0400275 // if it contains flashdata, add it
dchill42c5079de2012-07-23 10:53:47 -0400276 if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE)
277 {
dchill4226429202012-07-31 10:55:07 -0400278 $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key);
dchill42c5079de2012-07-23 10:53:47 -0400279 $out[$key] = $val;
280 }
281 }
282 return $out;
283 }
284
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300285 // ------------------------------------------------------------------------
286
dchill42c5079de2012-07-23 10:53:47 -0400287 /**
Darren Hillc4e266b2011-08-30 15:40:27 -0400288 * Add or change data in the "userdata" array
289 *
Darren Hill5073a372011-08-31 13:54:19 -0400290 * @param mixed Item name or array of items
291 * @param string Item value or empty string
292 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400293 */
294 public function set_userdata($newdata = array(), $newval = '')
295 {
296 // Wrap params as array if singular
297 if (is_string($newdata))
298 {
299 $newdata = array($newdata => $newval);
300 }
301
302 // Set each name/value pair
303 if (count($newdata) > 0)
304 {
305 foreach ($newdata as $key => $val)
306 {
307 $this->userdata[$key] = $val;
308 }
309 }
310
311 // Tell driver data changed
312 $this->current->sess_save();
313 }
314
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300315 // ------------------------------------------------------------------------
316
Darren Hillc4e266b2011-08-30 15:40:27 -0400317 /**
318 * Delete a session variable from the "userdata" array
319 *
Darren Hill5073a372011-08-31 13:54:19 -0400320 * @param mixed Item name or array of item names
321 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400322 */
323 public function unset_userdata($newdata = array())
324 {
325 // Wrap single name as array
326 if (is_string($newdata))
327 {
328 $newdata = array($newdata => '');
329 }
330
331 // Unset each item name
332 if (count($newdata) > 0)
333 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300334 foreach (array_keys($newdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400335 {
336 unset($this->userdata[$key]);
337 }
338 }
339
340 // Tell driver data changed
341 $this->current->sess_save();
342 }
343
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300344 // ------------------------------------------------------------------------
345
Darren Hillc4e266b2011-08-30 15:40:27 -0400346 /**
347 * Determine if an item exists
348 *
Darren Hill5073a372011-08-31 13:54:19 -0400349 * @param string Item name
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300350 * @return bool
Darren Hillc4e266b2011-08-30 15:40:27 -0400351 */
352 public function has_userdata($item)
353 {
Darren Hillc4e266b2011-08-30 15:40:27 -0400354 return isset($this->userdata[$item]);
355 }
356
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300357 // ------------------------------------------------------------------------
358
Darren Hillc4e266b2011-08-30 15:40:27 -0400359 /**
360 * Add or change flashdata, only available until the next request
361 *
Darren Hill5073a372011-08-31 13:54:19 -0400362 * @param mixed Item name or array of items
363 * @param string Item value or empty string
364 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400365 */
366 public function set_flashdata($newdata = array(), $newval = '')
367 {
368 // Wrap item as array if singular
369 if (is_string($newdata))
370 {
371 $newdata = array($newdata => $newval);
372 }
373
374 // Prepend each key name and set value
375 if (count($newdata) > 0)
376 {
377 foreach ($newdata as $key => $val)
378 {
379 $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key;
380 $this->set_userdata($flashdata_key, $val);
381 }
382 }
383 }
384
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300385 // ------------------------------------------------------------------------
386
Darren Hillc4e266b2011-08-30 15:40:27 -0400387 /**
388 * Keeps existing flashdata available to next request.
389 *
Darren Hill5073a372011-08-31 13:54:19 -0400390 * @param string Item key
391 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400392 */
393 public function keep_flashdata($key)
394 {
dchill42c5079de2012-07-23 10:53:47 -0400395 // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep()
396 // Note the function will return NULL if the $key provided cannot be found
Darren Hillc4e266b2011-08-30 15:40:27 -0400397 $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key;
398 $value = $this->userdata($old_flashdata_key);
399
400 $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key;
401 $this->set_userdata($new_flashdata_key, $value);
402 }
403
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300404 // ------------------------------------------------------------------------
405
Darren Hillc4e266b2011-08-30 15:40:27 -0400406 /**
407 * Fetch a specific flashdata item from the session array
408 *
Darren Hill5073a372011-08-31 13:54:19 -0400409 * @param string Item key
410 * @return string
Darren Hillc4e266b2011-08-30 15:40:27 -0400411 */
412 public function flashdata($key)
413 {
414 // Prepend key and retrieve value
415 $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key;
416 return $this->userdata($flashdata_key);
417 }
418
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300419 // ------------------------------------------------------------------------
420
Darren Hillc4e266b2011-08-30 15:40:27 -0400421 /**
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300422 * Add or change tempdata, only available until expiration
Darren Hillc4e266b2011-08-30 15:40:27 -0400423 *
Darren Hill5073a372011-08-31 13:54:19 -0400424 * @param mixed Item name or array of items
425 * @param string Item value or empty string
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300426 * @param int Item lifetime in seconds or 0 for default
Darren Hill5073a372011-08-31 13:54:19 -0400427 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400428 */
429 public function set_tempdata($newdata = array(), $newval = '', $expire = 0)
430 {
431 // Set expiration time
432 $expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF);
433
434 // Wrap item as array if singular
435 if (is_string($newdata))
436 {
437 $newdata = array($newdata => $newval);
438 }
439
440 // Get or create expiration list
441 $expirations = $this->userdata(self::EXPIRATION_KEY);
dchill4277ee3fd2012-07-24 11:50:01 -0400442 if ( ! $expirations)
Darren Hillc4e266b2011-08-30 15:40:27 -0400443 {
444 $expirations = array();
445 }
446
447 // Prepend each key name and set value
448 if (count($newdata) > 0)
449 {
450 foreach ($newdata as $key => $val)
451 {
452 $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
453 $expirations[$tempdata_key] = $expire;
454 $this->set_userdata($tempdata_key, $val);
455 }
456 }
457
458 // Update expiration list
459 $this->set_userdata(self::EXPIRATION_KEY, $expirations);
460 }
461
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300462 // ------------------------------------------------------------------------
463
Darren Hillc4e266b2011-08-30 15:40:27 -0400464 /**
465 * Delete a temporary session variable from the "userdata" array
466 *
Darren Hill5073a372011-08-31 13:54:19 -0400467 * @param mixed Item name or array of item names
468 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400469 */
470 public function unset_tempdata($newdata = array())
471 {
472 // Get expirations list
473 $expirations = $this->userdata(self::EXPIRATION_KEY);
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300474 if (empty($expirations))
Darren Hillc4e266b2011-08-30 15:40:27 -0400475 {
476 // Nothing to do
477 return;
478 }
479
480 // Wrap single name as array
481 if (is_string($newdata))
482 {
483 $newdata = array($newdata => '');
484 }
485
486 // Prepend each item name and unset
487 if (count($newdata) > 0)
488 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300489 foreach (array_keys($newdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400490 {
491 $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
492 unset($expirations[$tempdata_key]);
493 $this->unset_userdata($tempdata_key);
494 }
495 }
496
497 // Update expiration list
498 $this->set_userdata(self::EXPIRATION_KEY, $expirations);
499 }
500
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300501 // ------------------------------------------------------------------------
502
Darren Hillc4e266b2011-08-30 15:40:27 -0400503 /**
504 * Fetch a specific tempdata item from the session array
505 *
Darren Hill5073a372011-08-31 13:54:19 -0400506 * @param string Item key
507 * @return string
Darren Hillc4e266b2011-08-30 15:40:27 -0400508 */
509 public function tempdata($key)
510 {
511 // Prepend key and return value
512 $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
513 return $this->userdata($tempdata_key);
514 }
515
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300516 // ------------------------------------------------------------------------
517
Darren Hillc4e266b2011-08-30 15:40:27 -0400518 /**
519 * Identifies flashdata as 'old' for removal
520 * when _flashdata_sweep() runs.
521 *
Darren Hillc4e266b2011-08-30 15:40:27 -0400522 * @return void
523 */
Darren Hilla2ae6572011-09-01 07:36:26 -0400524 protected function _flashdata_mark()
Darren Hillc4e266b2011-08-30 15:40:27 -0400525 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300526 foreach ($this->all_userdata() as $name => $value)
Darren Hillc4e266b2011-08-30 15:40:27 -0400527 {
528 $parts = explode(self::FLASHDATA_NEW, $name);
Andrey Andreeve24eed72012-11-02 23:33:45 +0200529 if (count($parts) === 2)
Darren Hillc4e266b2011-08-30 15:40:27 -0400530 {
531 $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1];
532 $this->set_userdata($new_name, $value);
533 $this->unset_userdata($name);
534 }
535 }
536 }
537
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300538 // ------------------------------------------------------------------------
539
Darren Hillc4e266b2011-08-30 15:40:27 -0400540 /**
541 * Removes all flashdata marked as 'old'
542 *
Darren Hillc4e266b2011-08-30 15:40:27 -0400543 * @return void
544 */
Darren Hilla2ae6572011-09-01 07:36:26 -0400545 protected function _flashdata_sweep()
Darren Hillc4e266b2011-08-30 15:40:27 -0400546 {
547 $userdata = $this->all_userdata();
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300548 foreach (array_keys($userdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400549 {
550 if (strpos($key, self::FLASHDATA_OLD))
551 {
552 $this->unset_userdata($key);
553 }
554 }
555 }
556
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300557 // ------------------------------------------------------------------------
558
Darren Hillc4e266b2011-08-30 15:40:27 -0400559 /**
560 * Removes all expired tempdata
561 *
Darren Hillc4e266b2011-08-30 15:40:27 -0400562 * @return void
563 */
Darren Hilla2ae6572011-09-01 07:36:26 -0400564 protected function _tempdata_sweep()
Darren Hillc4e266b2011-08-30 15:40:27 -0400565 {
566 // Get expirations list
567 $expirations = $this->userdata(self::EXPIRATION_KEY);
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300568 if (empty($expirations))
Darren Hillc4e266b2011-08-30 15:40:27 -0400569 {
570 // Nothing to do
571 return;
572 }
573
574 // Unset expired elements
575 $now = time();
576 $userdata = $this->all_userdata();
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300577 foreach (array_keys($userdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400578 {
579 if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now)
580 {
581 unset($expirations[$key]);
582 $this->unset_userdata($key);
583 }
584 }
585
586 // Update expiration list
587 $this->set_userdata(self::EXPIRATION_KEY, $expirations);
588 }
Darren Hillc4e266b2011-08-30 15:40:27 -0400589
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300590}
591
592// ------------------------------------------------------------------------
Darren Hillc4e266b2011-08-30 15:40:27 -0400593
594/**
Darren Hill5073a372011-08-31 13:54:19 -0400595 * CI_Session_driver Class
Darren Hillc4e266b2011-08-30 15:40:27 -0400596 *
Darren Hill5073a372011-08-31 13:54:19 -0400597 * Extend this class to make a new CI_Session driver.
598 * A CI_Session driver basically manages an array of name/value pairs with some sort of storage mechanism.
599 * To make a new driver, derive from (extend) CI_Session_driver. Overload the initialize method and read or create
Darren Hillc4e266b2011-08-30 15:40:27 -0400600 * session data. Then implement a save handler to write changed data to storage (sess_save), a destroy handler
601 * to remove deleted data (sess_destroy), and an access handler to expose the data (get_userdata).
Darren Hill5073a372011-08-31 13:54:19 -0400602 * Put your driver in the libraries/Session/drivers folder anywhere in the loader paths. This includes the
603 * application directory, the system directory, or any path you add with $CI->load->add_package_path().
604 * Your driver must be named CI_Session_<name>, and your filename must be Session_<name>.php,
605 * preferably also capitalized. (e.g.: CI_Session_foo in libraries/Session/drivers/Session_foo.php)
606 * Then specify the driver by setting 'sess_driver' in your config file or as a parameter when loading the CI_Session
Darren Hillc4e266b2011-08-30 15:40:27 -0400607 * object. (e.g.: $config['sess_driver'] = 'foo'; OR $CI->load->driver('session', array('sess_driver' => 'foo')); )
608 * Already provided are the Native driver, which manages the native PHP $_SESSION array, and
609 * the Cookie driver, which manages the data in a browser cookie, with optional extra storage in a database table.
610 *
Darren Hill5073a372011-08-31 13:54:19 -0400611 * @package CodeIgniter
612 * @subpackage Libraries
Darren Hillc4e266b2011-08-30 15:40:27 -0400613 * @category Sessions
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300614 * @author EllisLab Dev Team
Darren Hillc4e266b2011-08-30 15:40:27 -0400615 */
Darren Hill5073a372011-08-31 13:54:19 -0400616abstract class CI_Session_driver extends CI_Driver {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300617
Andrey Andreev0fa95bd2012-11-01 23:33:14 +0200618 /**
619 * CI Singleton
620 *
621 * @see get_instance()
622 * @var object
623 */
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300624 protected $CI;
625
Andrey Andreev0fa95bd2012-11-01 23:33:14 +0200626 // ------------------------------------------------------------------------
627
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300628 /**
629 * Constructor
630 *
631 * Gets the CI singleton, so that individual drivers
632 * don't have to do it separately.
633 *
634 * @return void
635 */
636 public function __construct()
637 {
638 $this->CI =& get_instance();
639 }
640
641 // ------------------------------------------------------------------------
642
Darren Hillc4e266b2011-08-30 15:40:27 -0400643 /**
644 * Decorate
645 *
646 * Decorates the child with the parent driver lib's methods and properties
647 *
648 * @param object Parent library object
649 * @return void
650 */
651 public function decorate($parent)
652 {
653 // Call base class decorate first
654 parent::decorate($parent);
655
dchill42c5872252012-07-30 14:53:11 -0400656 // Call initialize method now that driver has access to $this->_parent
Darren Hillc4e266b2011-08-30 15:40:27 -0400657 $this->initialize();
658 }
659
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300660 // ------------------------------------------------------------------------
661
Darren Hillc4e266b2011-08-30 15:40:27 -0400662 /**
663 * __call magic method
664 *
665 * Handles access to the parent driver library's methods
666 *
Darren Hill5073a372011-08-31 13:54:19 -0400667 * @param string Library method name
668 * @param array Method arguments (default: none)
Darren Hillc4e266b2011-08-30 15:40:27 -0400669 * @return mixed
670 */
671 public function __call($method, $args = array())
672 {
673 // Make sure the parent library uses this driver
dchill42c5872252012-07-30 14:53:11 -0400674 $this->_parent->select_driver(get_class($this));
Darren Hillc4e266b2011-08-30 15:40:27 -0400675 return parent::__call($method, $args);
676 }
677
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300678 // ------------------------------------------------------------------------
679
Darren Hillc4e266b2011-08-30 15:40:27 -0400680 /**
681 * Initialize driver
682 *
Darren Hill5073a372011-08-31 13:54:19 -0400683 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400684 */
685 protected function initialize()
686 {
687 // Overload this method to implement initialization
688 }
689
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300690 // ------------------------------------------------------------------------
691
Darren Hillc4e266b2011-08-30 15:40:27 -0400692 /**
693 * Save the session data
694 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300695 * Data in the array has changed - perform any storage synchronization
696 * necessary. The child class MUST implement this abstract method!
Darren Hillc4e266b2011-08-30 15:40:27 -0400697 *
Darren Hill5073a372011-08-31 13:54:19 -0400698 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400699 */
700 abstract public function sess_save();
701
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300702 // ------------------------------------------------------------------------
703
Darren Hillc4e266b2011-08-30 15:40:27 -0400704 /**
705 * Destroy the current session
706 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300707 * Clean up storage for this session - it has been terminated.
Darren Hillc4e266b2011-08-30 15:40:27 -0400708 * The child class MUST implement this abstract method!
709 *
Darren Hill5073a372011-08-31 13:54:19 -0400710 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400711 */
712 abstract public function sess_destroy();
713
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300714 // ------------------------------------------------------------------------
715
Darren Hillc4e266b2011-08-30 15:40:27 -0400716 /**
717 * Regenerate the current session
718 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300719 * Regenerate the session ID.
Darren Hillc4e266b2011-08-30 15:40:27 -0400720 * The child class MUST implement this abstract method!
721 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300722 * @param bool Destroy session data flag (default: false)
Darren Hill5073a372011-08-31 13:54:19 -0400723 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400724 */
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300725 abstract public function sess_regenerate($destroy = FALSE);
726
727 // ------------------------------------------------------------------------
Darren Hillc4e266b2011-08-30 15:40:27 -0400728
729 /**
730 * Get a reference to user data array
731 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300732 * Give array access to the main CI_Session object.
Darren Hillc4e266b2011-08-30 15:40:27 -0400733 * The child class MUST implement this abstract method!
734 *
Darren Hill5073a372011-08-31 13:54:19 -0400735 * @return array Reference to userdata
Darren Hillc4e266b2011-08-30 15:40:27 -0400736 */
737 abstract public function &get_userdata();
Darren Hillc4e266b2011-08-30 15:40:27 -0400738
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300739}
Darren Hillc4e266b2011-08-30 15:40:27 -0400740
741/* End of file Session.php */
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300742/* Location: ./system/libraries/Session/Session.php */