From e9907829d7a44e498d0fc4a875754a79f66f740d Mon Sep 17 00:00:00 2001 From: Nikita Hovratov <nikita.h@live.de> Date: Fri, 1 Sep 2023 14:33:14 +0200 Subject: [PATCH] [FEATURE] Add BeforeLoadedPageTsConfigEvent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the recent deprecation of adding page TSconfig via ext_localconf as a string, the need for a new PSR-14 event arose. This event can be used to add global static page TSconfig before the global page.tsconfig files are loaded. This allows extensions to add basic config, which still can be overridden with page.tsconfig. Resolves: #101818 Releases: main Change-Id: Ic6fc0bff5e19c6c097c123386452b0e2bba0e17e Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80814 Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: core-ci <typo3@b13.com> --- composer.json | 1 + .../Event/BeforeLoadedPageTsConfigEvent.php | 47 +++++++++++++++++ .../IncludeTree/TsConfigTreeBuilder.php | 3 ++ ...e-101818-BeforeLoadedPageTsConfigEvent.rst | 50 +++++++++++++++++++ .../EventListener/AddGlobalPageTsConfig.php | 30 +++++++++++ .../Configuration/Services.yaml | 8 +++ .../test_tsconfig_event/composer.json | 19 +++++++ .../test_tsconfig_event/ext_emconf.php | 21 ++++++++ .../BeforeLoadedPageTsConfigEventTest.php | 41 +++++++++++++++ 9 files changed, 220 insertions(+) create mode 100644 typo3/sysext/core/Classes/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEvent.php create mode 100644 typo3/sysext/core/Documentation/Changelog/13.0/Feature-101818-BeforeLoadedPageTsConfigEvent.rst create mode 100644 typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Classes/EventListener/AddGlobalPageTsConfig.php create mode 100644 typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Configuration/Services.yaml create mode 100644 typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/composer.json create mode 100644 typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/ext_emconf.php create mode 100644 typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEventTest.php diff --git a/composer.json b/composer.json index 89be150d1bd3..b005717236ed 100644 --- a/composer.json +++ b/composer.json @@ -312,6 +312,7 @@ "TYPO3Tests\\TestMeta\\": "typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_meta/Classes/", "TYPO3Tests\\TestTyposcriptAstFunctionEvent\\": "typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_typoscript_ast_function_event/Classes/", "TYPO3Tests\\TestTyposcriptPagetsconfigfactory\\": "typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_typoscript_pagetsconfigfactory/Classes/", + "TYPO3Tests\\TestTsconfigEvent\\": "typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Classes/", "TYPO3Tests\\TypeConverterTest\\": "typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/type_converter_test/Classes/", "TYPO3Tests\\ViewhelperLibrary\\": "typo3/sysext/fluid/Tests/Functional/Fixtures/Libraries/viewhelper_library/src/" } diff --git a/typo3/sysext/core/Classes/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEvent.php b/typo3/sysext/core/Classes/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEvent.php new file mode 100644 index 000000000000..99b5decc0da5 --- /dev/null +++ b/typo3/sysext/core/Classes/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEvent.php @@ -0,0 +1,47 @@ +<?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\Core\TypoScript\IncludeTree\Event; + +/** + * Extensions can add global page TSconfig right before they are loaded from other sources + * like the global page.tsconfig file. + * + * Note: The added config should not depend on runtime / request. This is considered static + * config and thus should be identical on every request. + */ +final class BeforeLoadedPageTsConfigEvent +{ + public function __construct(private array $tsConfig = []) + { + } + + public function getTsConfig(): array + { + return $this->tsConfig; + } + + public function addTsConfig(string $tsConfig): void + { + $this->tsConfig[] = $tsConfig; + } + + public function setTsConfig(array $tsConfig): void + { + $this->tsConfig = $tsConfig; + } +} diff --git a/typo3/sysext/core/Classes/TypoScript/IncludeTree/TsConfigTreeBuilder.php b/typo3/sysext/core/Classes/TypoScript/IncludeTree/TsConfigTreeBuilder.php index 2270b150ed00..e7de781fc6b8 100644 --- a/typo3/sysext/core/Classes/TypoScript/IncludeTree/TsConfigTreeBuilder.php +++ b/typo3/sysext/core/Classes/TypoScript/IncludeTree/TsConfigTreeBuilder.php @@ -21,6 +21,7 @@ use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Cache\Frontend\PhpFrontend; use TYPO3\CMS\Core\EventDispatcher\EventDispatcher; use TYPO3\CMS\Core\Package\PackageManager; +use TYPO3\CMS\Core\TypoScript\IncludeTree\Event\BeforeLoadedPageTsConfigEvent; use TYPO3\CMS\Core\TypoScript\IncludeTree\Event\ModifyLoadedPageTsConfigEvent; use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\RootInclude; use TYPO3\CMS\Core\TypoScript\IncludeTree\IncludeNode\TsConfigInclude; @@ -115,6 +116,8 @@ final class TsConfigTreeBuilder } } if (!$gotPackagesPagesTsConfigFromCache) { + $event = $this->eventDispatcher->dispatch(new BeforeLoadedPageTsConfigEvent()); + $collectedPagesTsConfigArray = $event->getTsConfig(); foreach ($this->packageManager->getActivePackages() as $package) { $packagePath = $package->getPackagePath(); $tsConfigFile = null; diff --git a/typo3/sysext/core/Documentation/Changelog/13.0/Feature-101818-BeforeLoadedPageTsConfigEvent.rst b/typo3/sysext/core/Documentation/Changelog/13.0/Feature-101818-BeforeLoadedPageTsConfigEvent.rst new file mode 100644 index 000000000000..00ee3defc00f --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/13.0/Feature-101818-BeforeLoadedPageTsConfigEvent.rst @@ -0,0 +1,50 @@ +.. include:: /Includes.rst.txt + +.. _feature-101818-1693570608: + +================================================ +Feature: #101818 - BeforeLoadedPageTsConfigEvent +================================================ + +See :issue:`101818` + +Description +=========== + +The PSR-14 event :php:`\TYPO3\CMS\Core\TypoScript\IncludeTree\Event\BeforeLoadedPageTsConfigEvent` +can be used to add global static page TSconfig before anything else is loaded. +This is especially useful, if page TSconfig is generated automatically as a +string from a PHP function. + +It is important to understand that this config is considered static and thus +should not depend on runtime / request. + +Example +------- + +.. code-block:: php + + <?php + + namespace Vendor\MyExtension\EventListener; + + use TYPO3\CMS\Core\Attribute\AsEventListener; + use TYPO3\CMS\Core\TypoScript\IncludeTree\Event\BeforeLoadedPageTsConfigEvent; + + #[AsEventListener(identifier: 'vendor/my-extension/global-pagetsconfig')] + final class AddGlobalPageTsConfig + { + public function __invoke(BeforeLoadedPageTsConfigEvent $event): void + { + $event->addTsConfig('global = a global setting'); + } + } + + +Impact +====== + +Developers are able to define an event listener which is dispatched before any +other page TSconfig is loaded. + +.. index:: Backend, PHP-API, ext:core diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Classes/EventListener/AddGlobalPageTsConfig.php b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Classes/EventListener/AddGlobalPageTsConfig.php new file mode 100644 index 000000000000..cc2da7a89d05 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Classes/EventListener/AddGlobalPageTsConfig.php @@ -0,0 +1,30 @@ +<?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 TYPO3Tests\TestTsconfigEvent\EventListener; + +use TYPO3\CMS\Core\Attribute\AsEventListener; +use TYPO3\CMS\Core\TypoScript\IncludeTree\Event\BeforeLoadedPageTsConfigEvent; + +#[AsEventListener(identifier: 'typo3tests/test-tsconfig-event/add-global')] +final class AddGlobalPageTsConfig +{ + public function __invoke(BeforeLoadedPageTsConfigEvent $event): void + { + $event->addTsConfig('number = one'); + } +} diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Configuration/Services.yaml b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Configuration/Services.yaml new file mode 100644 index 000000000000..099f1b10ce39 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/Configuration/Services.yaml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + TYPO3Tests\TestTsconfigEvent\: + resource: '../Classes/*' diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/composer.json b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/composer.json new file mode 100644 index 000000000000..78995cd5297d --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/composer.json @@ -0,0 +1,19 @@ +{ + "name": "typo3tests/test-tsconfig-event", + "type": "typo3-cms-extension", + "description": "This extension defines event listeners for page TSConfig modification.", + "license": "GPL-2.0-or-later", + "require": { + "typo3/cms-core": "13.0.*@dev" + }, + "extra": { + "typo3/cms": { + "extension-key": "test_tsconfig_event" + } + }, + "autoload": { + "psr-4": { + "TYPO3Tests\\TestTsconfigEvent\\": "Classes/" + } + } +} diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/ext_emconf.php b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/ext_emconf.php new file mode 100644 index 000000000000..eee1548bc458 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event/ext_emconf.php @@ -0,0 +1,21 @@ +<?php + +declare(strict_types=1); + +$EM_CONF[$_EXTKEY] = [ + 'title' => 'This extension defines event listeners for page TSConfig modification.', + 'description' => 'This extension defines event listeners for page TSConfig modification.', + 'category' => 'example', + 'version' => '13.0.0', + 'state' => 'beta', + 'author' => 'Nikita Hovratov', + 'author_email' => 'info@nikita-hovratov.de', + 'author_company' => '', + 'constraints' => [ + 'depends' => [ + 'typo3' => '13.0.0', + ], + 'conflicts' => [], + 'suggests' => [], + ], +]; diff --git a/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEventTest.php b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEventTest.php new file mode 100644 index 000000000000..43bc45d9b31f --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/TypoScript/IncludeTree/Event/BeforeLoadedPageTsConfigEventTest.php @@ -0,0 +1,41 @@ +<?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\Core\Tests\Functional\TypoScript\IncludeTree\Event; + +use TYPO3\CMS\Core\Site\Entity\NullSite; +use TYPO3\CMS\Core\TypoScript\PageTsConfigFactory; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; + +final class BeforeLoadedPageTsConfigEventTest extends FunctionalTestCase +{ + protected array $testExtensionsToLoad = [ + 'typo3/sysext/core/Tests/Functional/Fixtures/Extensions/test_tsconfig_event', + ]; + + /** + * @test + */ + public function globalPageTsconfigIsAddedByEvent(): void + { + $subject = $this->get(PageTsConfigFactory::class); + + $pageTsConfig = $subject->create([], new NullSite()); + + self::assertSame('one', $pageTsConfig->getPageTsConfigArray()['number']); + } +} -- GitLab