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';
29 * Table definition for Session
31 * Superclass representing a saved session as it exists in the database and the associated interfaces.
35 class Session extends Managed_DataObject
38 /* the code below is auto generated do not remove the above tag */
40 public $__table = 'session'; // table name
41 public $id; // varchar(32) primary_key not_null
42 public $session_data; // text()
43 public $created; // datetime() not_null
44 public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
46 /* the code above is auto generated do not remove the tag below */
50 * Returns an array describing how the session is stored in the database.
52 public static function schemaDef()
56 'id' => ['type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'session ID'],
57 'session_data' => ['type' => 'text', 'description' => 'session data'],
58 'created' => ['type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'],
59 'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
61 'primary key' => ['id'],
63 'session_modified_idx' => ['modified'],
69 * A helper function to print a session-related message to the debug log if
70 * the site session debug configuration option is enabled.
74 public static function logdeb($msg)
76 if (common_config('sessions', 'debug')) {
77 common_debug("Session: " . $msg);
82 * Dummy option for saving to file needed for full PHP adherence.
85 * @param $session_name
88 public static function open($save_path, $session_name)
94 * Dummy option for saving to file needed for full PHP adherence.
98 public static function close()
104 * Fetch the session data for the session with the given $id.
107 * @return string Returns an encoded string of the read data. If nothing was read, it must return an empty string. Note this value is returned internally to PHP for processing.
109 public static function read($id)
111 self::logdeb("Fetching session '$id'");
113 $session = Session::getKV('id', $id);
115 if (empty($session)) {
116 self::logdeb("Couldn't find '$id'");
119 self::logdeb("Found '$id', returning " .
120 strlen($session->session_data) .
122 return (string)$session->session_data;
127 * Write the session data for session with given $id as $session_data.
130 * @param $session_data
131 * @return bool Returns TRUE on success or FALSE on failure.
133 public static function write($id, $session_data)
135 self::logdeb("Writing session '$id'");
137 $session = Session::getKV('id', $id);
139 if (empty($session)) {
140 self::logdeb("'$id' doesn't yet exist; inserting.");
141 $session = new Session();
144 $session->session_data = $session_data;
145 $session->created = common_sql_now();
147 $result = $session->insert();
150 common_log_db_error($session, 'INSERT', __FILE__);
151 self::logdeb("Failed to insert '$id'.");
153 self::logdeb("Successfully inserted '$id' (result = $result).");
155 return (bool) $result;
157 self::logdeb("'$id' already exists; updating.");
158 if (strcmp($session->session_data, $session_data) == 0) {
159 self::logdeb("Not writing session '$id'; unchanged");
162 self::logdeb("Session '$id' data changed; updating");
164 $orig = clone($session);
166 $session->session_data = $session_data;
168 $result = $session->update($orig);
171 common_log_db_error($session, 'UPDATE', __FILE__);
172 self::logdeb("Failed to update '$id'.");
174 self::logdeb("Successfully updated '$id' (result = $result).");
177 return (bool) $result;
183 * Find sessions that have persisted beyond $maxlifetime and delete them.
184 * This will be limited by config['sessions']['gc_limit'] - it won't delete
185 * more than the number of sessions specified there at a single pass.
187 * @param $maxlifetime
188 * @return bool Returns TRUE on success or FALSE on failure.
190 public static function gc($maxlifetime)
192 self::logdeb("garbage collection (maxlifetime = $maxlifetime)");
194 $epoch = common_sql_date(time() - $maxlifetime);
198 $session = new Session();
199 $session->whereAdd('modified < "' . $epoch . '"');
200 $session->selectAdd();
201 $session->selectAdd('id');
203 $limit = common_config('sessions', 'gc_limit');
205 // On large sites, too many sessions to expire
206 // at once will just result in failure.
207 $session->limit($limit);
212 while ($session->fetch()) {
213 $ids[] = $session->id;
218 self::logdeb("Found " . count($ids) . " ids to delete.");
220 foreach ($ids as $id) {
221 self::logdeb("Destroying session '$id'.");
229 * Deletes session with given id $id.
232 * @return bool Returns TRUE on success or FALSE on failure.
234 public static function destroy($id)
236 self::logdeb("Deleting session $id");
238 $session = Session::getKV('id', $id);
240 if (empty($session)) {
241 self::logdeb("Can't find '$id' to delete.");
244 $result = $session->delete();
246 common_log_db_error($session, 'DELETE', __FILE__);
247 self::logdeb("Failed to delete '$id'.");
249 self::logdeb("Successfully deleted '$id' (result = $result).");
251 return (bool) $result;
256 * Set our session handler as the handler for PHP session handling in the context of GNU social.
258 * @return bool Returns TRUE on success or FALSE on failure.
260 public static function setSaveHandler()
262 self::logdeb("setting save handlers");
263 $result = session_set_save_handler(
271 self::logdeb("save handlers result = $result");
273 // PHP 5.3 with APC ends up destroying a bunch of object stuff before the session
274 // save handlers get called on request teardown.
275 // Registering an explicit shutdown function should take care of this before
276 // everything breaks on us.
277 register_shutdown_function('Session::cleanup');
283 * Stuff to do before the request teardown.
287 public static function cleanup()
289 session_write_close();