From e94271f6d9f56f960fdda83eb190a363fdb0c68c Mon Sep 17 00:00:00 2001 From: Benjamin Franzke <ben@bnf.dev> Date: Thu, 22 Feb 2024 08:24:34 +0100 Subject: [PATCH] [BUGFIX] Allow TCA resultArray modification via CustomFileControlsEvent The event provides access to the `$resultArray` and documents that it can be modified to set `javaScriptModules`, but missed to take the resulting data into account. Releases: main, 12.4 Resolves: #103174 Change-Id: I0a53d1fbcdff0a3d57de237b44d3ff68f60c721d Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83072 Tested-by: core-ci <typo3@b13.com> Tested-by: Andreas Kienast <a.fernandez@scripting-base.de> Tested-by: Benjamin Franzke <ben@bnf.dev> Reviewed-by: Andreas Kienast <a.fernandez@scripting-base.de> Tested-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Benjamin Franzke <ben@bnf.dev> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- .../Form/Container/FilesControlContainer.php | 6 +- .../Container/FilesControlContainerTest.php | 110 ++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php diff --git a/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php index c231c8d07621..b213f3b1339c 100644 --- a/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php @@ -271,9 +271,11 @@ class FilesControlContainer extends AbstractContainer } } - $controls = $this->eventDispatcher->dispatch( + $event = $this->eventDispatcher->dispatch( new CustomFileControlsEvent($resultArray, $table, $field, $row, $config, $formFieldIdentifier, $formFieldName) - )->getControls(); + ); + $resultArray = $event->getResultArray(); + $controls = $event->getControls(); if ($controls !== []) { $view->assign('customControls', [ diff --git a/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php b/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php new file mode 100644 index 000000000000..1c41f77bd47f --- /dev/null +++ b/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php @@ -0,0 +1,110 @@ +<?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\Backend\Tests\Functional\Form\Container; + +use Symfony\Component\DependencyInjection\Container; +use TYPO3\CMS\Backend\Form\Container\FilesControlContainer; +use TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent; +use TYPO3\CMS\Backend\Routing\Route; +use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; +use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder; +use TYPO3\CMS\Core\EventDispatcher\ListenerProvider; +use TYPO3\CMS\Core\Http\ServerRequest; +use TYPO3\CMS\Core\Localization\LanguageServiceFactory; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; + +final class FilesControlContainerTest extends FunctionalTestCase +{ + protected function setUp(): void + { + parent::setUp(); + $GLOBALS['BE_USER'] = new BackendUserAuthentication(); + $GLOBALS['LANG'] = $this->get(LanguageServiceFactory::class)->create('default'); + } + + /** + * @test + */ + public function customFileControlsEventIsCalled(): void + { + $customFileControlsEvent = null; + $controls = ['foo', 'bar']; + $databaseRow = [ + 'uid' => 123, + ]; + $fieldConfig = [ + 'minitems' => 1, + 'maxitems' => 2, + ]; + $fieldName = 'assets'; + $tableName = 'tx_table'; + $formFieldIdentifier = 'data-123-tx_table-123-assets'; + $formFieldName = 'data[tx_table][123][assets]'; + + /** @var Container $container */ + $container = $this->get('service_container'); + $container->set( + 'custom-file-controls-listener', + static function (CustomFileControlsEvent $event) use (&$customFileControlsEvent, $controls) { + $customFileControlsEvent = $event; + $event->setControls($controls); + $event->setResultArray(['javaScriptModules' => ['fooJavaScriptModule']]); + } + ); + + $eventListener = $this->get(ListenerProvider::class); + $eventListener->addListener(CustomFileControlsEvent::class, 'custom-file-controls-listener'); + + $subject = $this->get(FilesControlContainer::class); + $subject->setData([ + 'inlineData' => [], + 'inlineStructure' => [], + 'inlineFirstPid' => 123, + 'fieldName' => $fieldName, + 'tableName' => $tableName, + 'renderType' => 'file', + 'databaseRow' => $databaseRow, + 'tabAndInlineStack' => '', + 'request' => (new ServerRequest()) + ->withAttribute('route', new Route('', [])) + ->withAttribute('applicationType', SystemEnvironmentBuilder::REQUESTTYPE_BE), + 'parameterArray' => [ + 'itemFormElName' => '', + 'fieldConf' => [ + 'label' => 'foobar', + 'config' => $fieldConfig, + 'children' => [], + ], + ], + 'returnUrl' => '', + ]); + $result = $subject->render(); + + self::assertInstanceOf(CustomFileControlsEvent::class, $customFileControlsEvent); + self::assertContains('fooJavaScriptModule', $result['javaScriptModules']); + self::assertContains('fooJavaScriptModule', $customFileControlsEvent->getResultArray()['javaScriptModules']); + self::assertEquals($controls, $customFileControlsEvent->getControls()); + self::assertEquals($databaseRow, $customFileControlsEvent->getDatabaseRow()); + self::assertArrayHasKey('minitems', $customFileControlsEvent->getFieldConfig()); + self::assertArrayHasKey('maxitems', $customFileControlsEvent->getFieldConfig()); + self::assertEquals($fieldName, $customFileControlsEvent->getFieldName()); + self::assertEquals($formFieldIdentifier, $customFileControlsEvent->getFormFieldIdentifier()); + self::assertEquals($formFieldName, $customFileControlsEvent->getFormFieldName()); + self::assertEquals($tableName, $customFileControlsEvent->getTableName()); + } +} -- GitLab