|
eZ Publish
[4.0]
|
00001 <?php 00002 // 00003 // Definition of eZSession class 00004 // 00005 // Created on: <19-Aug-2002 12:49:18 bf> 00006 // 00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00008 // SOFTWARE NAME: eZ Publish 00009 // SOFTWARE RELEASE: 4.0.x 00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00011 // SOFTWARE LICENSE: GNU General Public License v2.0 00012 // NOTICE: > 00013 // This program is free software; you can redistribute it and/or 00014 // modify it under the terms of version 2.0 of the GNU General 00015 // Public License as published by the Free Software Foundation. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of version 2.0 of the GNU General 00023 // Public License along with this program; if not, write to the Free 00024 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00025 // MA 02110-1301, USA. 00026 // 00027 // 00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00029 // 00030 00031 /*! 00032 Re-implementation of PHP session management using database. 00033 00034 The session system has a hook system which allows external code to perform 00035 extra tasks before and after a certain action is executed. For instance to 00036 cleanup a table when sessions are removed. 00037 To create a hook function the global variable \c eZSessionFunctions must be 00038 filled in. This contains an associative array with hook points, e.g. 00039 \c destroy_pre which is checked by the session system. 00040 Each hook point must contain an array with function names to execute, if the 00041 hook point does not exist the session handler will not handle the hooks. 00042 00043 \code 00044 function cleanupStuff( $db, $key, $escKey ) 00045 { 00046 // Do cleanup here 00047 } 00048 if ( !isset( $GLOBALS['eZSessionFunctions']['destroy_pre'] ) ) 00049 $GLOBALS['eZSessionFunctions']['destroy_pre'] = array(); 00050 $GLOBALS['eZSessionFunctions']['destroy_pre'][] = 'cleanupstuff'; 00051 \endcode 00052 00053 When new data is inserted to the database it will call the \c update_pre and 00054 \c update_post hooks. The signature of the function is 00055 function insert( $db, $key, $escapedKey, $expirationTime, $userID, $value ) 00056 00057 When existing data is updated in the databbase it will call the \c insert_pre 00058 and \c insert_post hook. The signature of the function is 00059 function update( $db, $key, $escapedKey, $expirationTime, $userID, $value ) 00060 00061 When a specific session is destroyed in the database it will call the 00062 \c destroy_pre and \c destroy_post hooks. The signature of the function is 00063 function destroy( $db, $key, $escapedKey ) 00064 00065 When multiple sessions are expired (garbage collector) in the database it 00066 will call the \c gc_pre and \c gc_post hooks. The signature of the function is 00067 function gcollect( $db, $expiredTime ) 00068 00069 When all sessionss are removed from the database it will call the 00070 \c empty_pre and \c empty_post hooks. The signature of the function is 00071 function empty( $db ) 00072 00073 \param $db The database object used by the session manager. 00074 \param $key The session key which are being worked on, see also \a $escapedKey 00075 \param $escapedKey The same key as \a $key but is escaped correctly for the database. 00076 Use this to save a call to eZDBInterface::escapeString() 00077 \param $expirationTime An integer specifying the timestamp of when the session 00078 will expire. 00079 \param $expiredTime Similar to \a $expirationTime but is the time used to figure 00080 if a session is expired in the database. ie. all sessions with 00081 lower expiration times will be removed. 00082 */ 00083 00084 function eZSessionOpen( ) 00085 { 00086 // do nothing eZDB will open connection when needed. 00087 } 00088 00089 function eZSessionClose( ) 00090 { 00091 // eZDB will handle closing the database 00092 } 00093 00094 function eZSessionRead( $key ) 00095 { 00096 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00097 $db = eZDB::instance(); 00098 00099 $key = $db->escapeString( $key ); 00100 00101 $sessionRes = $db->arrayQuery( "SELECT data, user_id, expiration_time FROM ezsession WHERE session_key='$key'" ); 00102 00103 if ( $sessionRes !== false and count( $sessionRes ) == 1 ) 00104 { 00105 $ini = eZINI::instance(); 00106 00107 $sessionUpdatesTime = $sessionRes[0]['expiration_time'] - $ini->variable( 'Session', 'SessionTimeout' ); 00108 $sessionIdle = time() - $sessionUpdatesTime; 00109 00110 $GLOBALS['eZSessionUserID'] = $sessionRes[0]['user_id']; 00111 $GLOBALS['eZSessionIdleTime'] = $sessionIdle; 00112 00113 /* 00114 * The line below is needed to correctly load list of content classes saved 00115 * in the CanInstantiateClassList session variable. 00116 * Without this we get incomplete classes loaded (__PHP_Incomplete_Class). 00117 */ 00118 require_once( 'kernel/classes/ezcontentclass.php' ); 00119 00120 return $sessionRes[0]['data']; 00121 } 00122 else 00123 { 00124 return false; 00125 } 00126 } 00127 00128 /*! 00129 Will write the session information to database. 00130 */ 00131 function eZSessionWrite( $key, $value ) 00132 { 00133 // //include_once( 'lib/ezdb/classes/ezdb.php' ); 00134 00135 if ( isset( $GLOBALS["eZRequestError"] ) && $GLOBALS["eZRequestError"] ) 00136 { 00137 return; 00138 } 00139 00140 $db = eZDB::instance(); 00141 $ini = eZINI::instance(); 00142 $expirationTime = time() + $ini->variable( 'Session', 'SessionTimeout' ); 00143 00144 if ( $db->bindingType() != eZDBInterface::BINDING_NO ) 00145 { 00146 $value = $db->bindVariable( $value, array( 'name' => 'data' ) ); 00147 } 00148 else 00149 { 00150 $value = '\'' . $db->escapeString( $value ) . '\''; 00151 00152 } 00153 // $value = $db->escapeString( $value ); 00154 $escKey = $db->escapeString( $key ); 00155 // check if session already exists 00156 00157 $userID = 0; 00158 if ( isset( $GLOBALS['eZSessionUserID'] ) ) 00159 $userID = $GLOBALS['eZSessionUserID']; 00160 $userID = $db->escapeString( $userID ); 00161 00162 $sessionRes = $db->arrayQuery( "SELECT session_key FROM ezsession WHERE session_key='$escKey'" ); 00163 00164 if ( count( $sessionRes ) == 1 ) 00165 { 00166 if ( isset( $GLOBALS['eZSessionFunctions']['update_pre'] ) ) 00167 { 00168 foreach ( $GLOBALS['eZSessionFunctions']['update_pre'] as $func ) 00169 { 00170 $func( $db, $key, $escKey, $expirationTime, $userID, $value ); 00171 } 00172 } 00173 00174 $updateQuery = "UPDATE ezsession 00175 SET expiration_time='$expirationTime', data=$value, user_id='$userID' 00176 WHERE session_key='$escKey'"; 00177 00178 $ret = $db->query( $updateQuery ); 00179 00180 if ( isset( $GLOBALS['eZSessionFunctions']['update_post'] ) ) 00181 { 00182 foreach ( $GLOBALS['eZSessionFunctions']['update_post'] as $func ) 00183 { 00184 $func( $db, $key, $escKey, $expirationTime, $userID, $value ); 00185 } 00186 } 00187 } 00188 else 00189 { 00190 if ( isset( $GLOBALS['eZSessionFunctions']['insert_pre'] ) ) 00191 { 00192 foreach ( $GLOBALS['eZSessionFunctions']['insert_pre'] as $func ) 00193 { 00194 $func( $db, $key, $escKey, $expirationTime, $userID, $value ); 00195 } 00196 } 00197 00198 $insertQuery = "INSERT INTO ezsession 00199 ( session_key, expiration_time, data, user_id ) 00200 VALUES ( '$escKey', '$expirationTime', $value, '$userID' )"; 00201 00202 $ret = $db->query( $insertQuery ); 00203 00204 if ( isset( $GLOBALS['eZSessionFunctions']['insert_post'] ) ) 00205 { 00206 foreach ( $GLOBALS['eZSessionFunctions']['insert_post'] as $func ) 00207 { 00208 $func( $db, $key, $escKey, $expirationTime, $userID, $value ); 00209 } 00210 } 00211 } 00212 } 00213 00214 /*! 00215 Will remove a session from the database. 00216 */ 00217 function eZSessionDestroy( $key ) 00218 { 00219 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00220 $db = eZDB::instance(); 00221 00222 $escKey = $db->escapeString( $key ); 00223 if ( isset( $GLOBALS['eZSessionFunctions']['destroy_pre'] ) ) 00224 { 00225 foreach ( $GLOBALS['eZSessionFunctions']['destroy_pre'] as $func ) 00226 { 00227 $func( $db, $key, $escKey ); 00228 } 00229 } 00230 00231 $query = "DELETE FROM ezsession WHERE session_key='$escKey'"; 00232 $db->query( $query ); 00233 00234 if ( isset( $GLOBALS['eZSessionFunctions']['destroy_post'] ) ) 00235 { 00236 foreach ( $GLOBALS['eZSessionFunctions']['destroy_post'] as $func ) 00237 { 00238 $func( $db, $key, $escKey ); 00239 } 00240 } 00241 } 00242 00243 /*! 00244 Handles session cleanup. Will delete timed out sessions from the database. 00245 */ 00246 function eZSessionGarbageCollector() 00247 { 00248 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00249 $db = eZDB::instance(); 00250 $time = time(); 00251 00252 if ( isset( $GLOBALS['eZSessionFunctions']['gc_pre'] ) ) 00253 { 00254 foreach ( $GLOBALS['eZSessionFunctions']['gc_pre'] as $func ) 00255 { 00256 $func( $db, $time ); 00257 } 00258 } 00259 00260 $query = "DELETE FROM ezsession WHERE expiration_time < " . $time; 00261 00262 $db->query( $query ); 00263 00264 if ( isset( $GLOBALS['eZSessionFunctions']['gc_post'] ) ) 00265 { 00266 foreach ( $GLOBALS['eZSessionFunctions']['gc_post'] as $func ) 00267 { 00268 $func( $db, $time ); 00269 } 00270 } 00271 } 00272 00273 /*! 00274 Removes all entries from session. 00275 */ 00276 function eZSessionEmpty() 00277 { 00278 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00279 $db = eZDB::instance(); 00280 00281 if ( isset( $GLOBALS['eZSessionFunctions']['empty_pre'] ) ) 00282 { 00283 foreach ( $GLOBALS['eZSessionFunctions']['empty_pre'] as $func ) 00284 { 00285 $func( $db ); 00286 } 00287 } 00288 00289 $query = "TRUNCATE TABLE ezsession"; 00290 00291 $db->query( $query ); 00292 00293 if ( isset( $GLOBALS['eZSessionFunctions']['empty_post'] ) ) 00294 { 00295 foreach ( $GLOBALS['eZSessionFunctions']['empty_post'] as $func ) 00296 { 00297 $func( $db ); 00298 } 00299 } 00300 } 00301 00302 /*! 00303 Counts the number of active session and returns it. 00304 */ 00305 function eZSessionCountActive() 00306 { 00307 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00308 $db = eZDB::instance(); 00309 $query = "SELECT count( * ) AS count FROM ezsession"; 00310 00311 $rows = $db->arrayQuery( $query ); 00312 return $rows[0]['count']; 00313 } 00314 00315 /*! 00316 Register the needed session functions. 00317 Call this only once. 00318 */ 00319 function eZRegisterSessionFunctions() 00320 { 00321 session_module_name( 'user' ); 00322 $ini = eZINI::instance(); 00323 if ( $ini->variable( 'Session', 'SessionNameHandler' ) == 'custom' ) 00324 { 00325 $sessionName = $ini->variable( 'Session', 'SessionNamePrefix' ); 00326 if ( $ini->variable( 'Session', 'SessionNamePerSiteAccess' ) == 'enabled' ) 00327 { 00328 $access = $GLOBALS['eZCurrentAccess']; 00329 $sessionName .= $access['name']; 00330 } 00331 session_name( $sessionName ); 00332 } 00333 session_set_save_handler( 00334 'ezsessionopen', 00335 'ezsessionclose', 00336 'ezsessionread', 00337 'ezsessionwrite', 00338 'ezsessiondestroy', 00339 'ezsessiongarbagecollector' ); 00340 } 00341 00342 /*! 00343 Makes sure that the session is started properly. 00344 Multiple calls will just be ignored. 00345 */ 00346 function eZSessionStart() 00347 { 00348 // Check if we are allowed to use sessions 00349 if ( isset( $GLOBALS['eZSiteBasics'] ) && 00350 isset( $GLOBALS['eZSiteBasics']['session-required'] ) && 00351 !$GLOBALS['eZSiteBasics']['session-required'] ) 00352 { 00353 return false; 00354 } 00355 if ( isset( $GLOBALS['eZSessionIsStarted'] ) && 00356 $GLOBALS['eZSessionIsStarted'] ) 00357 { 00358 return false; 00359 } 00360 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00361 $db = eZDB::instance(); 00362 if ( !$db->isConnected() ) 00363 { 00364 return false; 00365 } 00366 eZRegisterSessionFunctions(); 00367 $ini = eZINI::instance(); 00368 $cookieTimeout = isset( $GLOBALS['RememberMeTimeout'] ) ? $GLOBALS['RememberMeTimeout'] : $ini->variable( 'Session', 'CookieTimeout' ); 00369 00370 if ( is_numeric( $cookieTimeout ) ) 00371 { 00372 session_set_cookie_params( (int)$cookieTimeout ); 00373 } 00374 session_start(); 00375 return $GLOBALS['eZSessionIsStarted'] = true; 00376 } 00377 00378 /*! 00379 Makes sure session data is stored in the session and stops the session. 00380 */ 00381 function eZSessionStop() 00382 { 00383 if ( isset( $GLOBALS['eZSessionIsStarted'] ) && 00384 !$GLOBALS['eZSessionIsStarted'] ) 00385 { 00386 return false; 00387 } 00388 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00389 $db = eZDB::instance(); 00390 if ( !$db->isConnected() ) 00391 { 00392 return false; 00393 } 00394 session_write_close(); 00395 $GLOBALS['eZSessionIsStarted'] = false; 00396 return true; 00397 } 00398 00399 /*! 00400 Will make sure the user gets a new session ID while keepin the session data. 00401 This is useful to call on logins, to avoid sessions theft from users. 00402 \note This requires PHP 4.3.2 and higher which has the session_regenerate_id 00403 \return \c true if succesful 00404 */ 00405 function eZSessionRegenerate() 00406 { 00407 if ( isset( $GLOBALS['eZSessionIsStarted'] ) && 00408 !$GLOBALS['eZSessionIsStarted'] ) 00409 { 00410 return false; 00411 } 00412 if ( !function_exists( 'session_regenerate_id' ) ) 00413 { 00414 return false; 00415 } 00416 // This doesn't seem to work as expected 00417 // session_regenerate_id(); 00418 return true; 00419 } 00420 00421 /*! 00422 Removes the current session and resets session variables. 00423 */ 00424 function eZSessionRemove() 00425 { 00426 if ( isset( $GLOBALS['eZSessionIsStarted'] ) && 00427 !$GLOBALS['eZSessionIsStarted'] ) 00428 { 00429 return false; 00430 } 00431 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00432 $db = eZDB::instance(); 00433 if ( !$db->isConnected() ) 00434 { 00435 return false; 00436 } 00437 $_SESSION = array(); 00438 session_destroy(); 00439 $GLOBALS['eZSessionIsStarted'] = false; 00440 return true; 00441 } 00442 00443 /*! 00444 Sets the current user ID to \a $userID, 00445 this ID will be written to the session table field user_id 00446 when the page is done. 00447 \sa eZSessionUserID 00448 */ 00449 function eZSessionSetUserID( $userID ) 00450 { 00451 $GLOBALS['eZSessionUserID'] = $userID; 00452 } 00453 00454 /*! 00455 Returns the current session ID. 00456 The session handler will not care about value of the ID, 00457 it's entirely up to the clients of the session handler to use and update this value. 00458 */ 00459 function eZSessionUserID() 00460 { 00461 if ( isset( $GLOBALS['eZSessionUserID'] ) ) 00462 return $GLOBALS['eZSessionUserID']; 00463 return 0; 00464 } 00465 00466 ?>