oxsession.php

Go to the documentation of this file.
00001 <?php
00002 
00003 
00004 // Including database session managing class if needed.
00005 if (oxConfig::getInstance()->getConfigParam( 'blAdodbSessionHandler' ) )
00006     require_once getShopBasePath() . 'core/adodb/session/adodb-session.php';
00007 
00013 class oxSession extends oxSuperCfg
00014 {
00020     protected $_sName = 'sid';
00021 
00026     protected  $_sId     = null;
00027 
00033     protected static $_blIsNewSession = false;
00034 
00038     protected static $_instance = null;
00039 
00044     protected static  $_oUser = null;
00045 
00052     protected $_blNewSession = false;
00053 
00059     protected $_sErrorMsg = null;
00060 
00066     protected $_oBasket = null;
00067 
00073     protected $_aRequireCookiesInFncs = array( 'register' => null,
00074                                                'account'  => null,
00075                                                'tobasket',
00076                                                'login_noredirect',
00077                                                'tocomparelist'
00078                                                );
00079 
00085     protected $_blSidNeeded = null;
00086 
00092     protected $_aPersistentParams = array("actshop", "lang", "currency", "language", "tpllanguage");
00093 
00099     public static function getInstance()
00100     {
00101         if ( defined('OXID_PHP_UNIT')) {
00102             if ( isset( modSession::$unitMOD) && is_object( modSession::$unitMOD)) {
00103                 return modSession::$unitMOD;
00104             }
00105         }
00106         if (!isset(self::$_instance)) {
00107             self::$_instance  = oxNew( 'oxsession' );
00108         }
00109         return self::$_instance;
00110     }
00111 
00117     public function getId()
00118     {
00119         return $this->_sId;
00120     }
00121 
00129     public function setId($sVal)
00130     {
00131         $this->_sId = $sVal;
00132     }
00133 
00141     public function setName($sVal)
00142     {
00143         $this->_sName = $sVal;
00144     }
00145 
00151     public function getName()
00152     {
00153         return $this->_sName;
00154     }
00155 
00163     public function start()
00164     {
00165         $sid = null;
00166 
00167         if ( $this->isAdmin() ) {
00168             $this->setName("admin_sid");
00169         } else {
00170             $this->setName("sid");
00171         }
00172 
00173         $sForceSidParam = oxConfig::getParameter('force_sid');
00174         $sSidParam = oxConfig::getParameter($this->getName());
00175 
00176         $blUseCookies = $this->getConfig()->getConfigParam( 'blSessionUseCookies') || $this->isAdmin();
00177 
00178         //forcing sid for SSL<->nonSSL transitions
00179         if ($sForceSidParam) {
00180             $sid = $sForceSidParam;
00181         } elseif ($blUseCookies && $this->_getCookieSid()) {
00182             $sid = $this->_getCookieSid();
00183         } elseif ($sSidParam) {
00184             $sid = $sSidParam;
00185         }
00186 
00187         //creating new sid
00188         if ( !$sid) {
00189             $this->initNewSession();
00190             self::$_blIsNewSession = true;
00191         } else {
00192             $this->_setSessionId($sid);
00193         }
00194 
00195         //starting session if only we can
00196         if ($this->_allowSessionStart()) {
00197 
00198             $this->_sessionStart();
00199 
00200             //special handling for new ZP cluster session, as in that case session_start() regenerates id
00201             if ( $this->_sId != session_id() ) {
00202                 $this->_setSessionId( session_id() );
00203             }
00204         }
00205 
00206         //checking for swapped client in case cookies are not available
00207         if (!$this->_getCookieSid() && !oxUtils::getInstance()->isSearchEngine() && $this->_isSwappedClient() ) {
00208             $this->initNewSession();
00209         }
00210     }
00211 
00217     protected function _sessionStart()
00218     {
00219         return @session_start();
00220     }
00221 
00227     public function initNewSession()
00228     {
00229         //saving persistent params if old session exists
00230         $aPersistent = array();
00231         foreach ($this->_aPersistentParams as $sParam) {
00232             if ( self::getVar($sParam)) {
00233                 $aPersistent[$sParam] = self::getVar($sParam);
00234             }
00235         }
00236 
00237         $sid = md5(oxUtilsObject::getInstance()->generateUID());
00238 
00239         $this->_setSessionId($sid);
00240         session_unset();
00241 
00242         //restoring persistent params to session
00243         foreach ($aPersistent as $key => $sParam) {
00244             self::setVar($key, $aPersistent[$key]);
00245         }
00246     }
00247 
00253     public function freeze()
00254     {
00255         // storing basket ..
00256         self::setVar( $this->_getBasketName(), serialize( $this->getBasket() ) );
00257 
00258         session_write_close();
00259     }
00260 
00266     public function destroy()
00267     {
00268         //session_unset();
00269         unset($_SESSION);
00270         session_destroy();
00271     }
00272 
00280     public static function hasVar( $name )
00281     {
00282         if ( defined( 'OXID_PHP_UNIT' ) ) {
00283             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00284                 try{
00285                     $sVal = modSession::getInstance()->getVar( $name );
00286                     return isset( $sVal );
00287                 } catch( Exception $e ) {
00288                     // if exception is thrown, use default
00289                 }
00290             }
00291         }
00292 
00293         return isset($_SESSION[$name]);
00294     }
00295 
00304     public static function setVar( $name, $value)
00305     {
00306         if ( defined( 'OXID_PHP_UNIT' ) ) {
00307             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00308                 try{
00309                     return modSession::getInstance()->setVar(  $name, $value );
00310                 } catch( Exception $e ) {
00311                     // if exception is thrown, use default
00312                 }
00313             }
00314         }
00315 
00316         $_SESSION[$name] = $value;
00317         //logger( "set sessionvar : $name -> $value");
00318     }
00319 
00327     public static function getVar( $name )
00328     {
00329         if ( defined( 'OXID_PHP_UNIT' ) ) {
00330             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00331                 try{
00332                     return modSession::getInstance()->getVar( $name );
00333                 } catch( Exception $e ) {
00334                     // if exception is thrown, use default
00335                 }
00336             }
00337         }
00338 
00339         if ( isset( $_SESSION[$name] )) {
00340             return $_SESSION[$name];
00341         } else {
00342             return null;
00343         }
00344     }
00345 
00353     public static function deleteVar( $name )
00354     {
00355         if ( defined( 'OXID_PHP_UNIT' ) ) {
00356             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00357                 try{
00358                     return modSession::getInstance()->setVar( $name, null );
00359                 } catch( Exception $e ) {
00360                     // if exception is thrown, use default
00361                 }
00362             }
00363         }
00364 
00365         $_SESSION[$name] = null;
00366         //logger( "delete sessionvar : $name");
00367         unset($_SESSION[$name]);
00368     }
00369 
00377     public function url($url)
00378     {
00379         $myConfig = $this->getConfig();
00380         if (strpos(" ".$url, "https:") === 1 && !$myConfig->isSsl()) {
00381             $blForceSID = true;
00382         }
00383         if (strpos(" ".$url, "http:") === 1 && $myConfig->isSsl()) {
00384             $blForceSID = true;
00385         }
00386 
00387         $blUseCookies = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00388         $oStr = getStr();
00389         $sSeparator = $oStr->strstr($url, "?") !== false ?  "&amp;" : "?";
00390 
00391         if ($blUseCookies && $this->_getCookieSid()) {
00392             //cookies are supported so we do nothing
00393             $url .= $sSeparator;
00394 
00395             //or this is SSL link in non SSL environment (or vice versa)
00396             //and we force sid here
00397             if ($blForceSID) {
00398                 $url .= 'force_sid=' . $this->getId() . '&amp;';
00399             }
00400         } elseif (oxUtils::getInstance()->isSearchEngine()) {
00401             $url .= $sSeparator;
00402 
00403             //adding lang parameter for search engines
00404             $sLangParam = oxConfig::getParameter( "lang" );
00405             $sConfLang = $myConfig->getConfigParam( 'sDefaultLang' );
00406             if ( (int) $sLangParam != (int) $sConfLang ) {
00407                 $url   .= "lang=" . $sLangParam . "&amp;";
00408             }
00409         } elseif ($this->sid()) {
00410             //removing dublicate params
00411             //..hopefully this is not needed
00412             //$url    = ereg_replace("[&?]+$", "", $url);
00413 
00414             //cookies are not supported or this is first time visit
00415             $url   .= $sSeparator . $this->sid(). '&amp;';
00416         }
00417 
00418         return $url;
00419     }
00420 
00428     public function sid()
00429     {
00430         if ( !$this->getId() ) {
00431             return false;
00432         }
00433 
00434         $myConfig     = $this->getConfig();
00435         $blUseCookies = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00436 
00437         //no cookie?
00438         if (!$blUseCookies || !$this->_getCookieSid()) {
00439             $sRet = $this->getName()."=".$this->getId();
00440         }
00441 
00442         if (oxUtils::getInstance()->isSearchEngine() && is_array($myConfig->getConfigParam( 'aCacheViews' ) ) && !$this->isAdmin() ) {
00443 
00444             $sRet = '';
00445 
00446             $sShopId = $myConfig->getShopId();
00447             if ( $sShopId != 1) {
00448                 $sRet = "shp=" . $sShopId;
00449             }
00450         }
00451 
00452         return $sRet;
00453     }
00454 
00460     public function hiddenSid()
00461     {
00462         if ( $this->isAdmin()) {
00463             return '';
00464         }
00465 
00466         return "<input type=\"hidden\" name=\"force_sid\" value=\"". $this->getId() . "\">";
00467     }
00468 
00474     public function getBasket()
00475     {
00476         if ( $this->_oBasket === null ) {
00477             $sBasket = self::getVar( $this->_getBasketName() );
00478             if ( $sBasket && $oBasket = unserialize( $sBasket ) ) {
00479                 $this->setBasket( $oBasket );
00480             } else {
00481                 $this->setBasket( oxNew( 'oxbasket' ) );
00482             }
00483         }
00484 
00485         return $this->_oBasket;
00486     }
00487 
00495     public function setBasket( $oBasket )
00496     {
00497         // sets basket session object
00498         $this->_oBasket = $oBasket;
00499     }
00500 
00506     public function delBasket()
00507     {
00508         $this->setBasket( null );
00509         self::deleteVar( $this->_getBasketName());
00510     }
00511 
00517     public function isNewSession()
00518     {
00519         return self::$_blIsNewSession;
00520     }
00521 
00527     protected function _forceSessionStart()
00528     {
00529         return ( !oxUtils::getInstance()->isSearchEngine() ) && ( ( bool ) $this->getConfig()->getConfigParam( 'blForceSessionStart' ) ) ;
00530     }
00531 
00537     protected function _allowSessionStart()
00538     {
00539         $blAllowSessionStart = true;
00540 
00541         // special handling only in non-admin mode
00542         if ( !$this->isAdmin() ) {
00543             if ( oxUtils::getInstance()->isSearchEngine() || oxConfig::getParameter( 'skipSession' ) ) {
00544                 $blAllowSessionStart = false;
00545             } elseif ( !$this->_forceSessionStart() && !oxUtilsServer::getInstance()->getOxCookie( 'sid_key' ) ) {
00546 
00547                 // session is not needed to start when it is not necessary:
00548                 // - no sid in request and also user executes no session connected action
00549                 // - no cookie set and user executes no session connected action
00550                 if ( !oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) &&
00551                      !( oxConfig::getParameter( $this->_sName ) || oxConfig::getParameter( 'force_'.$this->_sName ) ) &&
00552                      !$this->_isSessionRequiredAction() ) {
00553                     $blAllowSessionStart = false;
00554                 }
00555             }
00556         }
00557 
00558         return $blAllowSessionStart;
00559     }
00560 
00568     protected function _isSwappedClient()
00569     {
00570         $myConfig = $this->getConfig();
00571         $myUtils  = oxUtils::getInstance();
00572 
00573         $blSwapped = false;
00574 
00575         //checking search engine
00576         if ( $myUtils->isSearchEngine() ) {
00577             return false;
00578         }
00579 
00580         /*
00581         //T2007-05-14
00582         //checking 'skipSession' paramter to prevent new session generation for popup
00583         elseif("x" == $this->getId() && !oxConfig::getParameter('skipSession'))
00584         {
00585             $this->_sErrorMsg = "Refered from search engine, creating new SID...<br>";
00586 
00587             $blSwapped = true;
00588         }*/
00589 
00590         $sAgent = oxUtilsServer::getInstance()->getServerVar( 'HTTP_USER_AGENT' );
00591         $sExistingAgent = self::getVar( 'sessionagent' );
00592         if ( $this->_checkUserAgent( $sAgent, $sExistingAgent ) ) {
00593             $blSwapped = true;
00594         }
00595 
00596         /*
00597         if ( $this->_checkByTimeOut() )
00598             $blSwapped = true;
00599         */
00600 
00601         if ( $myConfig->getConfigParam( 'blAdodbSessionHandler' ) ) {
00602             if ( $this->_checkSid() ) {
00603                 $blSwapped = true;
00604             }
00605         }
00606 
00607         $blDisableCookieCheck = $myConfig->getConfigParam( 'blDisableCookieCheck' );
00608         if ( !$blDisableCookieCheck ) {
00609             $sCookieSid = oxUtilsServer::getInstance()->getOxCookie( 'sid_key' );
00610             $aSessCookieSetOnce = self::getVar("sessioncookieisset");
00611             if ( $this->_checkCookies( $sCookieSid, $aSessCookieSetOnce ) ) {
00612                 $blSwapped = true;
00613             }
00614         }
00615 
00616         return $blSwapped;
00617     }
00618 
00627     protected function _checkUserAgent( $sAgent, $sExistingAgent)
00628     {
00629         $blIgnoreBrowserChange = oxConfig::getParameter("remoteaccess") == "true" && !$this->isAdmin();
00630         if ($sAgent && $sExistingAgent && $sAgent != $sExistingAgent && (!$blIgnoreBrowserChange)) {
00631             $this->_sErrorMsg = "Different browser ($sExistingAgent, $sAgent), creating new SID...<br>";
00632             return true;
00633         } elseif (!isset($sExistingAgent)) {
00634             self::setVar("sessionagent", $sAgent);
00635         }
00636         return false;
00637     }
00638 
00645     /*
00646     protected function _checkByTimeOut()
00647     {
00648         $myConfig = $this->getConfig();
00649         $iTimeStamp = oxUtilsDate::getInstance()->getTime();
00650 
00651         // #660
00652         $iSessionTimeout = null;
00653         if( $this->isAdmin() )
00654             $iSessionTimeout = $myConfig->getConfigParam( 'iSessionTimeoutAdmin' );
00655         if ( !$this->isAdmin() || !$iSessionTimeout )
00656             $iSessionTimeout = $myConfig->getConfigParam( 'iSessionTimeout' );
00657         if (!$iSessionTimeout)
00658             $iSessionTimeout = 60;
00659 
00660         $iTimeout = 60 * $iSessionTimeout;
00661         $iExistingTimeStamp = self::getVar( "sessiontimestamp");
00662         if ( $iExistingTimeStamp && ( $iExistingTimeStamp + $iTimeout < $iTimeStamp ) ) {
00663             $this->_sErrorMsg = "Shop timeout($iTimeStamp - $iExistingTimeStamp = ".($iTimeStamp - $iExistingTimeStamp)." ),
00664                                                                                                 creating new SID...<br>";
00665             return true;
00666         }
00667         self::setVar("sessiontimestamp", $iTimeStamp);
00668         return false;
00669     }*/
00670 
00676     protected function _checkSid()
00677     {
00678         //matze changed sesskey to SessionID because structure of oxsession changed!!
00679         $sSID = oxDb::getDb()->GetOne("select SessionID from oxsessions where SessionID = '".$this->getId()."'");
00680 
00681         //2007-05-14
00682         //we check _blNewSession as well as this may be actually new session not written to db yet
00683         if ( !$this->_blNewSession && (!isset( $sSID) || !$sSID)) {
00684             // this means, that this session has expired in the past and someone uses this sid to reactivate it
00685             $this->_sErrorMsg = "Session has expired in the past and someone uses this sid to reactivate it, creating new SID...<br>";
00686             return true;
00687         }
00688         return false;
00689     }
00690 
00700     protected function _checkCookies( $sCookieSid, $aSessCookieSetOnce )
00701     {
00702         $myConfig   = $this->getConfig();
00703         $blSwapped  = false;
00704 
00705         if ( isset( $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] ) ) {
00706             $blSessCookieSetOnce = $aSessCookieSetOnce[$myConfig->getCurrentShopURL()];
00707         } else {
00708             $blSessCookieSetOnce = false;
00709         }
00710 
00711         //if cookie was there once but now is gone it means we have to reset
00712         if ( $blSessCookieSetOnce && !$sCookieSid ) {
00713             if ( $myConfig->getConfigParam( 'iDebug' ) ) {
00714                 $this->_sErrorMsg  = "Cookie not found, creating new SID...<br>";
00715                 $this->_sErrorMsg .= "Cookie: $sCookieSid<br>";
00716                 $this->_sErrorMsg .= "Session: $blSessCookieSetOnce<br>";
00717                 $this->_sErrorMsg .= "URL: ".$myConfig->getCurrentShopURL()."<br>";
00718             }
00719             $blSwapped = true;
00720         }
00721 
00722         //if we detect the cookie then set session var for possible later use
00723         if ( $sCookieSid == "oxid" && !$blSessCookieSetOnce ) {
00724             $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] = "ox_true";
00725             self::setVar( "sessioncookieisset", $aSessCookieSetOnce );
00726         }
00727 
00728         //if we have no cookie then try to set it
00729         if ( !$sCookieSid ) {
00730             oxUtilsServer::getInstance()->setOxCookie( 'sid_key', 'oxid' );
00731         }
00732         return $blSwapped;
00733     }
00734 
00742     protected function _setSessionId($sSessId)
00743     {
00744         //marking this session as new one, as it might be not writen to db yet
00745         if ($sSessId && session_id() != $sSessId) {
00746             $this->_blNewSession = true;
00747         }
00748 
00749         session_id($sSessId);
00750 
00751         $this->setId($sSessId);
00752 
00753         if (!$this->_allowSessionStart()) {
00754             oxUtilsServer::getInstance()->setOxCookie($this->getName(), null);
00755             return;
00756         }
00757 
00758         //setting session cookie
00759          oxUtilsServer::getInstance()->setOxCookie($this->getName(), $sSessId);
00760 
00761         if ( $this->_sErrorMsg) {
00762             //display debug error msg
00763             echo $this->_sErrorMsg;
00764             $this->_sErrorMsg = null;
00765         }
00766     }
00767 
00773     protected function _getBasketName()
00774     {
00775         $myConfig = $this->getConfig();
00776         if ( $myConfig->getConfigParam( 'blMallSharedBasket' ) == 0) {
00777             return $myConfig->getShopId()."_basket";
00778         } else {
00779             return "basket";
00780         }
00781     }
00782 
00788     protected function _getCookieSid()
00789     {
00790         return oxUtilsServer::getInstance()->getOxCookie($this->getName());
00791     }
00792 
00798     protected function _isSessionRequiredAction()
00799     {
00800         $sFunction = oxConfig::getParameter( 'fnc' );
00801         $sClass = oxConfig::getParameter( 'cl' );
00802 
00803         return ( $sFunction && in_array( strtolower( $sFunction ), $this->_aRequireCookiesInFncs ) ) ||
00804                ( $sClass && array_key_exists( strtolower( $sClass ), $this->_aRequireCookiesInFncs ) );
00805     }
00806 
00812     public function isSidNeeded()
00813     {
00814         if ( $this->_blSidNeeded === null ) {
00815             // setting initial state
00816             $this->_blSidNeeded = false;
00817 
00818             // no SIDs for seach engines
00819             if ( !oxUtils::getInstance()->isSearchEngine() ) {
00820                 // cookie found - SID is not needed
00821                 if ( oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) ) {
00822                     $this->_blSidNeeded = false;
00823                 } elseif ( $this->_forceSessionStart() ) {
00824                     $this->_blSidNeeded = true;
00825                 } else {
00826                     // no cookie, so must check session
00827                     if ( $blSidNeeded = self::getVar( 'blSidNeeded' ) ) {
00828                         $this->_blSidNeeded = true;
00829                     } elseif ( $this->_isSessionRequiredAction() ) {
00830                         $this->_blSidNeeded = true;
00831 
00832                         // storing to session, performance..
00833                         self::setVar( 'blSidNeeded', $this->_blSidNeeded  );
00834                     }
00835                 }
00836             }
00837         }
00838 
00839         return $this->_blSidNeeded;
00840     }
00841 
00849     public function processUrl( $sUrl )
00850     {
00851         if ( $this->isSidNeeded() ) {
00852             $oStr = getStr();
00853             // only if sid is not yet set
00854             if ( $oStr->strstr( $sUrl, 'sid=' ) === false ) {
00855                 $sUrl .= ( $oStr->strstr( $sUrl, '?' ) !== false ?  '&amp;' : '?' ) . $this->sid(). '&amp;';
00856             }
00857         }
00858 
00859         return $sUrl;
00860     }
00861 }

Generated on Wed Jun 17 12:09:02 2009 for OXID eShop CE by  doxygen 1.5.5