Exemplo n.º 1
0
 /**
  * Changes the user stored in the session, this method is different from changeUser() because it
  * attempts to re-use sessions unless there are other virtual sessions for the same user (userID != 0).
  * In reverse, logging out attempts to re-use the current session or spawns a new session depending
  * on other virtual sessions.
  * 
  * @param	\wcf\data\user\User	$user
  */
 protected function changeUserVirtual(User $user)
 {
     $sessionTable = call_user_func(array($this->sessionClassName, 'getDatabaseTableName'));
     switch ($user->userID) {
         //
         // user -> guest (logout)
         //
         case 0:
             // delete virtual session
             if ($this->virtualSession) {
                 $virtualSessionEditor = new SessionVirtualEditor($this->virtualSession);
                 $virtualSessionEditor->delete();
             }
             // there are still other virtual sessions, create a new session
             if (SessionVirtual::countVirtualSessions($this->session->sessionID)) {
                 // save session
                 $sessionData = array('sessionID' => StringUtil::getRandomID(), 'userID' => $user->userID, 'ipAddress' => UserUtil::getIpAddress(), 'userAgent' => UserUtil::getUserAgent(), 'lastActivityTime' => TIME_NOW, 'requestURI' => UserUtil::getRequestURI(), 'requestMethod' => !empty($_SERVER['REQUEST_METHOD']) ? substr($_SERVER['REQUEST_METHOD'], 0, 7) : '');
                 $this->session = call_user_func(array($this->sessionEditorClassName, 'create'), $sessionData);
                 HeaderUtil::setCookie('cookieHash', $this->session->sessionID);
             } else {
                 // this was the last virtual session, re-use current session
                 // update session
                 $sessionEditor = new $this->sessionEditorClassName($this->session);
                 $sessionEditor->update(array('userID' => $user->userID));
             }
             break;
             //
             // guest -> user (login)
             //
         //
         // guest -> user (login)
         //
         default:
             // find existing session for this user
             $session = call_user_func(array($this->sessionClassName, 'getSessionByUserID'), $user->userID);
             // no session exists, re-use current session
             if ($session === null) {
                 // update session
                 $sessionEditor = new $this->sessionEditorClassName($this->session);
                 try {
                     $this->register('__changeSessionID', true);
                     $sessionEditor->update(array('userID' => $user->userID));
                 } catch (DatabaseException $e) {
                     // MySQL error 23000 = unique key
                     // do not check against the message itself, some weird systems localize them
                     if ($e->getCode() == 23000) {
                         // delete guest session
                         $sessionEditor = new $this->sessionEditorClassName($this->session);
                         $sessionEditor->delete();
                         // inherit existing session
                         $this->session = $session;
                     } else {
                         // not our business
                         throw $e;
                     }
                 }
             } else {
                 // delete guest session
                 $sessionEditor = new $this->sessionEditorClassName($this->session);
                 $sessionEditor->delete();
                 // inherit existing session
                 $this->session = $session;
                 // inherit security token
                 $variables = @unserialize($this->session->sessionVariables);
                 if (is_array($variables) && !empty($variables['__SECURITY_TOKEN'])) {
                     $this->register('__SECURITY_TOKEN', $variables['__SECURITY_TOKEN']);
                 }
                 HeaderUtil::setCookie('cookieHash', $this->session->sessionID);
             }
             break;
     }
     $this->user = $user;
     $this->loadVirtualSession(true);
 }