Commit ff90a7c7 authored by Morton Jonuschat's avatar Morton Jonuschat Committed by Benni Mack
Browse files

[BUGFIX] FormEngine: Fix broken invalid value handling for selects

The handling of invalid or non-matching items was handled inconsistently
in the different select elements. Determining the invalid items has been
moved into the data provider for select boxes so that the invalid values
can be correctly determined based on intermediate processing steps.

Resolves: #71257
Releases: master
Change-Id: I577089b29265a789612c7b3baaf60b66f4339b35
Reviewed-on: https://review.typo3.org/44540

Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent b4276ebd
......@@ -110,29 +110,6 @@ class SelectCheckBoxElement extends AbstractFormElement
}
}
}
// Remaining values (invalid):
if (!empty($itemArray) && !$parameterArray['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
$currentGroup++;
// Creating the label for the "No Matching Value" entry.
$noMatchingLabel = isset($parameterArray['fieldTSConfig']['noMatchingValue_label'])
? $this->getLanguageService()->sL($parameterArray['fieldTSConfig']['noMatchingValue_label'])
: '[ ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue') . ' ]';
foreach ($itemArray as $theNoMatchValue => $temp) {
// Build item array
$groups[$currentGroup]['items'][] = array(
'id' => StringUtility::getUniqueId('select_checkbox_row_'),
'name' => $parameterArray['itemFormElName'] . '[' . $c . ']',
'value' => $theNoMatchValue,
'checked' => 1,
'disabled' => $disabled,
'class' => 'danger',
'icon' => '',
'title' => htmlspecialchars(@sprintf($noMatchingLabel, $theNoMatchValue), ENT_COMPAT, 'UTF-8', false),
'help' => ''
);
$c++;
}
}
// Add an empty hidden field which will send a blank value if all items are unselected.
$html[] = '<input type="hidden" class="select-checkbox" name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="">';
......
......@@ -60,38 +60,24 @@ class SelectMultipleSideBySideElement extends AbstractFormElement
if (!$maxitems) {
$maxitems = 100000;
}
// Get "removeItems":
$removeItems = GeneralUtility::trimExplode(',', $parameterArray['fieldTSConfig']['removeItems'], true);
// Get the array with selected items:
$itemsArray = $parameterArray['itemFormElValue'] ?: [];
// Perform modification of the selected items array:
// @todo: this part should probably be moved to TcaSelectItems provider?!
foreach ($itemsArray as $itemNumber => $itemValue) {
$itemArray = array(
0 => $itemValue,
1 => '',
);
$itemIcon = null;
$isRemoved = in_array($itemValue, $removeItems)
|| $config['type'] == 'select' && $config['authMode']
&& !$this->getBackendUserAuthentication()->checkAuthMode($table, $field, $itemValue, $config['authMode']);
if ($isRemoved && !$parameterArray['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
$itemArray[1] = rawurlencode(@sprintf($noMatchingLabel, $itemValue));
} else {
if (isset($parameterArray['fieldTSConfig']['altLabels.'][$itemValue])) {
$itemArray[1] = rawurlencode($this->getLanguageService()->sL(trim($parameterArray['fieldTSConfig']['altLabels.'][$itemValue])));
}
if (isset($parameterArray['fieldTSConfig']['altIcons.'][$itemValue])) {
$itemArray[2] = $parameterArray['fieldTSConfig']['altIcons.'][$itemValue];
}
if (isset($parameterArray['fieldTSConfig']['altIcons.'][$itemValue])) {
$itemArray[2] = $parameterArray['fieldTSConfig']['altIcons.'][$itemValue];
}
if ($itemArray[1] === '') {
foreach ($selItems as $selItem) {
if ($selItem[1] == $itemValue) {
$itemArray[1] = $selItem[0];
break;
}
foreach ($selItems as $selItem) {
if ($selItem[1] == $itemValue) {
$itemArray[1] = $selItem[0];
break;
}
}
$itemsArray[$itemNumber] = implode('|', $itemArray);
......
......@@ -64,27 +64,6 @@ class SelectSingleBoxElement extends AbstractFormElement
$optionElements[] = $this->renderOptionElement($value, $item[0], $attributes);
}
// Remaining values:
if (!empty($itemArray)
&& !$parameterArray['fieldTSConfig']['disableNoMatchingValueElement']
&& !$config['disableNoMatchingValueElement']) {
// Creating the label for the "No Matching Value" entry.
$noMatchingLabel = isset($parameterArray['fieldTSConfig']['noMatchingValue_label'])
? $this->getLanguageService()->sL($parameterArray['fieldTSConfig']['noMatchingValue_label'])
: '[ ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue') . ' ]';
foreach ($itemArray as $unmatchedValue => $temp) {
// Compile <option> tag:
array_unshift($optionElements, $this->renderOptionElement(
$unmatchedValue,
// @todo Check if we can get rid of "@" here (catches missing %s in $noMatchingLabel)
@sprintf($noMatchingLabel, $unmatchedValue),
['selected' => 'selected']
));
}
}
$selectElement = $this->renderSelectElement($optionElements, $parameterArray, $config);
$resetButtonElement = $this->renderResetButtonElement($parameterArray['itemFormElName'] . '[]', $initiallySelectedIndices);
$html = [];
......
......@@ -43,11 +43,6 @@ class SelectSingleElement extends AbstractFormElement
$selectItems = $parameterArray['fieldConf']['config']['items'];
// Creating the label for the "No Matching Value" entry.
$noMatchingLabel = isset($parameterArray['fieldTSConfig']['noMatchingValue_label'])
? $this->getLanguageService()->sL(trim($parameterArray['fieldTSConfig']['noMatchingValue_label']))
: '[ ' . $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue') . ' ]';
// Check against inline uniqueness
/** @var InlineStackProcessor $inlineStackProcessor */
$inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
......@@ -78,9 +73,7 @@ class SelectSingleElement extends AbstractFormElement
// Initialization:
$selectId = StringUtility::getUniqueId('tceforms-select-');
$selectedIndex = 0;
$selectedIcon = '';
$selectedValueFound = false;
$size = (int)$config['size'];
// Style set on <select/>
......@@ -118,9 +111,7 @@ class SelectSingleElement extends AbstractFormElement
$selected = $selectedValue === (string)$item[1];
if ($selected) {
$selectedIndex = $selectItemCounter;
$selectedIcon = $icon;
$selectedValueFound = true;
}
$selectItemGroups[$selectItemGroupCount]['items'][] = array(
......@@ -144,11 +135,9 @@ class SelectSingleElement extends AbstractFormElement
}
}
// No-matching-value:
if ($selectedValue && !$selectedValueFound && !$parameterArray['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement']) {
$noMatchingLabel = @sprintf($noMatchingLabel, $selectedValue);
$options = '<option value="' . htmlspecialchars($selectedValue) . '" selected="selected">' . htmlspecialchars($noMatchingLabel) . '</option>';
} elseif (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
// Fallback icon
// @todo: assign a special icon for non matching values?
if (!$selectedIcon && $selectItemGroups[0]['items'][0]['icon']) {
$selectedIcon = $selectItemGroups[0]['items'][0]['icon'];
}
......
......@@ -1023,6 +1023,21 @@ abstract class AbstractItemProvider
return $foreignTableClauseArray;
}
/**
* Convert the current database values into an array
*
* @param array $row database row
* @param string $fieldName fieldname to process
* @return array
*/
protected function processDatabaseFieldValue(array $row, $fieldName)
{
$currentDatabaseValues = array_key_exists($fieldName, $row)
? $row[$fieldName]
: '';
return GeneralUtility::trimExplode(',', $currentDatabaseValues, true);
}
/**
* Validate and sanitize database row values of the select field with the given name.
* Creates an array out of databaseRow[selectField] values.
......@@ -1038,24 +1053,12 @@ abstract class AbstractItemProvider
{
$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.
// For maxitems=1 select fields is is also possible to select empty values.
// @todo: move handling of invalid values to this data provider.
if ($fieldConfig['config']['maxitems'] === 1 && empty($fieldConfig['config']['MM'])) {
return [$result['databaseRow'][$fieldName]];
}
$currentDatabaseValues = array_key_exists($fieldName, $result['databaseRow']) ? $result['databaseRow'][$fieldName] : '';
// Selecting empty values does not make sense for fields that can contain more than one item
// because it is impossible to determine if the empty value or nothing is selected.
// This is why empty values will be removed for multi value fields.
$currentDatabaseValuesArray = GeneralUtility::trimExplode(',', $currentDatabaseValues, true);
$currentDatabaseValueArray = array_key_exists($fieldName, $result['databaseRow']) ? $result['databaseRow'][$fieldName] : [];
$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) {
foreach ($currentDatabaseValueArray as $value) {
if (isset($staticValues[$value])) {
$newDatabaseValueArray[] = $value;
}
......@@ -1068,7 +1071,7 @@ abstract class AbstractItemProvider
if (!empty($fieldConfig['config']['MM']) && $result['command'] !== 'new') {
// MM relation
$relationHandler->start(
$currentDatabaseValues,
implode(',', $currentDatabaseValueArray),
$fieldConfig['config']['foreign_table'],
$fieldConfig['config']['MM'],
$result['databaseRow']['uid'],
......@@ -1079,7 +1082,7 @@ abstract class AbstractItemProvider
// Non MM relation
// If not dealing with MM relations, use default live uid, not versioned uid for record relations
$relationHandler->start(
$currentDatabaseValues,
implode(',', $currentDatabaseValueArray),
$fieldConfig['config']['foreign_table'],
'',
$this->getLiveUid($result),
......
......@@ -15,6 +15,7 @@ namespace TYPO3\CMS\Backend\Form\FormDataProvider;
*/
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Resolve select items, set processed item list in processedTca, sanitize and resolve database field
......@@ -53,12 +54,16 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
$fieldConfig['config']['items'] = $this->addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']);
$dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems);
$removedItems = $fieldConfig['config']['items'];
$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']);
$fieldConfig['config']['items'] = $this->removeItemsByUserAuthMode($result, $fieldName, $fieldConfig['config']['items']);
$fieldConfig['config']['items'] = $this->removeItemsByDoktypeUserRestriction($result, $fieldName, $fieldConfig['config']['items']);
$removedItems = array_diff_key($removedItems, $fieldConfig['config']['items']);
// Resolve "itemsProcFunc"
if (!empty($fieldConfig['config']['itemsProcFunc'])) {
$fieldConfig['config']['items'] = $this->resolveItemProcessorFunction($result, $fieldName, $fieldConfig['config']['items']);
......@@ -66,21 +71,79 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
unset($fieldConfig['config']['itemsProcFunc']);
}
// Translate labels
$fieldConfig['config']['items'] = $this->translateLabels($result, $fieldConfig['config']['items'], $table, $fieldName);
// needed to determine the items for invalid values
$currentDatabaseValuesArray = $this->processDatabaseFieldValue($result['databaseRow'], $fieldName);
$result['databaseRow'][$fieldName] = $currentDatabaseValuesArray;
$staticValues = $this->getStaticValues($fieldConfig['config']['items'], $dynamicItems);
$result['databaseRow'][$fieldName] = $this->processSelectFieldValue($result, $fieldName, $staticValues);
$fieldConfig['config']['items'] = $this->addInvalidItemsFromDatabase(
$result,
$table,
$fieldName,
$fieldConfig,
$currentDatabaseValuesArray,
$removedItems
);
// Translate labels
$fieldConfig['config']['items'] = $this->translateLabels($result, $fieldConfig['config']['items'], $table, $fieldName);
// Keys may contain table names, so a numeric array is created
$fieldConfig['config']['items'] = array_values($fieldConfig['config']['items']);
$result['processedTca']['columns'][$fieldName] = $fieldConfig;
$result['databaseRow'][$fieldName] = $this->processSelectFieldValue($result, $fieldName, $staticValues);
}
return $result;
}
/**
* Add values that are currently listed in the database columns but not in the selectable items list
* back to the list.
*
* @param array $result The current result array.
* @param string $table The current table name
* @param string $fieldName The current field name
* @param array $fieldConf The configuration of the current field.
* @param array $databaseValues The item values from the database, can contain invalid items!
* @param array $removedItems Items removed by access checks and restrictions, must not be added as invalid values
* @return array
*/
public function addInvalidItemsFromDatabase(array $result, $table, $fieldName, array $fieldConf, array $databaseValues, array $removedItems)
{
// 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']
) {
return $fieldConf['config']['items'];
}
$languageService = $this->getLanguageService();
$noMatchingLabel = isset($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['noMatchingValue_label'])
? $languageService->sL(trim($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['noMatchingValue_label']))
: '[ ' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue') . ' ]';
$unmatchedValues = array_diff(
array_values($databaseValues),
array_column($fieldConf['config']['items'], 1),
array_column($removedItems, 1)
);
foreach ($unmatchedValues as $unmatchedValue) {
$invalidItem = [
@sprintf($noMatchingLabel, $unmatchedValue),
$unmatchedValue
];
array_unshift($fieldConf['config']['items'], $invalidItem);
}
return $fieldConf['config']['items'];
}
/**
* Determines whether the current field is a valid target for this DataProvider
*
......
......@@ -74,6 +74,7 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide
$fieldConfig['config']['items'] = $this->translateLabels($result, $fieldConfig['config']['items'], $table, $fieldName);
$staticValues = $this->getStaticValues($fieldConfig['config']['items'], $dynamicItems);
$result['databaseRow'][$fieldName] = $this->processDatabaseFieldValue($result['databaseRow'], $fieldName);
$result['databaseRow'][$fieldName] = $this->processSelectFieldValue($result, $fieldName, $staticValues);
// Keys may contain table names, so a numeric array is created
......@@ -111,7 +112,7 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide
$fieldName,
$result['databaseRow']
);
$treeDataProvider->setSelectedList(implode(',', $result['databaseRow'][$fieldName]));
$treeDataProvider->setSelectedList(is_array($result['databaseRow'][$fieldName]) ? implode(',', $result['databaseRow'][$fieldName]) : $result['databaseRow'][$fieldName]);
$treeDataProvider->setItemWhiteList($allowedUids);
$treeDataProvider->initializeTreeData();
......
......@@ -156,6 +156,7 @@ class TcaSelectItemsTest extends UnitTestCase
/** @var LanguageService|ObjectProphecy $languageService */
$languageService = $this->prophesize(LanguageService::class);
$GLOBALS['LANG'] = $languageService->reveal();
$languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue')->willReturn('INVALID VALUE "%s"');
$languageService->sL('aLabel')->shouldBeCalled()->willReturn('translated');
......@@ -242,7 +243,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'databaseRow' => [
'aField' => 'aValue',
'aField' => '',
],
'tableName' => 'aTable',
'processedTca' => [
......@@ -275,12 +276,14 @@ class TcaSelectItemsTest extends UnitTestCase
/** @var LanguageService|ObjectProphecy $languageService */
$languageService = $this->prophesize(LanguageService::class);
$GLOBALS['LANG'] = $languageService->reveal();
$languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue')->willReturn('INVALID VALUE "%s"');
$languageService->sL(Argument::containingString('INVALID VALUE'))->willReturnArgument(0);
$languageService->sL('aTitle')->shouldBeCalled()->willReturnArgument(0);
$languageService->loadSingleTableDescription('aTable')->shouldBeCalled();
$expected = $input;
$expected['databaseRow']['aField'] = ['aValue'];
$expected['databaseRow']['aField'] = [];
$expected['processedTca']['columns']['aField']['config']['items'] = [
0 => [
0 => 'aTitle',
......@@ -339,6 +342,7 @@ class TcaSelectItemsTest extends UnitTestCase
/** @var LanguageService|ObjectProphecy $languageService */
$languageService = $this->prophesize(LanguageService::class);
$GLOBALS['LANG'] = $languageService->reveal();
$languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue')->willReturn('INVALID VALUE "%s"');
$languageService->sL('aLabel')->shouldBeCalled()->willReturnArgument(0);
......@@ -482,6 +486,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -514,6 +519,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -603,6 +609,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -673,6 +680,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -743,6 +751,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -834,6 +843,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -925,6 +935,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -971,6 +982,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -1027,6 +1039,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -1092,6 +1105,7 @@ class TcaSelectItemsTest extends UnitTestCase
$directory = $this->getUniqueId('typo3temp/test-') . '/';
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -1379,6 +1393,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
......@@ -1433,7 +1448,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'databaseRow' => [
'aField' => 'aValue',
'aField' => '',
],
'tableName' => 'aTable',
'processedTca' => [
......@@ -1492,7 +1507,7 @@ class TcaSelectItemsTest extends UnitTestCase
$flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
$expected = $input;
$expected['databaseRow']['aField'] = ['aValue'];
$expected['databaseRow']['aField'] = [];
$this->assertEquals($expected, $this->subject->addData($input));
}
......@@ -1500,11 +1515,11 @@ class TcaSelectItemsTest extends UnitTestCase
/**
* @test
*/
public function addDataForeignTableHandlesForegnTableRows()
public function addDataForeignTableHandlesForeignTableRows()
{
$input = [
'databaseRow' => [
'aField' => 'aValue',
'aField' => '',
],
'tableName' => 'aTable',
'processedTca' => [
......@@ -1571,7 +1586,7 @@ class TcaSelectItemsTest extends UnitTestCase
],
];
$expected['databaseRow']['aField'] = ['aValue'];
$expected['databaseRow']['aField'] = [];
$this->assertEquals($expected, $this->subject->addData($input));
}
......@@ -1583,7 +1598,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'databaseRow' => [
'aField' => 'aValue',
'aField' => '',
],
'tableName' => 'aTable',
'processedTca' => [
......@@ -1626,7 +1641,7 @@ class TcaSelectItemsTest extends UnitTestCase
$languageService->sL(Argument::cetera())->willReturnArgument(0);
$expected = $input;
$expected['databaseRow']['aField'] = ['aValue'];
$expected['databaseRow']['aField'] = [];
unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
$this->assertEquals($expected, $this->subject->addData($input));
......@@ -1639,7 +1654,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'databaseRow' => [
'aField' => 'aValue'
'aField' => ''
],
'tableName' => 'aTable',
'processedTca' => [
......@@ -1682,7 +1697,7 @@ class TcaSelectItemsTest extends UnitTestCase
$languageService->sL(Argument::cetera())->willReturnArgument(0);
$expected = $input;
$expected['databaseRow']['aField'] = ['aValue'];
$expected['databaseRow']['aField'] = [];
unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
$this->assertEquals($expected, $this->subject->addData($input));
......@@ -1695,7 +1710,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'databaseRow' => [
'aField' => 'aValue'
'aField' => 'aValue,remove'
],
'tableName' => 'aTable',
'processedTca' => [
......@@ -1729,6 +1744,7 @@ class TcaSelectItemsTest extends UnitTestCase
/** @var LanguageService|ObjectProphecy $languageService */
$languageService = $this->prophesize(LanguageService::class);
$GLOBALS['LANG'] = $languageService->reveal();
$languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.noMatchingValue')->willReturn('INVALID VALUE "%s"');
$languageService->sL(Argument::cetera())->willReturnArgument(0);
/** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
......@@ -1738,8 +1754,11 @@ class TcaSelectItemsTest extends UnitTestCase
$backendUserProphecy->checkLanguageAccess('remove')->shouldBeCalled()->willReturn(false);
$expected = $input;
$expected['databaseRow']['aField'] = ['aValue'];
unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
$expected['databaseRow']['aField'] = [];
$expected['processedTca']['columns']['aField']['config']['items'] = [
[ '[ INVALID VALUE "aValue" ]', 'aValue', null, null ],
[ 'keepMe', 'keep', null, null ],
];
$this->assertEquals($expected, $this->subject->addData($input));
}
......@@ -1751,7 +1770,7 @@ class TcaSelectItemsTest extends UnitTestCase
{
$input = [
'databaseRow' => [
'aField' => 'aValue'