Skip to content

Commit

Permalink
[FEATURE] Add MigrateRequiredFlagFlexFormRector
Browse files Browse the repository at this point in the history
Resolves: #3363
  • Loading branch information
simonschaufi committed Jan 4, 2024
1 parent 96d2fde commit 3d1b678
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/v12/flexform-120.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -19,5 +20,6 @@
$rectorConfig->rule(MigrateNullFlagFlexFormRector::class);
$rectorConfig->rule(MigratePasswordAndSaltedPasswordToPasswordTypeFlexFormRector::class);
$rectorConfig->rule(MigrateRenderTypeColorpickerToTypeColorFlexFormRector::class);
$rectorConfig->rule(MigrateRequiredFlagFlexFormRector::class);
$rectorConfig->rule(RemoveElementTceFormsRector::class);
};
135 changes: 135 additions & 0 deletions src/Rector/v12/v0/flexform/MigrateRequiredFlagFlexFormRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Rector\v12\v0\flexform;

use DOMDocument;
use DOMElement;
use DOMNodeList;
use DOMXPath;
use Ssch\TYPO3Rector\Contract\FileProcessor\FlexForms\Rector\FlexFormRectorInterface;
use Ssch\TYPO3Rector\Helper\ArrayUtility;
use Ssch\TYPO3Rector\Helper\FlexFormHelperTrait;
use Ssch\TYPO3Rector\Helper\StringUtility;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @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\flexform\MigrateRequiredFlagFlexFormRector\MigrateRequiredFlagFlexFormRectorTest
*/
final class MigrateRequiredFlagFlexFormRector implements FlexFormRectorInterface
{
use FlexFormHelperTrait;

private bool $domDocumentHasBeenChanged = false;

public function transform(DOMDocument $domDocument): bool
{
$xpath = new DOMXPath($domDocument);

/** @var DOMNodeList<DOMElement> $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'
<T3DataStructure>
<ROOT>
<sheetTitle>aTitle</sheetTitle>
<type>array</type>
<el>
<some_column>
<title>foo</title>
<config>
<eval>trim,required</eval>
</config>
</some_column>
</el>
</ROOT>
</T3DataStructure>
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
<T3DataStructure>
<ROOT>
<sheetTitle>aTitle</sheetTitle>
<type>array</type>
<el>
<some_column>
<title>foo</title>
<config>
<eval>trim</eval>
<required>1</required>
</config>
</some_column>
</el>
</ROOT>
</T3DataStructure>
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;
}
}
1 change: 1 addition & 0 deletions src/Rector/v12/v0/tca/MigrateRequiredFlagRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>sheetTitle</sheetTitle>
<type>array</type>
<el>
<settings.fieldContainsEvalRequired>
<config>
<type>input</type>
<eval>required</eval>
</config>
</settings.fieldContainsEvalRequired>
<settings.fieldContainsEvalTrimRequired>
<config>
<type>input</type>
<eval>trim,required</eval>
</config>
</settings.fieldContainsEvalTrimRequired>
<settings.fieldDoesNotContainEvalWithRequire>
<config>
<type>input</type>
<eval>trim</eval>
</config>
</settings.fieldDoesNotContainEvalWithRequire>
<settings.fieldDoesNotContainEval>
<config>
<type>input</type>
</config>
</settings.fieldDoesNotContainEval>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
-----
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>sheetTitle</sheetTitle>
<type>array</type>
<el>
<settings.fieldContainsEvalRequired>
<config>
<type>input</type>
<required>1</required></config>
</settings.fieldContainsEvalRequired>
<settings.fieldContainsEvalTrimRequired>
<config>
<type>input</type>
<eval>trim</eval>
<required>1</required></config>
</settings.fieldContainsEvalTrimRequired>
<settings.fieldDoesNotContainEvalWithRequire>
<config>
<type>input</type>
<eval>trim</eval>
</config>
</settings.fieldDoesNotContainEvalWithRequire>
<settings.fieldDoesNotContainEval>
<config>
<type>input</type>
</config>
</settings.fieldDoesNotContainEval>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\flexform\MigrateRequiredFlagFlexFormRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class MigrateRequiredFlagFlexFormRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

/**
* @return Iterator<array<string>>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture', '*.xml.inc');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Ssch\TYPO3Rector\Rector\v12\v0\flexform\MigrateRequiredFlagFlexFormRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->import(__DIR__ . '/../../../../../../../config/config_test.php');
$rectorConfig->rule(MigrateRequiredFlagFlexFormRector::class);
};

0 comments on commit 3d1b678

Please sign in to comment.