From 564b3f6ed206c10a74ee7b091bbd438c4b8b5b93 Mon Sep 17 00:00:00 2001 From: Oliver Bartsch <bo@cedev.de> Date: Tue, 4 Oct 2022 16:47:20 +0200 Subject: [PATCH] [FEATURE] Introduce PSR-14 event to modify form data for edit file form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This introduces a new PSR-14 event, enabling extension authors to modify the form data, used by FormEngine to generate the edit file form in the filelist module. TYPO3 internally makes use of this event to initialize t3editor with the suitable format options for the file to be edited. This functionality was previously done in a hook (#98494), which however did no longer work due to the removal of said hook in #97452. Effectively this means, the new Event is an improved replacement for the removed hook, since the Event now provides the whole form data array as well as the resolved FileInterface and the current PSR-7 Request. Resolves: #98521 Related: #98494 Related: #97452 Releases: main Change-Id: I5de9f8ea72fcb4296f6539449f991347cbef17b6 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75982 Tested-by: core-ci <typo3@b13.com> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Stefan Bürk <stefan@buerk.tech> --- composer.json | 1 + ...g-97452-RemovedEditFileControllerHooks.rst | 16 +++-- ...14EventToModifyFormDataForEditFileForm.rst | 71 +++++++++++++++++++ .../Controller/File/EditFileController.php | 7 ++ .../Event/ModifyEditFileFormDataEvent.php | 55 ++++++++++++++ .../Event/ModifyEditFileFormDataEventTest.php | 68 ++++++++++++++++++ .../Php/ArrayDimensionMatcher.php | 1 + .../InitializeT3editorInEditFileForm.php | 54 ++++++++++++++ .../t3editor/Configuration/Services.yaml | 5 ++ 9 files changed, 271 insertions(+), 7 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/12.1/Feature-98521-PSR-14EventToModifyFormDataForEditFileForm.rst create mode 100644 typo3/sysext/filelist/Classes/Event/ModifyEditFileFormDataEvent.php create mode 100644 typo3/sysext/filelist/Tests/Unit/Event/ModifyEditFileFormDataEventTest.php create mode 100644 typo3/sysext/t3editor/Classes/EventListener/InitializeT3editorInEditFileForm.php diff --git a/composer.json b/composer.json index 2341d0f7a550..6c8ae71f2071 100644 --- a/composer.json +++ b/composer.json @@ -269,6 +269,7 @@ "TYPO3\\CMS\\Extbase\\Tests\\": "typo3/sysext/extbase/Tests/", "TYPO3\\CMS\\Extensionmanager\\Tests\\": "typo3/sysext/extensionmanager/Tests/", "TYPO3\\CMS\\FrontendLogin\\Tests\\": "typo3/sysext/felogin/Tests/", + "TYPO3\\CMS\\Filelist\\Tests\\": "typo3/sysext/filelist/Tests/", "TYPO3\\CMS\\Filemetadata\\Tests\\": "typo3/sysext/filemetadata/Tests/", "TYPO3\\CMS\\Fluid\\Tests\\": "typo3/sysext/fluid/Tests/", "TYPO3\\CMS\\FluidStyledContent\\Tests\\": "typo3/sysext/fluid_styled_content/Tests/", diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97452-RemovedEditFileControllerHooks.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97452-RemovedEditFileControllerHooks.rst index 40e6acc4bfa4..4807a0ff0457 100644 --- a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97452-RemovedEditFileControllerHooks.rst +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-97452-RemovedEditFileControllerHooks.rst @@ -11,9 +11,11 @@ See :issue:`97452` Description =========== -The hooks :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']` and -:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook']` have been removed. -The same behavior may be achieved using template overrides. +The hooks :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']` +and :php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['postOutputProcessingHook']` +have been removed, since adjusting the generated content can be achieved using template overrides +and modifing the form data, used to generate the edit file form, can be done +using the PSR-14 :php:`TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent`. Impact ====== @@ -24,14 +26,14 @@ The extension scanner will report possible usages. Affected Installations ====================== -All TYPO3 installations using these hook in custom extension code. This is pretty -unlikely, since both hooks were of limited use. +All TYPO3 installations using these hook in custom extension code. This is +pretty unlikely, since both hooks were of limited use. Migration ========= -The content preparation allowed by :php:`preOutputProcessingHook` can be achieved with -:ref:`FormEngine data providers <t3coreapi:FormEngine-DataCompiling>`. +The form data modification, allowed by :php:`preOutputProcessingHook`, can be +achieved with the new :doc:`PSR-14 ModifyEditFileFormDataEvent <Feature-98521-PSR-14EventToModifyFormDataForEditFileForm>`. The content manipulation :php:`postOutputProcessingHook` hook can be substituted with a template override as outlined in :doc:`this changelog entry <Feature-96812-OverrideBackendTemplatesWithTSconfig>`. diff --git a/typo3/sysext/core/Documentation/Changelog/12.1/Feature-98521-PSR-14EventToModifyFormDataForEditFileForm.rst b/typo3/sysext/core/Documentation/Changelog/12.1/Feature-98521-PSR-14EventToModifyFormDataForEditFileForm.rst new file mode 100644 index 000000000000..8115f8b5a7ea --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.1/Feature-98521-PSR-14EventToModifyFormDataForEditFileForm.rst @@ -0,0 +1,71 @@ +.. include:: /Includes.rst.txt + +.. _feature-98521-1664890745: + +===================================================================== +Feature: #98521 - PSR-14 event to modify form data for edit file form +===================================================================== + +See :issue:`98521` + +Description +=========== + +A new PSR-14 :php:`TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent` +has been added, which allows to modify the form data, used to render the +file edit form in the :guilabel:`File => Filelist` module using +:ref:`FormEngine data compiling <t3coreapi:FormEngine-DataCompiling>`. + +The new event can be used as an improved alternative for the removed +:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/file_edit.php']['preOutputProcessingHook']` +hook. + +The event features the following methods: + +- :php:`getFormData()`: Returns the current :php:`$formData` array +- :php:`setFormData()`: Sets the :php:`$formData` array +- :php:`getFile()`: Returns the corresponding :php:`FileInterface` +- :php:`getRequest()`: Returns the full PSR-7 :php:`ServerRequestInterface` + +Registration of the event in your extensions' :file:`Services.yaml`: + +.. code-block:: yaml + + MyVendor\MyPackage\EventListener\ModifyEditFileFormDataEventListener: + tags: + - name: event.listener + identifier: 'my-package/modify-edit-file-form-data-event-listener' + +The corresponding event listener class: + +.. code-block:: php + + use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent; + + final class ModifyEditFileFormDataEventListener + { + public function __invoke(ModifyEditFileFormDataEvent $event): void + { + // Get current form data + $formData = $event->getFormData(); + + // Change TCA "renderType" based on the file extension + $fileExtension = $event->getFile()->getExtension(); + if ($fileExtension === 'ts') { + $formData['processedTca']['columns']['data']['config']['renderType'] = 'tsRenderer'; + } + + // Set updated form data + $event->setFormData($formData); + } + } + +Impact +====== + +It's now possible to modify the whole :php:`$formData` array, used to generate +the edit file form in the :guilabel:`File => Filelist` module, while having the +resolved :php:`FileInterface` and the current PSR-7 :php:`ServerRequestInterface` +available. + +.. index:: Backend, PHP-API, ext:filelist diff --git a/typo3/sysext/filelist/Classes/Controller/File/EditFileController.php b/typo3/sysext/filelist/Classes/Controller/File/EditFileController.php index 6b91bd115600..1f1da1952283 100644 --- a/typo3/sysext/filelist/Classes/Controller/File/EditFileController.php +++ b/typo3/sysext/filelist/Classes/Controller/File/EditFileController.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Filelist\Controller\File; +use Psr\EventDispatcher\EventDispatcherInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\StreamFactoryInterface; @@ -37,6 +38,7 @@ use TYPO3\CMS\Core\Resource\FileInterface; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity; use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent; /** * Edit text files via FormEngine. Reachable via FileList module "Edit content". @@ -98,6 +100,7 @@ class EditFileController protected readonly ModuleTemplateFactory $moduleTemplateFactory, protected readonly ResponseFactory $responseFactory, protected readonly StreamFactoryInterface $streamFactory, + protected readonly EventDispatcherInterface $eventDispatcher, ) { } @@ -146,6 +149,10 @@ class EditFileController $formData['databaseRow']['redirect'] = (string)$this->uriBuilder->buildUriFromRoute('file_edit', ['target' => $combinedIdentifier]); $formData['processedTca']['columns']['data'] = $dataColumnDefinition; + $formData = $this->eventDispatcher->dispatch( + new ModifyEditFileFormDataEvent($formData, $file, $request) + )->getFormData(); + $resultArray = GeneralUtility::makeInstance(NodeFactory::class)->create($formData)->render(); $formResultCompiler = GeneralUtility::makeInstance(FormResultCompiler::class); $formResultCompiler->mergeResult($resultArray); diff --git a/typo3/sysext/filelist/Classes/Event/ModifyEditFileFormDataEvent.php b/typo3/sysext/filelist/Classes/Event/ModifyEditFileFormDataEvent.php new file mode 100644 index 000000000000..bf345e1e7ccb --- /dev/null +++ b/typo3/sysext/filelist/Classes/Event/ModifyEditFileFormDataEvent.php @@ -0,0 +1,55 @@ +<?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\Filelist\Event; + +use Psr\Http\Message\ServerRequestInterface; +use TYPO3\CMS\Core\Resource\FileInterface; + +/** + * Listeners to this event are be able to modify the form data, + * used to render the edit file form in the filelist module. + */ +final class ModifyEditFileFormDataEvent +{ + public function __construct( + private array $formData, + private readonly FileInterface $file, + private readonly ServerRequestInterface $request + ) { + } + + public function getFormData(): array + { + return $this->formData; + } + + public function setFormData(array $formData): void + { + $this->formData = $formData; + } + + public function getFile(): FileInterface + { + return $this->file; + } + + public function getRequest(): ServerRequestInterface + { + return $this->request; + } +} diff --git a/typo3/sysext/filelist/Tests/Unit/Event/ModifyEditFileFormDataEventTest.php b/typo3/sysext/filelist/Tests/Unit/Event/ModifyEditFileFormDataEventTest.php new file mode 100644 index 000000000000..ee77f69c68ba --- /dev/null +++ b/typo3/sysext/filelist/Tests/Unit/Event/ModifyEditFileFormDataEventTest.php @@ -0,0 +1,68 @@ +<?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\Filelist\Tests\Unit\Event; + +use Prophecy\PhpUnit\ProphecyTrait; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\Http\Uri; +use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\ResourceStorage; +use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +class ModifyEditFileFormDataEventTest extends UnitTestCase +{ + use ProphecyTrait; + + /** + * @test + */ + public function gettersReturnInitializedObjects(): void + { + $formData = [ + 'databaseRow' => [ + 'uid' => 123, + ], + 'tableName' => 'editfile', + 'processedTca' => [ + 'columns' => [ + 'data' => [ + 'config' => [ + 'type' => 'someType', + ], + ], + ], + ], + ]; + $resourceStorageProphecy = $this->prophesize(ResourceStorage::class); + $file = new File([], $resourceStorageProphecy->reveal()); + $request = new ServerRequest(new Uri('https://example.com')); + + $event = new ModifyEditFileFormDataEvent($formData, $file, $request); + + self::assertEquals($formData, $event->getFormData()); + self::assertEquals($file, $event->getFile()); + self::assertEquals($request, $event->getRequest()); + + $modifyFormData = $event->getFormData(); + $modifyFormData['processedTca']['columns']['data']['config']['type'] = 'newType'; + $event->setFormData($modifyFormData); + + self::assertEquals($modifyFormData, $event->getFormData()); + } +} diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php index 5b6eb4eaaaf5..1b52919921f6 100644 --- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php +++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php @@ -904,6 +904,7 @@ return [ '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'typo3/file_edit.php\'][\'preOutputProcessingHook\']' => [ 'restFiles' => [ 'Breaking-97452-RemovedEditFileControllerHooks.rst', + 'Feature-98521-PSR-14EventToModifyFormDataForEditFileForm.rst', ], ], '$GLOBALS[\'TYPO3_CONF_VARS\'][\'SC_OPTIONS\'][\'typo3/file_edit.php\'][\'postOutputProcessingHook\']' => [ diff --git a/typo3/sysext/t3editor/Classes/EventListener/InitializeT3editorInEditFileForm.php b/typo3/sysext/t3editor/Classes/EventListener/InitializeT3editorInEditFileForm.php new file mode 100644 index 000000000000..96ce9ec7cd40 --- /dev/null +++ b/typo3/sysext/t3editor/Classes/EventListener/InitializeT3editorInEditFileForm.php @@ -0,0 +1,54 @@ +<?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\T3editor\EventListener; + +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Filelist\Event\ModifyEditFileFormDataEvent; +use TYPO3\CMS\T3editor\Exception\InvalidModeException; +use TYPO3\CMS\T3editor\Registry\ModeRegistry; +use TYPO3\CMS\T3editor\T3editor; + +/** + * Listener which modifies the form data to initialize t3editor with + * the resolved format option (based on the file extension). + */ +final class InitializeT3editorInEditFileForm +{ + public function __construct(private readonly ModeRegistry $modeRegistry) + { + } + + public function __invoke(ModifyEditFileFormDataEvent $event): void + { + // Compile and register t3editor configuration + GeneralUtility::makeInstance(T3editor::class)->registerConfiguration(); + + $fileExtension = $event->getFile()->getExtension(); + + try { + $mode = $this->modeRegistry->getByFileExtension($fileExtension); + } catch (InvalidModeException $e) { + $mode = $this->modeRegistry->getDefaultMode(); + } + + $formData = $event->getFormData(); + $formData['processedTca']['columns']['data']['config']['renderType'] = 't3editor'; + $formData['processedTca']['columns']['data']['config']['format'] = $mode->getFormatCode(); + $event->setFormData($formData); + } +} diff --git a/typo3/sysext/t3editor/Configuration/Services.yaml b/typo3/sysext/t3editor/Configuration/Services.yaml index f9134d1f5234..8ed6d26dbb82 100644 --- a/typo3/sysext/t3editor/Configuration/Services.yaml +++ b/typo3/sysext/t3editor/Configuration/Services.yaml @@ -6,3 +6,8 @@ services: TYPO3\CMS\T3editor\: resource: '../Classes/*' + + TYPO3\CMS\T3editor\EventListener\InitializeT3editorInEditFileForm: + tags: + - name: event.listener + identifier: 'typo3-t3editor/initialize-t3editor-in-edit-file-form' -- GitLab