4 +-----------------------------------------------------------------------+
5 | program/include/session.inc |
7 | This file is part of the RoundCube Webmail client |
8 | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland |
9 | Licensed under the GNU GPL |
12 | Provide database supported session management |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com> |
16 +-----------------------------------------------------------------------+
18 $Id: session.inc 2573 2009-05-29 19:10:24Z alec $
22 $GLOBALS['rcube_session_unsets'] = array();
24 function rcube_sess_open($save_path, $session_name)
30 function rcube_sess_close()
37 function rcube_sess_read($key)
39 global $SESS_CHANGED, $SESS_CLIENT_IP;
41 $DB = rcmail::get_instance()->get_dbh();
43 $sql_result = $DB->query(
44 "SELECT vars, ip, " . $DB->unixtimestamp('changed') . " AS changed
45 FROM " . get_table_name('session') . "
49 if ($sql_arr = $DB->fetch_assoc($sql_result)) {
50 $SESS_CHANGED = $sql_arr['changed'];
51 $SESS_CLIENT_IP = $sql_arr['ip'];
53 if (strlen($sql_arr['vars']))
54 return $sql_arr['vars'];
62 function rcube_sess_write($key, $vars)
64 $DB = rcmail::get_instance()->get_dbh();
66 $now = $DB->fromunixtime(time());
68 $sql_result = $DB->query(
69 "SELECT vars FROM " . get_table_name('session') . "
70 WHERE sess_id=?", $key);
72 if ($sql_arr = $DB->fetch_assoc($sql_result)) {
74 $a_oldvars = rcube_sess_unserialize($sql_arr['vars']);
75 foreach ((array)$GLOBALS['rcube_session_unsets'] as $k)
76 unset($a_oldvars[$k]);
79 "UPDATE " . get_table_name('session') . "
80 SET vars=?, changed= " . $now . "
82 rcube_sess_serialize(array_merge($a_oldvars, rcube_sess_unserialize($vars))),
87 "INSERT INTO " . get_table_name('session') . "
88 (sess_id, vars, ip, created, changed)
89 VALUES (?, ?, ?, " . $now . ", " . $now .")",
92 (string)$_SERVER['REMOTE_ADDR']);
95 $GLOBALS['rcube_session_unsets'] = array();
100 // unset session variable
101 function rcube_sess_unset($var=NULL)
104 return rcube_sess_destroy(session_id());
106 $GLOBALS['rcube_session_unsets'][] = $var;
107 unset($_SESSION[$var]);
113 // serialize session data
114 function rcube_sess_serialize($vars)
118 foreach ($vars as $var=>$value)
119 $data .= $var.'|'.serialize($value);
126 // unserialize session data
127 // http://www.php.net/manual/en/function.session-decode.php#56106
128 function rcube_sess_unserialize($str)
131 $endptr = strlen($str);
138 while ($p < $endptr) {
140 while ($str[$q] != '|')
141 if (++$q >= $endptr) break 2;
143 if ($str[$p] == '!') {
150 $name = substr($str, $p, $q - $p);
153 $serialized .= 's:' . strlen($name) . ':"' . $name . '";';
158 switch (strtolower($str[$q])) {
160 case 'b': /* boolean */
161 case 'i': /* integer */
162 case 'd': /* decimal */
164 while ( ($q < $endptr) && ($str[$q] != ';') );
166 $serialized .= substr($str, $p, $q - $p);
167 if ($level == 0) break 2;
169 case 'r': /* reference */
171 for ($id = ''; ($q < $endptr) && ($str[$q] != ';'); $q++) $id .= $str[$q];
173 $serialized .= 'R:' . ($id + 1) . ';'; /* increment pointer because of outer array */
174 if ($level == 0) break 2;
176 case 's': /* string */
178 for ($length=''; ($q < $endptr) && ($str[$q] != ':'); $q++) $length .= $str[$q];
180 $q+= (int)$length + 2;
181 $serialized .= substr($str, $p, $q - $p);
182 if ($level == 0) break 2;
184 case 'a': /* array */
185 case 'o': /* object */
187 while ( ($q < $endptr) && ($str[$q] != '{') );
190 $serialized .= substr($str, $p, $q - $p);
192 case '}': /* end of array|object */
194 $serialized .= substr($str, $p, $q - $p);
195 if (--$level == 0) break 2;
209 return unserialize( 'a:' . $items . ':{' . $serialized . '}' );
213 // handler for session_destroy()
214 function rcube_sess_destroy($key)
216 $DB = rcmail::get_instance()->get_dbh();
218 $DB->query("DELETE FROM " . get_table_name('session') . " WHERE sess_id=?", $key);
224 // garbage collecting function
225 function rcube_sess_gc($maxlifetime)
227 $rcmail = rcmail::get_instance();
228 $DB = $rcmail->get_dbh();
230 // just delete all expired sessions
231 $DB->query("DELETE FROM " . get_table_name('session') . "
232 WHERE changed < " . $DB->fromunixtime(time() - $maxlifetime));
234 if ($rcmail->config->get('enable_caching'))
243 function rcube_sess_regenerate_id()
245 $randval = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
247 for ($random = "", $i=1; $i <= 32; $i++) {
248 $random .= substr($randval, rand(0,(strlen($randval) - 1)), 1);
251 // use md5 value for id or remove capitals from string $randval
252 $random = md5($random);
254 // delete old session record
255 rcube_sess_destroy(session_id());
259 $cookie = session_get_cookie_params();
260 $lifetime = $cookie['lifetime'] ? time() + $cookie['lifetime'] : 0;
262 rcmail::setcookie(session_name(), $random, $lifetime);
268 // set custom functions for PHP session management
269 session_set_save_handler('rcube_sess_open', 'rcube_sess_close', 'rcube_sess_read', 'rcube_sess_write', 'rcube_sess_destroy', 'rcube_sess_gc');