[TASK] Streamline select field value handling 78/43278/12
authorAlexander Stehlik <alexander.stehlik@gmail.com>
Mon, 14 Sep 2015 16:26:56 +0000 (18:26 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Tue, 15 Sep 2015 06:38:01 +0000 (08:38 +0200)
The TcaSelectValues form data provider is merged in the
TcaSelectItems provider.

The possible select items are classified in dynamic items that
come from a foreign_table and static items that come from TCA,
PageTS etc.

The value for single item select fields (the default) will not
be processed because the handling of invalid values will currently
be done by the select field element renderer.

If the values from a multi value select field come from statically
defined items (e.g. items directly added in the TCA) the value will
always be added to the list of selected values.

If the values comes from dynamic select items from a database
relation the select values will only be added when they were
validated by the RelationHandler.

Finally the selected values are parsed by array_unique to prevent
duplicate entries.

Resolves: #69742
Relates: #69755
Relates: #69761
Releases: master
Change-Id: I4dca24b26c36ae91dc527edcd900b352f705f5c4
Reviewed-on: http://review.typo3.org/43278
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectValues.php [deleted file]
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectItemsTest.php
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectValuesTest.php [deleted file]
typo3/sysext/core/Configuration/DefaultConfiguration.php

index b9e142b..1bc9f2e 100644 (file)
@@ -21,6 +21,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\Utility\IconUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Database\RelationHandler;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
@@ -47,7 +48,6 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
 
                $table = $result['tableName'];
 
-               $newColumns = $result['processedTca']['columns'];
                foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
                        if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'select') {
                                continue;
@@ -55,7 +55,7 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
 
                        // Sanitize incoming item array
                        if (!is_array($fieldConfig['config']['items'])) {
-                               $fieldConfig['config']['items'] = array();
+                               $fieldConfig['config']['items'] = [];
                        }
                        foreach ($fieldConfig['config']['items'] as $item) {
                                if (!is_array($item)) {
@@ -69,7 +69,11 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                        $fieldConfig['config']['items'] = $this->addItemsFromPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
                        $fieldConfig['config']['items'] = $this->addItemsFromSpecial($result, $fieldName, $fieldConfig['config']['items']);
                        $fieldConfig['config']['items'] = $this->addItemsFromFolder($result, $fieldName, $fieldConfig['config']['items']);
+                       $staticItems = $fieldConfig['config']['items'];
+
                        $fieldConfig['config']['items'] = $this->addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']);
+                       $dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems);
+
                        $fieldConfig['config']['items'] = $this->removeItemsByKeepItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
                        $fieldConfig['config']['items'] = $this->removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
                        $fieldConfig['config']['items'] = $this->removeItemsByUserLanguageFieldRestriction($result, $fieldName, $fieldConfig['config']['items']);
@@ -84,8 +88,11 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                        }
 
                        // Translate labels
-                       $items = array();
-                       foreach ($fieldConfig['config']['items'] as $item) {
+                       $staticValues = [];
+                       foreach ($fieldConfig['config']['items'] as $key => $item) {
+                               if (!isset($dynamicItems[$key])) {
+                                       $staticValues[$item[1]] = $item;
+                               }
                                if (isset($result['pageTsConfigMerged']['TCEFORM.'][$table . '.'][$fieldName . '.']['altLabels.'][$item[1]])
                                        && !empty($result['pageTsConfigMerged']['TCEFORM.'][$table . '.'][$fieldName . '.']['altLabels.'][$item[1]])
                                ) {
@@ -96,15 +103,20 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                                $value = strlen((string)$item[1]) > 0 ? $item[1] : '';
                                $icon = $item[2] ?: NULL;
                                $helpText = $item[3] ?: NULL;
-                               $items[] = array($label, $value, $icon, $helpText);
+                               $fieldConfig['config']['items'][$key] = [
+                                       $label,
+                                       $value,
+                                       $icon,
+                                       $helpText
+                               ];
                        }
-                       $fieldConfig['config']['items'] = $items;
+                       // Keys may contain table names, so a numeric array is created
+                       $fieldConfig['config']['items'] = array_values($fieldConfig['config']['items']);
 
-                       $newColumns[$fieldName] = $fieldConfig;
+                       $result['processedTca']['columns'][$fieldName] = $fieldConfig;
+                       $result['databaseRow'][$fieldName] = $this->processSelectFieldValue($result, $fieldName, $staticValues);
                }
 
-               $result['processedTca']['columns'] = $newColumns;
-
                return $result;
        }
 
@@ -469,15 +481,13 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                        $result['pageTsConfigMerged']['TCEFORM.'][$table . '.'][$fieldName . '.']['removeItems'],
                        TRUE
                );
