diff --git a/Application/Component/DebugBarComponent.php b/Application/Component/DebugBarComponent.php index 7433bb7..bab791b 100644 --- a/Application/Component/DebugBarComponent.php +++ b/Application/Component/DebugBarComponent.php @@ -15,10 +15,12 @@ declare(strict_types=1); namespace D3\DebugBar\Application\Component; +use D3\DebugBar\Application\Models\AvailabilityCheck; use D3\DebugBar\Application\Models\Collectors\OxidConfigCollector; use D3\DebugBar\Application\Models\Collectors\OxidShopCollector; use D3\DebugBar\Application\Models\Collectors\OxidVersionCollector; use D3\DebugBar\Application\Models\Collectors\SmartyCollector; +use D3\DebugBar\Application\Models\Exceptions\UnavailableException; use D3\DebugBar\Application\Models\TimeDataCollectorHandler; use DebugBar\Bridge\DoctrineCollector; use DebugBar\Bridge\MonologCollector; @@ -43,8 +45,8 @@ use ReflectionException; class DebugBarComponent extends BaseController { - /** @var DebugBar */ - protected $debugBar; + /** @var DebugBar|null */ + protected $debugBar = null; /** @var JavascriptRenderer */ protected $debugBarRenderer; @@ -63,7 +65,7 @@ class DebugBarComponent extends BaseController { parent::__construct(); - if (false === isAdmin()) { + if (AvailabilityCheck::isAvailable()) { $debugbar = new DebugBar(); $this->addCollectors($debugbar); @@ -180,6 +182,10 @@ class DebugBarComponent extends BaseController */ public function addTimelineMessures(): void { + if (false === $this->debugBar instanceof DebugBar) { + throw new UnavailableException(); + } + $collectors = $this->debugBar->getCollectors(); $collectors['time'] = TimeDataCollectorHandler::getInstance(); @@ -191,9 +197,14 @@ class DebugBarComponent extends BaseController /** * @return DebugBar + * @throws UnavailableException */ public function getDebugBar(): DebugBar { + if (false === $this->debugBar instanceof DebugBar) { + throw new UnavailableException(); + } + return $this->debugBar; } diff --git a/Application/Models/AvailabilityCheck.php b/Application/Models/AvailabilityCheck.php new file mode 100644 index 0000000..d7cd9d2 --- /dev/null +++ b/Application/Models/AvailabilityCheck.php @@ -0,0 +1,83 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\DebugBar\Application\Models; + +use OxidEsales\Eshop\Application\Model\User; +use OxidEsales\Eshop\Core\Registry; + +class AvailabilityCheck +{ + /** + * @return bool + */ + public static function isAvailable(): bool + { + return !isAdmin() && ( + Registry::getConfig()->getShopConfVar('d3debugbar_showForAdminUsersOnly') != true || + self::userIsMallAdmin() + ); + } + + /** + * @return bool + */ + public static function userIsMallAdmin(): bool + { + $user = Registry::getConfig()->getUser(); + return $user != null && + $user->isMallAdmin(); + } + + /** + * @return bool + */ + public static function ifDebugBarNotSet(): bool + { + global $debugBarSet; + + return $debugBarSet !== 1; + } + + /** + * @return void + */ + public static function markDebugBarAsSet(): void + { + global $debugBarSet; + + $debugBarSet = 1; + } + + /** + * @return bool + */ + public static function ifNoErrorOccured(): bool + { + global $debugBarErrorOccured; + + return $debugBarErrorOccured !== 1; + } + + /** + * @return void + */ + public static function markErrorOccured(): void + { + global $debugBarErrorOccured; + + $debugBarErrorOccured = 1; + } +} diff --git a/Application/Models/DebugBarHandler.php b/Application/Models/DebugBarHandler.php index 0040e3a..e3d0eae 100644 --- a/Application/Models/DebugBarHandler.php +++ b/Application/Models/DebugBarHandler.php @@ -27,7 +27,7 @@ class DebugBarHandler */ public function setErrorHandler(): void { - if ($this->d3CanActivateDebugBar()) { + if (AvailabilityCheck::isAvailable()) { /** @var callable $callable */ $callable = [ new DebugBarErrorHandler(), @@ -50,7 +50,7 @@ class DebugBarHandler */ public function setExceptionHandler(): void { - if ($this->d3CanActivateDebugBar()) { + if (AvailabilityCheck::isAvailable()) { set_exception_handler([ new DebugBarExceptionHandler(), 'handleUncaughtException', @@ -63,7 +63,7 @@ class DebugBarHandler */ public function addDebugBarComponent(): void { - if ($this->d3CanActivateDebugBar()) { + if (AvailabilityCheck::isAvailable()) { $userComponentNames = Registry::getConfig()->getConfigParam('aUserComponentNames'); $d3CmpName = DebugBarComponent::class; $blDontUseCache = 1; @@ -78,12 +78,4 @@ class DebugBarHandler } } } - - /** - * @return bool - */ - protected function d3CanActivateDebugBar(): bool - { - return false === isAdmin(); - } } diff --git a/Application/Models/Exceptions/UnavailableException.php b/Application/Models/Exceptions/UnavailableException.php new file mode 100644 index 0000000..ee4277a --- /dev/null +++ b/Application/Models/Exceptions/UnavailableException.php @@ -0,0 +1,22 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +namespace D3\DebugBar\Application\Models\Exceptions; + +use OxidEsales\Eshop\Core\Exception\StandardException; + +class UnavailableException extends StandardException +{ +} diff --git a/Application/views/admin/de/debugbar_lang.php b/Application/views/admin/de/debugbar_lang.php new file mode 100644 index 0000000..fdcab7b --- /dev/null +++ b/Application/views/admin/de/debugbar_lang.php @@ -0,0 +1,26 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +$sLangName = "Deutsch"; +// ------------------------------- +// RESOURCE IDENTITFIER = STRING +// ------------------------------- +$aLang = [ + +//Navigation + 'charset' => 'UTF-8', + 'SHOP_MODULE_GROUP_d3debugbar_general' => 'Grundeinstellungen', + 'SHOP_MODULE_d3debugbar_showForAdminUsersOnly' => 'DebugBar nur anzeigen, wenn angemeldeter Benutzer ein Adminbenutzer ist', +]; diff --git a/Application/views/admin/en/debugbar_lang.php b/Application/views/admin/en/debugbar_lang.php new file mode 100644 index 0000000..b7d1827 --- /dev/null +++ b/Application/views/admin/en/debugbar_lang.php @@ -0,0 +1,26 @@ + + * @link https://www.oxidmodule.com + */ + +declare(strict_types=1); + +$sLangName = "English"; +// ------------------------------- +// RESOURCE IDENTITFIER = STRING +// ------------------------------- +$aLang = [ + +//Navigation + 'charset' => 'UTF-8', + 'SHOP_MODULE_GROUP_d3debugbar_general' => 'Default settings', + 'SHOP_MODULE_d3debugbar_showForAdminUsersOnly' => 'show DebugBar only if logged in user is an admin user', +]; diff --git a/Core/DebugBarErrorHandler.php b/Core/DebugBarErrorHandler.php index 1427f61..71b85b4 100644 --- a/Core/DebugBarErrorHandler.php +++ b/Core/DebugBarErrorHandler.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace D3\DebugBar\Core; +use D3\DebugBar\Application\Models\AvailabilityCheck; use D3\DebugBar\Application\Models\Exceptions\CompileErrorException; use D3\DebugBar\Application\Models\Exceptions\CoreErrorException; use D3\DebugBar\Application\Models\Exceptions\ParseException; @@ -39,8 +40,7 @@ class DebugBarErrorHandler */ public function callback(int $severity, string $message, string $file, int $line) { - global $debugBarErrorOccured; - $debugBarErrorOccured = 1; + AvailabilityCheck::markErrorOccured(); if (0 === error_reporting() || !(error_reporting() & $severity)) { // This error code is not included in error_reporting. diff --git a/Core/DebugBarExceptionHandler.php b/Core/DebugBarExceptionHandler.php index 2a962f1..95dbdb6 100644 --- a/Core/DebugBarExceptionHandler.php +++ b/Core/DebugBarExceptionHandler.php @@ -16,6 +16,8 @@ declare(strict_types=1); namespace D3\DebugBar\Core; use D3\DebugBar\Application\Component\DebugBarComponent; +use D3\DebugBar\Application\Models\AvailabilityCheck; +use D3\DebugBar\Application\Models\Exceptions\UnavailableException; use DebugBar\DataCollector\ExceptionsCollector; use DebugBar\DebugBarException; use OxidEsales\Eshop\Core\ConfigFile; @@ -42,7 +44,7 @@ class DebugBarExceptionHandler $defaultExceptionHandler->writeExceptionToLog($exception); } catch (Throwable $loggerException) { /** - * Its not possible to get the logger from the DI container. + * It's not possible to get the logger from the DI container. * Try again to log original exception (without DI container) in order to show the root cause of a problem. */ try { @@ -50,13 +52,11 @@ class DebugBarExceptionHandler $logger = $loggerServiceFactory->getLogger(); $logger->error($exception->getTraceAsString()); } catch (Throwable $throwableWithoutPossibilityToWriteToLogFile) { - // It is not possible to log because e.g. the log file is not writable. + // It's not possible to log because e.g. the log file is not writable. } } - global $debugBarSet; - - if ($debugBarSet !== 1 && false === isAdmin()) { + if (AvailabilityCheck::isAvailable() && AvailabilityCheck::ifDebugBarNotSet()) { try { /** @var DebugBarComponent $debugBarComponent */ $debugBarComponent = oxNew(DebugBarComponent::class); @@ -77,13 +77,13 @@ HTML; HTML; - $debugBarSet = 1; + AvailabilityCheck::markDebugBarAsSet(); echo $debugBarComponent->getRenderer()->render(); echo << HTML; - } catch (DebugBarException $e) { + } catch (DebugBarException|UnavailableException $e) { Registry::getLogger()->error($e->getMessage()); Registry::getUtilsView()->addErrorToDisplay($e); } diff --git a/Modules/Core/Config_DebugBar.php b/Modules/Core/Config_DebugBar.php index fa55d63..7bac4d9 100644 --- a/Modules/Core/Config_DebugBar.php +++ b/Modules/Core/Config_DebugBar.php @@ -15,15 +15,21 @@ declare(strict_types=1); namespace D3\DebugBar\Modules\Core; +use D3\DebugBar\Application\Models\AvailabilityCheck; use D3\DebugBar\Core\DebugBarExceptionHandler; +use OxidEsales\Eshop\Core\Exception\ExceptionHandler; class Config_DebugBar extends Config_DebugBar_parent { /** - * @return DebugBarExceptionHandler + * @return DebugBarExceptionHandler|ExceptionHandler */ protected function getExceptionHandler() { - return new DebugBarExceptionHandler(); + if (AvailabilityCheck::isAvailable()) { + return new DebugBarExceptionHandler(); + } + + return parent::getExceptionHandler(); } } diff --git a/Modules/Core/ShopControl_DebugBar.php b/Modules/Core/ShopControl_DebugBar.php index 281b7d0..606764e 100644 --- a/Modules/Core/ShopControl_DebugBar.php +++ b/Modules/Core/ShopControl_DebugBar.php @@ -16,6 +16,7 @@ declare(strict_types=1); namespace D3\DebugBar\Modules\Core; use D3\DebugBar\Application\Component\DebugBarComponent; +use D3\DebugBar\Application\Models\AvailabilityCheck; use D3\DebugBar\Application\Models\DebugBarHandler; use D3\DebugBar\Core\DebugBarExceptionHandler; use OxidEsales\Eshop\Core\Exception\StandardException; @@ -45,14 +46,12 @@ class ShopControl_DebugBar extends ShopControl_DebugBar_parent { parent::start(); - global $debugBarSet, $debugBarErrorOccured; - - if (!isAdmin() && $debugBarSet !== 1 && $debugBarErrorOccured !== 1) { + if (AvailabilityCheck::isAvailable() && AvailabilityCheck::ifDebugBarNotSet() && AvailabilityCheck::ifNoErrorOccured()) { $activeView = Registry::getConfig()->getTopActiveView(); /** @var DebugBarComponent|null $debugBarComponent */ $debugBarComponent = $activeView->getComponent(DebugBarComponent::class); if ($debugBarComponent) { - $debugBarSet = 1; + AvailabilityCheck::markDebugBarAsSet(); echo $debugBarComponent->getRenderer()->renderHead(); $debugBarComponent->addTimelineMessures(); echo $debugBarComponent->getRenderer()->render(); diff --git a/Modules/functions.php b/Modules/functions.php index 18ddf07..39fb8eb 100644 --- a/Modules/functions.php +++ b/Modules/functions.php @@ -14,6 +14,8 @@ declare(strict_types=1); use D3\DebugBar\Application\Component\DebugBarComponent; +use D3\DebugBar\Application\Models\AvailabilityCheck; +use D3\DebugBar\Application\Models\Exceptions\UnavailableException; use D3\DebugBar\Application\Models\TimeDataCollectorHandler; use DebugBar\DataCollector\MessagesCollector; use DebugBar\DebugBarException; @@ -60,7 +62,6 @@ function stopProfile(string $sProfileName): void $timeDataCollector = TimeDataCollectorHandler::getInstance(); $timeDataCollector->stopMeasure($hash); - global $aStartTimes; global $executionCounts; if (!isset($executionCounts[$sProfileName])) { @@ -90,17 +91,23 @@ function debugVar($mVar, bool $blToFile = false): void fclose($f); } } else { - if (!isAdmin()) { + try { + if (! AvailabilityCheck::isAvailable()) { + throw new UnavailableException(); + } $activeView = Registry::getConfig()->getTopActiveView(); - /** @var DebugBarComponent $debugBarComponent */ + /** @var DebugBarComponent|null $debugBarComponent */ $debugBarComponent = $activeView->getComponent(DebugBarComponent::class); + if ($debugBarComponent === null) { + throw new UnavailableException(); + } /** @var MessagesCollector $messages */ $messages = $debugBarComponent->getDebugBar()->getCollector('messages'); - $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); //$location = $trace[1]['class'] . '::' . $trace[1]['function']. '(' . $trace[0]['line'] . ')'; $location = $trace[1]['class'] . '::' . $trace[1]['function']; $messages->addMessage($mVar, $location); - } else { + } catch (UnavailableException $e) { dumpVar($mVar, $blToFile); } } diff --git a/Setup/Events.php b/Setup/Events.php index beae88e..768f5b6 100644 --- a/Setup/Events.php +++ b/Setup/Events.php @@ -27,7 +27,7 @@ class Events /** @var string $shopDir */ $shopDir = Registry::getConfig()->getConfigParam('sShopDir'); if (false === file_exists( - rtrim($shopDir, '/').'/out/debugbar/debugbar.jas' + rtrim($shopDir, '/').'/out/debugbar/debugbar.js' )) { Registry::getUtilsView()->addErrorToDisplay( 'The asset files cannot be found. Have you forgotten an installation step described in README? Then please run the installation again.'. diff --git a/ToDo.md b/ToDo.md index c5291ef..590628e 100644 --- a/ToDo.md +++ b/ToDo.md @@ -3,4 +3,3 @@ - clear tpl cache button - phpinfo() overview - automatic switch between Smarty and Twig -- displayed in live shop when logged in as admin diff --git a/metadata.php b/metadata.php index 059b365..71dc91d 100644 --- a/metadata.php +++ b/metadata.php @@ -46,6 +46,13 @@ $aModule = [ 'onActivate' => '\D3\DebugBar\Setup\Events::onActivate', ], 'templates' => [], - 'settings' => [], + 'settings' => [ + [ + 'group' => $sModuleId.'_general', + 'name' => $sModuleId.'_showForAdminUsersOnly', + 'type' => 'bool', + 'value' => false, + ], + ], 'blocks' => [], ]; diff --git a/phpstan.neon b/phpstan.neon index 00a8587..46cc7ca 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,6 +12,5 @@ parameters: - '#Offset .* does not exist on array{function: .*}.#' - '#ShopControl_DebugBar::_handle.*Exception\(\) has no return type specified#' - '#ShopControl_DebugBar::start\(\) has no return type specified.#' - - '#Config_DebugBar::getExceptionHandler\(\) should be compatible with return type #' - '#UtilsView::addErrorToDisplay\(\) expects OxidEsales\\Eshop\\Core\\Contract\\IDisplayError#' - '#PHPDoc tag @throws with type .*\\ContainerExceptionInterface is not subtype of Throwable#'