From ff76379800e6ca6ad2be6d350c3081b9e216de2a Mon Sep 17 00:00:00 2001 From: Christian Kuhn <lolli@schwarzbu.ch> Date: Sat, 19 Nov 2022 11:42:04 +0100 Subject: [PATCH] [TASK] Modernize ext:adminpanel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use more DI * Avoid MainController being a singleton, have it DI shared * Avoid static state in InMemoryLogWriter * Add various type hints * Streamline annotations * Avoid a useless exception class * Use inject* method for DI in an abstract class to avoid polluting __construct() for consumers. Resolves: #99137 Releases: main Change-Id: I15046da24581fccc1524af6ab3320de6c6880c78 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/76704 Tested-by: Nikita Hovratov <nikita.h@live.de> Reviewed-by: Nikita Hovratov <nikita.h@live.de> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: core-ci <typo3@b13.com> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> --- Build/phpstan/phpstan-baseline.neon | 5 --- .../Classes/Controller/AjaxController.php | 13 ++---- .../Classes/Controller/MainController.php | 32 +++++---------- .../InvalidConfigurationException.php | 25 ------------ .../Classes/Log/DoctrineSqlLogger.php | 33 ++++----------- .../Classes/Log/InMemoryLogWriter.php | 40 ++++++++++--------- .../Classes/Middleware/SqlLogging.php | 11 ++--- .../Classes/ModuleApi/AbstractModule.php | 34 +++++----------- .../Classes/ModuleApi/AbstractSubModule.php | 4 +- .../Classes/ModuleApi/ModuleData.php | 2 +- .../ModuleApi/ModuleDataStorageCollection.php | 5 +-- .../adminpanel/Classes/Modules/Debug/Log.php | 11 +++-- .../Classes/Modules/Debug/PageTitle.php | 5 ++- .../Classes/Modules/DebugModule.php | 4 +- .../Classes/Modules/PreviewModule.php | 3 +- .../Modules/TsDebug/TypoScriptWaterfall.php | 8 ++-- .../Classes/Service/ConfigurationService.php | 5 +-- .../Classes/Service/ModuleLoader.php | 5 +-- .../adminpanel/Configuration/Services.yaml | 19 +++++++++ .../Tests/Unit/Fixtures/MainModuleFixture.php | 23 ----------- .../Tests/Unit/Fixtures/SubModuleFixture.php | 16 -------- .../Middleware/AdminPanelInitiatorTest.php | 14 +++---- .../Tests/Unit/Modules/PreviewModuleTest.php | 5 +-- .../Unit/Service/ConfigurationServiceTest.php | 5 --- .../Tests/Unit/Service/ModuleLoaderTest.php | 9 ++--- .../Tests/Unit/Utility/StateUtilityTest.php | 8 ---- 26 files changed, 110 insertions(+), 234 deletions(-) delete mode 100644 typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon index 1f2aee62ec05..c3e889c5b358 100644 --- a/Build/phpstan/phpstan-baseline.neon +++ b/Build/phpstan/phpstan-baseline.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Call to an undefined method TYPO3\\\\CMS\\\\Core\\\\Context\\\\AspectInterface\\:\\:isPreview\\(\\)\\.$#" - count: 1 - path: ../../typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php - - message: "#^Call to an undefined method TYPO3\\\\CMS\\\\Core\\\\Resource\\\\FolderInterface\\:\\:getCombinedIdentifier\\(\\)\\.$#" count: 1 diff --git a/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php b/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php index c743eb75001f..6009e39602ec 100644 --- a/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php +++ b/typo3/sysext/adminpanel/Classes/Controller/AjaxController.php @@ -22,7 +22,6 @@ use TYPO3\CMS\Adminpanel\Service\ConfigurationService; use TYPO3\CMS\Adminpanel\Service\ModuleLoader; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Http\JsonResponse; -use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Admin Panel Ajax Controller - Route endpoint for ajax actions @@ -32,16 +31,12 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; class AjaxController { protected array $adminPanelModuleConfiguration; - protected ModuleLoader $moduleLoader; - private ConfigurationService $configurationService; - public function __construct(?ConfigurationService $configurationService = null, ?ModuleLoader $moduleLoader = null) - { - $this->configurationService = $configurationService - ?? - GeneralUtility::makeInstance(ConfigurationService::class); + public function __construct( + private readonly ConfigurationService $configurationService, + private readonly ModuleLoader $moduleLoader, + ) { $this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? []; - $this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class); } /** diff --git a/typo3/sysext/adminpanel/Classes/Controller/MainController.php b/typo3/sysext/adminpanel/Classes/Controller/MainController.php index bfa0129312db..a37fe53e5180 100644 --- a/typo3/sysext/adminpanel/Classes/Controller/MainController.php +++ b/typo3/sysext/adminpanel/Classes/Controller/MainController.php @@ -26,46 +26,35 @@ use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface; use TYPO3\CMS\Adminpanel\ModuleApi\RequestEnricherInterface; use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface; use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface; -use TYPO3\CMS\Adminpanel\Service\ConfigurationService; use TYPO3\CMS\Adminpanel\Service\ModuleLoader; use TYPO3\CMS\Adminpanel\Utility\ResourceUtility; use TYPO3\CMS\Adminpanel\Utility\StateUtility; use TYPO3\CMS\Backend\Routing\UriBuilder; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Cache\CacheManager; -use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Fluid\View\StandaloneView; /** - * Main controller for the admin panel + * Main controller for the admin panel. + * + * Note this is a "shared" / singleton object: Middleware AdminPanelInitiator + * instantiates the object and eventually calls initialize(). Later, + * AdminPanelRenderer calls render() on the same object. * * @internal */ -class MainController implements SingletonInterface +class MainController { - /** - * @var array<string, ModuleInterface> - */ + /** @var array<string, ModuleInterface> */ protected array $modules = []; - - protected ModuleLoader $moduleLoader; - protected UriBuilder $uriBuilder; - protected ConfigurationService $configurationService; protected array $adminPanelModuleConfiguration; public function __construct( - ?ModuleLoader $moduleLoader = null, - ?UriBuilder $uriBuilder = null, - ?ConfigurationService $configurationService = null + private readonly ModuleLoader $moduleLoader, + private readonly UriBuilder $uriBuilder, ) { - $this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class); - $this->uriBuilder = $uriBuilder ?? GeneralUtility::makeInstance(UriBuilder::class); - $this->configurationService = $configurationService - ?? GeneralUtility::makeInstance(ConfigurationService::class); - $adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? []; - $this->adminPanelModuleConfiguration = is_array($adminPanelModuleConfiguration) - ? $adminPanelModuleConfiguration : []; + $this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? []; } /** @@ -76,7 +65,6 @@ class MainController implements SingletonInterface $this->modules = $this->moduleLoader->validateSortAndInitializeModules( $this->adminPanelModuleConfiguration ); - if (StateUtility::isActivatedForUser()) { $request = $this->initializeModules($request, $this->modules); } diff --git a/typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php b/typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php deleted file mode 100644 index b47b9b5d0092..000000000000 --- a/typo3/sysext/adminpanel/Classes/Exceptions/InvalidConfigurationException.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -declare(strict_types=1); - -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -namespace TYPO3\CMS\Adminpanel\Exceptions; - -/** - * Exception class for invalid admin panel configuration - */ -class InvalidConfigurationException extends \RuntimeException -{ -} diff --git a/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php b/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php index 52dc67f905fb..63406d70e1b7 100644 --- a/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php +++ b/typo3/sysext/adminpanel/Classes/Log/DoctrineSqlLogger.php @@ -29,31 +29,14 @@ class DoctrineSqlLogger implements SQLLogger, LoggerAwareInterface { use LoggerAwareTrait; - /** - * Executed SQL queries. - * - * @var array - */ - protected $queries = []; + /** Executed SQL queries. */ + protected array $queries = []; + /** If Debug Stack is enabled (log queries) or not. */ + protected bool $enabled = true; + protected float $start; + protected int $currentQuery = 0; - /** - * If Debug Stack is enabled (log queries) or not. - * - * @var bool - */ - protected $enabled = true; - - /** - * @var float - */ - protected $start; - - /** - * @var int - */ - protected $currentQuery = 0; - - public function startQuery($sql, array $params = null, array $types = null) + public function startQuery($sql, array $params = null, array $types = null): void { if ($this->enabled && MemoryUtility::isMemoryConsumptionTooHigh()) { $this->enabled = false; @@ -78,7 +61,7 @@ class DoctrineSqlLogger implements SQLLogger, LoggerAwareInterface } } - public function stopQuery() + public function stopQuery(): void { if ($this->enabled) { $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start; diff --git a/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php b/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php index dc5fe97c07f5..4ae09603a55f 100644 --- a/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php +++ b/typo3/sysext/adminpanel/Classes/Log/InMemoryLogWriter.php @@ -24,28 +24,24 @@ use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Http\ApplicationType; use TYPO3\CMS\Core\Log\LogRecord; use TYPO3\CMS\Core\Log\Writer\AbstractWriter; +use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Log writer that writes the log records into a static public class variable - * for InMemory processing + * for InMemory processing. Note this implements SingletonInterface so multiple + * calls to this class can accumulate log records in the same instance. + * + * @internal */ -class InMemoryLogWriter extends AbstractWriter +final class InMemoryLogWriter extends AbstractWriter implements SingletonInterface { - /** - * @var LogRecord[] - */ - public static $log = []; - - /** - * @var bool - */ - private static $memoryLock = false; + /** @var LogRecord[] */ + private array $log = []; + private bool $memoryLock = false; /** * Writes the log record - * - * @param LogRecord $record Log record */ public function writeLog(LogRecord $record): self { @@ -53,7 +49,7 @@ class InMemoryLogWriter extends AbstractWriter if (Environment::isCli() || !(($GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface) || !ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend() - || self::$memoryLock === true + || $this->memoryLock === true ) { return $this; } @@ -64,23 +60,31 @@ class InMemoryLogWriter extends AbstractWriter return $this; } - self::$log[] = (clone $record)->setMessage($this->interpolate($record->getMessage(), $record->getData())); + $this->log[] = (clone $record)->setMessage($this->interpolate($record->getMessage(), $record->getData())); return $this; } + /** + * @return LogRecord[] + */ + public function getLogEntries(): array + { + return $this->log; + } + /** * Lock writer and add an info message that there may potentially be more entries. */ - protected function lockWriter(): void + private function lockWriter(): void { - self::$memoryLock = true; + $this->memoryLock = true; $record = GeneralUtility::makeInstance( LogRecord::class, 'TYPO3.CMS.AdminPanel.Log.InMemoryLogWriter', LogLevel::INFO, '... Further log entries omitted, memory usage too high.' ); - self::$log[] = $record; + $this->log[] = $record; } } diff --git a/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php b/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php index 90863809305f..7c9146fe2bfa 100644 --- a/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php +++ b/typo3/sysext/adminpanel/Classes/Middleware/SqlLogging.php @@ -33,14 +33,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class SqlLogging implements MiddlewareInterface { - /** - * @var ConnectionPool - */ - protected $connectionPool; - - public function __construct(ConnectionPool $connectionPool) - { - $this->connectionPool = $connectionPool; + public function __construct( + private readonly ConnectionPool $connectionPool + ) { } /** diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php index c2a5015796ea..3f62e5482b69 100644 --- a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php +++ b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractModule.php @@ -20,7 +20,6 @@ namespace TYPO3\CMS\Adminpanel\ModuleApi; use TYPO3\CMS\Adminpanel\Service\ConfigurationService; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Localization\LanguageService; -use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Abstract base class for Admin Panel Modules containing helper methods and default interface implementations @@ -28,34 +27,23 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ abstract class AbstractModule implements ModuleInterface, ConfigurableInterface, SubmoduleProviderInterface { - /** - * @var ModuleInterface[] - */ - protected $subModules = []; - - /** - * Main Configuration (from UserTSConfig, admPanel) - * - * @var array - */ - protected $mainConfiguration; - - /** - * @var ConfigurationService - */ - protected $configurationService; + /** @var ModuleInterface[] */ + protected array $subModules = []; + /** Main Configuration (from UserTSConfig, admPanel) */ + protected array $mainConfiguration; + protected ConfigurationService $configurationService; - public function __construct() + public function injectConfigurationService(ConfigurationService $configurationService): void { - $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class); + $this->configurationService = $configurationService; $this->mainConfiguration = $this->configurationService->getMainConfiguration(); } /** * Returns true if the module is - * -> either enabled via TSConfig admPanel.enable - * -> or any setting is overridden - * override is a way to use functionality of the admin panel without displaying the admin panel to users + * -> either enabled via TSConfig "admPanel.enable" + * -> or any setting is overridden. + * Override is a way to use functionality of the admin panel without displaying the admin panel to users * for example: hidden records or pages can be displayed by default */ public function isEnabled(): bool @@ -104,7 +92,7 @@ abstract class AbstractModule implements ModuleInterface, ConfigurableInterface, } /** - * Returns true if TSConfig admPanel.enable is set for this module (or all modules) + * Returns true if TSConfig "admPanel.enable" is set for this module (or all modules) */ protected function isEnabledViaTsConfig(): bool { diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php index dfa5ab615527..62f4aaf440a0 100644 --- a/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php +++ b/typo3/sysext/adminpanel/Classes/ModuleApi/AbstractSubModule.php @@ -21,9 +21,9 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Localization\LanguageService; /** - * Abstract SubModule - Base class for sub modules in the admin panel + * Abstract SubModule - Base class for submodules in the admin panel * - * Extend this class when writing own sub modules + * Extend this class when writing own submodules */ abstract class AbstractSubModule implements ModuleInterface, ContentProviderInterface { diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php index 5ebf56190d66..365cf5d87201 100644 --- a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php +++ b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleData.php @@ -21,7 +21,7 @@ namespace TYPO3\CMS\Adminpanel\ModuleApi; * ModuleData is a simple wrapper object which extends ArrayObject * which is used to hold Adminpanel module data * - * It's a separate class to add semantic meaning to its' usage + * It's a separate class to add semantic meaning to its usage */ class ModuleData extends \ArrayObject { diff --git a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php index 759b68b52fd8..9ec3df6e99d4 100644 --- a/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php +++ b/typo3/sysext/adminpanel/Classes/ModuleApi/ModuleDataStorageCollection.php @@ -27,10 +27,7 @@ class ModuleDataStorageCollection extends \SplObjectStorage $this->attach($module, $moduleData); } - /** - * @param object $object - */ - public function getHash($object): string + public function getHash(object $object): string { if ($object instanceof ModuleInterface) { return $object->getIdentifier(); diff --git a/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php b/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php index a784d7c57686..7ea1f9f441b7 100644 --- a/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php +++ b/typo3/sysext/adminpanel/Classes/Modules/Debug/Log.php @@ -37,12 +37,11 @@ use TYPO3\CMS\Fluid\View\StandaloneView; class Log extends AbstractSubModule implements DataProviderInterface, ModuleSettingsProviderInterface, RequestEnricherInterface { protected int $logLevel; - protected ConfigurationService $configurationService; - public function __construct() - { + public function __construct( + private readonly ConfigurationService $configurationService, + ) { $this->logLevel = LogLevel::normalizeLevel(\Psr\Log\LogLevel::INFO); - $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class); } public function getIdentifier(): string @@ -71,10 +70,10 @@ class Log extends AbstractSubModule implements DataProviderInterface, ModuleSett ]; } - $log = InMemoryLogWriter::$log; + $logRecords = GeneralUtility::makeInstance(InMemoryLogWriter::class)->getLogEntries(); $logArray = []; - foreach ($log as $logRecord) { + foreach ($logRecords as $logRecord) { $entry = $logRecord->toArray(); // store only necessary info unset($entry['data']); diff --git a/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php b/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php index 132c2c6196b9..a5a98835d3dc 100644 --- a/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php +++ b/typo3/sysext/adminpanel/Classes/Modules/Debug/PageTitle.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Adminpanel\Log\InMemoryLogWriter; use TYPO3\CMS\Adminpanel\ModuleApi\AbstractSubModule; use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface; use TYPO3\CMS\Adminpanel\ModuleApi\ModuleData; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; @@ -68,8 +69,8 @@ class PageTitle extends AbstractSubModule implements DataProviderInterface 'skippedProviders' => [], ]; - $log = InMemoryLogWriter::$log; - foreach ($log as $logEntry) { + $logRecords = GeneralUtility::makeInstance(InMemoryLogWriter::class)->getLogEntries(); + foreach ($logRecords as $logEntry) { if ($logEntry->getComponent() === self::LOG_COMPONENT) { $logEntryData = $logEntry->getData(); if (isset($logEntryData['orderedTitleProviders'])) { diff --git a/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php b/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php index bffa30ddaffd..cc6fd3911844 100644 --- a/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php +++ b/typo3/sysext/adminpanel/Classes/Modules/DebugModule.php @@ -22,6 +22,7 @@ use TYPO3\CMS\Adminpanel\ModuleApi\AbstractModule; use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface; use TYPO3\CMS\Core\Log\LogLevel; use TYPO3\CMS\Core\Log\LogRecord; +use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Debug Module of the AdminPanel @@ -47,7 +48,8 @@ class DebugModule extends AbstractModule implements ShortInfoProviderInterface public function getShortInfo(): string { - $errorsAndWarnings = array_filter(InMemoryLogWriter::$log, static function (LogRecord $entry) { + $logRecords = GeneralUtility::makeInstance(InMemoryLogWriter::class)->getLogEntries(); + $errorsAndWarnings = array_filter($logRecords, static function (LogRecord $entry) { return LogLevel::normalizeLevel($entry->getLevel()) <= 4; }); return sprintf($this->getLanguageService()->sL( diff --git a/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php b/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php index ae03bf02eb30..b7f8c1f8fb9c 100644 --- a/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php +++ b/typo3/sysext/adminpanel/Classes/Modules/PreviewModule.php @@ -49,7 +49,7 @@ class PreviewModule extends AbstractModule implements RequestEnricherInterface, * showFluidDebug?: bool * } */ - protected $config; + protected array $config; public function getIconIdentifier(): string { @@ -198,6 +198,7 @@ class PreviewModule extends AbstractModule implements RequestEnricherInterface, } $isPreview = $simulateUserGroup || $simTime || $showHiddenPages || $showHiddenRecords || $showScheduledRecords; if ($context->hasAspect('frontend.preview')) { + /** @var PreviewAspect $existingPreviewAspect */ $existingPreviewAspect = $context->getAspect('frontend.preview'); $isPreview = $existingPreviewAspect->isPreview() || $isPreview; } diff --git a/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php b/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php index 3608c3d2b53c..2abd7b560fa1 100644 --- a/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php +++ b/typo3/sysext/adminpanel/Classes/Modules/TsDebug/TypoScriptWaterfall.php @@ -36,11 +36,9 @@ use TYPO3\CMS\Fluid\View\StandaloneView; */ class TypoScriptWaterfall extends AbstractSubModule implements RequestEnricherInterface, ModuleSettingsProviderInterface { - protected ConfigurationService $configurationService; - - public function __construct() - { - $this->configurationService = GeneralUtility::makeInstance(ConfigurationService::class); + public function __construct( + private readonly ConfigurationService $configurationService, + ) { } public function getIdentifier(): string diff --git a/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php b/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php index b36200cc4b54..930aca99ddac 100644 --- a/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php +++ b/typo3/sysext/adminpanel/Classes/Service/ConfigurationService.php @@ -94,13 +94,10 @@ class ConfigurationService implements SingletonInterface return $GLOBALS['BE_USER']; } - /** - * @param array $configurationToSave - */ protected function triggerOnSubmitActors( array $modules, ServerRequestInterface $request, - $configurationToSave + array $configurationToSave ): void { foreach ($modules as $module) { if ( diff --git a/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php b/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php index 65e03af860e1..21829ecd1e62 100644 --- a/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php +++ b/typo3/sysext/adminpanel/Classes/Service/ModuleLoader.php @@ -17,7 +17,6 @@ declare(strict_types=1); namespace TYPO3\CMS\Adminpanel\Service; -use TYPO3\CMS\Adminpanel\Exceptions\InvalidConfigurationException; use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface; use TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface; use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface; @@ -45,7 +44,7 @@ class ModuleLoader } foreach ($modules as $identifier => $configuration) { if (empty($configuration) || !is_array($configuration)) { - throw new InvalidConfigurationException( + throw new \RuntimeException( 'Missing configuration for module "' . $identifier . '".', 1519490105 ); @@ -59,7 +58,7 @@ class ModuleLoader true ) ) { - throw new InvalidConfigurationException( + throw new \RuntimeException( 'The module "' . $identifier . '" defines an invalid module class. Ensure the class exists and implements the "' . diff --git a/typo3/sysext/adminpanel/Configuration/Services.yaml b/typo3/sysext/adminpanel/Configuration/Services.yaml index e7f368488d86..cd9d118b591c 100644 --- a/typo3/sysext/adminpanel/Configuration/Services.yaml +++ b/typo3/sysext/adminpanel/Configuration/Services.yaml @@ -12,6 +12,25 @@ services: factory: ['@TYPO3\CMS\Core\Cache\CacheManager', 'getCache'] arguments: ['adminpanel_requestcache'] + TYPO3\CMS\Adminpanel\Controller\AjaxController: + public: true + TYPO3\CMS\Adminpanel\Controller\MainController: + public: true + + TYPO3\CMS\Adminpanel\Modules\CacheModule: + public: true + TYPO3\CMS\Adminpanel\Modules\DebugModule: + public: true + TYPO3\CMS\Adminpanel\Modules\InfoModule: + public: true + TYPO3\CMS\Adminpanel\Modules\PreviewModule: + public: true + TYPO3\CMS\Adminpanel\Modules\TsDebugModule: + public: true + TYPO3\CMS\Adminpanel\Modules\Debug\Log: + public: true + TYPO3\CMS\Adminpanel\Modules\TsDebug\TypoScriptWaterfall: + public: true Psr\EventDispatcher\EventDispatcherInterface: alias: TYPO3\CMS\Adminpanel\Service\EventDispatcher diff --git a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php index bba8076625bf..7e5803c45018 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/MainModuleFixture.php @@ -40,8 +40,6 @@ class MainModuleFixture implements /** * Identifier for this module, * for example "preview" or "cache" - * - * @return string */ public function getIdentifier(): string { @@ -50,8 +48,6 @@ class MainModuleFixture implements /** * Module label - * - * @return string */ public function getLabel(): string { @@ -60,8 +56,6 @@ class MainModuleFixture implements /** * Module Icon identifier - needs to be registered in iconRegistry - * - * @return string */ public function getIconIdentifier(): string { @@ -70,17 +64,12 @@ class MainModuleFixture implements /** * Displayed directly in the bar if module has content - * - * @return string */ public function getShortInfo(): string { return 'short info'; } - /** - * @return string - */ public function getPageSettings(): string { return 'example settings'; @@ -92,8 +81,6 @@ class MainModuleFixture implements * A module may be enabled but not shown * -> only the initializeModule() method * will be called - * - * @return bool */ public function isEnabled(): bool { @@ -104,9 +91,6 @@ class MainModuleFixture implements * Executed on saving / submit of the configuration form * Can be used to react to changed settings * (for example: clearing a specific cache) - * - * @param array $configurationToSave - * @param ServerRequestInterface $request */ public function onSubmit(array $configurationToSave, ServerRequestInterface $request): void { @@ -114,8 +98,6 @@ class MainModuleFixture implements /** * Returns a string array with javascript files that will be rendered after the module - * - * @return array */ public function getJavaScriptFiles(): array { @@ -124,8 +106,6 @@ class MainModuleFixture implements /** * Returns a string array with css files that will be rendered after the module - * - * @return array */ public function getCssFiles(): array { @@ -159,9 +139,6 @@ class MainModuleFixture implements /** * Initialize the module - runs in the TYPO3 middleware stack at an early point * may manipulate the current request - * - * @param ServerRequestInterface $request - * @return ServerRequestInterface */ public function enrich(ServerRequestInterface $request): ServerRequestInterface { diff --git a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php index 769647a760f0..483e4cf94e45 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Fixtures/SubModuleFixture.php @@ -30,8 +30,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod /** * Identifier for this Sub-module, * for example "preview" or "cache" - * - * @return string */ public function getIdentifier(): string { @@ -40,8 +38,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod /** * Sub-Module label - * - * @return string */ public function getLabel(): string { @@ -50,9 +46,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod /** * Sub-Module content as rendered HTML - * - * @param ModuleData $data - * @return string */ public function getContent(ModuleData $data): string { @@ -61,8 +54,6 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod /** * Settings as HTML form elements (without wrapping form tag or save button) - * - * @return string */ public function getSettings(): string { @@ -73,18 +64,11 @@ class SubModuleFixture implements ModuleInterface, ContentProviderInterface, Mod * Executed on saving / submit of the configuration form * Can be used to react to changed settings * (for example: clearing a specific cache) - * - * @param array $configurationToSave - * @param ServerRequestInterface $request */ public function onSubmit(array $configurationToSave, ServerRequestInterface $request): void { } - /** - * @param ServerRequestInterface $request - * @return ModuleData - */ public function getDataToStore(ServerRequestInterface $request): ModuleData { return new ModuleData(['foo' => 'bar']); diff --git a/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php b/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php index e752af23b043..168f989b9cc3 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Middleware/AdminPanelInitiatorTest.php @@ -29,8 +29,6 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase; class AdminPanelInitiatorTest extends UnitTestCase { - protected bool $resetSingletonInstances = true; - /** * @test */ @@ -54,7 +52,7 @@ class AdminPanelInitiatorTest extends UnitTestCase $GLOBALS['BE_USER'] = $userAuthentication; $controller = $this->getMockBuilder(MainController::class)->disableOriginalConstructor()->getMock(); - GeneralUtility::setSingletonInstance(MainController::class, $controller); + GeneralUtility::addInstance(MainController::class, $controller); $handler = $this->getHandlerMock(); $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); $request->expects(self::any())->method('withAttribute')->withAnyParameters()->willReturn($request); @@ -100,10 +98,6 @@ class AdminPanelInitiatorTest extends UnitTestCase $this->checkAdminPanelDoesNotCallInitialize($tsConfig, $uc); } - /** - * @param array $tsConfig - * @param array $uc - */ protected function checkAdminPanelDoesNotCallInitialize(array $tsConfig, array $uc): void { $userAuthentication = $this->getMockBuilder(FrontendBackendUserAuthentication::class)->getMock(); @@ -112,14 +106,16 @@ class AdminPanelInitiatorTest extends UnitTestCase $GLOBALS['BE_USER'] = $userAuthentication; $controller = $this->getMockBuilder(MainController::class)->disableOriginalConstructor()->getMock(); - GeneralUtility::setSingletonInstance(MainController::class, $controller); + GeneralUtility::addInstance(MainController::class, $controller); $handler = $this->getHandlerMock(); $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock(); + $controller->expects(self::never())->method('initialize'); $adminPanelInitiator = new AdminPanelInitiator(); $adminPanelInitiator->process($request, $handler); - $controller->expects(self::never())->method('initialize'); + /** @var MainController&MockObject $controller */ + $controller = GeneralUtility::makeInstance(MainController::class); } protected function getHandlerMock(): RequestHandlerInterface&MockObject diff --git a/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php b/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php index f4ffbd2f267a..865bc223ccb2 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Modules/PreviewModuleTest.php @@ -63,9 +63,8 @@ class PreviewModuleTest extends UnitTestCase ]; $configurationService->method('getConfigurationOption')->withAnyParameters()->willReturnMap($valueMap); - GeneralUtility::setSingletonInstance(ConfigurationService::class, $configurationService); - $previewModule = new PreviewModule(); + $previewModule->injectConfigurationService($configurationService); $previewModule->enrich(new ServerRequest()); self::assertSame($GLOBALS['SIM_EXEC_TIME'], $expectedExecTime, 'EXEC_TIME'); @@ -90,7 +89,6 @@ class PreviewModuleTest extends UnitTestCase ['preview', 'showFluidDebug', '0'], ]; $configurationService->method('getConfigurationOption')->withAnyParameters()->willReturnMap($valueMap); - GeneralUtility::setSingletonInstance(ConfigurationService::class, $configurationService); $context = $this->getMockBuilder(Context::class)->getMock(); $context->method('hasAspect')->with('frontend.preview')->willReturn(false); @@ -105,6 +103,7 @@ class PreviewModuleTest extends UnitTestCase GeneralUtility::setSingletonInstance(Context::class, $context); $previewModule = new PreviewModule(); + $previewModule->injectConfigurationService($configurationService); $previewModule->enrich($request); } } diff --git a/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php b/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php index c26089ccfe05..aff1200e8a82 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Service/ConfigurationServiceTest.php @@ -127,8 +127,6 @@ class ConfigurationServiceTest extends UnitTestCase /** * @test * @dataProvider getConfigurationOptionEmptyArgumentDataProvider - * @param string $identifier - * @param string $option */ public function getConfigurationOptionThrowsExceptionOnEmptyArgument(string $identifier, string $option): void { @@ -216,9 +214,6 @@ class ConfigurationServiceTest extends UnitTestCase self::assertSame($expected, $this->beUser->uc); } - /** - * @param array $userTsAdmPanelConfig - */ private function setUpUserTsConfigForAdmPanel(array $userTsAdmPanelConfig): void { $this->beUser->method('getTSConfig')->willReturn( diff --git a/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php b/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php index 9fe70fcc2cde..31e8eca8c97b 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Service/ModuleLoaderTest.php @@ -17,7 +17,6 @@ declare(strict_types=1); namespace TYPO3\CMS\Adminpanel\Tests\Unit\Service; -use TYPO3\CMS\Adminpanel\Exceptions\InvalidConfigurationException; use TYPO3\CMS\Adminpanel\Service\ModuleLoader; use TYPO3\CMS\Adminpanel\Tests\Unit\Fixtures\DisabledMainModuleFixture; use TYPO3\CMS\Adminpanel\Tests\Unit\Fixtures\MainModuleFixture; @@ -49,11 +48,10 @@ class ModuleLoaderTest extends UnitTestCase /** * @test * @dataProvider missingConfigurationDataProvider - * @param array $configuration */ public function validateSortAndInitializeModulesThrowsExceptionIfModuleHasMissingConfiguration(array $configuration): void { - $this->expectException(InvalidConfigurationException::class); + $this->expectException(\RuntimeException::class); $this->expectExceptionCode(1519490105); $moduleLoader = new ModuleLoader(); @@ -88,12 +86,11 @@ class ModuleLoaderTest extends UnitTestCase /** * @test - * @dataProvider invalidConfigurationDataProvider - * @param array $configuration + * @dataProvider invalidConfigurationDataProvider */ public function validateSortAndInitializeModulesThrowsExceptionIfModuleHasInvalidConfiguration(array $configuration): void { - $this->expectException(InvalidConfigurationException::class); + $this->expectException(\RuntimeException::class); $this->expectExceptionCode(1519490112); $moduleLoader = new ModuleLoader(); diff --git a/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php b/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php index 1a15f83d4e86..ee81f4d92f51 100644 --- a/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php +++ b/typo3/sysext/adminpanel/Tests/Unit/Utility/StateUtilityTest.php @@ -71,7 +71,6 @@ class StateUtilityTest extends UnitTestCase /** * @test * @dataProvider tsConfigEnabledDataProvider - * @param array $tsConfig */ public function isEnabledReturnsTrueIfAtLeastOneModuleIsEnabled(array $tsConfig): void { @@ -108,7 +107,6 @@ class StateUtilityTest extends UnitTestCase /** * @test * @dataProvider tsConfigDisabledDataProvider - * @param array $tsConfig */ public function isEnabledReturnsFalseIfNoModulesEnabled(array $tsConfig): void { @@ -148,8 +146,6 @@ class StateUtilityTest extends UnitTestCase /** * @test * @dataProvider tsConfigHideDataProvider - * @param array $tsConfig - * @param bool $expected */ public function isHiddenForUserReturnsCorrectValue(array $tsConfig, bool $expected): void { @@ -199,8 +195,6 @@ class StateUtilityTest extends UnitTestCase /** * @test * @dataProvider ucDisplayOpenDataProvider - * @param array $uc - * @param bool $expected */ public function isOpenForUserReturnsCorrectValue(array $uc, bool $expected): void { @@ -250,8 +244,6 @@ class StateUtilityTest extends UnitTestCase /** * @test * @dataProvider typoScriptDataProvider - * @param array $typoScript - * @param bool $expected */ public function isActivatedInTypoScriptReturnsCorrectValue(array $typoScript, bool $expected): void { -- GitLab