oxsession.php

Go to the documentation of this file.
00001 <?php
00002 
00003 DEFINE('_DB_SESSION_HANDLER', getShopBasePath() . 'core/adodblite/session/adodb-session.php');
00004 // Including database session managing class if needed.
00005 if (oxConfig::getInstance()->getConfigParam( 'blAdodbSessionHandler' ) ) {
00006     $oDB = oxDb::getDb();
00007     require_once _DB_SESSION_HANDLER;
00008 }
00009 
00015 class oxSession extends oxSuperCfg
00016 {
00022     protected $_sName = 'sid';
00023 
00028     protected  $_sId     = null;
00029 
00035     protected static $_blIsNewSession = false;
00036 
00040     protected static $_instance = null;
00041 
00046     protected static  $_oUser = null;
00047 
00054     protected $_blNewSession = false;
00055 
00061     protected $_sErrorMsg = null;
00062 
00068     protected $_oBasket = null;
00069 
00075     protected $_aRequireCookiesInFncs = array( 'register' => null,
00076                                                'account'  => null,
00077                                                'tobasket',
00078                                                'login_noredirect',
00079                                                'tocomparelist'
00080                                                );
00081 
00087     protected $_blSidNeeded = null;
00088 
00094     protected $_aPersistentParams = array("actshop", "lang", "currency", "language", "tpllanguage");
00095 
00101     public static function getInstance()
00102     {
00103         if ( defined('OXID_PHP_UNIT')) {
00104             if ( isset( modSession::$unitMOD) && is_object( modSession::$unitMOD)) {
00105                 return modSession::$unitMOD;
00106             }
00107         }
00108         if (!isset(self::$_instance)) {
00109             self::$_instance  = oxNew( 'oxsession' );
00110         }
00111         return self::$_instance;
00112     }
00113 
00119     public function getId()
00120     {
00121         return $this->_sId;
00122     }
00123 
00131     public function setId($sVal)
00132     {
00133         $this->_sId = $sVal;
00134     }
00135 
00143     public function setName($sVal)
00144     {
00145         $this->_sName = $sVal;
00146     }
00147 
00153     public function getName()
00154     {
00155         return $this->_sName;
00156     }
00157 
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         $blForceSID = false;
00381         if (strpos(" ".$url, "https:") === 1 && !$myConfig->isSsl()) {
00382             $blForceSID = true;
00383         }
00384         if (strpos(" ".$url, "http:") === 1 && $myConfig->isSsl()) {
00385             $blForceSID = true;
00386         }
00387 
00388         $blUseCookies = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00389         $oStr = getStr();
00390         $sSeparator = $oStr->strstr($url, "?") !== false ?  "&amp;" : "?";
00391 
00392         if ($blUseCookies && $this->_getCookieSid()) {
00393             //cookies are supported so we do nothing
00394             $url .= $sSeparator;
00395 
00396             //or this is SSL link in non SSL environment (or vice versa)
00397             //and we force sid here
00398             if ($blForceSID) {
00399                 $url .= 'force_sid=' . $this->getId() . '&amp;';
00400             }
00401         } elseif (oxUtils::getInstance()->isSearchEngine()) {
00402             $url .= $sSeparator;
00403 
00404             //adding lang parameter for search engines
00405             $sLangParam = oxConfig::getParameter( "lang" );
00406             $sConfLang = $myConfig->getConfigParam( 'sDefaultLang' );
00407             if ( (int) $sLangParam != (int) $sConfLang ) {
00408                 $url   .= "lang=" . $sLangParam . "&amp;";
00409             }
00410         } elseif ($this->sid()) {
00411             //removing dublicate params
00412             //..hopefully this is not needed
00413             //$url    = ereg_replace("[&?]+$", "", $url);
00414 
00415             //cookies are not supported or this is first time visit
00416             $url   .= $sSeparator . $this->sid(). '&amp;';
00417         }
00418 
00419         return $url;
00420     }
00421 
00429     public function sid()
00430     {
00431         if ( !$this->getId() ) {
00432             return false;
00433         }
00434 
00435         $myConfig     = $this->getConfig();
00436         $blUseCookies = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00437 
00438         //no cookie?
00439         if (!$blUseCookies || !$this->_getCookieSid()) {
00440             $sRet = $this->getName()."=".$this->getId();
00441         }
00442 
00443         if (oxUtils::getInstance()->isSearchEngine() && is_array($myConfig->getConfigParam( 'aCacheViews' ) ) && !$this->isAdmin() ) {
00444 
00445             $sRet = '';
00446 
00447             $sShopId = $myConfig->getShopId();
00448             if ( $sShopId != 1) {
00449                 $sRet = "shp=" . $sShopId;
00450             }
00451         }
00452 
00453         return $sRet;
00454     }
00455 
00461     public function hiddenSid()
00462     {
00463         if ( $this->isAdmin()) {
00464             return '';
00465         }
00466 
00467         return "<input type=\"hidden\" name=\"force_sid\" value=\"". $this->getId() . "\">";
00468     }
00469 
00475     public function getBasket()
00476     {
00477         if ( $this->_oBasket === null ) {
00478             $sBasket = self::getVar( $this->_getBasketName() );
00479             if ( $sBasket && $oBasket = unserialize( $sBasket ) ) {
00480                 $this->setBasket( $oBasket );
00481             } else {
00482                 $this->setBasket( oxNew( 'oxbasket' ) );
00483             }
00484         }
00485 
00486         return $this->_oBasket;
00487     }
00488 
00496     public function setBasket( $oBasket )
00497     {
00498         // sets basket session object
00499         $this->_oBasket = $oBasket;
00500     }
00501 
00507     public function delBasket()
00508     {
00509         $this->setBasket( null );
00510         self::deleteVar( $this->_getBasketName());
00511     }
00512 
00518     public function isNewSession()
00519     {
00520         return self::$_blIsNewSession;
00521     }
00522 
00528     protected function _forceSessionStart()
00529     {
00530         return ( !oxUtils::getInstance()->isSearchEngine() ) && ( ( bool ) $this->getConfig()->getConfigParam( 'blForceSessionStart' ) ) ;
00531     }
00532 
00538     protected function _allowSessionStart()
00539     {
00540         $blAllowSessionStart = true;
00541 
00542         // special handling only in non-admin mode
00543         if ( !$this->isAdmin() ) {
00544             if ( oxUtils::getInstance()->isSearchEngine() || oxConfig::getParameter( 'skipSession' ) ) {
00545                 $blAllowSessionStart = false;
00546             } elseif ( !$this->_forceSessionStart() && !oxUtilsServer::getInstance()->getOxCookie( 'sid_key' ) ) {
00547 
00548                 // session is not needed to start when it is not necessary:
00549                 // - no sid in request and also user executes no session connected action
00550                 // - no cookie set and user executes no session connected action
00551                 if ( !oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) &&
00552                      !( oxConfig::getParameter( $this->_sName ) || oxConfig::getParameter( 'force_'.$this->_sName ) ) &&
00553                      !$this->_isSessionRequiredAction() ) {
00554                     $blAllowSessionStart = false;
00555                 }
00556             }
00557         }
00558 
00559         return $blAllowSessionStart;
00560     }
00561 
00569     protected function _isSwappedClient()
00570     {
00571         $myConfig = $this->getConfig();
00572         $myUtils  = oxUtils::getInstance();
00573 
00574         $blSwapped = false;
00575 
00576         //checking search engine
00577         if ( $myUtils->isSearchEngine() ) {
00578             return false;
00579         }
00580 
00581         /*
00582         //T2007-05-14
00583         //checking 'skipSession' paramter to prevent new session generation for popup
00584         elseif("x" == $this->getId() && !oxConfig::getParameter('skipSession'))
00585         {
00586             $this->_sErrorMsg = "Refered from search engine, creating new SID...<br>";
00587 
00588             $blSwapped = true;
00589         }*/
00590 
00591         $sAgent = oxUtilsServer::getInstance()->getServerVar( 'HTTP_USER_AGENT' );
00592         $sExistingAgent = self::getVar( 'sessionagent' );
00593         if ( $this->_checkUserAgent( $sAgent, $sExistingAgent ) ) {
00594             $blSwapped = true;
00595         }
00596 
00597         /*
00598         if ( $this->_checkByTimeOut() )
00599             $blSwapped = true;
00600         */
00601 
00602         if ( $myConfig->getConfigParam( 'blAdodbSessionHandler' ) ) {
00603             if ( $this->_checkSid() ) {
00604                 $blSwapped = true;
00605             }
00606         }
00607 
00608         $blDisableCookieCheck = $myConfig->getConfigParam( 'blDisableCookieCheck' );
00609         if ( !$blDisableCookieCheck ) {
00610             $sCookieSid = oxUtilsServer::getInstance()->getOxCookie( 'sid_key' );
00611             $aSessCookieSetOnce = self::getVar("sessioncookieisset");
00612             if ( $this->_checkCookies( $sCookieSid, $aSessCookieSetOnce ) ) {
00613                 $blSwapped = true;
00614             }
00615         }
00616 
00617         return $blSwapped;
00618     }
00619 
00628     protected function _checkUserAgent( $sAgent, $sExistingAgent)
00629     {
00630         $blIgnoreBrowserChange = oxConfig::getParameter("remoteaccess") == "true" && !$this->isAdmin();
00631         if ($sAgent && $sExistingAgent && $sAgent != $sExistingAgent && (!$blIgnoreBrowserChange)) {
00632             $this->_sErrorMsg = "Different browser ($sExistingAgent, $sAgent), creating new SID...<br>";
00633             return true;
00634         } elseif (!isset($sExistingAgent)) {
00635             self::setVar("sessionagent", $sAgent);
00636         }
00637         return false;
00638     }
00639 
00646     /*
00647     protected function _checkByTimeOut()
00648     {
00649         $myConfig = $this->getConfig();
00650         $iTimeStamp = oxUtilsDate::getInstance()->getTime();
00651 
00652         // #660
00653         $iSessionTimeout = null;
00654         if( $this->isAdmin() )
00655             $iSessionTimeout = $myConfig->getConfigParam( 'iSessionTimeoutAdmin' );
00656         if ( !$this->isAdmin() || !$iSessionTimeout )
00657             $iSessionTimeout = $myConfig->getConfigParam( 'iSessionTimeout' );
00658         if (!$iSessionTimeout)
00659             $iSessionTimeout = 60;
00660 
00661         $iTimeout = 60 * $iSessionTimeout;
00662         $iExistingTimeStamp = self::getVar( "sessiontimestamp");
00663         if ( $iExistingTimeStamp && ( $iExistingTimeStamp + $iTimeout < $iTimeStamp ) ) {
00664             $this->_sErrorMsg = "Shop timeout($iTimeStamp - $iExistingTimeStamp = ".($iTimeStamp - $iExistingTimeStamp)." ),
00665                                                                                                 creating new SID...<br>";
00666             return true;
00667         }
00668         self::setVar("sessiontimestamp", $iTimeStamp);
00669         return false;
00670     }*/
00671 
00677     protected function _checkSid()
00678     {
00679         //matze changed sesskey to SessionID because structure of oxsession changed!!
00680         $sSID = oxDb::getDb()->GetOne("select SessionID from oxsessions where SessionID = '".$this->getId()."'");
00681 
00682         //2007-05-14
00683         //we check _blNewSession as well as this may be actually new session not written to db yet
00684         if ( !$this->_blNewSession && (!isset( $sSID) || !$sSID)) {
00685             // this means, that this session has expired in the past and someone uses this sid to reactivate it
00686             $this->_sErrorMsg = "Session has expired in the past and someone uses this sid to reactivate it, creating new SID...<br>";
00687             return true;
00688         }
00689         return false;
00690     }
00691 
00701     protected function _checkCookies( $sCookieSid, $aSessCookieSetOnce )
00702     {
00703         $myConfig   = $this->getConfig();
00704         $blSwapped  = false;
00705 
00706         if ( isset( $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] ) ) {
00707             $blSessCookieSetOnce = $aSessCookieSetOnce[$myConfig->getCurrentShopURL()];
00708         } else {
00709             $blSessCookieSetOnce = false;
00710         }
00711 
00712         //if cookie was there once but now is gone it means we have to reset
00713         if ( $blSessCookieSetOnce && !$sCookieSid ) {
00714             if ( $myConfig->getConfigParam( 'iDebug' ) ) {
00715                 $this->_sErrorMsg  = "Cookie not found, creating new SID...<br>";
00716                 $this->_sErrorMsg .= "Cookie: $sCookieSid<br>";
00717                 $this->_sErrorMsg .= "Session: $blSessCookieSetOnce<br>";
00718                 $this->_sErrorMsg .= "URL: ".$myConfig->getCurrentShopURL()."<br>";
00719             }
00720             $blSwapped = true;
00721         }
00722 
00723         //if we detect the cookie then set session var for possible later use
00724         if ( $sCookieSid == "oxid" && !$blSessCookieSetOnce ) {
00725             $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] = "ox_true";
00726             self::setVar( "sessioncookieisset", $aSessCookieSetOnce );
00727         }
00728 
00729         //if we have no cookie then try to set it
00730         if ( !$sCookieSid ) {
00731             oxUtilsServer::getInstance()->setOxCookie( 'sid_key', 'oxid' );
00732         }
00733         return $blSwapped;
00734     }
00735 
00743     protected function _setSessionId($sSessId)
00744     {
00745         //marking this session as new one, as it might be not writen to db yet
00746         if ($sSessId && session_id() != $sSessId) {
00747             $this->_blNewSession = true;
00748         }
00749 
00750         session_id($sSessId);
00751 
00752         $this->setId($sSessId);
00753 
00754         if (!$this->_allowSessionStart()) {
00755             oxUtilsServer::getInstance()->setOxCookie($this->getName(), null);
00756             return;
00757         }
00758 
00759         //setting session cookie
00760          oxUtilsServer::getInstance()->setOxCookie($this->getName(), $sSessId);
00761 
00762         if ( $this->_sErrorMsg) {
00763             //display debug error msg
00764             echo $this->_sErrorMsg;
00765             $this->_sErrorMsg = null;
00766         }
00767     }
00768 
00774     protected function _getBasketName()
00775     {
00776         $myConfig = $this->getConfig();
00777         if ( $myConfig->getConfigParam( 'blMallSharedBasket' ) == 0) {
00778             return $myConfig->getShopId()."_basket";
00779         } else {
00780             return "basket";
00781         }
00782     }
00783 
00789     protected function _getCookieSid()
00790     {
00791         return oxUtilsServer::getInstance()->getOxCookie($this->getName());
00792     }
00793 
00799     protected function _isSessionRequiredAction()
00800     {
00801         $sFunction = oxConfig::getParameter( 'fnc' );
00802         $sClass = oxConfig::getParameter( 'cl' );
00803 
00804         return ( $sFunction && in_array( strtolower( $sFunction ), $this->_aRequireCookiesInFncs ) ) ||
00805                ( $sClass && array_key_exists( strtolower( $sClass ), $this->_aRequireCookiesInFncs ) );
00806     }
00807 
00813     public function isSidNeeded()
00814     {
00815         if ( $this->_blSidNeeded === null ) {
00816             // setting initial state
00817             $this->_blSidNeeded = false;
00818 
00819             // no SIDs for seach engines
00820             if ( !oxUtils::getInstance()->isSearchEngine() ) {
00821                 // cookie found - SID is not needed
00822                 if ( oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) ) {
00823                     $this->_blSidNeeded = false;
00824                 } elseif ( $this->_forceSessionStart() ) {
00825                     $this->_blSidNeeded = true;
00826                 } else {
00827                     // no cookie, so must check session
00828                     if ( $blSidNeeded = self::getVar( 'blSidNeeded' ) ) {
00829                         $this->_blSidNeeded = true;
00830                     } elseif ( $this->_isSessionRequiredAction() ) {
00831                         $this->_blSidNeeded = true;
00832 
00833                         // storing to session, performance..
00834                         self::setVar( 'blSidNeeded', $this->_blSidNeeded  );
00835                     }
00836                 }
00837             }
00838         }
00839 
00840         return $this->_blSidNeeded;
00841     }
00842 
00850     public function processUrl( $sUrl )
00851     {
00852         if ( $this->isSidNeeded() ) {
00853             $oStr = getStr();
00854             // only if sid is not yet set
00855             if ( $oStr->strstr( $sUrl, 'sid=' ) === false ) {
00856                 $sUrl .= ( $oStr->strstr( $sUrl, '?' ) !== false ?  '&amp;' : '?' ) . $this->sid(). '&amp;';
00857             }
00858         }
00859 
00860         return $sUrl;
00861     }
00862 }

Generated on Tue Aug 4 09:09:57 2009 for OXID eShop CE by  doxygen 1.5.5