diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index f6df3c4..4efc7c0 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -9,8 +9,8 @@ jobs: strategy: fail-fast: false matrix: - typo3: [ '^11.5' ] - php: ['8.0', '8.1', '8.2', '8.3'] + typo3: [ '^12.4' ] + php: ['8.1', '8.2', '8.3'] steps: - name: Start database server @@ -35,9 +35,9 @@ jobs: - name: Validate composer.json and composer.lock run: composer validate - - name: Install dependencies with nimut/typo3-complete:${{ matrix.typo3 }} + - name: Install dependencies with typo3/cms-core:${{ matrix.typo3 }} run: | - composer require --dev nimut/typo3-complete:${{ matrix.typo3 }} --no-progress + composer require --dev typo3/cms-core:${{ matrix.typo3 }} --no-progress git checkout composer.json ln -nfs .Build/vendor/typo3/cms/typo3 typo3 @@ -45,22 +45,22 @@ jobs: run: find . -name \*.php ! -path "./.Build/*" ! -path "./scripts/*" ! -path "./typo3_src/*" | parallel --gnu php -d display_errors=stderr -l {} > /dev/null \; - name: Unit Tests without coverage - if: matrix.typo3 != '^11.5' && matrix.php != '8.3' + if: matrix.typo3 != '^12.5' && matrix.php != '8.3' run: | export "UNIT_XML"=.Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTests.xml .Build/bin/phpunit --colors -c $UNIT_XML Tests/Unit - name: Unit Tests with coverage - if: matrix.typo3 == '^11.5' && matrix.php == '8.3' + if: matrix.typo3 == '^12.5' && matrix.php == '8.3' run: | export "UNIT_XML"=.Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTests-v10.xml .Build/bin/phpunit --coverage-filter Classes --coverage-clover=unittest-coverage.clover --colors -c $UNIT_XML Tests/Unit - name: Functional Tests without coverage run: | - export "FUNCTIONAL_XML"=.Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests-v10.xml + export "FUNCTIONAL_XML"=Tests/Functional/FunctionalTests.xml .Build/bin/phpunit --coverage-filter Classes --colors -c $FUNCTIONAL_XML Tests/Functional - if: matrix.typo3 != '^11.5' && matrix.php != '8.3' + if: matrix.typo3 != '^12.5' && matrix.php != '8.3' env: typo3DatabaseHost: 127.0.0.1 typo3DatabaseName: typo3 @@ -71,7 +71,7 @@ jobs: run: | export "FUNCTIONAL_XML"=.Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests-v10.xml .Build/bin/phpunit --coverage-filter Classes --coverage-clover=functional-coverage.clover --colors -c $FUNCTIONAL_XML Tests/Functional - if: matrix.typo3 == '^11.5' && matrix.php == '8.3' + if: matrix.typo3 == '^12.5' && matrix.php == '8.3' env: typo3DatabaseHost: 127.0.0.1 typo3DatabaseName: typo3 diff --git a/.gitignore b/.gitignore index 5efee1a..1fc94c6 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,9 @@ nbproject composer.lock .php_cs.cache var -.cache \ No newline at end of file +# PHPUnit Reports +Tests/reports +reports +.cache +.phpunit.cache +.phpunit.result.cache \ No newline at end of file diff --git a/Classes/Controller/BackendModuleController.php b/Classes/Controller/BackendModuleController.php index 797fe66..3d44768 100644 --- a/Classes/Controller/BackendModuleController.php +++ b/Classes/Controller/BackendModuleController.php @@ -29,7 +29,8 @@ use Aoe\Cachemgm\Domain\Repository\CacheTableRepository; use Aoe\Cachemgm\Utility\CacheUtility; -use TYPO3\CMS\Backend\View\BackendTemplateView; +use Psr\Http\Message\ResponseInterface; +use TYPO3\CMS\Backend\Template\ModuleTemplateFactory; use TYPO3\CMS\Core\Cache\Backend\BackendInterface; use TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend; use TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend; @@ -38,60 +39,67 @@ use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Extbase\Http\ForwardResponse; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException; -use TYPO3\CMS\Extbase\Mvc\View\ViewInterface; use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder; +use TYPO3\CMS\Fluid\View\TemplatePaths; class BackendModuleController extends ActionController { /** - * Backend Template Container - * - * @var string + * @var ModuleTemplateFactory */ - protected $defaultViewObjectName = BackendTemplateView::class; + public $moduleTemplateFactory; /** * BackendTemplateContainer - * - * @var BackendTemplateView */ protected $view; /** * @var CacheManager */ - private $cacheManager; + private readonly object $cacheManager; /** * @var LanguageService */ private $languageService; - public function __construct() - { + public function __construct( + ModuleTemplateFactory $moduleTemplateFactory, + ) { $this->cacheManager = GeneralUtility::makeInstance(CacheManager::class); $this->languageService = $GLOBALS['LANG']; + $this->moduleTemplateFactory = $moduleTemplateFactory; } - public function indexAction(): void + public function indexAction(): ResponseInterface { + $moduleTemplate = $this->moduleTemplateFactory->create($this->request); + $this->view->assignMultiple([ 'cacheConfigurations' => $this->buildCacheConfigurationArray(), 'action_confirm_flush_message' => $this->languageService->sL( 'LLL:EXT:cachemgm/Resources/Private/BackendModule/Language/locallang.xlf:bemodule.action_confirm_flush' ), ]); + + $moduleTemplate->setContent($this->view->render()); + + return $this->htmlResponse($moduleTemplate->renderContent()); } - public function detailAction(): void + public function detailAction(): ResponseInterface { + $moduleTemplate = $this->moduleTemplateFactory->create($this->request); + try { $cacheId = $this->request->getArgument('cacheId'); } catch (NoSuchArgumentException) { $this->showFlashMessage($this->getNoCacheFoundMessage()); - $this->forward('index'); + return new ForwardResponse('index'); } $cache = $this->cacheManager->getCache($cacheId); @@ -114,28 +122,37 @@ public function detailAction(): void 'overviewLink' => $this->getHref('BackendModule', 'index'), ] ); + + $moduleTemplate->setContent($this->view->render()); + + return $this->htmlResponse($moduleTemplate->renderContent()); } - public function flushAction(): void + public function flushAction(): ResponseInterface { try { $cacheId = $this->request->getArgument('cacheId'); } catch (NoSuchArgumentException) { $this->showFlashMessage($this->getNoCacheFoundMessage()); - $this->forward('index'); + return new ForwardResponse('index'); } $cache = $this->cacheManager->getCache($cacheId); $cache->flush(); $this->showFlashMessage($this->getFlushCacheMessage($cacheId)); - $this->forward('index'); + return new ForwardResponse('index'); } - protected function initializeView(ViewInterface $view): void + protected function initializeView(): void { - $this->view->setLayoutRootPaths(['EXT:cachemgm/Resources/Private/Layouts']); - $this->view->setPartialRootPaths(['EXT:cachemgm/Resources/Private/Partials']); - $this->view->setTemplateRootPaths(['EXT:cachemgm/Resources/Private/Templates/BackendModule']); + if ($this->view instanceof \TYPO3\CMS\Fluid\View\StandaloneView) { + $this->view->setLayoutRootPaths(['EXT:cachemgm/Resources/Private/Layouts']); + $this->view->setPartialRootPaths(['EXT:cachemgm/Resources/Private/Partials']); + $this->view->setTemplateRootPaths(['EXT:cachemgm/Resources/Private/Templates/BackendModule']); + } + + $moduleTemplate = $this->moduleTemplateFactory->create($this->request); + $moduleTemplate->setContent($this->view->render()); } /** @@ -248,7 +265,7 @@ private function getFlushCacheMessage(string $cacheId): object $this->languageService->sL( 'LLL:EXT:cachemgm/Resources/Private/BackendModule/Language/locallang.xlf:bemodule.flash.flush.header' ), - FlashMessage::OK, + \TYPO3\CMS\Core\Type\ContextualFeedbackSeverity::OK, true ); } @@ -261,7 +278,7 @@ private function getNoCacheFoundMessage(): object 'LLL:EXT:cachemgm/Resources/Private/BackendModule/Language/locallang.xlf:bemodule.flash.detailed.error' ), '', - FlashMessage::NOTICE, + \TYPO3\CMS\Core\Type\ContextualFeedbackSeverity::NOTICE, true ); } diff --git a/Classes/Domain/Repository/AbstractRepository.php b/Classes/Domain/Repository/AbstractRepository.php index 05b5f1f..612112e 100644 --- a/Classes/Domain/Repository/AbstractRepository.php +++ b/Classes/Domain/Repository/AbstractRepository.php @@ -40,7 +40,7 @@ public function countRowsInTable(string $table): int return $queryBuilder ->count('*') ->from($table) - ->execute() - ->fetchColumn(0); + ->executeQuery() + ->fetchOne(); } } diff --git a/Configuration/Backend/Modules.php b/Configuration/Backend/Modules.php new file mode 100644 index 0000000..6327238 --- /dev/null +++ b/Configuration/Backend/Modules.php @@ -0,0 +1,23 @@ + [ + 'parent' => 'tools', + 'access' => 'admin', + 'labels' => 'LLL:EXT:' . 'cachemgm' . '/Resources/Private/BackendModule/Language/locallang.xlf', + 'iconIdentifier' => 'module-cachemgm-backend-module', + 'extensionName' => 'Cachemgm', + 'controllerActions' => [ + BackendModuleController::class => [ + 'index', + 'detail', + 'flush', + ] + ], + 'path' => 'module/tools/cachemgm', + ], +]; diff --git a/Configuration/Icons.php b/Configuration/Icons.php new file mode 100644 index 0000000..c4ac476 --- /dev/null +++ b/Configuration/Icons.php @@ -0,0 +1,13 @@ + [ + 'provider' => SvgIconProvider::class, + 'source' => 'EXT:cachemgm/Resources/Public/Icons/Extension.svg', + ], +]; diff --git a/README.md b/README.md index c990e99..31cbb70 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ And then open `Documentation-GENERATED-temp/Result/project/0.0.0/Index.html` wit ## Copyright / License -Copyright: (c) 2009 - 2019, Kasper Skaarhoj & AOE GmbH +Copyright: (c) 2009 - 2024, Kasper Skaarhoj & AOE GmbH License: GPLv3, [1]: http://typo3.org/extensions/repository/view/cachemgm diff --git a/Resources/Private/Layouts/Default.html b/Resources/Private/Layouts/Default.html new file mode 100644 index 0000000..5ec0bfd --- /dev/null +++ b/Resources/Private/Layouts/Default.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Resources/Private/Templates/BackendModule/Flush.html b/Resources/Private/Templates/BackendModule/Flush.html new file mode 100644 index 0000000..af57e69 --- /dev/null +++ b/Resources/Private/Templates/BackendModule/Flush.html @@ -0,0 +1,6 @@ + + + +

