3 * Table Definition for session
5 * StatusNet - the distributed open-source microblogging tool
6 * Copyright (C) 2009, StatusNet, Inc.
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
24 require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
26 class Session extends Managed_DataObject
29 /* the code below is auto generated do not remove the above tag */
31 public $__table = 'session'; // table name
32 public $id; // varchar(32) primary_key not_null
33 public $session_data; // text()
34 public $created; // datetime() not_null
35 public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
38 function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Session',$k,$v); }
40 /* the code above is auto generated do not remove the tag below */
43 public static function schemaDef()
47 'id' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'session ID'),
48 'session_data' => array('type' => 'text', 'description' => 'session data'),
49 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
50 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
52 'primary key' => array('id'),
54 'session_modified_idx' => array('modified'),
59 static function logdeb($msg)
61 if (common_config('sessions', 'debug')) {
62 common_debug("Session: " . $msg);
66 static function open($save_path, $session_name)
71 static function close()
76 static function read($id)
78 self::logdeb("Fetching session '$id'");
80 $session = Session::staticGet('id', $id);
82 if (empty($session)) {
83 self::logdeb("Couldn't find '$id'");
86 self::logdeb("Found '$id', returning " .
87 strlen($session->session_data) .
89 return (string)$session->session_data;
93 static function write($id, $session_data)
95 self::logdeb("Writing session '$id'");
97 $session = Session::staticGet('id', $id);
99 if (empty($session)) {
100 self::logdeb("'$id' doesn't yet exist; inserting.");
101 $session = new Session();
104 $session->session_data = $session_data;
105 $session->created = common_sql_now();
107 $result = $session->insert();
110 common_log_db_error($session, 'INSERT', __FILE__);
111 self::logdeb("Failed to insert '$id'.");
113 self::logdeb("Successfully inserted '$id' (result = $result).");
117 self::logdeb("'$id' already exists; updating.");
118 if (strcmp($session->session_data, $session_data) == 0) {
119 self::logdeb("Not writing session '$id'; unchanged");
122 self::logdeb("Session '$id' data changed; updating");
124 $orig = clone($session);
126 $session->session_data = $session_data;
128 $result = $session->update($orig);
131 common_log_db_error($session, 'UPDATE', __FILE__);
132 self::logdeb("Failed to update '$id'.");
134 self::logdeb("Successfully updated '$id' (result = $result).");
142 static function destroy($id)
144 self::logdeb("Deleting session $id");
146 $session = Session::staticGet('id', $id);
148 if (empty($session)) {
149 self::logdeb("Can't find '$id' to delete.");
151 $result = $session->delete();
153 common_log_db_error($session, 'DELETE', __FILE__);
154 self::logdeb("Failed to delete '$id'.");
156 self::logdeb("Successfully deleted '$id' (result = $result).");
162 static function gc($maxlifetime)
164 self::logdeb("garbage collection (maxlifetime = $maxlifetime)");
166 $epoch = common_sql_date(time() - $maxlifetime);
170 $session = new Session();
171 $session->whereAdd('modified < "'.$epoch.'"');
172 $session->selectAdd();
173 $session->selectAdd('id');
175 $limit = common_config('sessions', 'gc_limit');
177 // On large sites, too many sessions to expire
178 // at once will just result in failure.
179 $session->limit($limit);
184 while ($session->fetch()) {
185 $ids[] = $session->id;
190 self::logdeb("Found " . count($ids) . " ids to delete.");
192 foreach ($ids as $id) {
193 self::logdeb("Destroying session '$id'.");
198 static function setSaveHandler()
200 self::logdeb("setting save handlers");
201 $result = session_set_save_handler('Session::open', 'Session::close', 'Session::read',
202 'Session::write', 'Session::destroy', 'Session::gc');
203 self::logdeb("save handlers result = $result");
205 // PHP 5.3 with APC ends up destroying a bunch of object stuff before the session
206 // save handlers get called on request teardown.
207 // Registering an explicit shutdown function should take care of this before
208 // everything breaks on us.
209 register_shutdown_function('Session::cleanup');
214 static function cleanup()
216 session_write_close();