From 3d1b678fc6f47b6b8288a12c008da62003812208 Mon Sep 17 00:00:00 2001 From: Simon Schaufelberger Date: Thu, 4 Jan 2024 22:59:56 +0100 Subject: [PATCH] [FEATURE] Add MigrateRequiredFlagFlexFormRector Resolves: #3363 --- config/v12/flexform-120.php | 2 + .../MigrateRequiredFlagFlexFormRector.php | 135 ++++++++++++++++++ .../v12/v0/tca/MigrateRequiredFlagRector.php | 1 + .../Fixture/fixture.xml.inc | 70 +++++++++ .../MigrateRequiredFlagFlexFormRectorTest.php | 32 +++++ .../config/configured_rule.php | 11 ++ 6 files changed, 251 insertions(+) create mode 100644 src/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector.php create mode 100644 tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/Fixture/fixture.xml.inc create mode 100644 tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/MigrateRequiredFlagFlexFormRectorTest.php create mode 100644 tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/config/configured_rule.php diff --git a/config/v12/flexform-120.php b/config/v12/flexform-120.php index 77517fd50..70fc4a268 100644 --- a/config/v12/flexform-120.php +++ b/config/v12/flexform-120.php @@ -9,6 +9,7 @@ use Ssch\TYPO3Rector\Rector\v12\v0\flexform\MigrateNullFlagFlexFormRector; use Ssch\TYPO3Rector\Rector\v12\v0\flexform\MigratePasswordAndSaltedPasswordToPasswordTypeFlexFormRector; use Ssch\TYPO3Rector\Rector\v12\v0\flexform\MigrateRenderTypeColorpickerToTypeColorFlexFormRector; +use Ssch\TYPO3Rector\Rector\v12\v0\flexform\MigrateRequiredFlagFlexFormRector; use Ssch\TYPO3Rector\Rector\v12\v0\flexform\RemoveElementTceFormsRector; return static function (RectorConfig $rectorConfig): void { @@ -19,5 +20,6 @@ $rectorConfig->rule(MigrateNullFlagFlexFormRector::class); $rectorConfig->rule(MigratePasswordAndSaltedPasswordToPasswordTypeFlexFormRector::class); $rectorConfig->rule(MigrateRenderTypeColorpickerToTypeColorFlexFormRector::class); + $rectorConfig->rule(MigrateRequiredFlagFlexFormRector::class); $rectorConfig->rule(RemoveElementTceFormsRector::class); }; diff --git a/src/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector.php b/src/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector.php new file mode 100644 index 000000000..c276119d1 --- /dev/null +++ b/src/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector.php @@ -0,0 +1,135 @@ + $elements */ + $elements = $xpath->query('//config'); + + if ($elements->count() === 0) { + return false; + } + + foreach ($elements as $element) { + $this->refactorColumn($domDocument, $element); + } + + return $this->domDocumentHasBeenChanged; + } + + /** + * @codeCoverageIgnore + */ + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Migrate required flag', [new CodeSample( + <<<'CODE_SAMPLE' + + + aTitle + array + + + foo + + trim,required + + + + + +CODE_SAMPLE + , + <<<'CODE_SAMPLE' + + + aTitle + array + + + foo + + trim + 1 + + + + + +CODE_SAMPLE + )]); + } + + private function refactorColumn(DOMDocument $domDocument, ?DOMElement $configElement): void + { + if (! $configElement instanceof DOMElement) { + return; + } + + if (! $this->hasKey($configElement, 'eval')) { + return; + } + + $evalDomElement = $this->extractDomElementByKey($configElement, 'eval'); + if (! $evalDomElement instanceof DOMElement) { + return; + } + + $evalListValue = $evalDomElement->nodeValue; + if (! is_string($evalListValue)) { + return; + } + + if (! StringUtility::inList($evalListValue, 'required')) { + return; + } + + $evalList = ArrayUtility::trimExplode(',', $evalListValue, true); + + // Remove "required" from $evalList + $evalList = array_filter($evalList, static fn (string $eval) => $eval !== 'required'); + + if ($evalList !== []) { + // Write back filtered 'eval' + $evalDomElement->nodeValue = ''; + $evalDomElement->appendChild($domDocument->createTextNode(implode(',', $evalList))); + } elseif ($evalDomElement->parentNode instanceof DOMElement) { + // 'eval' is empty, remove whole configuration + $evalDomElement->parentNode->removeChild($evalDomElement); + } + + $requiredDomElement = $this->extractDomElementByKey($configElement, 'required'); + if (! $requiredDomElement instanceof DOMElement) { + $configElement->appendChild($domDocument->createElement('required', '1')); + } + + $this->domDocumentHasBeenChanged = true; + } +} diff --git a/src/Rector/v12/v0/tca/MigrateRequiredFlagRector.php b/src/Rector/v12/v0/tca/MigrateRequiredFlagRector.php index b15bab577..70867abff 100644 --- a/src/Rector/v12/v0/tca/MigrateRequiredFlagRector.php +++ b/src/Rector/v12/v0/tca/MigrateRequiredFlagRector.php @@ -19,6 +19,7 @@ /** * @changelog https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/12.0/Deprecation-97035-RequiredOptionInEvalKeyword.html + * @changelog https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/12.0/Feature-97035-UtilizeRequiredDirectlyInTCAFieldConfiguration.html * @see \Ssch\TYPO3Rector\Tests\Rector\v12\v0\tca\MigrateRequiredFlagRector\MigrateRequiredFlagRectorTest */ final class MigrateRequiredFlagRector extends AbstractTcaRector diff --git a/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/Fixture/fixture.xml.inc b/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/Fixture/fixture.xml.inc new file mode 100644 index 000000000..60fbc3cdf --- /dev/null +++ b/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/Fixture/fixture.xml.inc @@ -0,0 +1,70 @@ + + + + + sheetTitle + array + + + + input + required + + + + + input + trim,required + + + + + input + trim + + + + + input + + + + + + + +----- + + + + + sheetTitle + array + + + + input + 1 + + + + input + trim + 1 + + + + input + trim + + + + + input + + + + + + + diff --git a/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/MigrateRequiredFlagFlexFormRectorTest.php b/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/MigrateRequiredFlagFlexFormRectorTest.php new file mode 100644 index 000000000..de6d305e5 --- /dev/null +++ b/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/MigrateRequiredFlagFlexFormRectorTest.php @@ -0,0 +1,32 @@ +doTestFile($filePath); + } + + /** + * @return Iterator> + */ + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture', '*.xml.inc'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/config/configured_rule.php b/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/config/configured_rule.php new file mode 100644 index 000000000..cba20b548 --- /dev/null +++ b/tests/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector/config/configured_rule.php @@ -0,0 +1,11 @@ +import(__DIR__ . '/../../../../../../../config/config_test.php'); + $rectorConfig->rule(MigrateRequiredFlagFlexFormRector::class); +};