diff --git a/config/v12/flexform-123.php b/config/v12/flexform-123.php
new file mode 100644
index 000000000..6a8e6f802
--- /dev/null
+++ b/config/v12/flexform-123.php
@@ -0,0 +1,10 @@
+rule(MigrateItemsToIndexedArrayKeysForFlexFormItemsRector::class);
+};
diff --git a/src/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector.php b/src/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector.php
new file mode 100644
index 000000000..4fc220eb3
--- /dev/null
+++ b/src/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector.php
@@ -0,0 +1,202 @@
+ $elements */
+ $elements = $xpath->query('//config');
+
+ if ($elements->count() === 0) {
+ return false;
+ }
+
+ foreach ($elements as $element) {
+ /** @var DOMElement $element */
+ $type = $element->getElementsByTagName('type')
+ ->item(0);
+
+ if (! $type instanceof DOMElement) {
+ continue;
+ }
+
+ if ($type->textContent !== 'select' && $type->textContent !== 'radio' && $type->textContent !== 'check') {
+ continue;
+ }
+
+ $items = $element->getElementsByTagName('items')
+ ->item(0);
+
+ if (! $items instanceof DOMElement) {
+ continue;
+ }
+
+ $array_filter = [];
+ foreach ($items->childNodes as $item) {
+ if ($item instanceof DOMElement && $item->nodeName === 'numIndex') {
+ $array_filter[] = $item;
+ }
+ }
+
+ // These are the main numIndex items
+ $numIndexes = $array_filter;
+
+ if ($numIndexes === []) {
+ continue;
+ }
+
+ foreach ($numIndexes as $item) {
+ /** @var DOMElement $item */
+
+ $numIndexes = $item->getElementsByTagName('numIndex');
+ $label = $numIndexes->item(0);
+ $value = $numIndexes->item(1);
+ $icon = $numIndexes->item(2);
+ $group = $numIndexes->item(3);
+ $description = $numIndexes->item(4);
+ if (! $label instanceof DOMElement) {
+ continue;
+ }
+
+ $hasChanged = true;
+ $this->changeTagName($label, 'label');
+
+ if ($type->textContent !== 'check') {
+ if (! $value instanceof DOMElement) {
+ continue;
+ }
+
+ $hasChanged = true;
+ $this->changeTagName($value, 'value');
+ }
+
+ if ($type->textContent === 'select') {
+ if (! $icon instanceof DOMElement) {
+ continue;
+ }
+
+ $hasChanged = true;
+ $this->changeTagName($icon, 'icon');
+
+ if (! $group instanceof DOMElement) {
+ continue;
+ }
+
+ $hasChanged = true;
+ $this->changeTagName($group, 'group');
+
+ if (! $description instanceof DOMElement) {
+ continue;
+ }
+
+ $hasChanged = true;
+ $this->changeTagName($description, 'description');
+ }
+ }
+ }
+
+ return $hasChanged;
+ }
+
+ /**
+ * @codeCoverageIgnore
+ */
+ public function getRuleDefinition(): RuleDefinition
+ {
+ return new RuleDefinition(
+ 'Migrates indexed item array keys to associative for type select, radio and check in FlexForms. This Rector Rule is sponsored by UDG Rhein-Main GmbH',
+ [
+ new CodeSample(
+ <<<'CODE_SAMPLE'
+
+
+ field description
+
+ select
+ selectSingle
+
+
+ Label 1
+ value1
+
+
+ Label 2
+ value2
+
+
+
+
+CODE_SAMPLE
+ ,
+ <<<'CODE_SAMPLE'
+
+
+ field description
+
+ select
+ selectSingle
+
+
+
+ value1
+
+
+
+ value2
+
+
+
+
+CODE_SAMPLE
+ ),
+ ]
+ );
+ }
+
+ private function changeTagName(DOMElement $node, string $name): void
+ {
+ $childNodes = [];
+ foreach ($node->childNodes as $child) {
+ $childNodes[] = $child;
+ }
+
+ if (! $node->ownerDocument instanceof DOMDocument) {
+ return;
+ }
+
+ $newNode = $node->ownerDocument->createElement($name);
+ foreach ($childNodes as $child) {
+ $child2 = $node->ownerDocument->importNode($child, false);
+ $newNode->appendChild($child2);
+ }
+
+ if (! $node->parentNode instanceof DOMNode) {
+ return;
+ }
+
+ $node->parentNode->replaceChild($newNode, $node);
+ }
+}
diff --git a/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture.xml.inc b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture.xml.inc
new file mode 100644
index 000000000..bd0b95199
--- /dev/null
+++ b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture.xml.inc
@@ -0,0 +1,67 @@
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ select
+ selectSingle
+
+
+ My label
+ 0
+
+
+ My label 1
+ 1
+
+
+
+
+
+
+
+
+
+-----
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ select
+ selectSingle
+
+
+
+ 0
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
diff --git a/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_check.xml.inc b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_check.xml.inc
new file mode 100644
index 000000000..d5da39dab
--- /dev/null
+++ b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_check.xml.inc
@@ -0,0 +1,57 @@
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ check
+
+
+ My label
+ 1
+
+
+
+
+
+
+
+
+
+-----
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ check
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
diff --git a/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_radio.xml.inc b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_radio.xml.inc
new file mode 100644
index 000000000..b1ac070c7
--- /dev/null
+++ b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_radio.xml.inc
@@ -0,0 +1,73 @@
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ radio
+
+
+ My label
+ 0
+
+
+ My label 1
+ 1
+
+
+ My label 2
+ 2
+
+
+
+
+
+
+
+
+
+-----
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ radio
+
+
+
+ 0
+
+
+
+ 1
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
diff --git a/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_with_all_keys.xml.inc b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_with_all_keys.xml.inc
new file mode 100644
index 000000000..81fd46be3
--- /dev/null
+++ b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/Fixture/fixture_with_all_keys.xml.inc
@@ -0,0 +1,79 @@
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ select
+ selectSingle
+
+
+ My label
+ 0
+ my-icon
+ group1
+ My Description
+
+
+ My label 1
+ 1
+ my-icon
+ group1
+ My Description
+
+
+
+
+
+
+
+
+
+-----
+
+
+
+
+
+ LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
+
+ array
+
+
+
+
+ select
+ selectSingle
+
+
+
+ 0
+ my-icon
+ group1
+ My Description
+
+
+
+ 1
+ my-icon
+ group1
+ My Description
+
+
+
+
+
+
+
+
+
diff --git a/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/MigrateItemsToIndexedArrayKeysForFlexFormItemsRectorTest.php b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/MigrateItemsToIndexedArrayKeysForFlexFormItemsRectorTest.php
new file mode 100644
index 000000000..52aaf60ce
--- /dev/null
+++ b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/MigrateItemsToIndexedArrayKeysForFlexFormItemsRectorTest.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/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/config/configured_rule.php b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/config/configured_rule.php
new file mode 100644
index 000000000..098a57be9
--- /dev/null
+++ b/tests/Rector/v12/v3/flexform/MigrateItemsToIndexedArrayKeysForFlexFormItemsRector/config/configured_rule.php
@@ -0,0 +1,11 @@
+import(__DIR__ . '/../../../../../../../config/config_test.php');
+ $rectorConfig->rule(MigrateItemsToIndexedArrayKeysForFlexFormItemsRector::class);
+};