blob: 19de97994b42757a60455aa8431c4f7e0c1a243e [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 Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2008 - 2013, 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 /**
Andrey Andreevc958eeb2013-07-31 14:28:50 +030063 * Valid drivers list
64 *
65 * @var array
66 */
67 public $valid_drivers = array('native', 'cookie');
68
69 /**
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020070 * Current driver in use
71 *
72 * @var string
73 */
Andrey Andreevc958eeb2013-07-31 14:28:50 +030074 public $current = NULL;
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020075
76 /**
77 * User data
78 *
79 * @var array
80 */
Darren Hilla2ae6572011-09-01 07:36:26 -040081 protected $userdata = array();
Darren Hillc4e266b2011-08-30 15:40:27 -040082
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020083 // ------------------------------------------------------------------------
84
Darren Hillc4e266b2011-08-30 15:40:27 -040085 const FLASHDATA_KEY = 'flash';
86 const FLASHDATA_NEW = ':new:';
87 const FLASHDATA_OLD = ':old:';
88 const FLASHDATA_EXP = ':exp:';
89 const EXPIRATION_KEY = '__expirations';
90 const TEMP_EXP_DEF = 300;
91
Andrey Andreev0fa95bd2012-11-01 23:33:14 +020092 // ------------------------------------------------------------------------
93
Darren Hillc4e266b2011-08-30 15:40:27 -040094 /**
Darren Hill5073a372011-08-31 13:54:19 -040095 * CI_Session constructor
Darren Hillc4e266b2011-08-30 15:40:27 -040096 *
97 * The constructor loads the configured driver ('sess_driver' in config.php or as a parameter), running
98 * routines in its constructor, and manages flashdata aging.
99 *
Darren Hill5073a372011-08-31 13:54:19 -0400100 * @param array Configuration parameters
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300101 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400102 */
103 public function __construct(array $params = array())
104 {
Andrey Andreevf964b162013-11-12 17:04:55 +0200105 $_config =& get_instance()->config;
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300106
107 // No sessions under CLI
Andrey Andreevf964b162013-11-12 17:04:55 +0200108 if (is_cli())
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300109 {
110 return;
111 }
112
Darren Hill5073a372011-08-31 13:54:19 -0400113 log_message('debug', 'CI_Session Class Initialized');
Darren Hillc4e266b2011-08-30 15:40:27 -0400114
Andrey Andreevc958eeb2013-07-31 14:28:50 +0300115 // Add possible extra entries to our valid drivers list
Andrey Andreevf964b162013-11-12 17:04:55 +0200116 $drivers = isset($params['sess_valid_drivers']) ? $params['sess_valid_drivers'] : $_config->item('sess_valid_drivers');
Andrey Andreevc958eeb2013-07-31 14:28:50 +0300117 if ( ! empty($drivers))
Darren Hillc4e266b2011-08-30 15:40:27 -0400118 {
Andrey Andreevc958eeb2013-07-31 14:28:50 +0300119 $drivers = array_map('strtolower', (array) $drivers);
120 $this->valid_drivers = array_merge($this->valid_drivers, array_diff($drivers, $this->valid_drivers));
Darren Hillc4e266b2011-08-30 15:40:27 -0400121 }
122
123 // Get driver to load
Andrey Andreevf964b162013-11-12 17:04:55 +0200124 $driver = isset($params['sess_driver']) ? $params['sess_driver'] : $_config->item('sess_driver');
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300125 if ( ! $driver)
126 {
Andrey Andreevc958eeb2013-07-31 14:28:50 +0300127 log_message('debug', "Session: No driver name is configured, defaulting to 'cookie'.");
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300128 $driver = 'cookie';
129 }
130
Andrey Andreevc958eeb2013-07-31 14:28:50 +0300131 if ( ! in_array($driver, $this->valid_drivers))
Darren Hillc4e266b2011-08-30 15:40:27 -0400132 {
Andrey Andreevc958eeb2013-07-31 14:28:50 +0300133 log_message('error', 'Session: Configured driver name is not valid, aborting.');
134 return;
Darren Hillc4e266b2011-08-30 15:40:27 -0400135 }
136
137 // Save a copy of parameters in case drivers need access
138 $this->params = $params;
139
140 // Load driver and get array reference
141 $this->load_driver($driver);
Darren Hillc4e266b2011-08-30 15:40:27 -0400142
143 // Delete 'old' flashdata (from last request)
144 $this->_flashdata_sweep();
145
146 // Mark all new flashdata as old (data will be deleted before next request)
147 $this->_flashdata_mark();
148
149 // Delete expired tempdata
150 $this->_tempdata_sweep();
151
Darren Hill5073a372011-08-31 13:54:19 -0400152 log_message('debug', 'CI_Session routines successfully run');
Darren Hillc4e266b2011-08-30 15:40:27 -0400153 }
154
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300155 // ------------------------------------------------------------------------
156
Darren Hillc4e266b2011-08-30 15:40:27 -0400157 /**
158 * Loads session storage driver
159 *
Darren Hill5073a372011-08-31 13:54:19 -0400160 * @param string Driver classname
161 * @return object Loaded driver object
Darren Hillc4e266b2011-08-30 15:40:27 -0400162 */
163 public function load_driver($driver)
164 {
dchill4226429202012-07-31 10:55:07 -0400165 // Save reference to most recently loaded driver as library default and sync userdata
Darren Hillc4e266b2011-08-30 15:40:27 -0400166 $this->current = parent::load_driver($driver);
dchill42b1855372012-07-31 09:32:23 -0400167 $this->userdata =& $this->current->get_userdata();
Darren Hillc4e266b2011-08-30 15:40:27 -0400168 return $this->current;
169 }
170
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300171 // ------------------------------------------------------------------------
172
Darren Hillc4e266b2011-08-30 15:40:27 -0400173 /**
174 * Select default session storage driver
175 *
dchill426262d052012-11-24 18:41:13 -0500176 * @param string Driver name
Darren Hill5073a372011-08-31 13:54:19 -0400177 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400178 */
179 public function select_driver($driver)
180 {
181 // Validate driver name
dchill426262d052012-11-24 18:41:13 -0500182 $prefix = (string) get_instance()->config->item('subclass_prefix');
183 $child = strtolower(str_replace(array('CI_', $prefix, $this->lib_name.'_'), '', $driver));
184 if (in_array($child, array_map('strtolower', $this->valid_drivers)))
Darren Hillc4e266b2011-08-30 15:40:27 -0400185 {
dchill42b1855372012-07-31 09:32:23 -0400186 // See if driver is loaded
dchill42b1855372012-07-31 09:32:23 -0400187 if (isset($this->$child))
Darren Hillc4e266b2011-08-30 15:40:27 -0400188 {
dchill42aee92652012-08-26 21:45:35 -0400189 // See if driver is already current
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300190 if ($this->$child !== $this->current)
191 {
dchill42aee92652012-08-26 21:45:35 -0400192 // Make driver current and sync userdata
193 $this->current = $this->$child;
194 $this->userdata =& $this->current->get_userdata();
195 }
Darren Hillc4e266b2011-08-30 15:40:27 -0400196 }
197 else
198 {
dchill4226429202012-07-31 10:55:07 -0400199 // Load new driver
dchill42aee92652012-08-26 21:45:35 -0400200 $this->load_driver($child);
Darren Hillc4e266b2011-08-30 15:40:27 -0400201 }
202 }
203 }
204
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300205 // ------------------------------------------------------------------------
206
Darren Hillc4e266b2011-08-30 15:40:27 -0400207 /**
208 * Destroy the current session
209 *
Darren Hill5073a372011-08-31 13:54:19 -0400210 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400211 */
212 public function sess_destroy()
213 {
214 // Just call destroy on driver
215 $this->current->sess_destroy();
216 }
217
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300218 // ------------------------------------------------------------------------
219
Darren Hillc4e266b2011-08-30 15:40:27 -0400220 /**
221 * Regenerate the current session
222 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300223 * @param bool Destroy session data flag (default: false)
Darren Hill5073a372011-08-31 13:54:19 -0400224 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400225 */
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300226 public function sess_regenerate($destroy = FALSE)
Darren Hillc4e266b2011-08-30 15:40:27 -0400227 {
dchill4226429202012-07-31 10:55:07 -0400228 // Call regenerate on driver and resync userdata
Darren Hillc4e266b2011-08-30 15:40:27 -0400229 $this->current->sess_regenerate($destroy);
dchill4226429202012-07-31 10:55:07 -0400230 $this->userdata =& $this->current->get_userdata();
Darren Hillc4e266b2011-08-30 15:40:27 -0400231 }
232
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300233 // ------------------------------------------------------------------------
234
Darren Hillc4e266b2011-08-30 15:40:27 -0400235 /**
236 * Fetch a specific item from the session array
237 *
Darren Hill5073a372011-08-31 13:54:19 -0400238 * @param string Item key
dchill42c5872252012-07-30 14:53:11 -0400239 * @return string Item value or NULL if not found
Darren Hillc4e266b2011-08-30 15:40:27 -0400240 */
241 public function userdata($item)
242 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300243 return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
Darren Hillc4e266b2011-08-30 15:40:27 -0400244 }
245
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300246 // ------------------------------------------------------------------------
247
Darren Hillc4e266b2011-08-30 15:40:27 -0400248 /**
249 * Fetch all session data
250 *
251 * @return array User data array
252 */
253 public function all_userdata()
254 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300255 return isset($this->userdata) ? $this->userdata : NULL;
Darren Hillc4e266b2011-08-30 15:40:27 -0400256 }
257
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300258 // ------------------------------------------------------------------------
259
Darren Hillc4e266b2011-08-30 15:40:27 -0400260 /**
dchill42c5079de2012-07-23 10:53:47 -0400261 * Fetch all flashdata
262 *
vkeranov3bb40292012-10-27 18:47:26 +0300263 * @return array Flash data array
dchill42c5079de2012-07-23 10:53:47 -0400264 */
265 public function all_flashdata()
266 {
267 $out = array();
268
269 // loop through all userdata
270 foreach ($this->all_userdata() as $key => $val)
271 {
dchill42c5872252012-07-30 14:53:11 -0400272 // if it contains flashdata, add it
dchill42c5079de2012-07-23 10:53:47 -0400273 if (strpos($key, self::FLASHDATA_KEY.self::FLASHDATA_OLD) !== FALSE)
274 {
dchill4226429202012-07-31 10:55:07 -0400275 $key = str_replace(self::FLASHDATA_KEY.self::FLASHDATA_OLD, '', $key);
dchill42c5079de2012-07-23 10:53:47 -0400276 $out[$key] = $val;
277 }
278 }
279 return $out;
280 }
281
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300282 // ------------------------------------------------------------------------
283
dchill42c5079de2012-07-23 10:53:47 -0400284 /**
Darren Hillc4e266b2011-08-30 15:40:27 -0400285 * Add or change data in the "userdata" array
286 *
Darren Hill5073a372011-08-31 13:54:19 -0400287 * @param mixed Item name or array of items
288 * @param string Item value or empty string
289 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400290 */
291 public function set_userdata($newdata = array(), $newval = '')
292 {
293 // Wrap params as array if singular
294 if (is_string($newdata))
295 {
296 $newdata = array($newdata => $newval);
297 }
298
299 // Set each name/value pair
300 if (count($newdata) > 0)
301 {
302 foreach ($newdata as $key => $val)
303 {
304 $this->userdata[$key] = $val;
305 }
306 }
307
308 // Tell driver data changed
309 $this->current->sess_save();
310 }
311
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300312 // ------------------------------------------------------------------------
313
Darren Hillc4e266b2011-08-30 15:40:27 -0400314 /**
315 * Delete a session variable from the "userdata" array
316 *
Darren Hill5073a372011-08-31 13:54:19 -0400317 * @param mixed Item name or array of item names
318 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400319 */
320 public function unset_userdata($newdata = array())
321 {
322 // Wrap single name as array
323 if (is_string($newdata))
324 {
325 $newdata = array($newdata => '');
326 }
327
328 // Unset each item name
329 if (count($newdata) > 0)
330 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300331 foreach (array_keys($newdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400332 {
333 unset($this->userdata[$key]);
334 }
335 }
336
337 // Tell driver data changed
338 $this->current->sess_save();
339 }
340
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300341 // ------------------------------------------------------------------------
342
Darren Hillc4e266b2011-08-30 15:40:27 -0400343 /**
344 * Determine if an item exists
345 *
Darren Hill5073a372011-08-31 13:54:19 -0400346 * @param string Item name
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300347 * @return bool
Darren Hillc4e266b2011-08-30 15:40:27 -0400348 */
349 public function has_userdata($item)
350 {
Darren Hillc4e266b2011-08-30 15:40:27 -0400351 return isset($this->userdata[$item]);
352 }
353
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300354 // ------------------------------------------------------------------------
355
Darren Hillc4e266b2011-08-30 15:40:27 -0400356 /**
357 * Add or change flashdata, only available until the next request
358 *
Darren Hill5073a372011-08-31 13:54:19 -0400359 * @param mixed Item name or array of items
360 * @param string Item value or empty string
361 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400362 */
363 public function set_flashdata($newdata = array(), $newval = '')
364 {
365 // Wrap item as array if singular
366 if (is_string($newdata))
367 {
368 $newdata = array($newdata => $newval);
369 }
370
371 // Prepend each key name and set value
372 if (count($newdata) > 0)
373 {
374 foreach ($newdata as $key => $val)
375 {
376 $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key;
377 $this->set_userdata($flashdata_key, $val);
378 }
379 }
380 }
381
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300382 // ------------------------------------------------------------------------
383
Darren Hillc4e266b2011-08-30 15:40:27 -0400384 /**
385 * Keeps existing flashdata available to next request.
386 *
Johnathan Croom9d9849b2012-11-24 13:03:13 -0700387 * @param mixed Item key(s)
Darren Hill5073a372011-08-31 13:54:19 -0400388 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400389 */
390 public function keep_flashdata($key)
391 {
Johnathan Croom8d8543d2012-11-25 10:36:57 -0700392
393 if (is_array($key))
Johnathan Croom4beca5c2012-11-23 18:32:46 -0700394 {
Johnathan Croom8d8543d2012-11-25 10:36:57 -0700395 foreach ($key as $k)
396 {
397 $this->keep_flashdata($k);
398 }
399
400 return;
Johnathan Croom4beca5c2012-11-23 18:32:46 -0700401 }
Darren Hillc4e266b2011-08-30 15:40:27 -0400402
Darren Hillc4e266b2011-08-30 15:40:27 -0400403 // 'old' flashdata gets removed. Here we mark all flashdata as 'new' to preserve it from _flashdata_sweep()
404 // Note the function will return NULL if the $key provided cannot be found
405 $old_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key;
406 $value = $this->userdata($old_flashdata_key);
407
Darren Hill5073a372011-08-31 13:54:19 -0400408 $new_flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_NEW.$key;
409 $this->set_userdata($new_flashdata_key, $value);
410 }
411
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300412 // ------------------------------------------------------------------------
413
Darren Hillc4e266b2011-08-30 15:40:27 -0400414 /**
415 * Fetch a specific flashdata item from the session array
416 *
417 * @param string Item key
418 * @return string
419 */
420 public function flashdata($key)
421 {
422 // Prepend key and retrieve value
423 $flashdata_key = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$key;
424 return $this->userdata($flashdata_key);
425 }
426
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300427 // ------------------------------------------------------------------------
428
Darren Hillc4e266b2011-08-30 15:40:27 -0400429 /**
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300430 * Add or change tempdata, only available until expiration
Darren Hillc4e266b2011-08-30 15:40:27 -0400431 *
432 * @param mixed Item name or array of items
433 * @param string Item value or empty string
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300434 * @param int Item lifetime in seconds or 0 for default
Darren Hillc4e266b2011-08-30 15:40:27 -0400435 * @return void
436 */
437 public function set_tempdata($newdata = array(), $newval = '', $expire = 0)
438 {
439 // Set expiration time
440 $expire = time() + ($expire ? $expire : self::TEMP_EXP_DEF);
441
442 // Wrap item as array if singular
443 if (is_string($newdata))
444 {
445 $newdata = array($newdata => $newval);
446 }
447
448 // Get or create expiration list
449 $expirations = $this->userdata(self::EXPIRATION_KEY);
dchill4277ee3fd2012-07-24 11:50:01 -0400450 if ( ! $expirations)
Darren Hillc4e266b2011-08-30 15:40:27 -0400451 {
452 $expirations = array();
453 }
454
455 // Prepend each key name and set value
456 if (count($newdata) > 0)
457 {
458 foreach ($newdata as $key => $val)
459 {
460 $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
461 $expirations[$tempdata_key] = $expire;
462 $this->set_userdata($tempdata_key, $val);
463 }
464 }
465
466 // Update expiration list
467 $this->set_userdata(self::EXPIRATION_KEY, $expirations);
468 }
469
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300470 // ------------------------------------------------------------------------
471
Darren Hillc4e266b2011-08-30 15:40:27 -0400472 /**
473 * Delete a temporary session variable from the "userdata" array
474 *
Darren Hill5073a372011-08-31 13:54:19 -0400475 * @param mixed Item name or array of item names
476 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400477 */
478 public function unset_tempdata($newdata = array())
479 {
480 // Get expirations list
481 $expirations = $this->userdata(self::EXPIRATION_KEY);
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300482 if (empty($expirations))
Darren Hillc4e266b2011-08-30 15:40:27 -0400483 {
484 // Nothing to do
485 return;
486 }
487
488 // Wrap single name as array
489 if (is_string($newdata))
490 {
491 $newdata = array($newdata => '');
492 }
493
494 // Prepend each item name and unset
495 if (count($newdata) > 0)
496 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300497 foreach (array_keys($newdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400498 {
499 $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
500 unset($expirations[$tempdata_key]);
501 $this->unset_userdata($tempdata_key);
502 }
503 }
504
505 // Update expiration list
506 $this->set_userdata(self::EXPIRATION_KEY, $expirations);
507 }
508
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300509 // ------------------------------------------------------------------------
510
Darren Hillc4e266b2011-08-30 15:40:27 -0400511 /**
512 * Fetch a specific tempdata item from the session array
513 *
Darren Hill5073a372011-08-31 13:54:19 -0400514 * @param string Item key
515 * @return string
Darren Hillc4e266b2011-08-30 15:40:27 -0400516 */
517 public function tempdata($key)
518 {
519 // Prepend key and return value
520 $tempdata_key = self::FLASHDATA_KEY.self::FLASHDATA_EXP.$key;
521 return $this->userdata($tempdata_key);
522 }
523
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300524 // ------------------------------------------------------------------------
525
Darren Hillc4e266b2011-08-30 15:40:27 -0400526 /**
527 * Identifies flashdata as 'old' for removal
528 * when _flashdata_sweep() runs.
529 *
Darren Hillc4e266b2011-08-30 15:40:27 -0400530 * @return void
531 */
Darren Hilla2ae6572011-09-01 07:36:26 -0400532 protected function _flashdata_mark()
Darren Hillc4e266b2011-08-30 15:40:27 -0400533 {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300534 foreach ($this->all_userdata() as $name => $value)
Darren Hillc4e266b2011-08-30 15:40:27 -0400535 {
536 $parts = explode(self::FLASHDATA_NEW, $name);
Andrey Andreeve24eed72012-11-02 23:33:45 +0200537 if (count($parts) === 2)
Darren Hillc4e266b2011-08-30 15:40:27 -0400538 {
539 $new_name = self::FLASHDATA_KEY.self::FLASHDATA_OLD.$parts[1];
540 $this->set_userdata($new_name, $value);
541 $this->unset_userdata($name);
542 }
543 }
544 }
545
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300546 // ------------------------------------------------------------------------
547
Darren Hillc4e266b2011-08-30 15:40:27 -0400548 /**
549 * Removes all flashdata marked as 'old'
550 *
Darren Hillc4e266b2011-08-30 15:40:27 -0400551 * @return void
552 */
Darren Hilla2ae6572011-09-01 07:36:26 -0400553 protected function _flashdata_sweep()
Darren Hillc4e266b2011-08-30 15:40:27 -0400554 {
555 $userdata = $this->all_userdata();
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300556 foreach (array_keys($userdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400557 {
558 if (strpos($key, self::FLASHDATA_OLD))
559 {
560 $this->unset_userdata($key);
561 }
562 }
563 }
564
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300565 // ------------------------------------------------------------------------
566
Darren Hillc4e266b2011-08-30 15:40:27 -0400567 /**
568 * Removes all expired tempdata
569 *
Darren Hillc4e266b2011-08-30 15:40:27 -0400570 * @return void
571 */
Darren Hilla2ae6572011-09-01 07:36:26 -0400572 protected function _tempdata_sweep()
Darren Hillc4e266b2011-08-30 15:40:27 -0400573 {
574 // Get expirations list
575 $expirations = $this->userdata(self::EXPIRATION_KEY);
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300576 if (empty($expirations))
Darren Hillc4e266b2011-08-30 15:40:27 -0400577 {
578 // Nothing to do
579 return;
580 }
581
582 // Unset expired elements
583 $now = time();
584 $userdata = $this->all_userdata();
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300585 foreach (array_keys($userdata) as $key)
Darren Hillc4e266b2011-08-30 15:40:27 -0400586 {
587 if (strpos($key, self::FLASHDATA_EXP) && $expirations[$key] < $now)
588 {
589 unset($expirations[$key]);
590 $this->unset_userdata($key);
591 }
592 }
593
594 // Update expiration list
595 $this->set_userdata(self::EXPIRATION_KEY, $expirations);
596 }
Darren Hillc4e266b2011-08-30 15:40:27 -0400597
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300598}
599
600// ------------------------------------------------------------------------
Darren Hillc4e266b2011-08-30 15:40:27 -0400601
602/**
Darren Hill5073a372011-08-31 13:54:19 -0400603 * CI_Session_driver Class
Darren Hillc4e266b2011-08-30 15:40:27 -0400604 *
Darren Hill5073a372011-08-31 13:54:19 -0400605 * Extend this class to make a new CI_Session driver.
606 * A CI_Session driver basically manages an array of name/value pairs with some sort of storage mechanism.
607 * 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 -0400608 * session data. Then implement a save handler to write changed data to storage (sess_save), a destroy handler
609 * to remove deleted data (sess_destroy), and an access handler to expose the data (get_userdata).
Darren Hill5073a372011-08-31 13:54:19 -0400610 * Put your driver in the libraries/Session/drivers folder anywhere in the loader paths. This includes the
611 * application directory, the system directory, or any path you add with $CI->load->add_package_path().
612 * Your driver must be named CI_Session_<name>, and your filename must be Session_<name>.php,
613 * preferably also capitalized. (e.g.: CI_Session_foo in libraries/Session/drivers/Session_foo.php)
614 * 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 -0400615 * object. (e.g.: $config['sess_driver'] = 'foo'; OR $CI->load->driver('session', array('sess_driver' => 'foo')); )
616 * Already provided are the Native driver, which manages the native PHP $_SESSION array, and
617 * the Cookie driver, which manages the data in a browser cookie, with optional extra storage in a database table.
618 *
Darren Hill5073a372011-08-31 13:54:19 -0400619 * @package CodeIgniter
620 * @subpackage Libraries
Darren Hillc4e266b2011-08-30 15:40:27 -0400621 * @category Sessions
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300622 * @author EllisLab Dev Team
Darren Hillc4e266b2011-08-30 15:40:27 -0400623 */
Darren Hill5073a372011-08-31 13:54:19 -0400624abstract class CI_Session_driver extends CI_Driver {
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300625
Andrey Andreev0fa95bd2012-11-01 23:33:14 +0200626 /**
627 * CI Singleton
628 *
629 * @see get_instance()
630 * @var object
631 */
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300632 protected $CI;
633
Andrey Andreev0fa95bd2012-11-01 23:33:14 +0200634 // ------------------------------------------------------------------------
635
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300636 /**
637 * Constructor
638 *
639 * Gets the CI singleton, so that individual drivers
640 * don't have to do it separately.
641 *
642 * @return void
643 */
644 public function __construct()
645 {
646 $this->CI =& get_instance();
647 }
648
649 // ------------------------------------------------------------------------
650
Darren Hillc4e266b2011-08-30 15:40:27 -0400651 /**
652 * Decorate
653 *
654 * Decorates the child with the parent driver lib's methods and properties
655 *
656 * @param object Parent library object
657 * @return void
658 */
659 public function decorate($parent)
660 {
661 // Call base class decorate first
662 parent::decorate($parent);
663
dchill42c5872252012-07-30 14:53:11 -0400664 // Call initialize method now that driver has access to $this->_parent
Darren Hillc4e266b2011-08-30 15:40:27 -0400665 $this->initialize();
666 }
667
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300668 // ------------------------------------------------------------------------
669
Darren Hillc4e266b2011-08-30 15:40:27 -0400670 /**
671 * __call magic method
672 *
673 * Handles access to the parent driver library's methods
674 *
Darren Hill5073a372011-08-31 13:54:19 -0400675 * @param string Library method name
676 * @param array Method arguments (default: none)
Darren Hillc4e266b2011-08-30 15:40:27 -0400677 * @return mixed
678 */
679 public function __call($method, $args = array())
680 {
681 // Make sure the parent library uses this driver
dchill42c5872252012-07-30 14:53:11 -0400682 $this->_parent->select_driver(get_class($this));
Darren Hillc4e266b2011-08-30 15:40:27 -0400683 return parent::__call($method, $args);
684 }
685
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300686 // ------------------------------------------------------------------------
687
Darren Hillc4e266b2011-08-30 15:40:27 -0400688 /**
689 * Initialize driver
690 *
Darren Hill5073a372011-08-31 13:54:19 -0400691 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400692 */
693 protected function initialize()
694 {
695 // Overload this method to implement initialization
696 }
697
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300698 // ------------------------------------------------------------------------
699
Darren Hillc4e266b2011-08-30 15:40:27 -0400700 /**
701 * Save the session data
702 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300703 * Data in the array has changed - perform any storage synchronization
704 * necessary. The child class MUST implement this abstract method!
Darren Hillc4e266b2011-08-30 15:40:27 -0400705 *
Darren Hill5073a372011-08-31 13:54:19 -0400706 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400707 */
708 abstract public function sess_save();
709
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300710 // ------------------------------------------------------------------------
711
Darren Hillc4e266b2011-08-30 15:40:27 -0400712 /**
713 * Destroy the current session
714 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300715 * Clean up storage for this session - it has been terminated.
Darren Hillc4e266b2011-08-30 15:40:27 -0400716 * The child class MUST implement this abstract method!
717 *
Darren Hill5073a372011-08-31 13:54:19 -0400718 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400719 */
720 abstract public function sess_destroy();
721
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300722 // ------------------------------------------------------------------------
723
Darren Hillc4e266b2011-08-30 15:40:27 -0400724 /**
725 * Regenerate the current session
726 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300727 * Regenerate the session ID.
Darren Hillc4e266b2011-08-30 15:40:27 -0400728 * The child class MUST implement this abstract method!
729 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300730 * @param bool Destroy session data flag (default: false)
Darren Hill5073a372011-08-31 13:54:19 -0400731 * @return void
Darren Hillc4e266b2011-08-30 15:40:27 -0400732 */
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300733 abstract public function sess_regenerate($destroy = FALSE);
734
735 // ------------------------------------------------------------------------
Darren Hillc4e266b2011-08-30 15:40:27 -0400736
737 /**
738 * Get a reference to user data array
739 *
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300740 * Give array access to the main CI_Session object.
Darren Hillc4e266b2011-08-30 15:40:27 -0400741 * The child class MUST implement this abstract method!
742 *
Darren Hill5073a372011-08-31 13:54:19 -0400743 * @return array Reference to userdata
Darren Hillc4e266b2011-08-30 15:40:27 -0400744 */
745 abstract public function &get_userdata();
Darren Hillc4e266b2011-08-30 15:40:27 -0400746
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300747}
Darren Hillc4e266b2011-08-30 15:40:27 -0400748
749/* End of file Session.php */
Andrey Andreev9ffcee62012-09-05 16:25:16 +0300750/* Location: ./system/libraries/Session/Session.php */