diff --git a/Application/Models/DebugBarHandler.php b/Application/Models/DebugBarHandler.php new file mode 100644 index 0000000..3a1ee7c --- /dev/null +++ b/Application/Models/DebugBarHandler.php @@ -0,0 +1,90 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\DebugBar\Application\Models; + +use D3\DebugBar\Application\Component\DebugBarComponent; +use D3\DebugBar\Core\DebugBarErrorHandler; +use D3\DebugBar\Core\DebugBarExceptionHandler; +use OxidEsales\Eshop\Core\Registry; + +class DebugBarHandler +{ + /** + * @return void + */ + public function setErrorHandler(): void + { + if ($this->d3CanActivateDebugBar()) { + set_error_handler( + [ + new DebugBarErrorHandler(), + 'callback' + ], + $this->getHandledErrorTypes() + ); + } + } + + /** + * @return int + */ + protected function getHandledErrorTypes(): int + { + return E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_PARSE; + } + + /** + * @return void + */ + public function setExceptionHandler(): void + { + if ($this->d3CanActivateDebugBar()) { + set_exception_handler( [ + new DebugBarExceptionHandler(), + 'handleUncaughtException' + ] ); + } + } + + /** + * @return void + */ + public function addDebugBarComponent(): void + { + if ($this->d3CanActivateDebugBar()) { + $userComponentNames = Registry::getConfig()->getConfigParam( 'aUserComponentNames' ); + $d3CmpName = DebugBarComponent::class; + $blDontUseCache = 1; + + if ( ! is_array( $userComponentNames ) ) { + $userComponentNames = []; + } + + if ( ! in_array( $d3CmpName, array_keys( $userComponentNames ) ) ) { + $userComponentNames[ $d3CmpName ] = $blDontUseCache; + Registry::getConfig()->setConfigParam( 'aUserComponentNames', $userComponentNames ); + } + } + } + + /** + * @return bool + */ + protected function d3CanActivateDebugBar(): bool + { + return false === isAdmin(); + } +} \ No newline at end of file diff --git a/Core/DebugBarErrorHandler.php b/Core/DebugBarErrorHandler.php new file mode 100644 index 0000000..dd93849 --- /dev/null +++ b/Core/DebugBarErrorHandler.php @@ -0,0 +1,99 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\DebugBar\Core; + +use D3\DebugBar\Application\Models\Exceptions\CompileErrorException; +use D3\DebugBar\Application\Models\Exceptions\CoreErrorException; +use D3\DebugBar\Application\Models\Exceptions\ParseException; +use D3\DebugBar\Application\Models\Exceptions\UserErrorException; +use ErrorException; +use OxidEsales\Eshop\Core\Registry; + +class DebugBarErrorHandler +{ + /** + * @param $severity + * @param $message + * @param $file + * @param $line + * + * @return void|false + * @throws CompileErrorException + * @throws CoreErrorException + * @throws ErrorException + * @throws ParseException + * @throws UserErrorException + */ + public function callback( $severity, $message, $file, $line ) + { + global $debugBarErrorOccured; + $debugBarErrorOccured = 1; + + if ( 0 === error_reporting() || !( error_reporting() & $severity ) ) { + // This error code is not included in error_reporting. + return false; + } + + $smartyTemplate = $this->getSmartyTemplateLocationFromError( $message ); + if ( is_array( $smartyTemplate ) ) { + [ $file, $line ] = $smartyTemplate; + } + + switch($severity) { + case E_CORE_ERROR: + throw new CoreErrorException($message, 0, $severity, $file, $line); + case E_COMPILE_ERROR: + throw new CompileErrorException($message, 0, $severity, $file, $line); + case E_USER_ERROR: + throw new UserErrorException($message, 0, $severity, $file, $line); + case E_PARSE: + throw new ParseException($message, 0, $severity, $file, $line); + case E_ERROR: + throw new ErrorException($message, 0, $severity, $file, $line); + default: + $this->handleUnregisteredErrorTypes($message, $severity, $file, $line); + } + } + + /** + * @param $messsage + * @return array|null + */ + protected function getSmartyTemplateLocationFromError($messsage): ?array + { + if (stristr($messsage, 'Smarty error: [in ')) { + $start = strpos($messsage, '[')+1; + $end = strpos($messsage, ']'); + $parts = explode(' ', substr($messsage, $start, $end - $start)); + return [Registry::getConfig()->getTemplateDir(isAdmin()).$parts[1], (int) $parts[3]]; + } + + return null; + } + + /** + * @param string $message + * @param int|null $severity + * @param string|null $file + * @param int|null $line + * + * @throws ErrorException + */ + protected function handleUnregisteredErrorTypes(string $message = '', int $severity = null, string $file = null, int $line = null) + { + throw new ErrorException($message, 0, $severity, $file, $line); + } +} \ No newline at end of file diff --git a/Core/DebugBarExceptionHandler.php b/Core/DebugBarExceptionHandler.php index 2f377cd..dbfda52 100644 --- a/Core/DebugBarExceptionHandler.php +++ b/Core/DebugBarExceptionHandler.php @@ -18,8 +18,7 @@ namespace D3\DebugBar\Core; use D3\DebugBar\Application\Component\DebugBarComponent; use DebugBar\DataCollector\ExceptionsCollector; use DebugBar\DebugBarException; -use OxidEsales\Eshop\Application\Controller\FrontendController; -use OxidEsales\Eshop\Core\Exception\DatabaseException; +use OxidEsales\Eshop\Core\ConfigFile; use OxidEsales\Eshop\Core\Exception\ExceptionHandler; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Framework\Logger\LoggerServiceFactory; @@ -32,12 +31,11 @@ class DebugBarExceptionHandler * Handler for uncaught exceptions. * * @param Throwable $exception exception object - * @throws DebugBarException */ public function handleUncaughtException(Throwable $exception) { try { - $debugMode = (bool) \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Core\ConfigFile::class)->getVar('iDebug'); + $debugMode = (bool) Registry::get( ConfigFile::class)->getVar( 'iDebug'); $defaultExceptionHandler = new ExceptionHandler($debugMode); $defaultExceptionHandler->writeExceptionToLog($exception); } catch (Throwable $loggerException) { @@ -46,7 +44,7 @@ class DebugBarExceptionHandler * Try again to log original exception (without DI container) in order to show the root cause of a problem. */ try { - $loggerServiceFactory = new LoggerServiceFactory(new Context(Registry::getConfig())); + $loggerServiceFactory = new LoggerServiceFactory(new Context()); $logger = $loggerServiceFactory->getLogger(); $logger->error($exception->getTraceAsString()); } catch (Throwable $throwableWithoutPossibilityToWriteToLogFile) { @@ -55,41 +53,38 @@ class DebugBarExceptionHandler } global $debugBarSet; + if ($debugBarSet !== 1 && false === isAdmin()) { - /** @var DebugBarComponent $debugBarComponent */ - $debugBarComponent = oxNew( DebugBarComponent::class ); + try { + /** @var DebugBarComponent $debugBarComponent */ + $debugBarComponent = oxNew( DebugBarComponent::class ); - /** @var ExceptionsCollector $excCollector */ - $excCollector = $debugBarComponent->getDebugBar()->getCollector('exceptions'); - $excCollector->addThrowable($exception); + /** @var ExceptionsCollector $excCollector */ + $excCollector = $debugBarComponent->getDebugBar()->getCollector( 'exceptions' ); + $excCollector->addThrowable( $exception ); - echo << - + echo << +
+