Cache Flush

+

The cache has been successfully flushed.

+
\ No newline at end of file diff --git a/Tests/Functional/Domain/Repository/CacheTableRepositoryTest.php b/Tests/Functional/Domain/Repository/CacheTableRepositoryTest.php index cc0edf5..6807b98 100644 --- a/Tests/Functional/Domain/Repository/CacheTableRepositoryTest.php +++ b/Tests/Functional/Domain/Repository/CacheTableRepositoryTest.php @@ -63,7 +63,7 @@ protected function setUp(): void public function testCountRowsInTable(): void { - $this->importDataSet(__DIR__ . '/Fixtures/cache_pages.xml'); + $this->importCSVDataSet(__DIR__ . '/Fixtures/cache_pages.csv'); $this->assertSame( 2, $this->subject->countRowsInTable('cache_pages') diff --git a/Tests/Functional/Domain/Repository/Fixtures/cache_pages.csv b/Tests/Functional/Domain/Repository/Fixtures/cache_pages.csv new file mode 100644 index 0000000..d5b46d3 --- /dev/null +++ b/Tests/Functional/Domain/Repository/Fixtures/cache_pages.csv @@ -0,0 +1,4 @@ +cache_pages,,, +,id,identifier,content +,1,c4355df29142213662c0561fe304de25,this-is-a-string-in-md5 +,2,f9982c771f6d32fe6830b4b3c2ef646a,this-is-another-string-in-md5 diff --git a/Tests/Functional/Domain/Repository/Fixtures/cache_pages.xml b/Tests/Functional/Domain/Repository/Fixtures/cache_pages.xml deleted file mode 100644 index 0ed4805..0000000 --- a/Tests/Functional/Domain/Repository/Fixtures/cache_pages.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - 1 - c4355df29142213662c0561fe304de25 - this-is-a-string-in-md5 - - - 2 - f9982c771f6d32fe6830b4b3c2ef646a - this-is-another-string-in-md5 - - diff --git a/Tests/Functional/FunctionalTests.xml b/Tests/Functional/FunctionalTests.xml new file mode 100644 index 0000000..fb64f27 --- /dev/null +++ b/Tests/Functional/FunctionalTests.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + ../../Classes + + + diff --git a/Tests/Unit/UnitTests.xml b/Tests/Unit/UnitTests.xml new file mode 100644 index 0000000..5ce94ed --- /dev/null +++ b/Tests/Unit/UnitTests.xml @@ -0,0 +1,25 @@ + + + + + ../Classes + + + diff --git a/Tests/Unit/Utility/CacheUtilityTest.php b/Tests/Unit/Utility/CacheUtilityTest.php index 35bfbdc..4f69186 100644 --- a/Tests/Unit/Utility/CacheUtilityTest.php +++ b/Tests/Unit/Utility/CacheUtilityTest.php @@ -37,6 +37,7 @@ class CacheUtilityTest extends UnitTestCase { protected function setUp(): void { + parent::setUp(); $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] = [ 'cache_core' => [ 'frontend' => PhpFrontend::class, diff --git a/code-quality/phpstan-baseline.neon b/code-quality/phpstan-baseline.neon index e841232..4184cd9 100644 --- a/code-quality/phpstan-baseline.neon +++ b/code-quality/phpstan-baseline.neon @@ -1,16 +1,2 @@ parameters: - ignoreErrors: - - - message: "#^Anonymous variable in a `\\$queryBuilder\\-\\>count\\('\\*'\\)\\-\\>\\.\\.\\.\\(\\)` method call can lead to false dead methods\\. Make sure the variable type is known$#" - count: 1 - path: ../Classes/Domain/Repository/AbstractRepository.php - - - message: "#^Anonymous variable in a `\\$queryBuilder\\-\\>count\\('\\*'\\)\\-\\>from\\(\\$table\\)\\-\\>\\.\\.\\.\\(\\)` method call can lead to false dead methods\\. Make sure the variable type is known$#" - count: 1 - path: ../Classes/Domain/Repository/AbstractRepository.php - - - - message: "#^Anonymous variable in a `\\$queryBuilder\\-\\>count\\('\\*'\\)\\-\\>from\\(\\$table\\)\\-\\>execute\\(\\)\\-\\>\\.\\.\\.\\(\\)` method call can lead to false dead methods\\. Make sure the variable type is known$#" - count: 1 - path: ../Classes/Domain/Repository/AbstractRepository.php \ No newline at end of file diff --git a/code-quality/phpstan.neon b/code-quality/phpstan.neon index 22d8534..86097e8 100644 --- a/code-quality/phpstan.neon +++ b/code-quality/phpstan.neon @@ -7,10 +7,10 @@ parameters: level: 6 paths: - "../Classes/" - + ignoreErrors: + - identifier: missingType.iterableValue + - identifier: missingType.generics inferPrivatePropertyTypeFromConstructor: true - checkMissingIterableValueType: false - checkGenericClassInNonGenericObjectType: false services: - diff --git a/code-quality/rector.php b/code-quality/rector.php index 870b6cc..95da72c 100644 --- a/code-quality/rector.php +++ b/code-quality/rector.php @@ -70,14 +70,8 @@ ]) ->withSkip([ RecastingRemovalRector::class, - PostIncDecToPreIncDecRector::class, - FinalizeClassesWithoutChildrenRector::class, - ChangeAndIfToEarlyReturnRector::class, IssetOnPropertyObjectToPropertyExistsRector::class, FlipTypeControlToUseExclusiveTypeRector::class, - RenameVariableToMatchNewTypeRector::class, - AddLiteralSeparatorToNumberRector::class, - RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class, ClassPropertyAssignToConstructorPromotionRector::class => [ __DIR__ . '/../Classes/Service/Typo3Service.php', ],// @todo strict php diff --git a/composer.json b/composer.json index b19f109..6e7edf0 100644 --- a/composer.json +++ b/composer.json @@ -17,14 +17,14 @@ } ], "require": { - "php": "^8.0", - "typo3/cms-core": "^11.5", - "typo3/cms-backend": "^11.5", - "typo3/cms-frontend": "^11.5", + "php": "^8.1", + "typo3/cms-core": "^12.4", + "typo3/cms-backend": "^12.4", + "typo3/cms-frontend": "^12.4", "psr/http-message": "^1.0" }, "require-dev": { - "typo3/testing-framework": "^7.0", + "typo3/testing-framework": "^8.0", "phpcompatibility/php-compatibility": "^9.3", "phpstan/phpstan": "^1.10", "rector/rector": "^1.0", @@ -57,11 +57,11 @@ ], "test:unit": [ "[ -e .Build/bin/phpunit ] || composer update", - "TYPO3_PATH_WEB=$PWD/.Build/Web .Build/bin/phpunit -c .Build/vendor/typo3/testing-framework/Resources/Core/Build/UnitTests-v10.xml Tests/Unit" + "XDEBUG_MODE=coverage TYPO3_PATH_WEB=$PWD/.Build/Web .Build/bin/phpunit -c Tests/Unit/UnitTests.xml Tests/Unit" ], "test:functional": [ "[ -e .Build/bin/phpunit ] || composer update", - "TYPO3_PATH_WEB=$PWD/.Build/Web typo3DatabaseName=cachemgm typo3DatabaseHost=127.0.0.1 typo3DatabaseUsername=root typo3DatabasePassword=root .Build/bin/phpunit -c .Build/vendor/typo3/testing-framework/Resources/Core/Build/FunctionalTests-v10.xml Tests/Functional/" + "XDEBUG_MODE=coverage TYPO3_PATH_WEB=$PWD/.Build/Web typo3DatabaseName=cachemgm typo3DatabaseHost=127.0.0.1 typo3DatabaseUsername=root typo3DatabasePassword=root .Build/bin/phpunit -c Tests/Functional/FunctionalTests.xml Tests/Functional/" ], "test:all": [ "@test:unit", @@ -85,7 +85,7 @@ "./.Build/bin/phpstan analyse -c code-quality/phpstan.neon --memory-limit=1G --generate-baseline" ], "code-compatibility": [ - "[ -e ./.Build/vendor/symplify/easy-coding-standard/vendor/squizlabs/php_codesniffer/bin/phpcs ] || composer install", + "[ -e ./.Build/vendor/symplify/easy-coding-standard/vendor/squizlabs/php_codesniffer/bin/phpcs ] || composer update", "[ -d ./reports/php_checkstyle ] || mkdir -p reports/php_checkstyle/", "./code-quality/configure-checkstyle.sh", "./.Build/vendor/symplify/easy-coding-standard/vendor/squizlabs/php_codesniffer/bin/phpcs -d memory_limit=1G --standard=PHPCompatibility --colors --ignore=*/.Build/*,*.min.js -p . --runtime-set testVersion 8.3" diff --git a/ext_emconf.php b/ext_emconf.php index d0432c6..dcccd23 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -5,23 +5,12 @@ 'category' => 'module', 'author' => 'AOE GmbH', 'author_email' => 'dev@aoe.com', - 'shy' => '', - 'dependencies' => '', - 'conflicts' => '', - 'priority' => '', - 'module' => 'mod', 'state' => 'stable', - 'internal' => '', - 'uploadfolder' => 0, - 'createDirs' => '', - 'modify_tables' => '', - 'clearCacheOnLoad' => 0, - 'lockType' => '', 'author_company' => '', - 'version' => '11.0.0', + 'version' => '12.0.0-dev', 'constraints' => [ 'depends' => [ - 'typo3' => '11.5.0-11.5.99', + 'typo3' => '12.4.0-12.4.99', ], 'conflicts' => [], 'suggests' => [], diff --git a/ext_localconf.php b/ext_localconf.php index 2328371..73b8792 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,10 +1,14 @@ isFrontend() +) { $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['headerNoCache']['tx_cachemgm'] = TypoScriptFrontendHook::class . '->fe_headerNoCache'; } diff --git a/ext_tables.php b/ext_tables.php index 8713097..871e1f7 100644 --- a/ext_tables.php +++ b/ext_tables.php @@ -1,35 +1,3 @@ registerIcon( - 'module-cachemgm-backend-module', - SvgIconProvider::class, - [ - 'source' => 'EXT:cachemgm/ext_icon.svg' - ] - ); - - ExtensionUtility::registerModule( - 'cachemgm', - 'tools', - 'cachemgm', - '', - [ - Aoe\Cachemgm\Controller\BackendModuleController::class => 'index,detail,flush', - ], - [ - 'access' => 'admin', - 'icon' => 'EXT:' . 'cachemgm' . '/Resources/Public/Icons/Extension.svg', - 'labels' => 'LLL:EXT:' . 'cachemgm' . '/Resources/Private/BackendModule/Language/locallang.xlf', - ] - ); -}