diff --git a/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php index 199f94fd320b40dd29a300089eb0c5dc1eb09dfd..c96e7c12aaa9d3d958857084b2bc711925a9f91d 100644 --- a/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php @@ -285,9 +285,11 @@ class FilesControlContainer extends AbstractContainer } } - $controls = GeneralUtility::makeInstance(EventDispatcherInterface::class)->dispatch( + $event = GeneralUtility::makeInstance(EventDispatcherInterface::class)->dispatch( new CustomFileControlsEvent($resultArray, $table, $field, $row, $config, $formFieldIdentifier, $formFieldName) - )->getControls(); + ); + $resultArray = $event->getResultArray(); + $controls = $event->getControls(); if ($controls !== []) { $view->assign('customControls', [ @@ -296,9 +298,9 @@ class FilesControlContainer extends AbstractContainer ]); } - $resultArray['html'] = $view->render('Form/FilesControlContainer'); - $resultArray['javaScriptModules'] = array_merge($resultArray['javaScriptModules'], $this->javaScriptModules); + $resultArray['javaScriptModules'] = array_merge($resultArray['javaScriptModules'] ?? [], $this->javaScriptModules); $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/container/files-control-container.js'); + $resultArray['html'] = $view->render('Form/FilesControlContainer'); return $resultArray; } 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 0000000000000000000000000000000000000000..99e6ea36e5c257e88174d7f00d346ffd08213385 --- /dev/null +++ b/typo3/sysext/backend/Tests/Functional/Form/Container/FilesControlContainerTest.php @@ -0,0 +1,113 @@ +<?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\Form\NodeFactory; +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\CMS\Core\Utility\GeneralUtility; +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'); + + $nodeFactory = GeneralUtility::makeInstance(NodeFactory::class); + $subject = new FilesControlContainer($nodeFactory, [ + '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' => [ + 'itemFormElID' => '', + '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()); + } +}