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')) {
26 require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
28 class Session extends Managed_DataObject
31 /* the code below is auto generated do not remove the above tag */
33 public $__table = 'session'; // table name
34 public $id; // varchar(32) primary_key not_null
35 public $session_data; // text()
36 public $created; // datetime() not_null
37 public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
39 /* the code above is auto generated do not remove the tag below */
42 public static function schemaDef()
46 'id' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'session ID'],
47 'session_data' => ['type' => 'text', 'description' => 'session data'],
48 'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'],
49 'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
51 'primary key' => ['id'],
53 'session_modified_idx' => ['modified'],
58 static function open($save_path, $session_name)
63 static function close()
68 static function read($id)
70 self::logdeb("Fetching session '$id'");
72 $session = Session::getKV('id', $id);
74 if (empty($session)) {
75 self::logdeb("Couldn't find '$id'");
78 self::logdeb("Found '$id', returning " .
79 strlen($session->session_data) .
81 return (string)$session->session_data;
85 static function logdeb($msg)
87 if (common_config('sessions', 'debug')) {
88 common_debug("Session: " . $msg);
92 static function write($id, $session_data)
94 self::logdeb("Writing session '$id'");
96 $session = Session::getKV('id', $id);
98 if (empty($session)) {
99 self::logdeb("'$id' doesn't yet exist; inserting.");
100 $session = new Session();
103 $session->session_data = $session_data;
104 $session->created = common_sql_now();
106 $result = $session->insert();
109 common_log_db_error($session, 'INSERT', __FILE__);
110 self::logdeb("Failed to insert '$id'.");
112 self::logdeb("Successfully inserted '$id' (result = $result).");
116 self::logdeb("'$id' already exists; updating.");
117 if (strcmp($session->session_data, $session_data) == 0) {
118 self::logdeb("Not writing session '$id'; unchanged");
121 self::logdeb("Session '$id' data changed; updating");
123 $orig = clone($session);
125 $session->session_data = $session_data;
127 $result = $session->update($orig);
130 common_log_db_error($session, 'UPDATE', __FILE__);
131 self::logdeb("Failed to update '$id'.");
133 self::logdeb("Successfully updated '$id' (result = $result).");
141 static function gc($maxlifetime)
143 self::logdeb("garbage collection (maxlifetime = $maxlifetime)");
145 $epoch = common_sql_date(time() - $maxlifetime);
149 $session = new Session();
150 $session->whereAdd('modified < "' . $epoch . '"');
151 $session->selectAdd();
152 $session->selectAdd('id');
154 $limit = common_config('sessions', 'gc_limit');
156 // On large sites, too many sessions to expire
157 // at once will just result in failure.
158 $session->limit($limit);
163 while ($session->fetch()) {
164 $ids[] = $session->id;
169 self::logdeb("Found " . count($ids) . " ids to delete.");
171 foreach ($ids as $id) {
172 self::logdeb("Destroying session '$id'.");
177 static function destroy($id)
179 self::logdeb("Deleting session $id");
181 $session = Session::getKV('id', $id);
183 if (empty($session)) {
184 self::logdeb("Can't find '$id' to delete.");
187 $result = $session->delete();
189 common_log_db_error($session, 'DELETE', __FILE__);
190 self::logdeb("Failed to delete '$id'.");
192 self::logdeb("Successfully deleted '$id' (result = $result).");
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();