-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDrupalSessionHandler.php
208 lines (188 loc) · 6.94 KB
/
DrupalSessionHandler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php
/**
* @file
* User session handling functions.
*
* The user-level session storage handlers:
* - _drupal_session_open()
* - _drupal_session_close()
* - _drupal_session_read()
* - _drupal_session_write()
* - _drupal_session_destroy()
* - _drupal_session_garbage_collection()
* are assigned by session_set_save_handler() in bootstrap.inc and are called
* automatically by PHP. These functions should not be called directly. Session
* data should instead be accessed via the $_SESSION superglobal.
*/
namespace Bangpound\Bundle\DrupalBundle;
class DrupalSessionHandler implements \SessionHandlerInterface
{
/**
* Session handler assigned by session_set_save_handler().
*
* This function is used to handle any initialization, such as file paths or
* database connections, that is needed before accessing session data. Drupal
* does not need to initialize anything in this function.
*
* This function should not be called directly.
*
* @param string $save_path
* @param string $session_id
* @return bool This function will always return TRUE.
*/
public function open($save_path, $session_id)
{
return TRUE;
}
/**
* Session handler assigned by session_set_save_handler().
*
* This function is used to close the current session. Because Drupal stores
* session data in the database immediately on write, this function does
* not need to do anything.
*
* This function should not be called directly.
*
* @return bool This function will always return TRUE.
*/
public function close()
{
return TRUE;
}
/**
* Reads an entire session from the database (internal use only).
*
* Also initializes the $user object for the user associated with the session.
* This function is registered with session_set_save_handler() to support
* database-backed sessions. It is called on every page load when PHP sets
* up the $_SESSION superglobal.
*
* This function is an internal function and must not be called directly.
* Doing so may result in logging out the current user, corrupting session data
* or other unexpected behavior. Session data must always be accessed via the
* $_SESSION superglobal.
*
* @param string $sid
* The session ID of the session to retrieve.
*
* @return string The user's session, or an empty string if no session exists.
*/
public function read($sid)
{
$session = db_query("SELECT session FROM {sessions} WHERE sid = :sid", array(':sid' => $sid))->fetchField();
return $session;
}
/**
* Writes an entire session to the database (internal use only).
*
* This function is registered with session_set_save_handler() to support
* database-backed sessions.
*
* This function is an internal function and must not be called directly.
* Doing so may result in corrupted session data or other unexpected behavior.
* Session data must always be accessed via the $_SESSION superglobal.
*
* @param string $sid
* The session ID of the session to write to.
* @param string $value
* Session data to write as a serialized string.
*
* @return bool Always returns TRUE.
*/
public function write($sid, $value)
{
global $user;
// The exception handler is not active at this point, so we need to do it
// manually.
try {
if (!drupal_save_session()) {
// We don't have anything to do if we are not allowed to save the session.
return;
}
// Either ssid or sid or both will be added from $key below.
$fields = array(
'uid' => $user->uid,
'cache' => isset($user->cache) ? $user->cache : 0,
'hostname' => ip_address(),
'session' => $value,
'timestamp' => REQUEST_TIME,
);
// Use the session ID as 'sid' and an empty string as 'ssid' by default.
// _drupal_session_read() does not allow empty strings so that's a safe
// default.
$key = array('sid' => $sid, 'ssid' => '');
// On HTTPS connections, use the session ID as both 'sid' and 'ssid'.
unset($key['ssid']);
db_merge('sessions')
->key($key)
->fields($fields)
->execute();
// Likewise, do not update access time more than once per 180 seconds.
if ($user->uid) {
db_update('users')
->fields(array(
'access' => REQUEST_TIME
))
->condition('uid', $user->uid)
->execute();
}
return TRUE;
} catch (\Exception $exception) {
require_once DRUPAL_ROOT . '/includes/errors.inc';
// If we are displaying errors, then do so with no possibility of a further
// uncaught exception being thrown.
if (error_displayable()) {
print '<h1>Uncaught exception thrown in session handler.</h1>';
print '<p>' . _drupal_render_exception_safe($exception) . '</p><hr />';
}
return FALSE;
}
}
/**
* Session handler assigned by session_set_save_handler().
*
* Cleans up a specific session.
*
* @param $sid
* Session ID.
* @return bool|void
*/
public function destroy($sid)
{
global $user;
// Nothing to do if we are not allowed to change the session.
if (!drupal_save_session()) {
return;
}
// Delete session data.
db_delete('sessions')
->condition('sid', $sid)
->execute();
// Reset $_SESSION and $user to prevent a new session from being started
// in drupal_session_commit().
$_SESSION = array();
$user = drupal_anonymous_user();
}
/**
* Session handler assigned by session_set_save_handler().
*
* Cleans up stalled sessions.
*
* @param $lifetime
* The value of session.gc_maxlifetime, passed by PHP.
* Sessions not updated for more than $lifetime seconds will be removed.
* @return bool
*/
public function gc($lifetime)
{
// Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
// value. For example, if you want user sessions to stay in your database
// for three weeks before deleting them, you need to set gc_maxlifetime
// to '1814400'. At that value, only after a user doesn't log in after
// three weeks (1814400 seconds) will his/her session be removed.
db_delete('sessions')
->condition('timestamp', REQUEST_TIME - $lifetime, '<')
->execute();
return TRUE;
}
}