oxshopcontrol.php

Go to the documentation of this file.
00001 <?php
00002 
00008 class oxShopControl extends oxSuperCfg
00009 {
00010 
00016     protected $_blHandlerSet = null;
00017 
00023     protected $_blMainTasksExecuted = null;
00024 
00030     protected $_dTimeStart = null;
00031 
00037     protected $_dTimeEnd = null;
00038 
00046     protected $_aErrors = null;
00047 
00055     protected $_aAllErrors = null;
00056 
00064     protected $_aControllerErrors = null;
00065 
00066 
00074     protected $_oOutput = null;
00075 
00076     protected $_oCache = null;
00077 
00094     public function start( $sClass = null, $sFunction = null, $aParams = null, $aViewsChain = null )
00095     {
00096         //sets default exception handler
00097         $this->_setDefaultExceptionHandler();
00098         try {
00099             //perform tasks once per session
00100             $this->_runOnce();
00101             $sFunction = ( isset( $sFunction ) ) ? $sFunction : oxRegistry::getConfig()->getRequestParameter( 'fnc' );
00102             $sClass = $this->_getControllerToLoad( $sClass );
00103             $this->_process( $sClass, $sFunction, $aParams, $aViewsChain );
00104         } catch( oxSystemComponentException $oEx ) {
00105             $this->_handleSystemException( $oEx );
00106         } catch ( oxCookieException $oEx ) {
00107             $this->_handleCookieException( $oEx );
00108         }
00109         catch ( oxConnectionException $oEx) {
00110             $this->_handleDbConnectionException( $oEx );
00111         }
00112         catch ( oxException $oEx) {
00113             $this->_handleBaseException( $oEx );
00114         }
00115     }
00116 
00123     protected function _setDefaultExceptionHandler()
00124     {
00125         if (isset($this->_blHandlerSet)) {
00126             return;
00127         }
00128         set_exception_handler(array(oxNew('oxexceptionhandler', $this->_isDebugMode()), 'handleUncaughtException'));
00129     }
00130 
00140     protected function _log( $sClass, $sFnc )
00141     {
00142         $oDb = oxDb::getDb();
00143         $sShopID = oxSession::getVar( 'actshop' );
00144         $sTime   = date( 'Y-m-d H:i:s' );
00145         $sSidQuoted    = $oDb->quote( $this->getSession()->getId() );
00146         $sUserIDQuoted = $oDb->quote( oxSession::getVar( 'usr' ) );
00147         $sCnid = oxConfig::getParameter( 'cnid' );
00148         $sAnid = oxConfig::getParameter( 'aid' ) ? oxConfig::getParameter( 'aid' ) : oxConfig::getParameter( 'anid' );
00149         $sParameter = '';
00150 
00151         if ( $sClass == 'content' ) {
00152             $sParameter = str_replace( '.tpl', '', oxConfig::getParameter('tpl') );
00153         } elseif ( $sClass == 'search' ) {
00154             $sParameter = oxConfig::getParameter( 'searchparam' );
00155         }
00156 
00157         $sFncQuoted = $oDb->quote( $sFnc );
00158         $sClassQuoted = $oDb->quote( $sClass );
00159         $sParameterQuoted = $oDb->quote( $sParameter );
00160 
00161 
00162         $sQ = "insert into oxlogs (oxtime, oxshopid, oxuserid, oxsessid, oxclass, oxfnc, oxcnid, oxanid, oxparameter) ".
00163               "values( '$sTime', '$sShopID', $sUserIDQuoted, $sSidQuoted, $sClassQuoted, $sFncQuoted, ".$oDb->quote( $sCnid ).", ".$oDb->quote( $sAnid ).", $sParameterQuoted )";
00164 
00165         $oDb->execute( $sQ );
00166     }
00167 
00168     // OXID : add timing
00174     protected function _startMonitor()
00175     {
00176         if ( $this->_isDebugMode() ) {
00177             $this->_dTimeStart = microtime(true);
00178         }
00179     }
00180 
00191     protected function _stopMonitor( $blIsCache = false, $blIsCached = false, $sViewID = null, $aViewData = array() )
00192     {
00193         if ( $this->_isDebugMode() && !$this->isAdmin() ) {
00194             /* @var $oDebugInfo oxDebugInfo */
00195             $iDebug = $this->getConfig()->getConfigParam( 'iDebug' );
00196             $oDebugInfo = oxNew('oxDebugInfo');
00197 
00198             $blHidden = ($iDebug == -1);
00199 
00200             $sLog = '';
00201             $sLogId = md5(time().rand().rand());
00202             $sLog .= "<div id='oxidDebugInfo_$sLogId'>";
00203 
00204             $sLog .= "<div style='color:#630;margin:15px 0 0;cursor:pointer' onclick='var el=document.getElementById(\"debugInfoBlock_$sLogId\"); if (el.style.display==\"block\")el.style.display=\"none\"; else el.style.display = \"block\";'> ".$oDebugInfo->formatGeneralInfo()."(show/hide)</div>";
00205             $sLog .= "<div id='debugInfoBlock_$sLogId' style='display:".($blHidden?'none':'block')."' class='debugInfoBlock' align='left'>";
00206 
00207 
00208             // outputting template params
00209             if ( $iDebug == 4 ) {
00210                 $sLog .= $oDebugInfo->formatTemplateData($aViewData);
00211             }
00212 
00213             // output timing
00214             $this->_dTimeEnd = microtime(true);
00215 
00216 
00217             $sLog .= $oDebugInfo->formatMemoryUsage();
00218 
00219             $sLog .= $oDebugInfo->formatTimeStamp();
00220 
00221 
00222             $sLog .= $oDebugInfo->formatExecutionTime($this->getTotalTime());
00223 
00224             if ( $iDebug == 7 ) {
00225                 $sLog .= $oDebugInfo->formatDbInfo();
00226             }
00227 
00228             if ( $iDebug == 2 || $iDebug == 3 || $iDebug == 4 ) {
00229                 $sLog .= $oDebugInfo->formatAdoDbPerf();
00230             }
00231 
00232             $sLog .= '</div>';
00233 
00234             $sLog .= "<script type='text/javascript'>
00235                 var b = document.getElementById('oxidDebugInfo_$sLogId');
00236                 var c = document.body;
00237                 if (c) { c.appendChild(b.parentNode.removeChild(b));}
00238             </script>";
00239 
00240             $sLog .= "</div>";
00241 
00242             $this->_getOutputManager()->output('debuginfo', $sLog);
00243         }
00244     }
00245 
00251     public function getTotalTime()
00252     {
00253         if ($this->_dTimeEnd && $this->_dTimeStart) {
00254             return $this->_dTimeEnd - $this->_dTimeStart;
00255         }
00256 
00257         return 0;
00258     }
00259 
00265     protected function _executeMaintenanceTasks()
00266     {
00267         if (isset($this->_blMainTasksExecuted)) {
00268             return;
00269         }
00270 
00271         startProfile('executeMaintenanceTasks');
00272         oxNew("oxArticleList")->updateUpcomingPrices();
00273         stopProfile('executeMaintenanceTasks');
00274     }
00275 
00293     protected function _process( $sClass, $sFunction, $aParams = null, $aViewsChain = null )
00294     {
00295         startProfile('process');
00296         $myConfig = $this->getConfig();
00297 
00298         // executing maintenance tasks
00299         $this->_executeMaintenanceTasks();
00300 
00301         $oUtils  = oxRegistry::getUtils();
00302         $sViewID = null;
00303 
00304         if ( !$oUtils->isSearchEngine() &&
00305              !( $this->isAdmin() || !$myConfig->getConfigParam( 'blLogging' ) ) ) {
00306             $this->_log( $sClass, $sFunction );
00307         }
00308 
00309         // starting resource monitor
00310         $this->_startMonitor();
00311 
00312         // caching params ...
00313         $sOutput      = null;
00314         $blIsCached   = false;
00315 
00316         // Initialize view object and it's components.
00317         $oViewObject = $this->_initializeViewObject($sClass, $sFunction, $aParams, $aViewsChain);
00318 
00319         if ( !$this->_canExecuteFunction( $oViewObject, $oViewObject->getFncName() ) ) {
00320             throw oxNew( 'oxSystemComponentException', 'Non public method cannot be accessed' );
00321         }
00322 
00323         // executing user defined function
00324         $oViewObject->executeFunction( $oViewObject->getFncName() );
00325 
00326 
00327 
00328         // if no cache was stored before we should generate it
00329         if ( !$blIsCached ) {
00330             $sOutput = $this->_render($oViewObject);
00331         }
00332 
00333 
00334         $oOutput = $this->_getOutputManager();
00335         $oOutput->setCharset($oViewObject->getCharSet());
00336 
00337         if (oxConfig::getParameter('renderPartial')) {
00338             $oOutput->setOutputFormat(oxOutput::OUTPUT_FORMAT_JSON);
00339             $oOutput->output('errors', $this->_getFormattedErrors( $oViewObject->getClassName() ));
00340         }
00341 
00342        $oOutput->sendHeaders();
00343 
00344 
00345         $oOutput->output('content', $sOutput);
00346 
00347         $myConfig->pageClose();
00348 
00349         stopProfile('process');
00350 
00351         // stopping resource monitor
00352         $this->_stopMonitor( $oViewObject->getIsCallForCache(), $blIsCached, $sViewID, $oViewObject->getViewData() );
00353 
00354         // flush output (finalize)
00355         $oOutput->flushOutput();
00356     }
00357 
00368     protected function _initializeViewObject($sClass, $sFunction, $aParams = null, $aViewsChain = null)
00369     {
00370         $myConfig = $this->getConfig();
00371 
00372         // creating current view object
00373         $oViewObject = oxNew( $sClass );
00374 
00375         // store this call
00376         $oViewObject->setClassName( $sClass );
00377         $oViewObject->setFncName( $sFunction );
00378         $oViewObject->setViewParameters( $aParams );
00379 
00380         $myConfig->setActiveView( $oViewObject );
00381 
00382 
00383         // init class
00384         $oViewObject->init();
00385 
00386         return $oViewObject;
00387     }
00388 
00396     protected function _canExecuteFunction( $oClass, $sFunction )
00397     {
00398         $blCanExecute = true;
00399 
00400         if ( method_exists( $oClass, $sFunction ) ) {
00401             $oReflectionMethod = new ReflectionMethod( $oClass, $sFunction );
00402             if ( !$oReflectionMethod->isPublic() ) {
00403                 $blCanExecute = false;
00404             }
00405         }
00406         return $blCanExecute;
00407     }
00408 
00409 
00417     protected function _getFormattedErrors( $sControllerName )
00418     {
00419         $aErrors = $this->_getErrors( $sControllerName );
00420         $aFmtErrors = array();
00421         if ( is_array($aErrors) && count($aErrors) ) {
00422             foreach ( $aErrors as $sLocation => $aEx2 ) {
00423                 foreach ( $aEx2 as $sKey => $oEr ) {
00424                     $oErr = unserialize( $oEr );
00425                     $aFmtErrors[$sLocation][$sKey] = $oErr->getOxMessage();
00426                 }
00427             }
00428         }
00429         return $aFmtErrors;
00430     }
00431 
00439     protected function _render($oViewObject)
00440     {
00441         // get Smarty is important here as it sets template directory correct
00442         $oSmarty = oxRegistry::get("oxUtilsView")->getSmarty();
00443 
00444         // render it
00445         $sTemplateName = $oViewObject->render();
00446 
00447         // check if template dir exists
00448         $sTemplateFile = $this->getConfig()->getTemplatePath( $sTemplateName, $this->isAdmin() ) ;
00449         if ( !file_exists( $sTemplateFile)) {
00450 
00451             $oEx = oxNew( 'oxSystemComponentException' );
00452             $oEx->setMessage( 'EXCEPTION_SYSTEMCOMPONENT_TEMPLATENOTFOUND' );
00453             $oEx->setComponent( $sTemplateName );
00454 
00455             $sTemplateName = "message/exception.tpl";
00456 
00457             if ( $this->_isDebugMode() ) {
00458                 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00459             }
00460             $oEx->debugOut();
00461         }
00462 
00463         // Output processing. This is useful for modules. As sometimes you may want to process output manually.
00464         $oOutput = $this->_getOutputManager();
00465         $aViewData = $oOutput->processViewArray( $oViewObject->getViewData(), $oViewObject->getClassName() );
00466         $oViewObject->setViewData( $aViewData );
00467 
00468         //add all exceptions to display
00469         $aErrors = $this->_getErrors( $oViewObject->getClassName() );
00470         if ( is_array($aErrors) && count($aErrors) ) {
00471             oxRegistry::get("oxUtilsView")->passAllErrorsToView( $aViewData, $aErrors );
00472         }
00473 
00474         foreach ( array_keys( $aViewData ) as $sViewName ) {
00475             $oSmarty->assign_by_ref( $sViewName, $aViewData[$sViewName] );
00476         }
00477 
00478         // passing current view object to smarty
00479         $oSmarty->oxobject = $oViewObject;
00480 
00481 
00482         $sOutput = $oSmarty->fetch( $sTemplateName, $oViewObject->getViewId() );
00483 
00484         //Output processing - useful for modules as sometimes you may want to process output manually.
00485         $sOutput = $oOutput->process( $sOutput, $oViewObject->getClassName() );
00486         return $oOutput->addVersionTags( $sOutput );
00487     }
00488 
00494     protected function _getOutputManager()
00495     {
00496         if (!$this->_oOutput) {
00497             $this->_oOutput = oxNew('oxOutput');
00498         }
00499         return $this->_oOutput;
00500     }
00501 
00509     protected function _getErrors( $sCurrentControllerName )
00510     {
00511         if ( null === $this->_aErrors ) {
00512             $this->_aErrors = oxRegistry::getSession()->getVariable( 'Errors' );
00513             $this->_aControllerErrors = oxRegistry::getSession()->getVariable( 'ErrorController' );
00514             if ( null === $this->_aErrors ) {
00515                 $this->_aErrors = array();
00516             }
00517             $this->_aAllErrors = $this->_aErrors;
00518         }
00519         // resetting errors of current controller or widget from session
00520         if ( is_array($this->_aControllerErrors) && !empty($this->_aControllerErrors) ) {
00521             foreach ( $this->_aControllerErrors as $sErrorName => $sControllerName ) {
00522                 if ( $sControllerName == $sCurrentControllerName ) {
00523                     unset( $this->_aAllErrors[$sErrorName] );
00524                     unset( $this->_aControllerErrors[$sErrorName] );
00525                 }
00526             }
00527         } else {
00528             $this->_aAllErrors = array();
00529         }
00530         oxRegistry::getSession()->setVariable( 'ErrorController', $this->_aControllerErrors );
00531         oxRegistry::getSession()->setVariable( 'Errors', $this->_aAllErrors );
00532         return $this->_aErrors;
00533     }
00534 
00541     protected function _runOnce()
00542     {
00543         $myConfig = $this->getConfig();
00544         $blProductive = true;
00545         $blRunOnceExecuted = oxSession::getVar( 'blRunOnceExecuted' );
00546 
00547             $iErrorReporting = error_reporting();
00548             if ( defined( 'E_DEPRECATED' ) ) {
00549                 // some 3rd party libraries still use deprecated functions
00550                 $iErrorReporting = E_ALL ^ E_NOTICE ^ E_DEPRECATED;
00551             } else {
00552                 $iErrorReporting = E_ALL ^ E_NOTICE;
00553             }
00554             // A. is it the right place for this code ?
00555             // productive mode ?
00556             if ( ! ( $blProductive = $myConfig->isProductiveMode() ) ) {
00557                 if ( is_null($myConfig->getConfigParam( 'iDebug' )) ) {
00558                     $myConfig->setConfigParam( 'iDebug', -1 );
00559                 }
00560             } else {
00561                 // disable error logging if server is misconfigured
00562                 // #2015 E_NONE replaced with 0
00563                 if ( !ini_get( 'log_errors' ) ) {
00564                     $iErrorReporting = 0;
00565                 }
00566             }
00567             error_reporting($iErrorReporting);
00568 
00569 
00570         if ( !$blRunOnceExecuted && !$this->isAdmin() && $blProductive ) {
00571 
00572             $sTpl = false;
00573             // perform stuff - check if setup is still there
00574             if ( file_exists( $myConfig->getConfigParam( 'sShopDir' ) . '/setup/index.php' ) ) {
00575                 $sTpl = 'message/err_setup.tpl';
00576             }
00577 
00578             if ( $sTpl ) {
00579                 $oActView = oxNew( 'oxubase' );
00580                 $oSmarty = oxRegistry::get("oxUtilsView")->getSmarty();
00581                 $oSmarty->assign('oView', $oActView );
00582                 $oSmarty->assign('oViewConf', $oActView->getViewConfig() );
00583                 oxRegistry::getUtils()->showMessageAndExit( $oSmarty->fetch( $sTpl ) );
00584             }
00585 
00586             oxSession::setVar( 'blRunOnceExecuted', true );
00587         }
00588     }
00589 
00595     protected function _isDebugMode()
00596     {
00597         if ( OxRegistry::get("OxConfigFile")->getVar('iDebug') ) {
00598             return true;
00599         }
00600 
00601         return false;
00602     }
00603 
00604 
00611     protected function _handleSystemException( $oEx )
00612     {
00613         //possible reason: class does not exist etc. --> just redirect to start page
00614         if ( $this->_isDebugMode() ) {
00615             oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00616             $this->_process( 'exceptionError', 'displayExceptionError' );
00617         }
00618         $oEx->debugOut();
00619 
00620         $myConfig = $this->getConfig();
00621         if ( !$myConfig->getConfigParam( 'iDebug' ) ) {
00622             oxRegistry::getUtils()->redirect( $myConfig->getShopHomeUrl() .'cl=start', true, 302 );
00623         }
00624     }
00625 
00631     protected function _handleCookieException( $oEx )
00632     {
00633         if ( $this->_isDebugMode() ) {
00634             oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00635         }
00636         oxRegistry::getUtils()->redirect( $this->getConfig()->getShopHomeUrl() .'cl=start', true, 302 );
00637     }
00638 
00644     protected function _handleAccessRightsException( $oEx )
00645     {
00646         oxRegistry::getUtils()->redirect( $this->getConfig()->getShopHomeUrl() .'cl=content&tpl=err_accessdenied.tpl', true, 302 );
00647     }
00648 
00654     protected function _handleDbConnectionException( $oEx )
00655     {
00656         $oEx->debugOut();
00657         if ( $this->_isDebugMode() ) {
00658             oxUtils::getInstance()->showMessageAndExit( $oEx->getString() );
00659         } else {
00660             header( "HTTP/1.1 500 Internal Server Error");
00661             header( "Location: offline.html");
00662             header( "Connection: close");
00663         }
00664     }
00665 
00671     protected function _handleBaseException( $oEx )
00672     {
00673         $oEx->debugOut();
00674         if ( $this->_isDebugMode() ) {
00675             oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx );
00676             $this->_process( 'exceptionError', 'displayExceptionError' );
00677         }
00678     }
00679 
00687     protected function _getControllerToLoad( $sClass = null )
00688     {
00689         $oConfig = $this->getConfig();
00690         $sClass = ( isset( $sClass ) ) ? $sClass : oxRegistry::getConfig()->getRequestParameter( 'cl' );
00691         if ( !$sClass ) {
00692 
00693             if ( !$this->isAdmin() ) {
00694 
00695                 // first start of the shop
00696                 // check wether we have to display mall startscreen or not
00697                 if ( $oConfig->isMall() ) {
00698 
00699                     $iShopCount = oxDb::getDb()->getOne( 'select count(*) from oxshops where oxactive = 1' );
00700 
00701                     $sMallShopURL = $oConfig->getConfigParam( 'sMallShopURL' );
00702                     if ( $iShopCount && $iShopCount > 1 && $oConfig->getConfigParam( 'iMallMode' ) != 0 && !$sMallShopURL ) {
00703                         // no class specified so we need to change back to baseshop
00704                         $sClass = 'mallstart';
00705                     }
00706                 }
00707 
00708                 if ( !$sClass ) {
00709                     $sClass = 'start';
00710                 }
00711             } else {
00712                 $sClass = 'login';
00713             }
00714 
00715             oxRegistry::getSession()->setVariable( 'cl', $sClass );
00716         }
00717 
00718         return $sClass;
00719     }
00720 }