]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/internalsessionhandler.php
[SESSION] Log messages were a bit confusing
[quix0rs-gnu-social.git] / lib / internalsessionhandler.php
1 <?php
2 /**
3  * GNU social's implementation of SessionHandler
4  *
5  * StatusNet - the distributed open-source microblogging tool
6  * Copyright (C) 2009, StatusNet, Inc.
7  *
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.
12  *
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.
17  *
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/>.
20  */
21
22 if (!defined('GNUSOCIAL')) {
23     exit(1);
24 }
25
26 /**
27  * Superclass representing the associated interfaces of session handling.
28  *
29  * @author GNU social
30  */
31 class InternalSessionHandler implements SessionHandlerInterface
32 {
33     /**
34      * A helper function to print a session-related message to the debug log if
35      * the site session debug configuration option is enabled.
36      * @param $msg
37      * @return void
38      */
39     public static function logdeb($msg)
40     {
41         if (common_config('sessions', 'debug')) {
42             common_debug("Session: " . $msg);
43         }
44     }
45
46     /**
47      * Dummy option for saving to file needed for full PHP adherence.
48      *
49      * @param $save_path
50      * @param $session_name
51      * @return bool true
52      */
53     public function open($save_path, $session_name)
54     {
55         return true;
56     }
57
58     /**
59      * Dummy option for saving to file needed for full PHP adherence.
60      *
61      * @return bool true
62      */
63     public function close()
64     {
65         return true;
66     }
67
68     /**
69      * Fetch the session data for the session with the given $id.
70      *
71      * @param $id
72      * @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.
73      */
74     public function read($id)
75     {
76         self::logdeb("Fetching session '$id'.");
77
78         $session = Session::getKV('id', $id);
79
80         if (empty($session)) {
81             self::logdeb("Couldn't find '$id'.");
82             return '';
83         } else {
84             self::logdeb("Found '$id', returning " .
85                          strlen($session->session_data) .
86                          " chars of data.");
87             return (string)$session->session_data;
88         }
89     }
90
91     /**
92      * Write the session data for session with given $id as $session_data.
93      *
94      * @param $id
95      * @param $session_data
96      * @return bool Returns TRUE on success or FALSE on failure.
97      */
98     public function write($id, $session_data)
99     {
100         self::logdeb("Writing session '$id'.");
101
102         $session = Session::getKV('id', $id);
103
104         if (empty($session)) {
105             self::logdeb("'$id' doesn't yet exist; inserting.");
106             $session = new Session();
107
108             $session->id = $id;
109             $session->session_data = $session_data;
110             $session->created = common_sql_now();
111
112             $result = $session->insert();
113
114             if (!$result) {
115                 common_log_db_error($session, 'INSERT', __FILE__);
116                 self::logdeb("Failed to insert '$id'.");
117             } else {
118                 self::logdeb("Successfully inserted '$id' (result = $result).");
119             }
120             return (bool) $result;
121         } else {
122             self::logdeb("'$id' already exists; updating.");
123             if (strcmp($session->session_data, $session_data) == 0) {
124                 self::logdeb("Not writing session '$id' - unchanged.");
125                 return true;
126             } else {
127                 self::logdeb("Session '$id' data changed - updating.");
128
129                 // Only update the required field
130                 $orig = clone($session);
131                 $session->session_data = $session_data;
132                 $result = $session->update($orig);
133
134                 if (!$result) {
135                     common_log_db_error($session, 'UPDATE', __FILE__);
136                     self::logdeb("Failed to update '$id'.");
137                 } else {
138                     self::logdeb("Successfully updated '$id' (result = $result).");
139                 }
140
141                 return (bool) $result;
142             }
143         }
144     }
145
146     /**
147      * Find sessions that have persisted beyond $maxlifetime and delete them.
148      * This will be limited by config['sessions']['gc_limit'] - it won't delete
149      * more than the number of sessions specified there at a single pass.
150      *
151      * @param $maxlifetime
152      * @return bool Returns TRUE on success or FALSE on failure.
153      */
154     public function gc($maxlifetime)
155     {
156         self::logdeb("Garbage Collector has now started with maxlifetime = '$maxlifetime'.");
157
158         $epoch = common_sql_date(time() - $maxlifetime);
159
160         $ids = [];
161
162         $session = new Session();
163         $session->whereAdd('modified < "' . $epoch . '"');
164         $session->selectAdd();
165         $session->selectAdd('id');
166
167         $limit = common_config('sessions', 'gc_limit');
168         if ($limit > 0) {
169             // On large sites, too many sessions to expire
170             // at once will just result in failure.
171             $session->limit($limit);
172         }
173
174         $session->find();
175
176         while ($session->fetch()) {
177             $ids[] = $session->id;
178         }
179
180         $session->free();
181
182         self::logdeb("Garbage Collector found " . count($ids) . " ids to delete.");
183
184         foreach ($ids as $id) {
185             self::logdeb("Garbage Collector will now delete session '$id'.");
186             self::destroy($id);
187         }
188
189         return true;
190     }
191
192     /**
193      * Deletes session with given id $id.
194      *
195      * @param $id
196      * @return bool Returns TRUE on success or FALSE on failure.
197      */
198     public function destroy($id)
199     {
200         self::logdeb("Destroying session '$id'.");
201
202         $session = Session::getKV('id', $id);
203
204         if (empty($session)) {
205             self::logdeb("Can't find '$id' to destroy.");
206             return false;
207         } else {
208             $result = $session->delete();
209             if (!$result) {
210                 common_log_db_error($session, 'DELETE', __FILE__);
211                 self::logdeb("Failed to destroy '$id'.");
212             } else {
213                 self::logdeb("Successfully destroyed '$id' (result = $result).");
214             }
215             return (bool) $result;
216         }
217     }
218 }