Take two:
[www-register-wizard.git] / libraries / Session.php
1 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
2 /**\r
3  * CodeIgniter\r
4  *\r
5  * An open source application development framework for PHP 4.3.2 or newer\r
6  *\r
7  * @package             CodeIgniter\r
8  * @author              ExpressionEngine Dev Team\r
9  * @copyright   Copyright (c) 2008, EllisLab, Inc.\r
10  * @license             http://codeigniter.com/user_guide/license.html\r
11  * @link                http://codeigniter.com\r
12  * @since               Version 1.0\r
13  * @filesource\r
14  */\r
15 \r
16 // ------------------------------------------------------------------------\r
17 \r
18 /**\r
19  * Session Class\r
20  *\r
21  * @package             CodeIgniter\r
22  * @subpackage  Libraries\r
23  * @category    Sessions\r
24  * @author              ExpressionEngine Dev Team\r
25  * @link                http://codeigniter.com/user_guide/libraries/sessions.html\r
26  */\r
27 class CI_Session {\r
28 \r
29         var $sess_encrypt_cookie                = FALSE;\r
30         var $sess_use_database                  = FALSE;\r
31         var $sess_table_name                    = '';\r
32         var $sess_expiration                    = 7200;\r
33         var $sess_match_ip                              = FALSE;\r
34         var $sess_match_useragent               = TRUE;\r
35         var $sess_cookie_name                   = 'ci_session';\r
36         var $cookie_prefix                              = '';\r
37         var $cookie_path                                = '';\r
38         var $cookie_domain                              = '';\r
39         var $sess_time_to_update                = 300;\r
40         var $encryption_key                             = '';\r
41         var $flashdata_key                              = 'flash';\r
42         var $time_reference                             = 'time';\r
43         var $gc_probability                             = 5;\r
44         var $userdata                                   = array();\r
45         var $CI;\r
46         var $now;\r
47 \r
48         /**\r
49          * Session Constructor\r
50          *\r
51          * The constructor runs the session routines automatically\r
52          * whenever the class is instantiated.\r
53          */             \r
54         function CI_Session($params = array())\r
55         {\r
56                 log_message('debug', "Session Class Initialized");\r
57 \r
58                 // Set the super object to a local variable for use throughout the class\r
59                 $this->CI =& get_instance();\r
60                 \r
61                 // Set all the session preferences, which can either be set \r
62                 // manually via the $params array above or via the config file\r
63                 foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)\r
64                 {\r
65                         $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);\r
66                 }               \r
67         \r
68                 // Load the string helper so we can use the strip_slashes() function\r
69                 $this->CI->load->helper('string');\r
70 \r
71                 // Do we need encryption? If so, load the encryption class\r
72                 if ($this->sess_encrypt_cookie == TRUE)\r
73                 {\r
74                         $this->CI->load->library('encrypt');\r
75                 }\r
76 \r
77                 // Are we using a database?  If so, load it\r
78                 if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')\r
79                 {\r
80                         $this->CI->load->database();\r
81                 }\r
82 \r
83                 // Set the "now" time.  Can either be GMT or server time, based on the\r
84                 // config prefs.  We use this to set the "last activity" time\r
85                 $this->now = $this->_get_time();\r
86 \r
87                 // Set the session length. If the session expiration is\r
88                 // set to zero we'll set the expiration two years from now.\r
89                 if ($this->sess_expiration == 0)\r
90                 {\r
91                         $this->sess_expiration = (60*60*24*365*2);\r
92                 }\r
93                                                 \r
94                 // Set the cookie name\r
95                 $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;\r
96         \r
97                 // Run the Session routine. If a session doesn't exist we'll \r
98                 // create a new one.  If it does, we'll update it.\r
99                 if ( ! $this->sess_read())\r
100                 {\r
101                         $this->sess_create();\r
102                 }\r
103                 else\r
104                 {       \r
105                         $this->sess_update();\r
106                 }\r
107                 \r
108                 // Delete 'old' flashdata (from last request)\r
109                 $this->_flashdata_sweep();\r
110                 \r
111                 // Mark all new flashdata as old (data will be deleted before next request)\r
112                 $this->_flashdata_mark();\r
113 \r
114                 // Delete expired sessions if necessary\r
115                 $this->_sess_gc();\r
116 \r
117                 log_message('debug', "Session routines successfully run");\r
118         }\r
119         \r
120         // --------------------------------------------------------------------\r
121         \r
122         /**\r
123          * Fetch the current session data if it exists\r
124          *\r
125          * @access      public\r
126          * @return      void\r
127          */\r
128         function sess_read()\r
129         {       \r
130                 // Fetch the cookie\r
131                 $session = $this->CI->input->cookie($this->sess_cookie_name);\r
132                 \r
133                 // No cookie?  Goodbye cruel world!...\r
134                 if ($session === FALSE)\r
135                 {\r
136                         log_message('debug', 'A session cookie was not found.');\r
137                         return FALSE;\r
138                 }\r
139                 \r
140                 // Decrypt the cookie data\r
141                 if ($this->sess_encrypt_cookie == TRUE)\r
142                 {\r
143                         $session = $this->CI->encrypt->decode($session);\r
144                 }\r
145                 else\r
146                 {       \r
147                         // encryption was not used, so we need to check the md5 hash\r
148                         $hash    = substr($session, strlen($session)-32); // get last 32 chars\r
149                         $session = substr($session, 0, strlen($session)-32);\r
150 \r
151                         // Does the md5 hash match?  This is to prevent manipulation of session data in userspace\r
152                         if ($hash !==  md5($session.$this->encryption_key))\r
153                         {\r
154                                 log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');\r
155                                 $this->sess_destroy();\r
156                                 return FALSE;\r
157                         }\r
158                 }\r
159                 \r
160                 // Unserialize the session array\r
161                 $session = $this->_unserialize($session);\r
162                 \r
163                 // Is the session data we unserialized an array with the correct format?\r
164                 if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))\r
165                 {\r
166                         $this->sess_destroy();\r
167                         return FALSE;\r
168                 }\r
169                 \r
170                 // Is the session current?\r
171                 if (($session['last_activity'] + $this->sess_expiration) < $this->now)\r
172                 {\r
173                         $this->sess_destroy();\r
174                         return FALSE;\r
175                 }\r
176 \r
177                 // Does the IP Match?\r
178                 if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())\r
179                 {\r
180                         $this->sess_destroy();\r
181                         return FALSE;\r
182                 }\r
183                 \r
184                 // Does the User Agent Match?\r
185                 if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50)))\r
186                 {\r
187                         $this->sess_destroy();\r
188                         return FALSE;\r
189                 }\r
190                 \r
191                 // Is there a corresponding session in the DB?\r
192                 if ($this->sess_use_database === TRUE)\r
193                 {\r
194                         $this->CI->db->where('session_id', $session['session_id']);\r
195                                         \r
196                         if ($this->sess_match_ip == TRUE)\r
197                         {\r
198                                 $this->CI->db->where('ip_address', $session['ip_address']);\r
199                         }\r
200 \r
201                         if ($this->sess_match_useragent == TRUE)\r
202                         {\r
203                                 $this->CI->db->where('user_agent', $session['user_agent']);\r
204                         }\r
205                         \r
206                         $query = $this->CI->db->get($this->sess_table_name);\r
207 \r
208                         // No result?  Kill it!\r
209                         if ($query->num_rows() == 0)\r
210                         {\r
211                                 $this->sess_destroy();\r
212                                 return FALSE;\r
213                         }\r
214 \r
215                         // Is there custom data?  If so, add it to the main session array\r
216                         $row = $query->row();\r
217                         if (isset($row->user_data) AND $row->user_data != '')\r
218                         {\r
219                                 $custom_data = $this->_unserialize($row->user_data);\r
220 \r
221                                 if (is_array($custom_data))\r
222                                 {\r
223                                         foreach ($custom_data as $key => $val)\r
224                                         {\r
225                                                 $session[$key] = $val;\r
226                                         }\r
227                                 }\r
228                         }                               \r
229                 }\r
230         \r
231                 // Session is valid!\r
232                 $this->userdata = $session;\r
233                 unset($session);\r
234                 \r
235                 return TRUE;\r
236         }\r
237         \r
238         // --------------------------------------------------------------------\r
239         \r
240         /**\r
241          * Write the session data\r
242          *\r
243          * @access      public\r
244          * @return      void\r
245          */\r
246         function sess_write()\r
247         {\r
248                 // Are we saving custom data to the DB?  If not, all we do is update the cookie\r
249                 if ($this->sess_use_database === FALSE)\r
250                 {\r
251                         $this->_set_cookie();\r
252                         return;\r
253                 }\r
254 \r
255                 // set the custom userdata, the session data we will set in a second\r
256                 $custom_userdata = $this->userdata;\r
257                 $cookie_userdata = array();\r
258                 \r
259                 // Before continuing, we need to determine if there is any custom data to deal with.\r
260                 // Let's determine this by removing the default indexes to see if there's anything left in the array\r
261                 // and set the session data while we're at it\r
262                 foreach (array('session_id','ip_address','user_agent','last_activity') as $val)\r
263                 {\r
264                         unset($custom_userdata[$val]);\r
265                         $cookie_userdata[$val] = $this->userdata[$val];\r
266                 }\r
267                 \r
268                 // Did we find any custom data?  If not, we turn the empty array into a string\r
269                 // since there's no reason to serialize and store an empty array in the DB\r
270                 if (count($custom_userdata) === 0)\r
271                 {\r
272                         $custom_userdata = '';\r
273                 }\r
274                 else\r
275                 {       \r
276                         // Serialize the custom data array so we can store it\r
277                         $custom_userdata = $this->_serialize($custom_userdata);\r
278                 }\r
279                 \r
280                 // Run the update query\r
281                 $this->CI->db->where('session_id', $this->userdata['session_id']);\r
282                 $this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));\r
283 \r
284                 // Write the cookie.  Notice that we manually pass the cookie data array to the\r
285                 // _set_cookie() function. Normally that function will store $this->userdata, but \r
286                 // in this case that array contains custom data, which we do not want in the cookie.\r
287                 $this->_set_cookie($cookie_userdata);\r
288         }\r
289         \r
290         // --------------------------------------------------------------------\r
291         \r
292         /**\r
293          * Create a new session\r
294          *\r
295          * @access      public\r
296          * @return      void\r
297          */\r
298         function sess_create()\r
299         {       \r
300                 $sessid = '';\r
301                 while (strlen($sessid) < 32)\r
302                 {\r
303                         $sessid .= mt_rand(0, mt_getrandmax());\r
304                 }\r
305                 \r
306                 // To make the session ID even more secure we'll combine it with the user's IP\r
307                 $sessid .= $this->CI->input->ip_address();\r
308         \r
309                 $this->userdata = array(\r
310                                                         'session_id'    => md5(uniqid($sessid, TRUE)),\r
311                                                         'ip_address'    => $this->CI->input->ip_address(),\r
312                                                         'user_agent'    => substr($this->CI->input->user_agent(), 0, 50),\r
313                                                         'last_activity' => $this->now\r
314                                                         );\r
315                 \r
316                 \r
317                 // Save the data to the DB if needed\r
318                 if ($this->sess_use_database === TRUE)\r
319                 {\r
320                         $this->CI->db->query($this->CI->db->insert_string($this->sess_table_name, $this->userdata));\r
321                 }\r
322                         \r
323                 // Write the cookie\r
324                 $this->_set_cookie();\r
325         }\r
326         \r
327         // --------------------------------------------------------------------\r
328         \r
329         /**\r
330          * Update an existing session\r
331          *\r
332          * @access      public\r
333          * @return      void\r
334          */\r
335         function sess_update()\r
336         {\r
337                 // We only update the session every five minutes by default\r
338                 if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)\r
339                 {\r
340                         return;\r
341                 }\r
342         \r
343                 // Save the old session id so we know which record to \r
344                 // update in the database if we need it\r
345                 $old_sessid = $this->userdata['session_id'];\r
346                 $new_sessid = '';\r
347                 while (strlen($new_sessid) < 32)\r
348                 {\r
349                         $new_sessid .= mt_rand(0, mt_getrandmax());\r
350                 }\r
351                 \r
352                 // To make the session ID even more secure we'll combine it with the user's IP\r
353                 $new_sessid .= $this->CI->input->ip_address();\r
354                 \r
355                 // Turn it into a hash\r
356                 $new_sessid = md5(uniqid($new_sessid, TRUE));\r
357                 \r
358                 // Update the session data in the session data array\r
359                 $this->userdata['session_id'] = $new_sessid;\r
360                 $this->userdata['last_activity'] = $this->now;\r
361                 \r
362                 // _set_cookie() will handle this for us if we aren't using database sessions\r
363                 // by pushing all userdata to the cookie.\r
364                 $cookie_data = NULL;\r
365                 \r
366                 // Update the session ID and last_activity field in the DB if needed\r
367                 if ($this->sess_use_database === TRUE)\r
368                 {\r
369                         // set cookie explicitly to only have our session data\r
370                         $cookie_data = array();\r
371                         foreach (array('session_id','ip_address','user_agent','last_activity') as $val)\r
372                         {\r
373                                 $cookie_data[$val] = $this->userdata[$val];\r
374                         }\r
375                         \r
376                         $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)));\r
377                 }\r
378                 \r
379                 // Write the cookie\r
380                 $this->_set_cookie($cookie_data);\r
381         }\r
382         \r
383         // --------------------------------------------------------------------\r
384         \r
385         /**\r
386          * Destroy the current session\r
387          *\r
388          * @access      public\r
389          * @return      void\r
390          */\r
391         function sess_destroy()\r
392         {       \r
393                 // Kill the session DB row\r
394                 if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))\r
395                 {\r
396                         $this->CI->db->where('session_id', $this->userdata['session_id']);\r
397                         $this->CI->db->delete($this->sess_table_name);\r
398                 }\r
399         \r
400                 // Kill the cookie\r
401                 setcookie(\r
402                                         $this->sess_cookie_name,\r
403                                         addslashes(serialize(array())),\r
404                                         ($this->now - 31500000),\r
405                                         $this->cookie_path,\r
406                                         $this->cookie_domain,\r
407                                         0\r
408                                 );\r
409         }\r
410         \r
411         // --------------------------------------------------------------------\r
412         \r
413         /**\r
414          * Fetch a specific item from the session array\r
415          *\r
416          * @access      public\r
417          * @param       string\r
418          * @return      string\r
419          */             \r
420         function userdata($item)\r
421         {\r
422                 return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];\r
423         }\r
424 \r
425         // --------------------------------------------------------------------\r
426         \r
427         /**\r
428          * Fetch all session data\r
429          *\r
430          * @access      public\r
431          * @return      mixed\r
432          */     \r
433         function all_userdata()\r
434         {\r
435                 return ( ! isset($this->userdata)) ? FALSE : $this->userdata;\r
436         }\r
437         \r
438         // --------------------------------------------------------------------\r
439         \r
440         /**\r
441          * Add or change data in the "userdata" array\r
442          *\r
443          * @access      public\r
444          * @param       mixed\r
445          * @param       string\r
446          * @return      void\r
447          */             \r
448         function set_userdata($newdata = array(), $newval = '')\r
449         {\r
450                 if (is_string($newdata))\r
451                 {\r
452                         $newdata = array($newdata => $newval);\r
453                 }\r
454         \r
455                 if (count($newdata) > 0)\r
456                 {\r
457                         foreach ($newdata as $key => $val)\r
458                         {\r
459                                 $this->userdata[$key] = $val;\r
460                         }\r
461                 }\r
462 \r
463                 $this->sess_write();\r
464         }\r
465         \r
466         // --------------------------------------------------------------------\r
467         \r
468         /**\r
469          * Delete a session variable from the "userdata" array\r
470          *\r
471          * @access      array\r
472          * @return      void\r
473          */             \r
474         function unset_userdata($newdata = array())\r
475         {\r
476                 if (is_string($newdata))\r
477                 {\r
478                         $newdata = array($newdata => '');\r
479                 }\r
480         \r
481                 if (count($newdata) > 0)\r
482                 {\r
483                         foreach ($newdata as $key => $val)\r
484                         {\r
485                                 unset($this->userdata[$key]);\r
486                         }\r
487                 }\r
488         \r
489                 $this->sess_write();\r
490         }\r
491         \r
492         // ------------------------------------------------------------------------\r
493 \r
494         /**\r
495          * Add or change flashdata, only available\r
496          * until the next request\r
497          *\r
498          * @access      public\r
499          * @param       mixed\r
500          * @param       string\r
501          * @return      void\r
502          */\r
503         function set_flashdata($newdata = array(), $newval = '')\r
504         {\r
505                 if (is_string($newdata))\r
506                 {\r
507                         $newdata = array($newdata => $newval);\r
508                 }\r
509                 \r
510                 if (count($newdata) > 0)\r
511                 {\r
512                         foreach ($newdata as $key => $val)\r
513                         {\r
514                                 $flashdata_key = $this->flashdata_key.':new:'.$key;\r
515                                 $this->set_userdata($flashdata_key, $val);\r
516                         }\r
517                 }\r
518         } \r
519         \r
520         // ------------------------------------------------------------------------\r
521 \r
522         /**\r
523          * Keeps existing flashdata available to next request.\r
524          *\r
525          * @access      public\r
526          * @param       string\r
527          * @return      void\r
528          */\r
529         function keep_flashdata($key)\r
530         {\r
531                 // 'old' flashdata gets removed.  Here we mark all \r
532                 // flashdata as 'new' to preserve it from _flashdata_sweep()\r
533                 // Note the function will return FALSE if the $key \r
534                 // provided cannot be found\r
535                 $old_flashdata_key = $this->flashdata_key.':old:'.$key;\r
536                 $value = $this->userdata($old_flashdata_key);\r
537 \r
538                 $new_flashdata_key = $this->flashdata_key.':new:'.$key;\r
539                 $this->set_userdata($new_flashdata_key, $value);\r
540         }\r
541         \r
542         // ------------------------------------------------------------------------\r
543 \r
544         /**\r
545          * Fetch a specific flashdata item from the session array\r
546          *\r
547          * @access      public\r
548          * @param       string\r
549          * @return      string\r
550          */     \r
551         function flashdata($key)\r
552         {\r
553                 $flashdata_key = $this->flashdata_key.':old:'.$key;\r
554                 return $this->userdata($flashdata_key);\r
555         }\r
556 \r
557         // ------------------------------------------------------------------------\r
558 \r
559         /**\r
560          * Identifies flashdata as 'old' for removal\r
561          * when _flashdata_sweep() runs.\r
562          *\r
563          * @access      private\r
564          * @return      void\r
565          */\r
566         function _flashdata_mark()\r
567         {\r
568                 $userdata = $this->all_userdata();\r
569                 foreach ($userdata as $name => $value)\r
570                 {\r
571                         $parts = explode(':new:', $name);\r
572                         if (is_array($parts) && count($parts) === 2)\r
573                         {\r
574                                 $new_name = $this->flashdata_key.':old:'.$parts[1];\r
575                                 $this->set_userdata($new_name, $value);\r
576                                 $this->unset_userdata($name);\r
577                         }\r
578                 }\r
579         }\r
580 \r
581         // ------------------------------------------------------------------------\r
582 \r
583         /**\r
584          * Removes all flashdata marked as 'old'\r
585          *\r
586          * @access      private\r
587          * @return      void\r
588          */\r
589 \r
590         function _flashdata_sweep()\r
591         {\r
592                 $userdata = $this->all_userdata();\r
593                 foreach ($userdata as $key => $value)\r
594                 {\r
595                         if (strpos($key, ':old:'))\r
596                         {\r
597                                 $this->unset_userdata($key);\r
598                         }\r
599                 }\r
600 \r
601         }\r
602 \r
603         // --------------------------------------------------------------------\r
604         \r
605         /**\r
606          * Get the "now" time\r
607          *\r
608          * @access      private\r
609          * @return      string\r
610          */\r
611         function _get_time()\r
612         {\r
613                 if (strtolower($this->time_reference) == 'gmt')\r
614                 {\r
615                         $now = time();\r
616                         $time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));\r
617                 }\r
618                 else\r
619                 {\r
620                         $time = time();\r
621                 }\r
622         \r
623                 return $time;\r
624         }\r
625 \r
626         // --------------------------------------------------------------------\r
627         \r
628         /**\r
629          * Write the session cookie\r
630          *\r
631          * @access      public\r
632          * @return      void\r
633          */\r
634         function _set_cookie($cookie_data = NULL)\r
635         {\r
636                 if (is_null($cookie_data))\r
637                 {\r
638                         $cookie_data = $this->userdata;\r
639                 }\r
640         \r
641                 // Serialize the userdata for the cookie\r
642                 $cookie_data = $this->_serialize($cookie_data);\r
643                 \r
644                 if ($this->sess_encrypt_cookie == TRUE)\r
645                 {\r
646                         $cookie_data = $this->CI->encrypt->encode($cookie_data);\r
647                 }\r
648                 else\r
649                 {\r
650                         // if encryption is not used, we provide an md5 hash to prevent userside tampering\r
651                         $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);\r
652                 }\r
653                 \r
654                 // Set the cookie\r
655                 setcookie(\r
656                                         $this->sess_cookie_name,\r
657                                         $cookie_data,\r
658                                         $this->sess_expiration + time(),\r
659                                         $this->cookie_path,\r
660                                         $this->cookie_domain,\r
661                                         0\r
662                                 );\r
663         }\r
664 \r
665         // --------------------------------------------------------------------\r
666         \r
667         /**\r
668          * Serialize an array\r
669          *\r
670          * This function first converts any slashes found in the array to a temporary\r
671          * marker, so when it gets unserialized the slashes will be preserved\r
672          *\r
673          * @access      private\r
674          * @param       array\r
675          * @return      string\r
676          */     \r
677         function _serialize($data)\r
678         {\r
679                 if (is_array($data))\r
680                 {\r
681                         foreach ($data as $key => $val)\r
682                         {\r
683                                 $data[$key] = str_replace('\\', '{{slash}}', $val);\r
684                         }\r
685                 }\r
686                 else\r
687                 {\r
688                         $data = str_replace('\\', '{{slash}}', $data);\r
689                 }\r
690                 \r
691                 return serialize($data);\r
692         }\r
693 \r
694         // --------------------------------------------------------------------\r
695         \r
696         /**\r
697          * Unserialize\r
698          *\r
699          * This function unserializes a data string, then converts any\r
700          * temporary slash markers back to actual slashes\r
701          *\r
702          * @access      private\r
703          * @param       array\r
704          * @return      string\r
705          */             \r
706         function _unserialize($data)\r
707         {\r
708                 $data = @unserialize(strip_slashes($data));\r
709                 \r
710                 if (is_array($data))\r
711                 {\r
712                         foreach ($data as $key => $val)\r
713                         {\r
714                                 $data[$key] = str_replace('{{slash}}', '\\', $val);\r
715                         }\r
716                         \r
717                         return $data;\r
718                 }\r
719                 \r
720                 return str_replace('{{slash}}', '\\', $data);\r
721         }\r
722 \r
723         // --------------------------------------------------------------------\r
724         \r
725         /**\r
726          * Garbage collection\r
727          *\r
728          * This deletes expired session rows from database\r
729          * if the probability percentage is met\r
730          *\r
731          * @access      public\r
732          * @return      void\r
733          */\r
734         function _sess_gc()\r
735         {\r
736                 if ($this->sess_use_database != TRUE)\r
737                 {\r
738                         return;\r
739                 }\r
740                 \r
741                 srand(time());\r
742                 if ((rand() % 100) < $this->gc_probability)\r
743                 {\r
744                         $expire = $this->now - $this->sess_expiration;\r
745                         \r
746                         $this->CI->db->where("last_activity < {$expire}");\r
747                         $this->CI->db->delete($this->sess_table_name);\r
748 \r
749                         log_message('debug', 'Session garbage collection performed.');\r
750                 }\r
751         }\r
752 \r
753         \r
754 }\r
755 // END Session Class\r
756 \r
757 /* End of file Session.php */\r
758 /* Location: ./system/libraries/Session.php */