4 * @file classes/session/SessionManager.inc.php
6 * Copyright (c) 2000-2009 John Willinsky
7 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
9 * @class SessionManager
12 * @brief Implements PHP methods for a custom session storage handler (see http://php.net/session).
15 // $Id: SessionManager.inc.php,v 1.7 2009/05/13 16:35:48 asmecher Exp $
18 class SessionManager
{
20 /** The DAO for accessing Session objects */
23 /** The Session associated with the current request */
28 * Initialize session configuration and set PHP session handlers.
29 * Attempts to rejoin a user's session if it exists, or create a new session otherwise.
31 function SessionManager(&$sessionDao) {
32 $this->sessionDao
=& $sessionDao;
34 // Configure PHP session parameters
35 ini_set('session.use_trans_sid', 0);
36 ini_set('session.save_handler', 'user');
37 ini_set('session.serialize_handler', 'php');
38 ini_set('session.use_cookies', 1);
39 ini_set('session.name', Config
::getVar('general', 'session_cookie_name')); // Cookie name
40 ini_set('session.cookie_lifetime', 0);
41 ini_set('session.cookie_path', PKPRequest
::getBasePath() . '/');
42 ini_set('session.gc_probability', 1);
43 ini_set('session.gc_maxlifetime', 60 * 60);
44 ini_set('session.auto_start', 1);
45 ini_set('session.cache_limiter', 'none');
47 session_set_save_handler(
48 array(&$this, 'open'),
49 array(&$this, 'close'),
50 array(&$this, 'read'),
51 array(&$this, 'write'),
52 array(&$this, 'destroy'),
56 // Initialize the session
58 $sessionId = session_id();
60 $ip = PKPRequest
::getRemoteAddr();
61 $userAgent = PKPRequest
::getUserAgent();
64 if (!isset($this->userSession
) ||
(Config
::getVar('security', 'session_check_ip') && $this->userSession
->getIpAddress() != $ip) ||
$this->userSession
->getUserAgent() != $userAgent) {
65 if (isset($this->userSession
)) {
66 // Destroy old session
71 $this->userSession
= new Session();
72 $this->userSession
->setId($sessionId);
73 $this->userSession
->setIpAddress($ip);
74 $this->userSession
->setUserAgent($userAgent);
75 $this->userSession
->setSecondsCreated($now);
76 $this->userSession
->setSecondsLastUsed($now);
77 $this->userSession
->setSessionData('');
79 $this->sessionDao
->insertSession($this->userSession
);
82 if ($this->userSession
->getRemember()) {
83 // Update session timestamp for remembered sessions so it doesn't expire in the middle of a browser session
84 if (Config
::getVar('general', 'session_lifetime') > 0) {
85 $this->updateSessionLifetime(time() + Config
::getVar('general', 'session_lifetime') * 86400);
87 $this->userSession
->setRemember(0);
88 $this->updateSessionLifetime(0);
92 // Update existing session's timestamp
93 $this->userSession
->setSecondsLastUsed($now);
94 $this->sessionDao
->updateObject($this->userSession
);
99 * Return an instance of the session manager.
100 * @return SessionManager
102 function &getManager() {
103 $instance =& Registry
::get('sessionManager', true, null);
105 if ($instance === null) {
106 $instance = new SessionManager(DAORegistry
::getDAO('SessionDAO'));
112 * Get the session associated with the current request.
115 function &getUserSession() {
116 return $this->userSession
;
121 * Does nothing; only here to satisfy PHP session handler requirements.
130 * Does nothing; only here to satisfy PHP session handler requirements.
138 * Read session data from database.
139 * @param $sessionId string
142 function read($sessionId) {
143 if (!isset($this->userSession
)) {
144 $this->userSession
=& $this->sessionDao
->getSession($sessionId);
145 if (isset($this->userSession
)) {
146 $data = $this->userSession
->getSessionData();
149 return isset($data) ?
$data : '';
153 * Save session data to database.
154 * @param $sessionId string
158 function write($sessionId, $data) {
159 if (isset($this->userSession
)) {
160 $this->userSession
->setSessionData($data);
161 return $this->sessionDao
->updateObject($this->userSession
);
169 * Destroy (delete) a session.
170 * @param $sessionId string
173 function destroy($sessionId) {
174 return $this->sessionDao
->deleteSessionById($sessionId);
178 * Garbage collect unused session data.
179 * TODO: Use $maxlifetime instead of assuming 24 hours?
180 * @param $maxlifetime int the number of seconds after which data will be seen as "garbage" and cleaned up
183 function gc($maxlifetime) {
184 return $this->sessionDao
->deleteSessionByLastUsed(time() - 86400, Config
::getVar('general', 'session_lifetime') <= 0 ?
0 : time() - Config
::getVar('general', 'session_lifetime') * 86400);
188 * Resubmit the session cookie.
189 * @param $sessionId string new session ID (or false to keep current ID)
190 * @param $expireTime int new expiration time in seconds (0 = current session)
193 function updateSessionCookie($sessionId = false, $expireTime = 0) {
194 return setcookie(session_name(), ($sessionId === false) ?
session_id() : $sessionId, $expireTime, ini_get('session.cookie_path'));
198 * Regenerate the session ID for the current user session.
199 * This is useful to guard against the "session fixation" form of hijacking
200 * by changing the user's session ID after they have logged in (in case the
201 * original session ID had been pre-populated).
204 function regenerateSessionId() {
206 $currentSessionId = session_id();
208 if (function_exists('session_regenerate_id')) {
209 // session_regenerate_id is only available on PHP >= 4.3.2
210 if (session_regenerate_id() && isset($this->userSession
)) {
211 // Delete old session and insert new session
212 $this->sessionDao
->deleteSessionById($currentSessionId);
213 $this->userSession
->setId(session_id());
214 $this->sessionDao
->insertSession($this->userSession
);
215 $this->updateSessionCookie(); // TODO: this might not be needed on >= 4.3.3
220 // Regenerate session ID (for PHP < 4.3.2)
222 // Generate new session ID -- should be random enough to typically execute only once
223 $newSessionId = md5(mt_rand());
224 } while ($this->sessionDao
->sessionExistsById($newSessionId));
226 if (isset($this->userSession
)) {
227 // Delete old session and insert new session
228 $this->sessionDao
->deleteSessionById($currentSessionId);
229 $this->userSession
->setId($newSessionId);
230 $this->sessionDao
->insertSession($this->userSession
);
231 $this->updateSessionCookie($newSessionId);
240 * Change the lifetime of the current session cookie.
241 * @param $expireTime int new expiration time in seconds (0 = current session)
244 function updateSessionLifetime($expireTime = 0) {
245 return $this->updateSessionCookie(false, $expireTime);