From 2f6df56cfeec04132bd9624bce2ab75b1080e863 Mon Sep 17 00:00:00 2001 From: Nikita Hovratov <nikita.h@live.de> Date: Thu, 7 Oct 2021 18:16:16 +0200 Subject: [PATCH] [BUGFIX] Fix validation in form override settings The FinisherOptionGenerator of the form extension generates the data structure for the form setting overrides on the fly. By doing so, it didn't make a distinction between normal TCA fields and flexform specific sections/containers and added the wrapper "TCEforms" to sections as well, which broke the validation in DataHandler for the fields inside the container (E.g. the email field). The patch checks if section is set to "true" and adds the "TCEforms" key only for normal TCA field configurations. Unit tests have been added for the DataHandler checkValue_flex_procInData_travDS method, which show cases with and without the "TCEforms" key. Also, since this works now, a PHP 8 warning appeared. This is fixed now, too. Resolves: #95441 Releases: main, 11.5 Change-Id: Ib12a0484bcbdc827664181ca6af89edfadee13d8 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/71490 Tested-by: core-ci <typo3@b13.com> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Reviewed-by: Benni Mack <benni@typo3.org> --- .../core/Classes/DataHandling/DataHandler.php | 2 +- .../Unit/DataHandling/DataHandlerTest.php | 182 ++++++++++++++++++ .../Processors/FinisherOptionGenerator.php | 6 +- 3 files changed, 188 insertions(+), 2 deletions(-) diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index 90b3346c6429..5c8657cd194a 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -2910,7 +2910,7 @@ class DataHandler implements LoggerAwareInterface foreach ($DSelements as $key => $dsConf) { // Array/Section: if (isset($DSelements[$key]['type']) && $DSelements[$key]['type'] === 'array') { - if (!is_array($dataValues[$key]['el'])) { + if (!is_array($dataValues[$key]['el'] ?? null)) { continue; } diff --git a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php index 18d6fb5ababe..ac446a9888a6 100644 --- a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php +++ b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php @@ -652,6 +652,188 @@ class DataHandlerTest extends UnitTestCase $this->subject->_call('checkValueForFlex', [], [], [], '', 0, '', '', 0, 0, 0, ''); } + public function checkValue_flex_procInData_travDSDataProvider(): iterable + { + yield 'Flat structure with TCEForms' => [ + 'dataValues' => [ + 'field1' => [ + 'vDEF' => 'wrong input', + ], + ], + 'DSelements' => [ + 'field1' => [ + 'TCEforms' => [ + 'label' => 'A field', + 'config' => [ + 'type' => 'input', + 'eval' => 'required,int', + ], + ], + ], + ], + 'expected' => [ + 'field1' => [ + 'vDEF' => 0, + ], + ], + ]; + + yield 'Flat structure without TCEForms' => [ + 'dataValues' => [ + 'field1' => [ + 'vDEF' => 'wrong input', + ], + ], + 'DSelements' => [ + 'field1' => [ + 'label' => 'A field', + 'config' => [ + 'type' => 'input', + 'eval' => 'required,int', + ], + ], + ], + 'expected' => [ + 'field1' => [ + 'vDEF' => 0, + ], + ], + ]; + + yield 'Array structure with TCEforms key' => [ + 'dataValues' => [ + 'section' => [ + 'el' => [ + '1' => [ + 'container1' => [ + 'el' => [ + 'field1' => [ + 'vDEF' => 'wrong input', + ], + ], + ], + ], + ], + ], + ], + 'DSelements' => [ + 'section' => [ + 'type' => 'array', + 'section' => true, + 'el' => [ + 'container1' => [ + 'type' => 'array', + 'el' => [ + 'field1' => [ + 'TCEforms' => [ + 'label' => 'A field', + 'config' => [ + 'type' => 'input', + 'eval' => 'required,int', + ], + ], + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'section' => [ + 'el' => [ + '1' => [ + 'container1' => [ + 'el' => [ + 'field1' => [ + 'vDEF' => 0, + ], + ], + ], + ], + ], + ], + ], + ]; + + yield 'Array structure without TCEforms key' => [ + 'dataValues' => [ + 'section' => [ + 'el' => [ + '1' => [ + 'container_1' => [ + 'el' => [ + 'field1' => [ + 'vDEF' => 'wrong input', + ], + ], + ], + ], + ], + ], + ], + 'DSelements' => [ + 'section' => [ + 'type' => 'array', + 'section' => true, + 'el' => [ + 'container_1' => [ + 'type' => 'array', + 'el' => [ + 'field1' => [ + 'label' => 'A field', + 'config' => [ + 'type' => 'input', + 'eval' => 'required,int', + ], + ], + ], + ], + ], + ], + ], + 'expected' => [ + 'section' => [ + 'el' => [ + '1' => [ + 'container_1' => [ + 'el' => [ + 'field1' => [ + 'vDEF' => 0, + ], + ], + ], + ], + ], + ], + ], + ]; + } + + /** + * This test ensures, that the eval method checkValue_SW is called on + * flexform structures. + * + * @test + * @dataProvider checkValue_flex_procInData_travDSDataProvider + */ + public function checkValue_flex_procInData_travDS(array $dataValues, array $DSelements, array $expected): void + { + $pParams = [ + 'tt_content', + 777, + '<?xml ... ?>', + 'update', + 1, + 'tt_content:777:pi_flexform', + 0, + ]; + + $languageServiceProphecy = $this->prophesize(LanguageService::class); + $GLOBALS['LANG'] = $languageServiceProphecy->reveal(); + $this->subject->checkValue_flex_procInData_travDS($dataValues, [], $DSelements, $pParams, '', ''); + self::assertSame($expected, $dataValues); + } + ///////////////////////////////////// // Tests concerning log ///////////////////////////////////// diff --git a/typo3/sysext/form/Classes/Domain/Configuration/FlexformConfiguration/Processors/FinisherOptionGenerator.php b/typo3/sysext/form/Classes/Domain/Configuration/FlexformConfiguration/Processors/FinisherOptionGenerator.php index 1ac281f2edd0..1ab63eecd768 100644 --- a/typo3/sysext/form/Classes/Domain/Configuration/FlexformConfiguration/Processors/FinisherOptionGenerator.php +++ b/typo3/sysext/form/Classes/Domain/Configuration/FlexformConfiguration/Processors/FinisherOptionGenerator.php @@ -88,7 +88,11 @@ class FinisherOptionGenerator extends AbstractProcessor } $sheetElements = $this->converterDto->getResult(); - $sheetElements['settings.finishers.' . $finisherIdentifier . '.' . $optionKey]['TCEforms'] = $elementConfiguration; + if ($elementConfiguration['section'] ?? false) { + $sheetElements['settings.finishers.' . $finisherIdentifier . '.' . $optionKey] = $elementConfiguration; + } else { + $sheetElements['settings.finishers.' . $finisherIdentifier . '.' . $optionKey]['TCEforms'] = $elementConfiguration; + } $this->converterDto->setResult($sheetElements); } -- GitLab