diff --git a/typo3/sysext/core/Classes/DataHandling/Localization/State.php b/typo3/sysext/core/Classes/DataHandling/Localization/State.php index 9c1026d00b30d1403e979d7cb68e77eaab0b3761..fce8365868144ee83b2e9720dfa9dc46ff9633f0 100644 --- a/typo3/sysext/core/Classes/DataHandling/Localization/State.php +++ b/typo3/sysext/core/Classes/DataHandling/Localization/State.php @@ -82,7 +82,7 @@ class State { return array_keys( array_filter( - $GLOBALS['TCA'][$tableName]['columns'], + $GLOBALS['TCA'][$tableName]['columns'] ?? [], function (array $fieldConfiguration) { return !empty( $fieldConfiguration['config'] @@ -138,6 +138,15 @@ class State */ protected $originalStates; + /** + * @var array + */ + protected $validStates = [ + self::STATE_CUSTOM, + self::STATE_SOURCE, + self::STATE_PARENT, + ]; + /** * @param string $tableName * @param array $states @@ -148,8 +157,9 @@ class State $this->states = $states; $this->originalStates = $states; - $this->states = $this->sanitize($states); - $this->states = $this->enrich($states); + $this->states = $this->enrich( + $this->sanitize($states) + ); } /** @@ -311,7 +321,12 @@ class State protected function enrich(array $states) { foreach (static::getFieldNames($this->tableName) as $fieldName) { - if (!empty($states[$fieldName])) { + $isValid = in_array( + $states[$fieldName] ?? null, + $this->validStates, + true + ); + if ($isValid) { continue; } $states[$fieldName] = static::STATE_PARENT; diff --git a/typo3/sysext/core/Tests/Unit/DataHandling/Localization/StateTest.php b/typo3/sysext/core/Tests/Unit/DataHandling/Localization/StateTest.php new file mode 100644 index 0000000000000000000000000000000000000000..30921468ecb20b4175750b47f3ee4ba047334659 --- /dev/null +++ b/typo3/sysext/core/Tests/Unit/DataHandling/Localization/StateTest.php @@ -0,0 +1,193 @@ +<?php + +namespace TYPO3\CMS\Core\Tests\Unit\DataHandler\Localization; + +/* + * 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\Core\DataHandling\Localization\State; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +/** + * Test case + */ +class StateTest extends UnitTestCase +{ + const TABLE_NAME = 'tx_test_table'; + + /** + * Set up the tests + */ + protected function setUp() + { + $GLOBALS['TCA'] = []; + } + + /** + * @param string $tableName + * @param array $states + * + * @test + * @dataProvider stateObjectCanBeCreatedDataProvider + */ + public function stateObjectCanBeCreated(string $tableName, array $states) + { + $subject = new State($tableName, $states); + + $this->assertInstanceOf(State::class, $subject); + } + + /** + * @return array + */ + public function stateObjectCanBeCreatedDataProvider(): array + { + return [ + 'without states' => [ + static::TABLE_NAME, + [], + ], + 'with states' => [ + static::TABLE_NAME, + ['nonExistingField' => 'invalidState'], + ], + ]; + } + + /** + * @param array $states + * @param array $expected + * + * @test + * @dataProvider statesAreEnrichedAndSanitizedOnObjectCreationDataProvider + */ + public function statesAreEnrichedAndSanitizedOnObjectCreation( + array $states, + array $expected + ) { + $GLOBALS['TCA'] = $this->provideTableConfiguration( + 'first_field', + 'second_field' + ); + + $subject = new State(static::TABLE_NAME, $states); + + $this->assertSame( + $expected, + $subject->toArray() + ); + } + + /** + * @return array + */ + public function statesAreEnrichedAndSanitizedOnObjectCreationDataProvider(): array + { + return [ + 'empty' => [ + [], + [ + 'first_field' => 'parent', + 'second_field' => 'parent', + ], + ], + 'invalid field only' => [ + [ + 'invalid_field' => 'invalidState', + ], + [ + 'first_field' => 'parent', + 'second_field' => 'parent', + ], + ], + 'first_field only, valid state' => [ + [ + 'first_field' => 'custom', + ], + [ + 'first_field' => 'custom', + 'second_field' => 'parent', + ], + ], + 'first_field only, invalid state' => [ + [ + 'first_field' => 'invalidState', + ], + [ + 'first_field' => 'parent', + 'second_field' => 'parent', + ], + ], + 'all valid fields, valid states' => [ + [ + 'first_field' => 'custom', + 'second_field' => 'parent', + ], + [ + 'first_field' => 'custom', + 'second_field' => 'parent', + ], + ], + 'all valid fields, invalid states' => [ + [ + 'first_field' => 'invalidState', + 'second_field' => 'invalidState', + ], + [ + 'first_field' => 'parent', + 'second_field' => 'parent', + ], + ], + 'all valid fields, valid states and invalid field' => [ + [ + 'invalid_field' => 'invalidState', + 'first_field' => 'custom', + 'second_field' => 'parent', + ], + [ + 'first_field' => 'custom', + 'second_field' => 'parent', + ], + ], + 'all valid fields, invalid states and invalid field' => [ + [ + 'invalid_field' => 'invalidState', + 'first_field' => 'invalidState', + 'second_field' => 'invalidState', + ], + [ + 'first_field' => 'parent', + 'second_field' => 'parent', + ], + ], + ]; + } + + /** + * @param string[] ...$fieldNames + * + * @return array + */ + private function provideTableConfiguration(string ...$fieldNames): array + { + $columnsConfiguration = []; + foreach ($fieldNames as $fieldName) { + $columnsConfiguration[$fieldName]['config']['behaviour']['allowLanguageSynchronization'] = true; + } + return [ + static::TABLE_NAME => [ + 'columns' => $columnsConfiguration, + ], + ]; + } +}