diff --git a/composer.json b/composer.json index 89be150d1bd3ef696b5c702860c68a153e16af60..b005717236ed0fab37d79f852dc8ad63afd918d6 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 0000000000000000000000000000000000000000..99b5decc0da5630822e959428beaefb57305815f --- /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 2270b150ed009e847f0745e47ca522f0f67ea6ed..e7de781fc6b8def2f767c57784bb65a2410a442a 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 0000000000000000000000000000000000000000..00ee3defc00fb277e176a6fbdf31e2d019abdecf --- /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 0000000000000000000000000000000000000000..cc2da7a89d0511622460bb59bf5f149f4827e1de --- /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 0000000000000000000000000000000000000000..099f1b10ce39572085245a9c0dd14e2b067e8208 --- /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 0000000000000000000000000000000000000000..78995cd5297d8a1de544cc17e13cd1731df0668c --- /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 0000000000000000000000000000000000000000..eee1548bc458dc62435ce919d14b01a7bf646728 --- /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 0000000000000000000000000000000000000000..43bc45d9b31f3141594397e9c11be0eacb64818b --- /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']); + } +}