-               $newItems = [];
-               foreach ($items as $itemValues) {
+               foreach ($items as $key => $itemValues) {
                        if (in_array($itemValues[1], $removeItems)) {
-                               continue;
+                               unset($items[$key]);
                        }
-                       $newItems[] = $itemValues;
                }
 
-               return $newItems;
+               return $items;
        }
 
        /**
@@ -497,13 +507,13 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                }
 
                $backendUser = $this->getBackendUser();
-               $newItems = [];
-               foreach ($items as $itemValues) {
-                       if ($backendUser->checkLanguageAccess($itemValues[1])) {
-                               $newItems[] = $itemValues;
+               foreach ($items as $key => $itemValues) {
+                       if (!$backendUser->checkLanguageAccess($itemValues[1])) {
+                               unset($items[$key]);
                        }
                }
-               return $newItems;
+
+               return $items;
        }
 
        /**
@@ -524,14 +534,14 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
 
                $backendUser = $this->getBackendUser();
                $authMode = $result['processedTca']['columns'][$fieldName]['config']['authMode'];
-               $newItems = [];
-               foreach ($items as $itemValues) {
+               foreach ($items as $key => $itemValues) {
                        // @todo: checkAuthMode() uses $GLOBAL access for "individual" authMode - get rid of this
-                       if ($backendUser->checkAuthMode($result['tableName'], $fieldName, $itemValues[1], $authMode)) {
-                               $newItems[] = $itemValues;
+                       if (!$backendUser->checkAuthMode($result['tableName'], $fieldName, $itemValues[1], $authMode)) {
+                               unset($items[$key]);
                        }
                }
-               return $newItems;
+
+               return $items;
        }
 
        /**
@@ -552,14 +562,14 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                        return $items;
                }
 
-               $newItems = [];
                $allowedPageTypes = $backendUser->groupData['pagetypes_select'];
-               foreach ($items as $itemValues) {
-                       if (GeneralUtility::inList($allowedPageTypes, $itemValues[1])) {
-                               $newItems[] = $itemValues;
+               foreach ($items as $key => $itemValues) {
+                       if (!GeneralUtility::inList($allowedPageTypes, $itemValues[1])) {
+                               unset($items[$key]);
                        }
                }
-               return $newItems;
+
+               return $items;
        }
 
        /**
@@ -961,6 +971,95 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
        }
 
        /**
+        * Validate and sanitize database row values of the select field with the given name.
+        * Creates an array out of databaseRow[selectField] values.
+        *
+        * @param array $result The current result array.
+        * @param string $fieldName Name of the current select field.
+        * @param array $staticValues Array with statically defined items, item value is used as array key.
+        * @return array
+        */
+       protected function processSelectFieldValue(array $result, $fieldName, array $staticValues) {
+               $fieldConfig = $result['processedTca']['columns'][$fieldName];
+
+               // For single select fields we just keep the current value because the renderer
+               // will take care of showing the "Invalid value" text.
+               // @todo: move handling of invalid values to this data provider.
+               if (!isset($fieldConfig['config']['maxitems']) || (int)$fieldConfig['config']['maxitems'] <= 1) {
+                       return array($result['databaseRow'][$fieldName]);
+               }
+
+               $currentDatabaseValues = array_key_exists($fieldName, $result['databaseRow']) ? $result['databaseRow'][$fieldName] : '';
+               $currentDatabaseValuesArray = GeneralUtility::trimExplode(',', $currentDatabaseValues);
+               $newDatabaseValueArray = [];
+
+               // Add all values that were defined by static methods and do not come from the relation
+               // e.g. TCA, TSconfig, itemProcFunc etc.
+               foreach ($currentDatabaseValuesArray as $value) {
+                       if (isset($staticValues[$value])) {
+                               $newDatabaseValueArray[] = $value;
+                       }
+               }
+
+               if (isset($fieldConfig['config']['foreign_table']) && !empty($fieldConfig['config']['foreign_table'])) {
+                       /** @var RelationHandler $relationHandler */
+                       $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
+                       $relationHandler->registerNonTableValues = !empty($fieldConfig['config']['allowNonIdValues']);
+                       if (isset($fieldConfig['config']['MM']) && !empty($fieldConfig['config']['MM'])) {
+                               // MM relation
+                               $relationHandler->start(
+                                       $currentDatabaseValues,
+                                       $fieldConfig['config']['foreign_table'],
+                                       $fieldConfig['config']['MM'],
+                                       $result['databaseRow']['uid'],
+                                       $result['tableName'],
+                                       $fieldConfig['config']
+                               );
+                       } else {
+                               // Non MM relation
+                               // If not dealing with MM relations, use default live uid, not versioned uid for record relations
+                               $relationHandler->start(
+                                       $currentDatabaseValues,
+                                       $fieldConfig['config']['foreign_table'],
+                                       '',
+                                       $this->getLiveUid($result),
+                                       $result['tableName'],
+                                       $fieldConfig['config']
+                               );
+                       }
+                       $newDatabaseValueArray = array_merge($newDatabaseValueArray, $relationHandler->getValueArray());
+               }
+
+               return array_unique($newDatabaseValueArray);
+       }
+
+       /**
+        * Gets the record uid of the live default record. If already
+        * pointing to the live record, the submitted record uid is returned.
+        *
+        * @param array $result Result array
+        * @return int
+        * @throws \UnexpectedValueException
+        */
+       protected function getLiveUid(array $result) {
+               $table = $result['tableName'];
+               $row = $result['databaseRow'];
+               $uid = $row['uid'];
+               if (!empty($result['processedTca']['ctrl']['versioningWS'])
+                       && $result['pid'] === -1
+               ) {
+                       if (empty($row['t3ver_oid'])) {
+                               throw new \UnexpectedValueException(
+                                       'No t3ver_oid found for record ' . $row['uid'] . ' on table ' . $table,
+                                       1440066481
+                               );
+                       }
+                       $uid = $row['t3ver_oid'];
+               }
+               return $uid;
+       }
+
+       /**
         * @return LanguageService
         */
        protected function getLanguageService() {
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectValues.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectValues.php
deleted file mode 100644 (file)
index 6714fcb..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Form\FormDataProvider;
-
-/*
- * 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!
- */
-
-use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
-use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Database\RelationHandler;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * Handle "databaseRow" select values
- */
-class TcaSelectValues implements FormDataProviderInterface {
-
-       /**
-        * Validate and sanitize database row values of select elements
-        * Creates an array out of databaseRow[selectField] values.
-        *
-        * @param array $result
-        * @return array
-        * @todo: It might be better to merge this one with TcaSelectItems again. For instance, the validation for
-        * @todo: == 0 or == 1 below could be done between the "plain" processing methods of TcaSelectItems and before
-        * @todo: the db fetching methods and would be more solid this way.
-        */
-       public function addData(array $result) {
-               foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
-                       if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'select') {
-                               continue;
-                       }
-                       $currentDatabaseValues = array_key_exists($fieldName, $result['databaseRow']) ? $result['databaseRow'][$fieldName] : '';
-                       $currentDatabaseValuesArray = GeneralUtility::trimExplode(',', $currentDatabaseValues);
-                       $newDatabaseValueArray = array();
-                       if (isset($fieldConfig['config']['foreign_table']) && !empty($fieldConfig['config']['foreign_table'])
-                               && isset($fieldConfig['config']['MM']) && !empty($fieldConfig['config']['MM'])
-                       ) {
-                               // MM relation
-                               /** @var RelationHandler $relationHandler */
-                               $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
-                               $relationHandler->registerNonTableValues = !empty($fieldConfig['config']['allowNonIdValues']);
-                               $relationHandler->start(
-                                       $currentDatabaseValues,
-                                       $fieldConfig['config']['foreign_table'],
-                                       $fieldConfig['config']['MM'],
-                                       $result['databaseRow']['uid'],
-                                       $result['tableName'],
-                                       $fieldConfig['config']
-                               );
-                               $newDatabaseValueArray = $relationHandler->getValueArray();
-                       } elseif (isset($fieldConfig['config']['foreign_table']) && !empty($fieldConfig['config']['foreign_table'])) {
-                               // Non MM relation
-                               // If not dealing with MM relations, use default live uid, not versioned uid for record relations
-                               $uid = $this->getLiveUid($result);
-                               /** @var RelationHandler $relationHandler */
-                               $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
-                               $relationHandler->registerNonTableValues = !empty($fieldConfig['config']['allowNonIdValues']);
-                               $relationHandler->start(
-                                       $currentDatabaseValues,
-                                       $fieldConfig['config']['foreign_table'],
-                                       '',
-                                       $uid,
-                                       $result['tableName'],
-                                       $fieldConfig['config']
-                               );
-                               $connectedUidsFromRelationHandler = $relationHandler->getValueArray();
-                               foreach ($currentDatabaseValuesArray as $aCurrentDatabaseValue) {
-                                       $aCurrentDatabaseValue = (int)$aCurrentDatabaseValue;
-                                       if (in_array($aCurrentDatabaseValue, $connectedUidsFromRelationHandler)) {
-                                               $newDatabaseValueArray[] = $aCurrentDatabaseValue;
-                                       }
-                                       // Values 0 and -1 can not come from db relations but may be set as default additional items. Keep them.
-                                       // Used for instance in tt_content sys_language_uid
-                                       // @todo: Test missing for this case
-                                       if ($aCurrentDatabaseValue == '0' || $aCurrentDatabaseValue == '-1') {
-                                               $newDatabaseValueArray[] = $aCurrentDatabaseValue;
-                                       }
-                               }
-                       } else {
-                               $newDatabaseValueArray = $currentDatabaseValuesArray;
-                       }
-                       $result['databaseRow'][$fieldName] = $newDatabaseValueArray;
-               }
-
-               return $result;
-       }
-
-       /**
-        * Gets the record uid of the live default record. If already
-        * pointing to the live record, the submitted record uid is returned.
-        *
-        * @param array $result Result array
-        * @return int
-        * @throws \UnexpectedValueException
-        */
-       protected function getLiveUid(array $result) {
-               $table = $result['tableName'];
-               $row = $result['databaseRow'];
-               $uid = $row['uid'];
-               if (!empty($result['processedTca']['ctrl']['versioningWS'])
-                       && $result['pid'] === -1
-               ) {
-                       if (empty($row['t3ver_oid'])) {
-                               throw new \UnexpectedValueException(
-                                       'No t3ver_oid found for record ' . $row['uid'] . ' on table ' . $table,
-                                       1440066481
-                               );
-                       }
-                       $uid = $row['t3ver_oid'];
-               }
-               return $uid;
-       }
-
-}
index bba7241..7168431 100644 (file)
@@ -20,6 +20,7 @@ use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
 use TYPO3\CMS\Backend\Module\ModuleLoader;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Database\RelationHandler;
 use TYPO3\CMS\Core\Tests\UnitTestCase;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
@@ -42,7 +43,7 @@ class TcaSelectItemsTest extends UnitTestCase {
        /**
         * @var array A backup of registered singleton instances
         */
-       protected $singletonInstances = array();
+       protected $singletonInstances = [];
 
        public function setUp() {
                $this->singletonInstances = GeneralUtility::getSingletonInstances();
@@ -124,6 +125,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataTranslatesItemLabels() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -152,6 +156,8 @@ class TcaSelectItemsTest extends UnitTestCase {
                $expected['processedTca']['columns']['aField']['config']['items'][0][2] = NULL;
                $expected['processedTca']['columns']['aField']['config']['items'][0][3] = NULL;
 
+               $expected['databaseRow']['aField'] = ['aValue'];
+
                $this->assertSame($expected, $this->subject->addData($input));
        }
 
@@ -160,6 +166,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataKeepsIconFromItem() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -185,6 +194,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->sL(Argument::cetera())->willReturnArgument(0);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
 
                $this->assertSame($expected, $this->subject->addData($input));
        }
@@ -200,7 +210,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                                        'aField' => [
                                                'config' => [
                                                        'type' => 'select',
-                                                       'special' => 'anUnkownValue',
+                                                       'special' => 'anUnknownValue',
                                                ],
                                        ],
                                ],
