Index: branches/5.1.x/core/kernel/session/session.php =================================================================== diff -u -N -r12657 -r13086 --- branches/5.1.x/core/kernel/session/session.php (.../session.php) (revision 12657) +++ branches/5.1.x/core/kernel/session/session.php (.../session.php) (revision 13086) @@ -1,6 +1,6 @@ SessionDataTable.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID); $this->Conn->Query($query); - $this->OriginalData = Array(); + $this->DirectVars = $this->ChangedDirectVars = $this->OriginalData = Array(); } function UpdateSession(&$session, $timeout=0) @@ -503,6 +503,12 @@ */ var $OptionalData = Array (); + /** + * Session expiration mark + * + * @var bool + */ + var $expired = false; function Session($mode = smAUTO) { @@ -564,7 +570,7 @@ $check = $this->Check(); - if ($this->Application->IsAdmin()) { + if ($this->Application->isAdmin) { // 1. Front-End session may not be created (SID is present, but no data in database). // Check expiration LATER from kApplication::Init, because template, used in session // expiration redirect should be retrieved from mod-rewrite url first. @@ -595,10 +601,9 @@ return ; } - $expired_sids = $this->DeleteExpired(); - $my_sid_expired = in_array($this->CachedSID, $expired_sids); + $this->DeleteExpired(); - if ( ($expired_sids && $my_sid_expired) || ($this->CachedSID && !$this->_fromGet && !$this->SessionSet) ) { + if ($this->expired || ($this->CachedSID && !$this->_fromGet && !$this->SessionSet)) { $this->RemoveSessionCookie(); // true was here to force new session creation, but I (kostja) used // RemoveCookie a line above, to avoid redirect loop with expired sid @@ -608,6 +613,7 @@ // case #1: I've OR other site visitor expired my session // case #2: I have no session in database, but SID is present + $this->expired = false; $expire_event = new kEvent('u:OnSessionExpire'); $this->Application->HandleEvent($expire_event); } @@ -689,6 +695,13 @@ */ function SetCookie($name, $value, $expires = null) { + if (isset($expires) && $expires < adodb_mktime()) { + unset($this->Application->HttpQuery->Cookie[$name]); + } + else { + $this->Application->HttpQuery->Cookie[$name] = $value; + } + setcookie($name, $value, $expires, $this->CookiePath, $this->CookieDomain, $this->CookieSecure); } @@ -718,8 +731,13 @@ // If session has expired if ($this->Expiration < adodb_mktime()) { + // when expired session is loaded, then SID is + // not assigned, but used in Destroy method + $this->SID = $sid; $this->Destroy(); + $this->expired = true; + // when Destory methods calls SetSession inside and new session get created return $this->SessionSet; } @@ -729,6 +747,10 @@ } else { // fake or deleted due to expiration SID + if (!$this->_fromGet) { + $this->expired = true; + } + return false; } } @@ -851,7 +873,7 @@ return true; } - if (!$force && !($this->Application->IsAdmin() || $this->Application->GetVar('admin')) && !$this->NeedSession()) { + if (!$force && !($this->Application->isAdmin || $this->Application->GetVar('admin')) && !$this->NeedSession()) { // don't create session (in db) on Front-End, when sid is present (GPC), but data in db isn't if ($this->_fromGet) { // set sid, that was given in GET @@ -887,7 +909,7 @@ $this->Storage->StoreSession($this); - if ($this->Application->IsAdmin() || $this->Special == 'admin') { + if ($this->Application->isAdmin || $this->Special == 'admin') { $this->StoreVar('admin', 1); } @@ -1092,7 +1114,7 @@ // save last_template in persistant session if (!$wid) { - if ($this->Application->IsAdmin()) { + if ($this->Application->isAdmin) { // only for main window, not popups, not login template, not temp mode (used in adm:MainFrameLink tag) $temp_mode = false; $passed = explode(',', $this->Application->GetVar('passed')); @@ -1114,11 +1136,15 @@ } elseif ($this->Application->GetVar('admin')) { // admin checking by session data to prevent recursive session save - if (!$this->RecallVar('admin')) { + static $admin_saved = null; + + if (!$this->RecallVar('admin') && !isset($admin_saved)) { // bug: we get recursion in this place, when cookies are disabled in browser and we are browsing // front-end in admin's frame (front-end session is initialized using admin's sid and they are // mixed together) + $admin_saved = true; + $admin_session =& $this->Application->recallObject('Session.admin'); /* @var $admin_session Session */