[BUGFIX] Notice free TcaSelectItems testing 23/55823/3
authorChristian Kuhn <lolli@schwarzbu.ch>
Tue, 20 Feb 2018 11:41:48 +0000 (12:41 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 20 Feb 2018 13:15:35 +0000 (14:15 +0100)
Making FormEngine data providers notice free is a mixture of
fixing notices in the test subject, and improving test setup:
* It is assumed that stuff like BE_USER and LANG object exists,
  $subject access to these globals which throw notices is not
  fixed, instead the test setup is changed to mock these where
  needed.
* Data provider which have dependencies to other data prodivers
  assume their data is properly set, too. In those cases the
  test setup porperly sets this dependent data.
* Various other "real" notice fixes in test subject and code
  called by the test subject is actually fixed.

Change-Id: I7ae6444dc646ec114c15b2738ef4e30f67f88595
Resolves: #83975
Releases: master
Reviewed-on: https://review.typo3.org/55823
Reviewed-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Tested-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php
typo3/sysext/backend/Classes/Utility/BackendUtility.php
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectItemsTest.php
typo3/sysext/core/Classes/Database/Query/QueryHelper.php
typo3/sysext/core/Classes/Database/RelationHandler.php
typo3/sysext/core/Classes/Utility/GeneralUtility.php

index a299fdb..806e3d9 100644 (file)
@@ -234,7 +234,7 @@ abstract class AbstractItemProvider
                     // Add help text
                     $helpText = [];
                     $languageService->loadSingleTableDescription($excludeArray['table']);
-                    $helpTextArray = $GLOBALS['TCA_DESCR'][$excludeArray['table']]['columns'][$excludeArray['table']];
+                    $helpTextArray = $GLOBALS['TCA_DESCR'][$excludeArray['table']]['columns'][$excludeArray['table']] ?? [];
                     if (!empty($helpTextArray['description'])) {
                         $helpText['description'] = $helpTextArray['description'];
                     }
@@ -255,7 +255,7 @@ abstract class AbstractItemProvider
                 ];
                 // Traverse types:
                 foreach ($theTypes as $tableFieldKey => $theTypeArrays) {
-                    if (is_array($theTypeArrays['items'])) {
+                    if (!empty($theTypeArrays['items'])) {
                         // Add header:
                         $items[] = [
                             $theTypeArrays['tableFieldLabel'],
@@ -326,7 +326,9 @@ abstract class AbstractItemProvider
                 if (is_array($modList)) {
                     foreach ($modList as $theMod) {
                         $moduleLabels = $loadModules->getLabelsForModule($theMod);
-                        list($mainModule, $subModule) = explode('_', $theMod, 2);
+                        $moduleArray = GeneralUtility::trimExplode('_', $theMod, true);
+                        $mainModule = $moduleArray[0] ?? '';
+                        $subModule = $moduleArray[1] ?? '';
                         // Icon:
                         if (!empty($subModule)) {
                             $icon = $loadModules->modules[$mainModule]['sub'][$subModule]['iconIdentifier'];
@@ -443,7 +445,7 @@ abstract class AbstractItemProvider
 
         $foreignTable = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
 
-        if (!is_array($GLOBALS['TCA'][$foreignTable])) {
+        if (!isset($GLOBALS['TCA'][$foreignTable]) || !is_array($GLOBALS['TCA'][$foreignTable])) {
             throw new \UnexpectedValueException(
                 'Field ' . $fieldName . ' of table ' . $result['tableName'] . ' reference to foreign table '
                 . $foreignTable . ', but this table is not defined in TCA',
@@ -491,8 +493,10 @@ abstract class AbstractItemProvider
                 $isReferenceField = false;
                 if (!empty($GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'])) {
                     $iconFieldName = $GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'];
-                    if ($GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'] === 'inline'
-                        && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['foreign_table'] === 'sys_file_reference') {
+                    if (isset($GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'])
+                        && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'] === 'inline'
+                        && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['foreign_table'] === 'sys_file_reference'
+                    ) {
                         $isReferenceField = true;
                     }
                 }
@@ -749,7 +753,7 @@ abstract class AbstractItemProvider
                 && (empty($GLOBALS['TCA'][$table]['ctrl']['rootLevel']) || !empty($GLOBALS['TCA'][$table]['ctrl']['security']['ignoreRootLevelRestriction']))
             ) {
                 foreach ($GLOBALS['TCA'][$table]['columns'] as $field => $_) {
-                    if ($GLOBALS['TCA'][$table]['columns'][$field]['exclude']) {
+                    if (isset($GLOBALS['TCA'][$table]['columns'][$field]['exclude']) && (bool)$GLOBALS['TCA'][$table]['columns'][$field]['exclude']) {
                         // Get human readable names of fields
                         $translatedField = $languageService->sL($GLOBALS['TCA'][$table]['columns'][$field]['label']);
                         // Add entry, key 'labels' needed for sorting
@@ -918,9 +922,9 @@ abstract class AbstractItemProvider
                                         $iMode = 'DENY';
                                         break;
                                     case 'individual':
-                                        if ($iVal[4] === 'EXPL_ALLOW') {
+                                        if (isset($iVal[4]) && $iVal[4] === 'EXPL_ALLOW') {
                                             $iMode = 'ALLOW';
-                                        } elseif ($iVal[4] === 'EXPL_DENY') {
+                                        } elseif (isset($iVal[4]) && $iVal[4] === 'EXPL_DENY') {
                                             $iMode = 'DENY';
                                         }
                                         break;
@@ -1101,12 +1105,16 @@ abstract class AbstractItemProvider
             }
 
             $pageTsConfigId = 0;
-            if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID']) {
+            if (isset($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID'])
+                && $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID']
+            ) {
                 $pageTsConfigId = (int)$result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID'];
             }
 
             $pageTsConfigIdList = 0;
-            if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST']) {
+            if (isset($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST'])
+                && $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST']
+            ) {
                 $pageTsConfigIdList = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST'];
             }
             $pageTsConfigIdListArray = GeneralUtility::trimExplode(',', $pageTsConfigIdList, true);
@@ -1119,7 +1127,9 @@ abstract class AbstractItemProvider
             $pageTsConfigIdList = implode(',', $pageTsConfigIdList);
 
             $pageTsConfigString = '';
-            if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR']) {
+            if (isset($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR'])
+                && $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR']
+            ) {
                 $pageTsConfigString = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR'];
                 $pageTsConfigString = $connection->quote($pageTsConfigString);
             }
@@ -1253,7 +1263,7 @@ abstract class AbstractItemProvider
             $newDatabaseValueArray = array_merge($newDatabaseValueArray, $relationHandler->getValueArray());
         }
 
-        if ($fieldConfig['config']['multiple']) {
+        if ($fieldConfig['config']['multiple'] ?? false) {
             return $newDatabaseValueArray;
         }
         return array_unique($newDatabaseValueArray);
@@ -1286,8 +1296,8 @@ abstract class AbstractItemProvider
                 $label = $languageService->sL(trim($item[0]));
             }
             $value = strlen((string)$item[1]) > 0 ? $item[1] : '';
-            $icon = $item[2] ?: null;
-            $helpText = $item[3] ?: null;
+            $icon = !empty($item[2]) ? $item[2] : null;
+            $helpText = !empty($item[3]) ? $item[3] : null;
             $itemArray[$key] = [
                 $label,
                 $value,
index 11db844..a5a72ec 100644 (file)
@@ -43,7 +43,7 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                 continue;
             }
 
-            $fieldConfig['config']['items'] = $this->sanitizeItemArray($fieldConfig['config']['items'], $table, $fieldName);
+            $fieldConfig['config']['items'] = $this->sanitizeItemArray($fieldConfig['config']['items'] ?? [], $table, $fieldName);
 
             // Resolve "itemsProcFunc"
             if (!empty($fieldConfig['config']['itemsProcFunc'])) {
@@ -52,7 +52,7 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                 unset($fieldConfig['config']['itemsProcFunc']);
             }
 
-            $fieldConfig['config']['maxitems'] = MathUtility::forceIntegerInRange($fieldConfig['config']['maxitems'], 0, 99999);
+            $fieldConfig['config']['maxitems'] = MathUtility::forceIntegerInRange($fieldConfig['config']['maxitems'] ?? 0, 0, 99999);
             if ($fieldConfig['config']['maxitems'] === 0) {
                 $fieldConfig['config']['maxitems'] = 99999;
             }
@@ -124,8 +124,8 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
         // Early return if there are no items or invalid values should not be displayed
         if (empty($fieldConf['config']['items'])
             || $fieldConf['config']['renderType'] !== 'selectSingle'
-            || $result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['disableNoMatchingValueElement']
-            || $fieldConf['config']['disableNoMatchingValueElement']
+            || ($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['disableNoMatchingValueElement'] ?? false)
+            || ($fieldConf['config']['disableNoMatchingValueElement'] ?? false)
         ) {
             return $fieldConf['config']['items'];
         }
index 1ed8f68..b22d3b7 100644 (file)
@@ -1869,11 +1869,11 @@ class BackendUtility
             return $value;
         }
         // Check if table and field is configured
-        if (!is_array($GLOBALS['TCA'][$table]) || !is_array($GLOBALS['TCA'][$table]['columns'][$col])) {
+        if (!isset($GLOBALS['TCA'][$table]['columns'][$col]) || !is_array($GLOBALS['TCA'][$table]['columns'][$col])) {
             return null;
         }
         // Depending on the fields configuration, make a meaningful output value.
-        $theColConf = $GLOBALS['TCA'][$table]['columns'][$col]['config'];
+        $theColConf = $GLOBALS['TCA'][$table]['columns'][$col]['config'] ?? [];
         /*****************
          *HOOK: pre-processing the human readable output from a record
          ****************/
@@ -1884,7 +1884,7 @@ class BackendUtility
 
         $l = '';
         $lang = static::getLanguageService();
-        switch ((string)$theColConf['type']) {
+        switch ((string)($theColConf['type'] ?? '')) {
             case 'radio':
                 $l = self::getLabelFromItemlist($table, $col, $value);
                 $l = $lang->sL($l);
@@ -2225,7 +2225,7 @@ class BackendUtility
             default:
                 if ($defaultPassthrough) {
                     $l = $value;
-                } elseif ($theColConf['MM']) {
+                } elseif (isset($theColConf['MM'])) {
                     $l = 'N/A';
                 } elseif ($value) {
                     $l = GeneralUtility::fixed_lgd_cs(strip_tags($value), 200);
@@ -2310,7 +2310,7 @@ class BackendUtility
         if (isset($GLOBALS['TCA'][$table]['ctrl']['label']) && $GLOBALS['TCA'][$table]['ctrl']['label'] != '') {
             $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['label'];
         }
-        if ($GLOBALS['TCA'][$table]['ctrl']['label_alt']) {
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['label_alt'])) {
             $secondFields = GeneralUtility::trimExplode(',', $GLOBALS['TCA'][$table]['ctrl']['label_alt'], true);
             foreach ($secondFields as $fieldN) {
                 $fields[] = $prefix . $fieldN;
@@ -2322,25 +2322,23 @@ class BackendUtility
             $fields[] = $prefix . 't3ver_wsid';
             $fields[] = $prefix . 't3ver_count';
         }
-        if ($GLOBALS['TCA'][$table]['ctrl']['selicon_field']) {
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['selicon_field'])) {
             $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['selicon_field'];
         }
-        if ($GLOBALS['TCA'][$table]['ctrl']['typeicon_column']) {
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['typeicon_column'])) {
             $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['typeicon_column'];
         }
-        if (is_array($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'])) {
-            if ($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled']) {
-                $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
-            }
-            if ($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime']) {
-                $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'];
-            }
-            if ($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime']) {
-                $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'];
-            }
-            if ($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group']) {
-                $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'];
-            }
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'])) {
+            $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['disabled'];
+        }
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'])) {
+            $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['starttime'];
+        }
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'])) {
+            $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['endtime'];
+        }
+        if (!empty($GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'])) {
+            $fields[] = $prefix . $GLOBALS['TCA'][$table]['ctrl']['enablecolumns']['fe_group'];
         }
         return implode(',', array_unique($fields));
     }
index e760c5d..42da7bb 100644 (file)
@@ -33,23 +33,14 @@ use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 /**
  * Test case
  */
-class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
+class TcaSelectItemsTest extends UnitTestCase
 {
     /**
-     * Subject is not notice free, disable E_NOTICES
-     */
-    protected static $suppressNotices = true;
-
-    /**
-     * @var TcaSelectItems|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $subject;
-
-    /**
      * @var array A backup of registered singleton instances
      */
     protected $singletonInstances = [];
@@ -57,7 +48,15 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     protected function setUp()
     {
         $this->singletonInstances = GeneralUtility::getSingletonInstances();
-        $this->subject = new TcaSelectItems();
+
+        // Default LANG prophecy just returns incoming value as label if calling ->sL()
+        $languageServiceProphecy = $this->prophesize(LanguageService::class);
+        $languageServiceProphecy->loadSingleTableDescription(Argument::cetera())->willReturn(null);
+        $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
+        $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
+
+        $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
+        $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
     }
 
     protected function tearDown()
@@ -152,6 +151,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     public function addDataKeepExistingItems()
     {
         $input = [
+            'tableName' => 'aTable',
             'processedTca' => [
                 'columns' => [
                     'aField' => [
@@ -179,12 +179,9 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
                 ],
             ],
         ];
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
 
         $expected = $input;
-        $this->assertSame($expected, $this->subject->addData($input));
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -193,6 +190,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     public function addDataThrowsExceptionIfAnItemIsNotAnArray()
     {
         $input = [
+            'tableName' => 'aTable',
             'processedTca' => [
                 'columns' => [
                     'aField' => [
@@ -211,7 +209,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $this->expectException(\UnexpectedValueException::class);
         $this->expectExceptionCode(1439288036);
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -220,6 +218,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     public function addDataTranslatesItemLabels()
     {
         $input = [
+            'tableName' => 'aTable',
             'databaseRow' => [
                 'aField' => 'aValue',
             ],
@@ -256,7 +255,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $expected['databaseRow']['aField'] = ['aValue'];
 
-        $this->assertSame($expected, $this->subject->addData($input));
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -265,6 +264,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     public function addDataKeepsIconFromItem()
     {
         $input = [
+            'tableName' => 'aTable',
             'databaseRow' => [
                 'aField' => 'aValue',
             ],
@@ -289,15 +289,10 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = ['aValue'];
 
-        $this->assertSame($expected, $this->subject->addData($input));
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -323,7 +318,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $this->expectException(\UnexpectedValueException::class);
         $this->expectExceptionCode(1439298496);
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -385,7 +380,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ]
         ];
 
-        $this->assertSame($expected, $this->subject->addData($input));
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -447,7 +442,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ]
         ];
 
-        $this->assertSame($expected, $this->subject->addData($input));
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -591,13 +586,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         ];
         $GLOBALS['TCA'] = $tca;
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->loadSingleTableDescription(Argument::cetera())->willReturn(null);
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -661,12 +650,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->loadSingleTableDescription(Argument::cetera())->willReturn(null);
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expectedItems = [
             0 => [
                 0 => 'fooTableTitle aFlexFieldTitle dummy',
@@ -682,7 +665,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -753,7 +736,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -824,7 +807,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -916,7 +899,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -1008,7 +991,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -1041,11 +1024,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expectedItems = [
             0 => [
                 0 => 'aLangTitle [42]',
@@ -1055,7 +1033,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -1081,11 +1059,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $GLOBALS['TYPO3_CONF_VARS']['BE']['customPermOptions'] = [
             'aKey' => [
                 'header' => 'aHeader',
@@ -1123,7 +1096,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -1151,11 +1124,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $GLOBALS['TBE_MODULES'] = [];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         /** @var ModuleLoader|ObjectProphecy $moduleLoaderProphecy */
         $moduleLoaderProphecy = $this->prophesize(ModuleLoader::class);
         GeneralUtility::addInstance(ModuleLoader::class, $moduleLoaderProphecy->reveal());
@@ -1186,7 +1154,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $result['processedTca']['columns']['aField']['config']['items'][0][2] = str_replace([CR, LF, TAB], ['', '', ''], $result['processedTca']['columns']['aField']['config']['items'][0][2]);
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
@@ -1216,11 +1184,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         mkdir(PATH_site . $directory);
         $this->testFilesToDelete[] = PATH_site . $directory;
         touch(PATH_site . $directory . 'anImage.gif');
@@ -1243,7 +1206,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $result = $this->subject->addData($input);
+        $result = (new TcaSelectItems)->addData($input);
 
         $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
     }
@@ -1271,7 +1234,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $this->expectException(\RuntimeException::class);
         $this->expectExceptionCode(1479399227);
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -1316,11 +1279,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         $expected['processedTca']['columns']['aField']['config']['items'][1] = [
@@ -1330,7 +1288,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             null,
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -1375,11 +1333,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         $expected['processedTca']['columns']['aField']['config']['items'][1] = [
@@ -1389,7 +1342,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             null,
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -1709,7 +1662,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
         $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -1735,7 +1688,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $this->expectException(\UnexpectedValueException::class);
         $this->expectExceptionCode(1439569743);
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -1745,7 +1698,10 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     {
         $input = [
             'tableName' => 'aTable',
-            'databaseRow' => [],
+            'effectivePid' => 42,
+            'databaseRow' => [
+                'uid' => 23,
+            ],
             'processedTca' => [
                 'columns' => [
                     'aField' => [
@@ -1793,7 +1749,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
         GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal());
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -1803,9 +1759,11 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     {
         $input = [
             'databaseRow' => [
+                'uid' => 23,
                 'aField' => '',
             ],
             'tableName' => 'aTable',
+            'effectivePid' => 42,
             'processedTca' => [
                 'columns' => [
                     'aField' => [
@@ -1836,11 +1794,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
         $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
 
-        /** @var LanguageService|ObjectProphecy $languageServiceProphecy */
-        $languageServiceProphecy = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
-        $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
-
         list($queryBuilderProphet, $connectionPoolProphet) = $this->mockDatabaseConnection();
 
         /** @var Statement|ObjectProphecy $statementProphet */
@@ -1877,7 +1830,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -1887,9 +1840,11 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     {
         $input = [
             'databaseRow' => [
+                'uid' => 5,
                 'aField' => '',
             ],
             'tableName' => 'aTable',
+            'effectivePid' => 42,
             'processedTca' => [
                 'columns' => [
                     'aField' => [
@@ -1907,24 +1862,24 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'rootline' => [],
         ];
 
-        $GLOBALS['TCA']['fTable'] = [];
+        $GLOBALS['TCA']['fTable'] = [
+            'ctrl' => [
+                'label' => 'labelField',
+            ],
+            'columns' => [],
+        ];
 
         /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
         $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
         $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
 
-        /** @var LanguageService|ObjectProphecy $languageServiceProphecy */
-        $languageServiceProphecy = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
-        $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
-
         list($queryBuilderProphet, $connectionPoolProphet) = $this->mockDatabaseConnection();
 
         /** @var Statement|ObjectProphecy $statementProphet */
         $statementProphet = $this->prophesize(Statement::class);
 
-        $queryBuilderProphet->select('fTable.uid')->shouldBeCalled()->willReturn($queryBuilderProphet->reveal());
+        $queryBuilderProphet->select('fTable.uid', 'fTable.labelField')->shouldBeCalled()->willReturn($queryBuilderProphet->reveal());
         $queryBuilderProphet->from('fTable')->shouldBeCalled()->willReturn($queryBuilderProphet->reveal());
         $queryBuilderProphet->from('pages')->shouldBeCalled()->willReturn($queryBuilderProphet->reveal());
         $queryBuilderProphet->where('')->shouldBeCalled()->willReturn($queryBuilderProphet->reveal());
@@ -1944,6 +1899,8 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             }
             return [
                 'uid' => $counter,
+                'pid' => 23,
+                'labelField' => 'aLabel',
                 'aValue' => 'bar,',
             ];
         });
@@ -1966,7 +1923,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $expected['databaseRow']['aField'] = [];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -1976,9 +1933,11 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     {
         $input = [
             'databaseRow' => [
+                'uid' => 5,
                 'aField' => '',
             ],
             'tableName' => 'aTable',
+            'effectivePid' => 42,
             'processedTca' => [
                 'columns' => [
                     'aField' => [
@@ -2011,11 +1970,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
         $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
 
-        /** @var LanguageService|ObjectProphecy $languageServiceProphecy */
-        $languageServiceProphecy = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
-        $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
-
         list($queryBuilderProphet, $connectionPoolProphet) = $this->mockDatabaseConnection();
 
         /** @var Statement|ObjectProphecy $statementProphet */
@@ -2036,6 +1990,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         // Query returns one row, then false on second call
         $foreignTableRowResultOne = [
             'uid' => 1,
+            'pid' => 23,
             'icon' => 'foo.jpg',
         ];
         $statementProphet->fetch()->shouldBeCalled()->willReturn($foreignTableRowResultOne, false);
@@ -2051,7 +2006,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         ];
         $expected['databaseRow']['aField'] = [];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2102,11 +2057,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         unset(
@@ -2114,7 +2064,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             $expected['processedTca']['columns']['aField']['config']['items'][2]
         );
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2161,16 +2111,11 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         $expected['processedTca']['columns']['aField']['config']['items'] = [];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2221,11 +2166,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         $expected['processedTca']['columns']['aField']['config']['items'] = [
@@ -2249,7 +2189,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2302,16 +2242,11 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
         $expected['processedTca']['columns']['aField']['config']['items'] = array_values($expected['processedTca']['columns']['aField']['config']['items']);
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2364,15 +2299,10 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         unset($expected['processedTca']['columns']['aField']['config']['items'][2]);
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2422,16 +2352,11 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
         unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2491,7 +2416,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             [ 'keepMe', 'keep', null, null ],
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2530,11 +2455,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
         $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
@@ -2545,7 +2465,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected['databaseRow']['aField'] = ['keep'];
         unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2579,11 +2499,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
         $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
@@ -2592,7 +2507,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['doktype'] = ['keep'];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2630,11 +2545,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
         $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
         $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
@@ -2647,7 +2557,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected['databaseRow']['doktype'] = ['keep'];
         unset($expected['processedTca']['columns']['doktype']['config']['items'][1]);
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2683,11 +2593,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ],
         ];
 
-        /** @var LanguageService|ObjectProphecy $languageService */
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $expected = $input;
         $expected['databaseRow']['aField'] = ['aValue'];
         $expected['processedTca']['columns']['aField']['config'] = [
@@ -2704,7 +2609,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'maxitems' => 99999,
         ];
 
-        $this->assertSame($expected, $this->subject->addData($input));
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2774,7 +2679,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         // itemsProcFunc must NOT have raised an exception
         $flashMessageQueue->enqueue($flashMessage)->shouldNotBeCalled();
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -2834,7 +2739,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
 
-        $this->subject->addData($input);
+        (new TcaSelectItems)->addData($input);
     }
 
     /**
@@ -2890,8 +2795,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected['databaseRow']['aField'] = ['aValue'];
         $expected['processedTca']['columns']['aField']['config']['items'][0][0] = 'labelOverride';
 
-        $this->assertSame($expected, $this->subject->addData($input));
-        $this->subject->addData($input);
+        $this->assertSame($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2909,7 +2813,9 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $this->mockDatabaseConnectionForProcessSelectField();
 
         $input = [
+            'command' => 'edit',
             'tableName' => 'aTable',
+            'effectivePid' => 23,
             'databaseRow' => [
                 'uid' => 42,
                 // Two connected rows
@@ -2946,7 +2852,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = $relationHandlerUids;
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -2965,6 +2871,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $input = [
             'tableName' => 'aTable',
+            'effectivePid' => 23,
             'databaseRow' => [
                 'uid' => 42,
                 // Two connected rows
@@ -3000,7 +2907,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = $relationHandlerUids;
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3008,10 +2915,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     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 */
@@ -3028,7 +2931,9 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
 
         $input = [
             'tableName' => 'aTable',
+            'effectivePid' => 23,
             'databaseRow' => [
+                'uid' => 5,
                 'aField' => '1,2,bar,foo',
             ],
             'processedTca' => [
@@ -3051,7 +2956,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = ['foo', 1];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3059,10 +2964,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     public function processSelectFieldValueKeepsValuesFromStaticItems()
     {
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $input = [
             'tableName' => 'aTable',
             'databaseRow' => [
@@ -3091,7 +2992,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'bar'
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3099,10 +3000,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     public function processSelectFieldValueReturnsEmptyValueForSingleSelect()
     {
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $input = [
             'tableName' => 'aTable',
             'databaseRow' => [
@@ -3125,7 +3022,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = [];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3133,10 +3030,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     public function processSelectFieldValueTrimsEmptyValueForMultiValueSelect()
     {
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $input = [
             'tableName' => 'aTable',
             'databaseRow' => [
@@ -3166,7 +3059,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'c',
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3174,10 +3067,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     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();
@@ -3207,7 +3096,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = ['foo'];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3254,7 +3143,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ['[ INVALID VALUE "1" ]', '1', null, null],
             ['foo', 'foo', null, null],
         ];
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3262,10 +3151,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     public function processSelectFieldValueReturnsDuplicateValuesForMultipleSelect()
     {
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $input = [
             'tableName' => 'aTable',
             'databaseRow' => [
@@ -3300,7 +3185,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'bar'
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3308,10 +3193,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
      */
     public function processSelectFieldValueReturnsUniqueValuesForMultipleSelect()
     {
-        $languageService = $this->prophesize(LanguageService::class);
-        $GLOBALS['LANG'] = $languageService->reveal();
-        $languageService->sL(Argument::cetera())->willReturnArgument(0);
-
         $input = [
             'tableName' => 'aTable',
             'databaseRow' => [
@@ -3345,7 +3226,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             4 => 'bar',
         ];
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 
     /**
@@ -3360,6 +3241,7 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
                 [
                     'tableName' => 'aTable',
                     'command' => 'new',
+                    'effectivePid' => 42,
                     'databaseRow' => [
                         'uid' => 'NEW1234',
                         'aField' => '24,35',
@@ -3389,6 +3271,8 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'Relation with MM table and item array in list but no new status' => [
                 [
                     'tableName' => 'aTable',
+                    'command' => 'edit',
+                    'effectivePid' => 42,
                     'databaseRow' => [
                         'uid' => 'NEW1234',
                         'aField' => '24,35',
@@ -3414,6 +3298,8 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'Relation with MM table and maxitems = 1 processes field value (item count)' => [
                 [
                     'tableName' => 'aTable',
+                    'command' => 'edit',
+                    'effectivePid' => 42,
                     'databaseRow' => [
                         'uid' => 42,
                         // MM relation with one item has 1 in field value
@@ -3442,6 +3328,8 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             'Relation with MM table and maxitems = 1 results in empty array if no items are set' => [
                 [
                     'tableName' => 'aTable',
+                    'command' => 'edit',
+                    'effectivePid' => 42,
                     'databaseRow' => [
                         'uid' => 58,
                         // MM relation with no items has 0 in field value
@@ -3504,6 +3392,6 @@ class TcaSelectItemsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
         $expected = $input;
         $expected['databaseRow']['aField'] = $relationHandlerUids;
 
-        $this->assertEquals($expected, $this->subject->addData($input));
+        $this->assertEquals($expected, (new TcaSelectItems)->addData($input));
     }
 }
index c7002c8..fe4561a 100644 (file)
@@ -46,7 +46,9 @@ class QueryHelper
 
         return array_map(
             function ($expression) {
-                list($fieldName, $order) = GeneralUtility::trimExplode(' ', $expression, true);
+                $fieldNameOrderArray = GeneralUtility::trimExplode(' ', $expression, true);
+                $fieldName = $fieldNameOrderArray[0] ?? null;
+                $order = $fieldNameOrderArray[1] ?? null;
 
                 return [$fieldName, $order];
             },
index 84d79db..b2632ae 100644 (file)
@@ -263,12 +263,12 @@ class RelationHandler
     {
         $conf = (array)$conf;
         // SECTION: MM reverse relations
-        $this->MM_is_foreign = (bool)$conf['MM_opposite_field'];
-        $this->MM_oppositeField = $conf['MM_opposite_field'];
-        $this->MM_table_where = $conf['MM_table_where'];
-        $this->MM_hasUidField = $conf['MM_hasUidField'];
-        $this->MM_match_fields = is_array($conf['MM_match_fields']) ? $conf['MM_match_fields'] : [];
-        $this->MM_insert_fields = is_array($conf['MM_insert_fields']) ? $conf['MM_insert_fields'] : $this->MM_match_fields;
+        $this->MM_is_foreign = (bool)($conf['MM_opposite_field'] ?? false);
+        $this->MM_oppositeField = $conf['MM_opposite_field'] ?? null;
+        $this->MM_table_where = $conf['MM_table_where'] ?? null;
+        $this->MM_hasUidField = $conf['MM_hasUidField'] ?? null;
+        $this->MM_match_fields = (isset($conf['MM_match_fields']) && is_array($conf['MM_match_fields'])) ? $conf['MM_match_fields'] : [];
+        $this->MM_insert_fields = (isset($conf['MM_insert_fields']) && is_array($conf['MM_insert_fields'])) ? $conf['MM_insert_fields'] : $this->MM_match_fields;
         $this->currentTable = $currentTable;
         if (!empty($conf['MM_oppositeUsage']) && is_array($conf['MM_oppositeUsage'])) {
             $this->MM_oppositeUsage = $conf['MM_oppositeUsage'];
@@ -301,8 +301,9 @@ class RelationHandler
         foreach ($tempTableArray as $val) {
             $tName = trim($val);
             $this->tableArray[$tName] = [];
-            if ($this->checkIfDeleted && $GLOBALS['TCA'][$tName]['ctrl']['delete']) {
-                $fieldN = $tName . '.' . $GLOBALS['TCA'][$tName]['ctrl']['delete'];
+            $deleteField = $GLOBALS['TCA'][$tName]['ctrl']['delete'] ?? false;
+            if ($this->checkIfDeleted && $deleteField) {
+                $fieldN = $tName . '.' . $deleteField;
                 $this->additionalWhere[$tName] .= ' AND ' . $fieldN . '=0';
             }
         }
@@ -330,14 +331,14 @@ class RelationHandler
                 $this->readList($itemlist, $conf);
                 $this->purgeItemArray();
             }
-        } elseif ($MMuid && $conf['foreign_field']) {
+        } elseif ($MMuid && isset($conf['foreign_field']) && (bool)$conf['foreign_field']) {
             // If not MM but foreign_field, the read the records by the foreign_field
             $this->readForeignField($MMuid, $conf);
         } else {
             // If not MM, then explode the itemlist by "," and traverse the list:
             $this->readList($itemlist, $conf);
             // Do automatic default_sortby, if any
-            if ($conf['foreign_default_sortby']) {
+            if (isset($conf['foreign_default_sortby']) && $conf['foreign_default_sortby']) {
                 $this->sortList($conf['foreign_default_sortby']);
             }
         }
index 3cf65c0..b1f835a 100644 (file)
@@ -1610,7 +1610,7 @@ class GeneralUtility
         // Default output charset is UTF-8, only ASCII, ISO-8859-1 and UTF-8 are supported!!!
         $match = [];
         preg_match('/^[[:space:]]*<\\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/', substr($string, 0, 200), $match);
-        $theCharset = $match[1] ?: 'utf-8';
+        $theCharset = $match[1] ?? 'utf-8';
         // us-ascii / utf-8 / iso-8859-1
         xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset);
         // Parse content: