blob: 137b037b8be0e18d22a70aaa8a605a2383b3a497 [file] [log] [blame]
Andrey Andreev57ffbbb2011-12-25 04:48:47 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev57ffbbb2011-12-25 04:48:47 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev57ffbbb2011-12-25 04:48:47 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * 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.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * Session Class
32 *
33 * @package CodeIgniter
34 * @subpackage Libraries
35 * @category Sessions
Derek Jonesf4a4bd82011-10-20 12:18:42 -050036 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000037 * @link http://codeigniter.com/user_guide/libraries/sessions.html
38 */
39class CI_Session {
40
Andrey Andreev57ffbbb2011-12-25 04:48:47 +020041 public $sess_encrypt_cookie = FALSE;
42 public $sess_use_database = FALSE;
43 public $sess_table_name = '';
44 public $sess_expiration = 7200;
45 public $sess_expire_on_close = FALSE;
46 public $sess_match_ip = FALSE;
47 public $sess_match_useragent = TRUE;
48 public $sess_cookie_name = 'ci_session';
49 public $cookie_prefix = '';
50 public $cookie_path = '';
51 public $cookie_domain = '';
52 public $cookie_secure = FALSE;
53 public $sess_time_to_update = 300;
54 public $encryption_key = '';
55 public $flashdata_key = 'flash';
56 public $time_reference = 'time';
57 public $gc_probability = 5;
58 public $userdata = array();
59 public $CI;
60 public $now;
Derek Allard2067d1a2008-11-13 22:59:24 +000061
62 /**
63 * Session Constructor
64 *
65 * The constructor runs the session routines automatically
66 * whenever the class is instantiated.
67 */
Greg Akera9263282010-11-10 15:26:43 -060068 public function __construct($params = array())
Derek Allard2067d1a2008-11-13 22:59:24 +000069 {
70 log_message('debug', "Session Class Initialized");
71
72 // Set the super object to a local variable for use throughout the class
73 $this->CI =& get_instance();
74
75 // Set all the session preferences, which can either be set
76 // manually via the $params array above or via the config file
tobiasbgba6432c2011-02-18 21:58:48 +010077 foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)
Derek Allard2067d1a2008-11-13 22:59:24 +000078 {
79 $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);
80 }
81
Derek Jones5485db52010-08-30 21:31:08 -050082 if ($this->encryption_key == '')
83 {
84 show_error('In order to use the Session class you are required to set an encryption key in your config file.');
85 }
86
Derek Allard2067d1a2008-11-13 22:59:24 +000087 // Load the string helper so we can use the strip_slashes() function
88 $this->CI->load->helper('string');
89
90 // Do we need encryption? If so, load the encryption class
91 if ($this->sess_encrypt_cookie == TRUE)
92 {
93 $this->CI->load->library('encrypt');
94 }
95
Derek Jones4b9c6292011-07-01 17:40:48 -050096 // Are we using a database? If so, load it
Derek Allard2067d1a2008-11-13 22:59:24 +000097 if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
98 {
99 $this->CI->load->database();
100 }
101
Derek Jones4b9c6292011-07-01 17:40:48 -0500102 // Set the "now" time. Can either be GMT or server time, based on the
103 // config prefs. We use this to set the "last activity" time
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 $this->now = $this->_get_time();
105
106 // Set the session length. If the session expiration is
107 // set to zero we'll set the expiration two years from now.
108 if ($this->sess_expiration == 0)
109 {
110 $this->sess_expiration = (60*60*24*365*2);
111 }
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200112
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 // Set the cookie name
114 $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;
115
116 // Run the Session routine. If a session doesn't exist we'll
Derek Jones4b9c6292011-07-01 17:40:48 -0500117 // create a new one. If it does, we'll update it.
Derek Allard2067d1a2008-11-13 22:59:24 +0000118 if ( ! $this->sess_read())
119 {
120 $this->sess_create();
121 }
122 else
123 {
124 $this->sess_update();
125 }
126
127 // Delete 'old' flashdata (from last request)
Barry Mienydd671972010-10-04 16:33:58 +0200128 $this->_flashdata_sweep();
Derek Allard2067d1a2008-11-13 22:59:24 +0000129
130 // Mark all new flashdata as old (data will be deleted before next request)
Barry Mienydd671972010-10-04 16:33:58 +0200131 $this->_flashdata_mark();
Derek Allard2067d1a2008-11-13 22:59:24 +0000132
133 // Delete expired sessions if necessary
134 $this->_sess_gc();
135
136 log_message('debug', "Session routines successfully run");
137 }
138
139 // --------------------------------------------------------------------
140
141 /**
142 * Fetch the current session data if it exists
143 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 * @return bool
145 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200146 public function sess_read()
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 {
148 // Fetch the cookie
149 $session = $this->CI->input->cookie($this->sess_cookie_name);
150
Derek Jones4b9c6292011-07-01 17:40:48 -0500151 // No cookie? Goodbye cruel world!...
Derek Allard2067d1a2008-11-13 22:59:24 +0000152 if ($session === FALSE)
153 {
154 log_message('debug', 'A session cookie was not found.');
155 return FALSE;
156 }
157
158 // Decrypt the cookie data
159 if ($this->sess_encrypt_cookie == TRUE)
160 {
161 $session = $this->CI->encrypt->decode($session);
162 }
163 else
164 {
165 // encryption was not used, so we need to check the md5 hash
166 $hash = substr($session, strlen($session)-32); // get last 32 chars
167 $session = substr($session, 0, strlen($session)-32);
168
Derek Jones4b9c6292011-07-01 17:40:48 -0500169 // Does the md5 hash match? This is to prevent manipulation of session data in userspace
170 if ($hash !== md5($session.$this->encryption_key))
Derek Allard2067d1a2008-11-13 22:59:24 +0000171 {
172 log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
173 $this->sess_destroy();
174 return FALSE;
175 }
176 }
177
178 // Unserialize the session array
179 $session = $this->_unserialize($session);
180
181 // Is the session data we unserialized an array with the correct format?
182 if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
183 {
184 $this->sess_destroy();
185 return FALSE;
186 }
187
188 // Is the session current?
189 if (($session['last_activity'] + $this->sess_expiration) < $this->now)
190 {
191 $this->sess_destroy();
192 return FALSE;
193 }
194
195 // Does the IP Match?
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200196 if ($this->sess_match_ip == TRUE AND $session['ip_address'] !== $this->CI->input->ip_address())
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 {
198 $this->sess_destroy();
199 return FALSE;
200 }
201
202 // Does the User Agent Match?
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200203 if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 {
205 $this->sess_destroy();
206 return FALSE;
207 }
208
209 // Is there a corresponding session in the DB?
210 if ($this->sess_use_database === TRUE)
211 {
212 $this->CI->db->where('session_id', $session['session_id']);
213
214 if ($this->sess_match_ip == TRUE)
215 {
216 $this->CI->db->where('ip_address', $session['ip_address']);
217 }
218
219 if ($this->sess_match_useragent == TRUE)
220 {
221 $this->CI->db->where('user_agent', $session['user_agent']);
222 }
223
224 $query = $this->CI->db->get($this->sess_table_name);
225
Derek Jones4b9c6292011-07-01 17:40:48 -0500226 // No result? Kill it!
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200227 if ($query->num_rows() === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000228 {
229 $this->sess_destroy();
230 return FALSE;
231 }
232
Derek Jones4b9c6292011-07-01 17:40:48 -0500233 // Is there custom data? If so, add it to the main session array
Derek Allard2067d1a2008-11-13 22:59:24 +0000234 $row = $query->row();
235 if (isset($row->user_data) AND $row->user_data != '')
236 {
237 $custom_data = $this->_unserialize($row->user_data);
238
239 if (is_array($custom_data))
240 {
241 foreach ($custom_data as $key => $val)
242 {
243 $session[$key] = $val;
244 }
245 }
246 }
247 }
248
249 // Session is valid!
250 $this->userdata = $session;
251 unset($session);
252
253 return TRUE;
254 }
255
256 // --------------------------------------------------------------------
257
258 /**
259 * Write the session data
260 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 * @return void
262 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200263 public function sess_write()
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500265 // Are we saving custom data to the DB? If not, all we do is update the cookie
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 if ($this->sess_use_database === FALSE)
267 {
268 $this->_set_cookie();
269 return;
270 }
271
272 // set the custom userdata, the session data we will set in a second
273 $custom_userdata = $this->userdata;
274 $cookie_userdata = array();
275
276 // Before continuing, we need to determine if there is any custom data to deal with.
277 // Let's determine this by removing the default indexes to see if there's anything left in the array
278 // and set the session data while we're at it
279 foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
280 {
281 unset($custom_userdata[$val]);
282 $cookie_userdata[$val] = $this->userdata[$val];
283 }
284
Derek Jones4b9c6292011-07-01 17:40:48 -0500285 // Did we find any custom data? If not, we turn the empty array into a string
Derek Allard2067d1a2008-11-13 22:59:24 +0000286 // since there's no reason to serialize and store an empty array in the DB
287 if (count($custom_userdata) === 0)
288 {
289 $custom_userdata = '';
290 }
291 else
292 {
293 // Serialize the custom data array so we can store it
294 $custom_userdata = $this->_serialize($custom_userdata);
295 }
296
297 // Run the update query
298 $this->CI->db->where('session_id', $this->userdata['session_id']);
299 $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));
300
Derek Jones4b9c6292011-07-01 17:40:48 -0500301 // Write the cookie. Notice that we manually pass the cookie data array to the
Derek Allard2067d1a2008-11-13 22:59:24 +0000302 // _set_cookie() function. Normally that function will store $this->userdata, but
303 // in this case that array contains custom data, which we do not want in the cookie.
304 $this->_set_cookie($cookie_userdata);
305 }
306
307 // --------------------------------------------------------------------
308
309 /**
310 * Create a new session
311 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000312 * @return void
313 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200314 public function sess_create()
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 {
316 $sessid = '';
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200317 do
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 {
319 $sessid .= mt_rand(0, mt_getrandmax());
320 }
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200321 while (strlen($sessid) < 32);
Derek Allard2067d1a2008-11-13 22:59:24 +0000322
323 // To make the session ID even more secure we'll combine it with the user's IP
324 $sessid .= $this->CI->input->ip_address();
325
326 $this->userdata = array(
Barry Mienydd671972010-10-04 16:33:58 +0200327 'session_id' => md5(uniqid($sessid, TRUE)),
328 'ip_address' => $this->CI->input->ip_address(),
Greg Aker50671cf2011-04-20 11:36:45 -0500329 'user_agent' => substr($this->CI->input->user_agent(), 0, 120),
Kyle Farrisf57a46b2011-08-29 23:26:07 -0300330 'last_activity' => $this->now,
331 'user_data' => ''
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 );
333
334
335 // Save the data to the DB if needed
336 if ($this->sess_use_database === TRUE)
337 {
338 $this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));
339 }
340
341 // Write the cookie
342 $this->_set_cookie();
343 }
344
345 // --------------------------------------------------------------------
346
347 /**
348 * Update an existing session
349 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 * @return void
351 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200352 public function sess_update()
Derek Allard2067d1a2008-11-13 22:59:24 +0000353 {
354 // We only update the session every five minutes by default
355 if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
356 {
357 return;
358 }
359
360 // Save the old session id so we know which record to
361 // update in the database if we need it
362 $old_sessid = $this->userdata['session_id'];
363 $new_sessid = '';
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200364 do
Derek Allard2067d1a2008-11-13 22:59:24 +0000365 {
366 $new_sessid .= mt_rand(0, mt_getrandmax());
367 }
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200368 while (strlen($new_sessid) < 32);
Derek Allard2067d1a2008-11-13 22:59:24 +0000369
370 // To make the session ID even more secure we'll combine it with the user's IP
371 $new_sessid .= $this->CI->input->ip_address();
372
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200373 // Turn it into a hash and update the session data array
374 $this->userdata['session_id'] = $new_sessid = md5(uniqid($new_sessid, TRUE));
Derek Allard2067d1a2008-11-13 22:59:24 +0000375 $this->userdata['last_activity'] = $this->now;
376
377 // _set_cookie() will handle this for us if we aren't using database sessions
378 // by pushing all userdata to the cookie.
379 $cookie_data = NULL;
380
381 // Update the session ID and last_activity field in the DB if needed
382 if ($this->sess_use_database === TRUE)
383 {
384 // set cookie explicitly to only have our session data
385 $cookie_data = array();
386 foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
387 {
388 $cookie_data[$val] = $this->userdata[$val];
389 }
390
391 $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
392 }
393
394 // Write the cookie
395 $this->_set_cookie($cookie_data);
396 }
397
398 // --------------------------------------------------------------------
399
400 /**
401 * Destroy the current session
402 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000403 * @return void
404 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200405 public function sess_destroy()
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 {
407 // Kill the session DB row
408 if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))
409 {
410 $this->CI->db->where('session_id', $this->userdata['session_id']);
411 $this->CI->db->delete($this->sess_table_name);
412 }
413
414 // Kill the cookie
415 setcookie(
416 $this->sess_cookie_name,
417 addslashes(serialize(array())),
418 ($this->now - 31500000),
419 $this->cookie_path,
420 $this->cookie_domain,
421 0
422 );
423 }
424
425 // --------------------------------------------------------------------
426
427 /**
428 * Fetch a specific item from the session array
429 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 * @param string
431 * @return string
432 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200433 public function userdata($item)
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 {
435 return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];
436 }
437
438 // --------------------------------------------------------------------
439
440 /**
441 * Fetch all session data
442 *
Greg Aker34033662011-04-18 11:18:09 -0500443 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000444 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200445 public function all_userdata()
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 {
Greg Aker34033662011-04-18 11:18:09 -0500447 return $this->userdata;
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 }
449
450 // --------------------------------------------------------------------
451
452 /**
453 * Add or change data in the "userdata" array
454 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 * @param mixed
456 * @param string
457 * @return void
458 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200459 public function set_userdata($newdata = array(), $newval = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 {
461 if (is_string($newdata))
462 {
463 $newdata = array($newdata => $newval);
464 }
465
466 if (count($newdata) > 0)
467 {
468 foreach ($newdata as $key => $val)
469 {
470 $this->userdata[$key] = $val;
471 }
472 }
473
474 $this->sess_write();
475 }
476
477 // --------------------------------------------------------------------
478
479 /**
480 * Delete a session variable from the "userdata" array
481 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 * @return void
483 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200484 public function unset_userdata($newdata = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000485 {
486 if (is_string($newdata))
487 {
488 $newdata = array($newdata => '');
489 }
490
491 if (count($newdata) > 0)
492 {
493 foreach ($newdata as $key => $val)
494 {
495 unset($this->userdata[$key]);
496 }
497 }
498
499 $this->sess_write();
500 }
501
502 // ------------------------------------------------------------------------
503
504 /**
505 * Add or change flashdata, only available
506 * until the next request
507 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000508 * @param mixed
509 * @param string
510 * @return void
511 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200512 public function set_flashdata($newdata = array(), $newval = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000513 {
514 if (is_string($newdata))
515 {
516 $newdata = array($newdata => $newval);
517 }
518
519 if (count($newdata) > 0)
520 {
521 foreach ($newdata as $key => $val)
522 {
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200523 $this->set_userdata($this->flashdata_key.':new:'.$key, $val);
Derek Allard2067d1a2008-11-13 22:59:24 +0000524 }
525 }
526 }
527
528 // ------------------------------------------------------------------------
529
530 /**
531 * Keeps existing flashdata available to next request.
532 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000533 * @param string
534 * @return void
535 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200536 public function keep_flashdata($key)
Derek Allard2067d1a2008-11-13 22:59:24 +0000537 {
Derek Jones4b9c6292011-07-01 17:40:48 -0500538 // 'old' flashdata gets removed. Here we mark all
Derek Allard2067d1a2008-11-13 22:59:24 +0000539 // flashdata as 'new' to preserve it from _flashdata_sweep()
540 // Note the function will return FALSE if the $key
541 // provided cannot be found
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200542 $value = $this->userdata($this->flashdata_key.':old:'.$key);
Derek Allard2067d1a2008-11-13 22:59:24 +0000543
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200544 $this->set_userdata($this->flashdata_key.':new:'.$key, $value);
Derek Allard2067d1a2008-11-13 22:59:24 +0000545 }
546
547 // ------------------------------------------------------------------------
548
549 /**
550 * Fetch a specific flashdata item from the session array
551 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000552 * @param string
553 * @return string
554 */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200555 public function flashdata($key)
Derek Allard2067d1a2008-11-13 22:59:24 +0000556 {
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200557 return $this->userdata($this->flashdata_key.':old:'.$key);
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 }
559
560 // ------------------------------------------------------------------------
561
562 /**
563 * Identifies flashdata as 'old' for removal
564 * when _flashdata_sweep() runs.
565 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000566 * @return void
567 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200568 protected function _flashdata_mark()
Derek Allard2067d1a2008-11-13 22:59:24 +0000569 {
570 $userdata = $this->all_userdata();
571 foreach ($userdata as $name => $value)
572 {
573 $parts = explode(':new:', $name);
574 if (is_array($parts) && count($parts) === 2)
575 {
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200576 $this->set_userdata($this->flashdata_key.':old:'.$parts[1], $value);
Derek Allard2067d1a2008-11-13 22:59:24 +0000577 $this->unset_userdata($name);
578 }
579 }
580 }
581
582 // ------------------------------------------------------------------------
583
584 /**
585 * Removes all flashdata marked as 'old'
586 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000587 * @return void
588 */
589
Andrey Andreev2c79b762011-12-26 16:54:44 +0200590 protected function _flashdata_sweep()
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 {
592 $userdata = $this->all_userdata();
593 foreach ($userdata as $key => $value)
594 {
595 if (strpos($key, ':old:'))
596 {
597 $this->unset_userdata($key);
598 }
599 }
600
601 }
602
603 // --------------------------------------------------------------------
604
605 /**
606 * Get the "now" time
607 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 * @return string
609 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200610 protected function _get_time()
Derek Allard2067d1a2008-11-13 22:59:24 +0000611 {
Andrey Andreev85f018f2011-12-27 02:52:36 +0200612 if (strtolower($this->time_reference) === 'gmt')
613 {
614 $now = time();
615 return mktime(gmdate('H', $now), gmdate('i', $now), gmdate('s', $now), gmdate('m', $now), gmdate('d', $now), gmdate('Y', $now));
616 }
617
618 return time();
Derek Allard2067d1a2008-11-13 22:59:24 +0000619 }
620
621 // --------------------------------------------------------------------
622
623 /**
624 * Write the session cookie
625 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000626 * @return void
627 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200628 protected function _set_cookie($cookie_data = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000629 {
630 if (is_null($cookie_data))
631 {
632 $cookie_data = $this->userdata;
633 }
634
635 // Serialize the userdata for the cookie
636 $cookie_data = $this->_serialize($cookie_data);
637
638 if ($this->sess_encrypt_cookie == TRUE)
639 {
640 $cookie_data = $this->CI->encrypt->encode($cookie_data);
641 }
642 else
643 {
644 // if encryption is not used, we provide an md5 hash to prevent userside tampering
645 $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
646 }
Barry Mienydd671972010-10-04 16:33:58 +0200647
Derek Joneseaa71ba2010-09-02 10:32:07 -0500648 $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
Barry Mienydd671972010-10-04 16:33:58 +0200649
Derek Allard2067d1a2008-11-13 22:59:24 +0000650 // Set the cookie
651 setcookie(
652 $this->sess_cookie_name,
653 $cookie_data,
Derek Joneseaa71ba2010-09-02 10:32:07 -0500654 $expire,
Derek Allard2067d1a2008-11-13 22:59:24 +0000655 $this->cookie_path,
656 $this->cookie_domain,
tobiasbgba6432c2011-02-18 21:58:48 +0100657 $this->cookie_secure
Derek Allard2067d1a2008-11-13 22:59:24 +0000658 );
659 }
660
661 // --------------------------------------------------------------------
662
663 /**
664 * Serialize an array
665 *
666 * This function first converts any slashes found in the array to a temporary
667 * marker, so when it gets unserialized the slashes will be preserved
668 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000669 * @param array
670 * @return string
671 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200672 protected function _serialize($data)
Derek Allard2067d1a2008-11-13 22:59:24 +0000673 {
674 if (is_array($data))
675 {
Chris Muench95933492011-10-16 14:14:04 -0400676 array_walk_recursive($data, array(&$this, '_escape_slashes'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000677 }
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200678 elseif (is_string($data))
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 {
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200680 $data = str_replace('\\', '{{slash}}', $data);
Derek Allard2067d1a2008-11-13 22:59:24 +0000681 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000682 return serialize($data);
683 }
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200684
Chris Muench95933492011-10-16 14:14:04 -0400685 /**
686 * Escape slashes
687 *
688 * This function converts any slashes found into a temporary marker
689 *
Chris Muench95933492011-10-16 14:14:04 -0400690 */
691 function _escape_slashes(&$val, $key)
692 {
693 if (is_string($val))
694 {
695 $val = str_replace('\\', '{{slash}}', $val);
696 }
697 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000698
699 // --------------------------------------------------------------------
700
701 /**
702 * Unserialize
703 *
704 * This function unserializes a data string, then converts any
705 * temporary slash markers back to actual slashes
706 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000707 * @param array
708 * @return string
709 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200710 protected function _unserialize($data)
Derek Allard2067d1a2008-11-13 22:59:24 +0000711 {
712 $data = @unserialize(strip_slashes($data));
713
714 if (is_array($data))
715 {
Chris Muench95933492011-10-16 14:14:04 -0400716 array_walk_recursive($data, array(&$this, '_unescape_slashes'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000717 return $data;
718 }
719
Derek Jones133e6662010-03-29 11:36:42 -0500720 return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data;
Derek Allard2067d1a2008-11-13 22:59:24 +0000721 }
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200722
Chris Muench95933492011-10-16 14:14:04 -0400723 /**
724 * Unescape slashes
725 *
726 * This function converts any slash markers back into actual slashes
727 *
Chris Muench95933492011-10-16 14:14:04 -0400728 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200729 protected function _unescape_slashes(&$val, $key)
Chris Muench95933492011-10-16 14:14:04 -0400730 {
Chris Muench3e414f92011-10-16 23:03:55 -0400731 if (is_string($val))
732 {
733 $val= str_replace('{{slash}}', '\\', $val);
734 }
Chris Muench95933492011-10-16 14:14:04 -0400735 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000736
737 // --------------------------------------------------------------------
738
739 /**
740 * Garbage collection
741 *
742 * This deletes expired session rows from database
743 * if the probability percentage is met
744 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000745 * @return void
746 */
Andrey Andreev2c79b762011-12-26 16:54:44 +0200747 protected function _sess_gc()
Derek Allard2067d1a2008-11-13 22:59:24 +0000748 {
749 if ($this->sess_use_database != TRUE)
750 {
751 return;
752 }
753
754 srand(time());
755 if ((rand() % 100) < $this->gc_probability)
756 {
757 $expire = $this->now - $this->sess_expiration;
758
759 $this->CI->db->where("last_activity < {$expire}");
760 $this->CI->db->delete($this->sess_table_name);
761
762 log_message('debug', 'Session garbage collection performed.');
763 }
764 }
765
766
767}
768// END Session Class
769
770/* End of file Session.php */
Andrey Andreev57ffbbb2011-12-25 04:48:47 +0200771/* Location: ./system/libraries/Session.php */