@@ -217,6 +227,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataAddsTablesWithSpecialTables() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -251,6 +264,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->loadSingleTableDescription('aTable')->shouldBeCalled();
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                $expected['processedTca']['columns']['aField']['config']['items'] = [
                        0 => [
                                0 => 'aTitle',
@@ -270,6 +284,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataAddsTablesWithSpecialPageTypes() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -277,6 +294,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                                                'config' => [
                                                        'type' => 'select',
                                                        'special' => 'pagetypes',
+                                                       'items' => [],
                                                ],
                                        ],
                                ],
@@ -306,6 +324,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->sL('aLabel')->shouldBeCalled()->willReturnArgument(0);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                $expected['processedTca']['columns']['aField']['config']['items'] = [
                        0 => [
                                0 => 'aLabel',
@@ -1066,13 +1085,13 @@ class TcaSelectItemsTest extends UnitTestCase {
                                0 => 'anImage.gif',
                                1 => 'anImage.gif',
                                2 => '../' . $directory . 'anImage.gif',
-                               3 => null,
+                               3 => NULL,
                        ],
                        1 => [
                                0 => 'subdir/anotherImage.gif',
                                1 => 'subdir/anotherImage.gif',
                                2 => '../' . $directory . 'subdir/anotherImage.gif',
-                               3 => null,
+                               3 => NULL,
                        ],
                ];
 
@@ -1265,7 +1284,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $databaseProphecy->sql_error()->shouldBeCalled()->willReturn(FALSE);
                $databaseProphecy->quoteStr(Argument::cetera())->willReturnArgument(0);
                $databaseProphecy->fullQuoteStr(Argument::cetera())->will(function ($args) {
-                       return '\''. $args[0] . '\'';
+                       return '\'' . $args[0] . '\'';
                });
                $databaseProphecy->sql_fetch_assoc(Argument::cetera())->shouldBeCalled()->willReturn(FALSE);
                $databaseProphecy->sql_free_result(Argument::cetera())->shouldBeCalled()->willReturn(NULL);
@@ -1340,7 +1359,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $databaseProphecy->sql_error()->shouldBeCalled()->willReturn(FALSE);
                $databaseProphecy->quoteStr(Argument::cetera())->willReturnArgument(0);
                $databaseProphecy->fullQuoteStr(Argument::cetera())->will(function ($args) {
-                       return '\''. $args[0] . '\'';
+                       return '\'' . $args[0] . '\'';
                });
                $databaseProphecy->sql_fetch_assoc(Argument::cetera())->shouldBeCalled()->willReturn(FALSE);
                $databaseProphecy->sql_free_result(Argument::cetera())->shouldBeCalled()->willReturn(NULL);
@@ -1355,6 +1374,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataForeignTableQueuesFlashMessageOnDatabaseError() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -1410,6 +1432,8 @@ class TcaSelectItemsTest extends UnitTestCase {
                $flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
+
                $this->assertEquals($expected, $this->subject->addData($input));
        }
 
@@ -1418,6 +1442,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataForeignTableHandlesForegnTableRows() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -1426,6 +1453,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                                                        'type' => 'select',
                                                        'foreign_table' => 'fTable',
                                                        'foreign_table_prefix' => 'aPrefix',
+                                                       'items' => [],
                                                ],
                                        ],
                                ]
