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 
00029     protected $_sForcedPrefix = 'force_';
00030 
00035     protected  $_sId     = null;
00036 
00042     protected static $_blIsNewSession = false;
00043 
00047     protected static $_instance = null;
00048 
00053     protected static  $_oUser = null;
00054 
00061     protected $_blNewSession = false;
00062 
00068     protected $_sErrorMsg = null;
00069 
00075     protected $_oBasket = null;
00076 
00082     protected $_aRequireCookiesInFncs = array( 'register' => null,
00083                                                'account'  => null,
00084                                                'tobasket',
00085                                                'login_noredirect',
00086                                                'tocomparelist'
00087                                                );
00088 
00094     protected $_blSidNeeded = null;
00095 
00101     protected $_aPersistentParams = array("actshop", "lang", "currency", "language", "tpllanguage");
00102 
00108     public static function getInstance()
00109     {
00110         if ( defined('OXID_PHP_UNIT')) {
00111             if ( isset( modSession::$unitMOD) && is_object( modSession::$unitMOD)) {
00112                 return modSession::$unitMOD;
00113             }
00114         }
00115         if (!isset(self::$_instance)) {
00116             self::$_instance  = oxNew( 'oxsession' );
00117         }
00118         return self::$_instance;
00119     }
00120 
00126     public function getId()
00127     {
00128         return $this->_sId;
00129     }
00130 
00138     public function setId($sVal)
00139     {
00140         $this->_sId = $sVal;
00141     }
00142 
00150     public function setName($sVal)
00151     {
00152         $this->_sName = $sVal;
00153     }
00154 
00160     public function getForcedName()
00161     {
00162         return $this->_sForcedPrefix . $this->getName();
00163     }
00164 
00170     public function getName()
00171     {
00172         return $this->_sName;
00173     }
00174 
00180     public function start()
00181     {
00182         $sid = null;
00183 
00184         if ( $this->isAdmin() ) {
00185             $this->setName("admin_sid");
00186         } else {
00187             $this->setName("sid");
00188         }
00189 
00190         $sForceSidParam = oxConfig::getParameter($this->getForcedName());
00191         $sSidParam = oxConfig::getParameter($this->getName());
00192 
00193         $blUseCookies = $this->getConfig()->getConfigParam( 'blSessionUseCookies') || $this->isAdmin();
00194 
00195         //forcing sid for SSL<->nonSSL transitions
00196         if ($sForceSidParam) {
00197             $sid = $sForceSidParam;
00198         } elseif ($blUseCookies && $this->_getCookieSid()) {
00199             $sid = $this->_getCookieSid();
00200         } elseif ($sSidParam) {
00201             $sid = $sSidParam;
00202         }
00203 
00204         //starting session if only we can
00205         if ($this->_allowSessionStart()) {
00206 
00207             //creating new sid
00208             if ( !$sid) {
00209                 $this->initNewSession();
00210                 self::$_blIsNewSession = true;
00211             } else {
00212                 $this->_setSessionId($sid);
00213             }
00214 
00215             $this->_sessionStart();
00216 
00217             //special handling for new ZP cluster session, as in that case session_start() regenerates id
00218             if ( $this->_sId != session_id() ) {
00219                 $this->_setSessionId( session_id() );
00220             }
00221         }
00222 
00223         //checking for swapped client in case cookies are not available
00224         if (!$this->_getCookieSid() && !oxUtils::getInstance()->isSearchEngine() && $this->_isSwappedClient() ) {
00225             $this->initNewSession();
00226         }
00227     }
00228 
00234     protected function _sessionStart()
00235     {
00236         return @session_start();
00237     }
00238 
00244     public function initNewSession()
00245     {
00246         //saving persistent params if old session exists
00247         $aPersistent = array();
00248         foreach ($this->_aPersistentParams as $sParam) {
00249             if ( self::getVar($sParam)) {
00250                 $aPersistent[$sParam] = self::getVar($sParam);
00251             }
00252         }
00253 
00254         $sid = md5(oxUtilsObject::getInstance()->generateUID());
00255 
00256         $this->_setSessionId($sid);
00257         session_unset();
00258 
00259         //restoring persistent params to session
00260         foreach ($aPersistent as $key => $sParam) {
00261             self::setVar($key, $aPersistent[$key]);
00262         }
00263     }
00264 
00270     public function freeze()
00271     {
00272         // storing basket ..
00273         self::setVar( $this->_getBasketName(), serialize( $this->getBasket() ) );
00274 
00275         session_write_close();
00276     }
00277 
00283     public function destroy()
00284     {
00285         //session_unset();
00286         unset($_SESSION);
00287         session_destroy();
00288     }
00289 
00297     public static function hasVar( $name )
00298     {
00299         if ( defined( 'OXID_PHP_UNIT' ) ) {
00300             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00301                 try{
00302                     $sVal = modSession::getInstance()->getVar( $name );
00303                     return isset( $sVal );
00304                 } catch( Exception $e ) {
00305                     // if exception is thrown, use default
00306                 }
00307             }
00308         }
00309 
00310         return isset($_SESSION[$name]);
00311     }
00312 
00321     public static function setVar( $name, $value)
00322     {
00323         if ( defined( 'OXID_PHP_UNIT' ) ) {
00324             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00325                 try{
00326                     return modSession::getInstance()->setVar(  $name, $value );
00327                 } catch( Exception $e ) {
00328                     // if exception is thrown, use default
00329                 }
00330             }
00331         }
00332 
00333         $_SESSION[$name] = $value;
00334         //logger( "set sessionvar : $name -> $value");
00335     }
00336 
00344     public static function getVar( $name )
00345     {
00346         if ( defined( 'OXID_PHP_UNIT' ) ) {
00347             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00348                 try{
00349                     return modSession::getInstance()->getVar( $name );
00350                 } catch( Exception $e ) {
00351                     // if exception is thrown, use default
00352                 }
00353             }
00354         }
00355 
00356         if ( isset( $_SESSION[$name] )) {
00357             return $_SESSION[$name];
00358         } else {
00359             return null;
00360         }
00361     }
00362 
00370     public static function deleteVar( $name )
00371     {
00372         if ( defined( 'OXID_PHP_UNIT' ) ) {
00373             if ( isset( modSession::$unitMOD ) && is_object( modSession::$unitMOD ) ) {
00374                 try{
00375                     return modSession::getInstance()->setVar( $name, null );
00376                 } catch( Exception $e ) {
00377                     // if exception is thrown, use default
00378                 }
00379             }
00380         }
00381 
00382         $_SESSION[$name] = null;
00383         //logger( "delete sessionvar : $name");
00384         unset($_SESSION[$name]);
00385     }
00386 
00394     public function url($url)
00395     {
00396         $myConfig = $this->getConfig();
00397         $blForceSID = false;
00398         if (strpos(" ".$url, "https:") === 1 && !$myConfig->isSsl()) {
00399             $blForceSID = true;
00400         }
00401         if (strpos(" ".$url, "http:") === 1 && $myConfig->isSsl()) {
00402             $blForceSID = true;
00403         }
00404 
00405         $blUseCookies = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00406         $oStr = getStr();
00407         $sSeparator = $oStr->strstr($url, "?") !== false ?  "&amp;" : "?";
00408 
00409         if ($blUseCookies && $this->_getCookieSid()) {
00410             //cookies are supported so we do nothing
00411             $url .= $sSeparator;
00412 
00413             //or this is SSL link in non SSL environment (or vice versa)
00414             //and we force sid here
00415             if ($blForceSID) {
00416                 $url .= $this->getForcedName().'=' . $this->getId() . '&amp;';
00417             }
00418         } elseif (oxUtils::getInstance()->isSearchEngine()) {
00419             $url .= $sSeparator;
00420 
00421             //adding lang parameter for search engines
00422             $sLangParam = oxConfig::getParameter( "lang" );
00423             $sConfLang = $myConfig->getConfigParam( 'sDefaultLang' );
00424             if ( (int) $sLangParam != (int) $sConfLang ) {
00425                 $url   .= "lang=" . $sLangParam . "&amp;";
00426             }
00427         } elseif ( ($sIcludeParams = $this->sid()) ) {
00428             //cookies are not supported or this is first time visit
00429             $url .= $sSeparator . $sIcludeParams . '&amp;';
00430         } else {
00431             $url .= $sSeparator;
00432         }
00433 
00434         return $url;
00435     }
00436 
00446     public function sid( $blForceSid = false )
00447     {
00448         $myConfig     = $this->getConfig();
00449         $blUseCookies = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00450         $sRet         = '';
00451 
00452         //no cookie?
00453         if ( $this->getId() && ($blForceSid || !$blUseCookies || !$this->_getCookieSid())) {
00454             $sRet = ( $blForceSid ? $this->getForcedName() : $this->getName() )."=".$this->getId();
00455         }
00456 
00457         if (oxUtils::getInstance()->isSearchEngine() && is_array($myConfig->getConfigParam( 'aCacheViews' ) ) && !$this->isAdmin() ) {
00458 
00459             $sRet = '';
00460 
00461             $sShopId = $myConfig->getShopId();
00462             if ( $sShopId != 1) {
00463                 $sRet = "shp=" . $sShopId;
00464             }
00465         }
00466 
00467         return $sRet;
00468     }
00469 
00475     public function hiddenSid()
00476     {
00477         if ( $this->isAdmin()) {
00478             return '';
00479         }
00480 
00481         return "<input type=\"hidden\" name=\"".$this->getForcedName()."\" value=\"". $this->getId() . "\">";
00482     }
00483 
00489     public function getBasket()
00490     {
00491         if ( $this->_oBasket === null ) {
00492             $sBasket = self::getVar( $this->_getBasketName() );
00493             if ( $sBasket && $oBasket = unserialize( $sBasket ) ) {
00494                 $this->setBasket( $oBasket );
00495             } else {
00496                 $this->setBasket( oxNew( 'oxbasket' ) );
00497             }
00498         }
00499 
00500         return $this->_oBasket;
00501     }
00502 
00510     public function setBasket( $oBasket )
00511     {
00512         // sets basket session object
00513         $this->_oBasket = $oBasket;
00514     }
00515 
00521     public function delBasket()
00522     {
00523         $this->setBasket( null );
00524         self::deleteVar( $this->_getBasketName());
00525     }
00526 
00532     public function isNewSession()
00533     {
00534         return self::$_blIsNewSession;
00535     }
00536 
00542     protected function _forceSessionStart()
00543     {
00544         return ( !oxUtils::getInstance()->isSearchEngine() ) && ( ( bool ) $this->getConfig()->getConfigParam( 'blForceSessionStart' ) ) ;
00545     }
00546 
00552     protected function _allowSessionStart()
00553     {
00554         $blAllowSessionStart = true;
00555 
00556         // special handling only in non-admin mode
00557         if ( !$this->isAdmin() ) {
00558             if ( oxUtils::getInstance()->isSearchEngine() || oxConfig::getParameter( 'skipSession' ) ) {
00559                 $blAllowSessionStart = false;
00560             } elseif ( !$this->_forceSessionStart() && !oxUtilsServer::getInstance()->getOxCookie( 'sid_key' ) ) {
00561 
00562                 // session is not needed to start when it is not necessary:
00563                 // - no sid in request and also user executes no session connected action
00564                 // - no cookie set and user executes no session connected action
00565                 if ( !oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) &&
00566                      !( oxConfig::getParameter( $this->getName() ) || oxConfig::getParameter( $this->getForcedName() ) ) &&
00567                      !$this->_isSessionRequiredAction() ) {
00568                     $blAllowSessionStart = false;
00569                 }
00570             }
00571         }
00572 
00573         return $blAllowSessionStart;
00574     }
00575 
00583     protected function _isSwappedClient()
00584     {
00585         $myConfig = $this->getConfig();
00586         $myUtils  = oxUtils::getInstance();
00587 
00588         $blSwapped = false;
00589 
00590         //checking search engine
00591         if ( $myUtils->isSearchEngine() ) {
00592             return false;
00593         }
00594 
00595         /*
00596         //T2007-05-14
00597         //checking 'skipSession' paramter to prevent new session generation for popup
00598         elseif("x" == $this->getId() && !oxConfig::getParameter('skipSession'))
00599         {
00600             $this->_sErrorMsg = "Refered from search engine, creating new SID...<br>";
00601 
00602             $blSwapped = true;
00603         }*/
00604 
00605         $sAgent = oxUtilsServer::getInstance()->getServerVar( 'HTTP_USER_AGENT' );
00606         $sExistingAgent = self::getVar( 'sessionagent' );
00607         if ( $this->_checkUserAgent( $sAgent, $sExistingAgent ) ) {
00608             $blSwapped = true;
00609         }
00610 
00611         /*
00612         if ( $this->_checkByTimeOut() )
00613             $blSwapped = true;
00614         */
00615 
00616         if ( $myConfig->getConfigParam( 'blAdodbSessionHandler' ) ) {
00617             if ( $this->_checkSid() ) {
00618                 $blSwapped = true;
00619             }
00620         }
00621 
00622         $blDisableCookieCheck = $myConfig->getConfigParam( 'blDisableCookieCheck' );
00623         $blUseCookies         = $myConfig->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00624         if ( !$blDisableCookieCheck && $blUseCookies ) {
00625             $sCookieSid = oxUtilsServer::getInstance()->getOxCookie( 'sid_key' );
00626             $aSessCookieSetOnce = self::getVar("sessioncookieisset");
00627             if ( $this->_checkCookies( $sCookieSid, $aSessCookieSetOnce ) ) {
00628                 $blSwapped = true;
00629             }
00630         }
00631 
00632         return $blSwapped;
00633     }
00634 
00643     protected function _checkUserAgent( $sAgent, $sExistingAgent)
00644     {
00645         $blIgnoreBrowserChange = oxConfig::getParameter("remoteaccess") == "true" && !$this->isAdmin();
00646         if ($sAgent && $sExistingAgent && $sAgent != $sExistingAgent && (!$blIgnoreBrowserChange)) {
00647             $this->_sErrorMsg = "Different browser ($sExistingAgent, $sAgent), creating new SID...<br>";
00648             return true;
00649         } elseif (!isset($sExistingAgent)) {
00650             self::setVar("sessionagent", $sAgent);
00651         }
00652         return false;
00653     }
00654 
00661     /*
00662     protected function _checkByTimeOut()
00663     {
00664         $myConfig = $this->getConfig();
00665         $iTimeStamp = oxUtilsDate::getInstance()->getTime();
00666 
00667         // #660
00668         $iSessionTimeout = null;
00669         if( $this->isAdmin() )
00670             $iSessionTimeout = $myConfig->getConfigParam( 'iSessionTimeoutAdmin' );
00671         if ( !$this->isAdmin() || !$iSessionTimeout )
00672             $iSessionTimeout = $myConfig->getConfigParam( 'iSessionTimeout' );
00673         if (!$iSessionTimeout)
00674             $iSessionTimeout = 60;
00675 
00676         $iTimeout = 60 * $iSessionTimeout;
00677         $iExistingTimeStamp = self::getVar( "sessiontimestamp");
00678         if ( $iExistingTimeStamp && ( $iExistingTimeStamp + $iTimeout < $iTimeStamp ) ) {
00679             $this->_sErrorMsg = "Shop timeout($iTimeStamp - $iExistingTimeStamp = ".($iTimeStamp - $iExistingTimeStamp)." ),
00680                                                                                                 creating new SID...<br>";
00681             return true;
00682         }
00683         self::setVar("sessiontimestamp", $iTimeStamp);
00684         return false;
00685     }*/
00686 
00692     protected function _checkSid()
00693     {
00694         //matze changed sesskey to SessionID because structure of oxsession changed!!
00695         $sSID = oxDb::getDb()->GetOne("select SessionID from oxsessions where SessionID = '".$this->getId()."'");
00696 
00697         //2007-05-14
00698         //we check _blNewSession as well as this may be actually new session not written to db yet
00699         if ( !$this->_blNewSession && (!isset( $sSID) || !$sSID)) {
00700             // this means, that this session has expired in the past and someone uses this sid to reactivate it
00701             $this->_sErrorMsg = "Session has expired in the past and someone uses this sid to reactivate it, creating new SID...<br>";
00702             return true;
00703         }
00704         return false;
00705     }
00706 
00716     protected function _checkCookies( $sCookieSid, $aSessCookieSetOnce )
00717     {
00718         $myConfig   = $this->getConfig();
00719         $blSwapped  = false;
00720 
00721         if ( isset( $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] ) ) {
00722             $blSessCookieSetOnce = $aSessCookieSetOnce[$myConfig->getCurrentShopURL()];
00723         } else {
00724             $blSessCookieSetOnce = false;
00725         }
00726 
00727         //if cookie was there once but now is gone it means we have to reset
00728         if ( $blSessCookieSetOnce && !$sCookieSid ) {
00729             if ( $myConfig->getConfigParam( 'iDebug' ) ) {
00730                 $this->_sErrorMsg  = "Cookie not found, creating new SID...<br>";
00731                 $this->_sErrorMsg .= "Cookie: $sCookieSid<br>";
00732                 $this->_sErrorMsg .= "Session: $blSessCookieSetOnce<br>";
00733                 $this->_sErrorMsg .= "URL: ".$myConfig->getCurrentShopURL()."<br>";
00734             }
00735             $blSwapped = true;
00736         }
00737 
00738         //if we detect the cookie then set session var for possible later use
00739         if ( $sCookieSid == "oxid" && !$blSessCookieSetOnce ) {
00740             $aSessCookieSetOnce[$myConfig->getCurrentShopURL()] = "ox_true";
00741             self::setVar( "sessioncookieisset", $aSessCookieSetOnce );
00742         }
00743 
00744         //if we have no cookie then try to set it
00745         if ( !$sCookieSid ) {
00746             oxUtilsServer::getInstance()->setOxCookie( 'sid_key', 'oxid' );
00747         }
00748         return $blSwapped;
00749     }
00750 
00758     protected function _setSessionId($sSessId)
00759     {
00760         //marking this session as new one, as it might be not writen to db yet
00761         if ($sSessId && session_id() != $sSessId) {
00762             $this->_blNewSession = true;
00763         }
00764 
00765         session_id($sSessId);
00766 
00767         $this->setId($sSessId);
00768 
00769         $blUseCookies = $this->getConfig()->getConfigParam( 'blSessionUseCookies' ) || $this->isAdmin();
00770 
00771         if (!$this->_allowSessionStart()) {
00772             if ($blUseCookies) {
00773                 oxUtilsServer::getInstance()->setOxCookie($this->getName(), null);
00774             }
00775             return;
00776         }
00777 
00778         if ($blUseCookies) {
00779             //setting session cookie
00780             oxUtilsServer::getInstance()->setOxCookie($this->getName(), $sSessId);
00781         }
00782 
00783         if ( $this->_sErrorMsg) {
00784             //display debug error msg
00785             echo $this->_sErrorMsg;
00786             $this->_sErrorMsg = null;
00787         }
00788     }
00789 
00795     protected function _getBasketName()
00796     {
00797         $myConfig = $this->getConfig();
00798         if ( $myConfig->getConfigParam( 'blMallSharedBasket' ) == 0) {
00799             return $myConfig->getShopId()."_basket";
00800         } else {
00801             return "basket";
00802         }
00803     }
00804 
00810     protected function _getCookieSid()
00811     {
00812         return oxUtilsServer::getInstance()->getOxCookie($this->getName());
00813     }
00814 
00820     protected function _isSessionRequiredAction()
00821     {
00822         $sFunction = oxConfig::getParameter( 'fnc' );
00823         $sClass = oxConfig::getParameter( 'cl' );
00824 
00825         return ( $sFunction && in_array( strtolower( $sFunction ), $this->_aRequireCookiesInFncs ) ) ||
00826                ( $sClass && array_key_exists( strtolower( $sClass ), $this->_aRequireCookiesInFncs ) );
00827     }
00828 
00836     public function isSidNeeded( $sUrl = null )
00837     {
00838         if ( $sUrl && !$this->getConfig()->isCurrentUrl( $sUrl ) ) {
00839             return true;
00840         } elseif ( $this->_blSidNeeded === null ) {
00841             // setting initial state
00842             $this->_blSidNeeded = false;
00843 
00844             // no SIDs for seach engines
00845             if ( !oxUtils::getInstance()->isSearchEngine() ) {
00846                 // cookie found - SID is not needed
00847                 if ( oxUtilsServer::getInstance()->getOxCookie( $this->getName() ) ) {
00848                     $this->_blSidNeeded = false;
00849                 } elseif ( $this->_forceSessionStart() ) {
00850                     $this->_blSidNeeded = true;
00851                 } else {
00852                     // no cookie, so must check session
00853                     if ( $blSidNeeded = self::getVar( 'blSidNeeded' ) ) {
00854                         $this->_blSidNeeded = true;
00855                     } elseif ( $this->_isSessionRequiredAction() ) {
00856                         $this->_blSidNeeded = true;
00857 
00858                         // storing to session, performance..
00859                         self::setVar( 'blSidNeeded', $this->_blSidNeeded  );
00860                     }
00861                 }
00862             }
00863         }
00864 
00865         return $this->_blSidNeeded;
00866     }
00867 
00875     public function processUrl( $sUrl )
00876     {
00877         if ( $this->isSidNeeded( $sUrl ) ) {
00878             $oStr = getStr();
00879             // only if sid is not yet set and we have something to append
00880             $sSid = $this->sid( true );
00881             if ( $sSid && $oStr->strstr( $sUrl, 'sid=' ) === false ) {
00882                 $sUrl .= ( $oStr->strstr( $sUrl, '?' ) !== false ?  '&amp;' : '?' ) . $sSid . '&amp;';
00883             }
00884         }
00885 
00886         return $sUrl;
00887     }
00888 }

Generated on Tue Sep 29 16:45:13 2009 for OXID eShop CE by  doxygen 1.5.5