@@ -1470,16 +1498,18 @@ class TcaSelectItemsTest extends UnitTestCase {
                                0 => 'aPrefix[LLL:EXT:lang/locallang_core.xlf:labels.no_title]',
                                1 => 1,
                                2 => 'status-status-icon-missing',
-                               3 => null,
+                               3 => NULL,
                        ],
                        1 => [
                                0 => 'aPrefix[LLL:EXT:lang/locallang_core.xlf:labels.no_title]',
                                1 => 2,
                                2 => 'status-status-icon-missing',
-                               3 => null,
+                               3 => NULL,
                        ],
                ];
 
+               $expected['databaseRow']['aField'] = ['aValue'];
+
                $this->assertEquals($expected, $this->subject->addData($input));
        }
 
@@ -1488,6 +1518,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataRemovesItemsByKeepItemsPageTsConfig() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -1527,6 +1560,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->sL(Argument::cetera())->willReturnArgument(0);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
 
                $this->assertEquals($expected, $this->subject->addData($input));
@@ -1537,6 +1571,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataRemovesItemsByRemoveItemsPageTsConfig() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue'
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -1576,6 +1613,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->sL(Argument::cetera())->willReturnArgument(0);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
 
                $this->assertEquals($expected, $this->subject->addData($input));
@@ -1586,6 +1624,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataRemovesItemsByLanguageFieldUserRestriction() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue'
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'ctrl' => [
@@ -1625,6 +1666,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $backendUserProphecy->checkLanguageAccess('remove')->shouldBeCalled()->willReturn(FALSE);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
 
                $this->assertEquals($expected, $this->subject->addData($input));
@@ -1635,6 +1677,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataRemovesItemsByUserAuthModeRestriction() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue'
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -1672,6 +1717,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $backendUserProphecy->checkAuthMode('aTable', 'aField', 'remove', 'explicitAllow')->shouldBeCalled()->willReturn(FALSE);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
 
                $this->assertEquals($expected, $this->subject->addData($input));
@@ -1682,6 +1728,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataKeepsAllPagesDoktypesForAdminUser() {
                $input = [
+                       'databaseRow' => [
+                               'doktype' => 'keep'
+                       ],
                        'tableName' => 'pages',
                        'processedTca' => [
                                'columns' => [
@@ -1713,6 +1762,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $backendUserProphecy->isAdmin()->shouldBeCalled()->willReturn(TRUE);
 
                $expected = $input;
+               $expected['databaseRow']['doktype'] = ['keep'];
 
                $this->assertEquals($expected, $this->subject->addData($input));
        }
@@ -1722,6 +1772,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataKeepsAllowedPageTypesForNonAdminUser() {
                $input = [
+                       'databaseRow' => [
+                               'doktype' => 'keep',
+                       ],
                        'tableName' => 'pages',
                        'processedTca' => [
                                'columns' => [
@@ -1760,6 +1813,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                ];
 
                $expected = $input;
+               $expected['databaseRow']['doktype'] = ['keep'];
                unset($expected['processedTca']['columns']['doktype']['config']['items'][1]);
 
                $this->assertEquals($expected, $this->subject->addData($input));
@@ -1771,7 +1825,9 @@ class TcaSelectItemsTest extends UnitTestCase {
        public function addDataCallsItemsProcFunc() {
                $input = [
                        'tableName' => 'aTable',
-                       'databaseRow' => [],
+                       'databaseRow' => [
+                               'aField' => 'aValue'
+                       ],
                        'processedTca' => [
                                'columns' => [
                                        'aField' => [
@@ -1800,6 +1856,7 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->sL(Argument::cetera())->willReturnArgument(0);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                $expected['processedTca']['columns']['aField']['config'] = [
                        'type' => 'select',
                        'items' => [
@@ -1946,6 +2003,9 @@ class TcaSelectItemsTest extends UnitTestCase {
         */
        public function addDataTranslatesItemLabelsFromPageTsConfig() {
                $input = [
+                       'databaseRow' => [
+                               'aField' => 'aValue',
+                       ],
                        'tableName' => 'aTable',
                        'processedTca' => [
                                'columns' => [
@@ -1985,10 +2045,285 @@ class TcaSelectItemsTest extends UnitTestCase {
                $languageService->sL('labelOverride')->shouldBeCalled()->willReturnArgument(0);
 
                $expected = $input;
+               $expected['databaseRow']['aField'] = ['aValue'];
                $expected['processedTca']['columns']['aField']['config']['items'][0][0] = 'labelOverride';
 
                $this->assertSame($expected, $this->subject->addData($input));
                $this->subject->addData($input);
        }
 
+       /**
+        * @test
+        */
+       public function processSelectFieldValueSetsMmForeignRelationValues() {
+               $GLOBALS['TCA']['foreignTable'] = [];
+
+               /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
+               $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
+               $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
+
+               /** @var DatabaseConnection|ObjectProphecy $database */
+               $database = $this->prophesize(DatabaseConnection::class);
+               $GLOBALS['TYPO3_DB'] = $database->reveal();
+
+               $input = [
+                       'tableName' => 'aTable',
+                       'databaseRow' => [
+                               'uid' => 42,
+                               // Two connected rows
+                               'aField' => 2,
+                       ],
+                       'processedTca' => [
+                               'columns' => [
+                                       'aField' => [
+                                               'config' => [
+                                                       'type' => 'select',
+                                                       'maxitems' => 999,
+                                                       'foreign_table' => 'foreignTable',
+                                                       'MM' => 'aTable_foreignTable_mm',
+                                                       'items' => [],
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+               $fieldConfig = $input['processedTca']['columns']['aField']['config'];
+               /** @var RelationHandler|ObjectProphecy $relationHandlerProphecy */
+               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
+               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
+
+               $relationHandlerUids = [
+                       23,
+                       24
+               ];
+
+               $relationHandlerProphecy->start(2, 'foreignTable', 'aTable_foreignTable_mm', 42, 'aTable', $fieldConfig)->shouldBeCalled();
+               $relationHandlerProphecy->getValueArray()->shouldBeCalled()->willReturn($relationHandlerUids);
+
+               $expected = $input;
+               $expected['databaseRow']['aField'] = $relationHandlerUids;
+
+               $this->assertEquals($expected, $this->subject->addData($input));
+       }
+
+       /**
+        * @test
+        */
+       public function processSelectFieldValueSetsForeignRelationValues() {
+               $GLOBALS['TCA']['foreignTable'] = [];
+
+               /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
+               $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
+               $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
+
+               /** @var DatabaseConnection|ObjectProphecy $database */
+               $database = $this->prophesize(DatabaseConnection::class);
+               $GLOBALS['TYPO3_DB'] = $database->reveal();
+
+               $input = [
+                       'tableName' => 'aTable',
+                       'databaseRow' => [
+                               'uid' => 42,
+                               // Two connected rows
+                               'aField' => '22,23,24,25',
+                       ],
+                       'processedTca' => [
+                               'columns' => [
+                                       'aField' => [
+                                               'config' => [
+                                                       'type' => 'select',
+                                                       'maxitems' => 999,
+                                                       'foreign_table' => 'foreignTable',
+                                                       'items' => [],
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+               $fieldConfig = $input['processedTca']['columns']['aField']['config'];
+               /** @var RelationHandler|ObjectProphecy $relationHandlerProphecy */
+               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
+               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
+
+               $relationHandlerUids = [
+                       23,
+                       24
+               ];
+
+               $relationHandlerProphecy->start('22,23,24,25', 'foreignTable', '', 42, 'aTable', $fieldConfig)->shouldBeCalled();
+               $relationHandlerProphecy->getValueArray()->shouldBeCalled()->willReturn($relationHandlerUids);
+
+               $expected = $input;
+               $expected['databaseRow']['aField'] = $relationHandlerUids;
+
+               $this->assertEquals($expected, $this->subject->addData($input));
+       }
+
+       /**
+        * @test
+        */
+       public function processSelectFieldValueRemovesInvalidDynamicValues() {
+               $languageService = $this->prophesize(LanguageService::class);
+               $GLOBALS['LANG'] = $languageService->reveal();
+               $languageService->sL(Argument::cetera())->willReturnArgument(0);
+
+               $GLOBALS['TCA']['foreignTable'] = [];
+
+               /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
+               $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
+               $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
+
+               /** @var DatabaseConnection|ObjectProphecy $database */
+               $database = $this->prophesize(DatabaseConnection::class);
+               $GLOBALS['TYPO3_DB'] = $database->reveal();
+
+               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
+               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
+               $relationHandlerProphecy->start(Argument::cetera())->shouldBeCalled();
+               $relationHandlerProphecy->getValueArray(Argument::cetera())->shouldBeCalled()->willReturn([1]);
+
+               $input = [
+                       'tableName' => 'aTable',
+                       'databaseRow' => [
+                               'aField' => '1,2,bar,foo',
+                       ],
+                       'processedTca' => [
+                               'columns' => [
+                                       'aField' => [
+                                               'config' => [
+                                                       'type' => 'select',
+                                                       'foreign_table' => 'foreignTable',
+                                                       'maxitems' => 999,
+                                                       'items' => [
+                                                               ['foo', 'foo', NULL, NULL],
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+
+               $expected = $input;
+               $expected['databaseRow']['aField'] = ['foo', 1];
+
+               $this->assertEquals($expected, $this->subject->addData($input));
+       }
+
+       /**
+        * @test
+        */
+       public function processSelectFieldValueKeepsValuesFromStaticItems() {
+               $languageService = $this->prophesize(LanguageService::class);
+               $GLOBALS['LANG'] = $languageService->reveal();
+               $languageService->sL(Argument::cetera())->willReturnArgument(0);
+
+               $input = [
+                       'tableName' => 'aTable',
+                       'databaseRow' => [
+                               'aField' => 'foo,bar',
+                       ],
+                       'processedTca' => [
+                               'columns' => [
+                                       'aField' => [
+                                               'config' => [
+                                                       'type' => 'select',
+                                                       'maxitems' => 999,
+                                                       'items' => [
+                                                               ['foo', 'foo', NULL, NULL],
+                                                               ['bar', 'bar', NULL, NULL],
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+
+               $expected = $input;
+               $expected['databaseRow']['aField'] = [
+                       'foo',
+                       'bar'
+               ];
+
+               $this->assertEquals($expected, $this->subject->addData($input));
+       }
+
+       /**
+        * @test
+        */
+       public function processSelectFieldValueDoesNotCallRelationManagerForStaticOnlyItems() {
+               $languageService = $this->prophesize(LanguageService::class);
+               $GLOBALS['LANG'] = $languageService->reveal();
+               $languageService->sL(Argument::cetera())->willReturnArgument(0);
+
+               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
+               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
+               $relationHandlerProphecy->start(Argument::cetera())->shouldNotBeCalled();
+               $relationHandlerProphecy->getValueArray(Argument::cetera())->shouldNotBeCalled();
+
+               $input = [
+                       'tableName' => 'aTable',
+                       'databaseRow' => [
+                               'aField' => '1,2,bar,foo',
+                       ],
+                       'processedTca' => [
+                               'columns' => [
+                                       'aField' => [
+                                               'config' => [
+                                                       'type' => 'select',
+                                                       'maxitems' => 999,
+                                                       'items' => [
+                                                               ['foo', 'foo', NULL, NULL],
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+
+               $expected = $input;
+               $expected['databaseRow']['aField'] = ['foo'];
+
+               $this->assertEquals($expected, $this->subject->addData($input));
+
+       }
+
+       /**
+        * @test
+        */
+       public function processSelectFieldValueDoesNotTouchValueForSingleSelects() {
+               $languageService = $this->prophesize(LanguageService::class);
+               $GLOBALS['LANG'] = $languageService->reveal();
+               $languageService->sL(Argument::cetera())->willReturnArgument(0);
+
+               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
+               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
+               $relationHandlerProphecy->start(Argument::cetera())->shouldNotBeCalled();
+               $relationHandlerProphecy->getValueArray(Argument::cetera())->shouldNotBeCalled();
+
+               $input = [
+                       'tableName' => 'aTable',
+                       'databaseRow' => [
+                               'aField' => '1,2,bar,foo',
+                       ],
+                       'processedTca' => [
+                               'columns' => [
+                                       'aField' => [
+                                               'config' => [
+                                                       'type' => 'select',
+                                                       'maxitems' => 1,
+                                                       'items' => [
+                                                               ['foo', 'foo', NULL, NULL],
+                                                       ],
+                                               ],
+                                       ],
+                               ],
+                       ],
+               ];
+
+               $expected = $input;
+               $expected['databaseRow']['aField'] = ['1,2,bar,foo'];
+
+               $this->assertEquals($expected, $this->subject->addData($input));
+
+       }
 }
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectValuesTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectValuesTest.php
deleted file mode 100644 (file)
index dd604f6..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
-
-/*
- * 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!
- */
-
-use Prophecy\Argument;
-use Prophecy\Prophecy\ObjectProphecy;
-use TYPO3\CMS\Core\Database\RelationHandler;
-use TYPO3\CMS\Core\Tests\UnitTestCase;
-use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectValues;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * Test case
- */
-class TcaSelectValuesTest extends UnitTestCase {
-
-       /**
-        * @var TcaSelectValues
-        */
-       protected $subject;
-
-       /**
-        * @var array A backup of registered singleton instances
-        */
-       protected $singletonInstances = array();
-
-       public function setUp() {
-               $this->subject = new TcaSelectValues();
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsMmForeignRelationValues() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'uid' => 42,
-                               // Two connected rows
-                               'aField' => 2,
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'select',
-                                                       'foreign_table' => 'foreignTable',
-                                                       'MM' => 'aTable_foreignTable_mm',
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-               $fieldConfig = $input['processedTca']['columns']['aField']['config'];
-               /** @var RelationHandler|ObjectProphecy $relationHandlerProphecy */
-               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
-               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
-
-               $relationHandlerUids = [
-                       23,
-                       24
-               ];
-
-               $relationHandlerProphecy->start(2, 'foreignTable', 'aTable_foreignTable_mm', 42, 'aTable', $fieldConfig)->shouldBeCalled();
-               $relationHandlerProphecy->getValueArray()->shouldBeCalled()->willReturn($relationHandlerUids);
-
-               $expected = $input;
-               $expected['databaseRow']['aField'] = $relationHandlerUids;
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsForeignRelationValues() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'uid' => 42,
-                               // Two connected rows
-                               'aField' => '22,23,24,25',
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'select',
-                                                       'foreign_table' => 'foreignTable',
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-               $fieldConfig = $input['processedTca']['columns']['aField']['config'];
-               /** @var RelationHandler|ObjectProphecy $relationHandlerProphecy */
-               $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
-               GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
-
-               $relationHandlerUids = [
-                       23,
-                       24
-               ];
-
-               $relationHandlerProphecy->start('22,23,24,25', 'foreignTable', '', 42, 'aTable', $fieldConfig)->shouldBeCalled();
-               $relationHandlerProphecy->getValueArray()->shouldBeCalled()->willReturn($relationHandlerUids);
-
-               $expected = $input;
-               $expected['databaseRow']['aField'] = $relationHandlerUids;
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-       /**
-        * @test
-        */
-       public function addDataSetsValues() {
-               $input = [
-                       'tableName' => 'aTable',
-                       'databaseRow' => [
-                               'uid' => 42,
-                               // Two connected rows
-                               'aField' => 'foo,bar',
-                       ],
-                       'processedTca' => [
-                               'columns' => [
-                                       'aField' => [
-                                               'config' => [
-                                                       'type' => 'select',
-                                               ],
-                                       ],
-                               ],
-                       ],
-               ];
-
-               $expected = $input;
-               $expected['databaseRow']['aField'] = [
-                       'foo',
-                       'bar'
-               ];
-
-               $this->assertEquals($expected, $this->subject->addData($input));
-       }
-
-}
index 0b70415..35dae43 100644 (file)
@@ -431,18 +431,13 @@ return array(
                                                        \TYPO3\CMS\Backend\Form\FormDataProvider\InitializeProcessedTca::class,
                                                        \TYPO3\CMS\Backend\Form\FormDataProvider\TcaTypesShowitem::class,
                                                        \TYPO3\CMS\Backend\Form\FormDataProvider\TcaCheckboxItems::class,
-                                               ),
-                                       ),
-                                       \TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectValues::class => array(
-                                               'depends' => array(
                                                        // GeneralUtility::getFlexFormDS() needs unchanged databaseRow values as string
                                                        \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlex::class,
-                                                       \TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems::class,
                                                ),
                                        ),
                                        \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class => array(
                                                'depends' => array(
-                                                       \TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectValues::class,
+                                                       \TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems::class,
                                                ),
                                        ),
                                ),