Commit 20128778 authored by Christian Kuhn's avatar Christian Kuhn Committed by Susanne Moog
Browse files

[!!!][TASK] Remove inline localizationMode

Drop the TCA inline releated localizationMode settings.
This one has been deprecated with v8 including an
automatic TCA migration.

Change-Id: Ibb73721b188368605dd3cd75a29d2b7a8986966e
Releases: master
Resolves: #82634
Related: #80700
Reviewed-on: https://review.typo3.org/52496


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
parent 9c45facf
......@@ -97,21 +97,6 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController
}
$childData = $formDataCompiler->compile($formDataCompilerInput);
// Set language of new child record to the language of the parent record:
// @todo: To my understanding, the below case can't happen: With localizationMode select, lang overlays
// @todo: of children are only created with the "synchronize" button that will trigger a different ajax action.
// @todo: The edge case of new page overlay together with localized media field, this code won't kick in either.
// @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9
/*
if ($parent['localizationMode'] === 'select' && MathUtility::canBeInterpretedAsInteger($parent['uid'])) {
$parentRecord = $inlineRelatedRecordResolver->getRecord($parent['table'], $parent['uid']);
$parentLanguageField = $GLOBALS['TCA'][$parent['table']]['ctrl']['languageField'];
$childLanguageField = $GLOBALS['TCA'][$child['table']]['ctrl']['languageField'];
if ($parentRecord[$parentLanguageField] > 0) {
$record[$childLanguageField] = $parentRecord[$parentLanguageField];
}
}
*/
if ($parentConfig['foreign_selector'] && $parentConfig['appearance']['useCombination']) {
// We have a foreign_selector. So, we just created a new record on an intermediate table in $childData.
// Now, if a valid id is given as second ajax parameter, the intermediate row should be connected to an
......
......@@ -120,7 +120,6 @@ class InlineControlContainer extends AbstractContainer
'uid' => $row['uid'],
'field' => $field,
'config' => $config,
'localizationMode' => BackendUtility::getInlineLocalizationMode($table, $config),
];
// Extract FlexForm parts (if any) from element name, e.g. array('vDEF', 'lDEF', 'FlexField', 'vDEF')
if (!empty($parameterArray['itemFormElName'])) {
......
......@@ -272,8 +272,8 @@ class FormDataCompiler
// configuration - of the new intermediate sys_file_reference record. Data provider that are called later
// will then use this relation to resolve for instance input placeholder relation values.
'inlineChildChildUid' => null,
// Inline scenario: A localized parent record is handled and localizationMode is set to "select", so inline
// parents can have localized children. This value is set to TRUE if this array represents a default language
// Inline scenario: A localized parent record is handled, so inline parents can have localized children.
// This value is set to TRUE if this array represents a default language
// child record that was not yet localized.
'isInlineDefaultLanguageRecordInLocalizedParentContext' => false,
// If set, inline children will be resolved. This is set to FALSE in inline ajax context where new children
......
......@@ -123,105 +123,52 @@ class TcaInline extends AbstractDatabaseRecordProvider implements FormDataProvid
{
$childTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
// localizationMode is either "none", "keep" or "select":
// * none: Handled parent row is not a localized record, or if it is a localized row, this is ignored.
// Default language records and overlays have distinct children that are not connected to each other.
// * keep: Handled parent row is a localized record, but child table is either not localizable, or
// "keep" is explicitly set. A localized parent and its default language row share the same
// children records. Editing a child from a localized record will change this record for the
// default language row, too.
// * select: Handled parent row is a localized record, child table is localizable. Children records are
// localized overlays of a default language record. Three scenarios can happen:
// ** Localized child overlay and its default language row exist - show localized overlay record
// ** Default child language row exists but child overlay doesn't - show a "synchronize this record" button
// ** Localized child overlay exists but default language row does not - this dangling child is a data inconsistency
// Mode was prepared by TcaInlineConfiguration provider
// @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9
$mode = $result['processedTca']['columns'][$fieldName]['config']['behaviour']['localizationMode'];
if ($mode === 'none') {
$connectedUids = [];
// A new record that has distinct children can not have children yet, fetch connected uids for existing only
if ($result['command'] === 'edit') {
$connectedUids = $this->resolveConnectedRecordUids(
$result['processedTca']['columns'][$fieldName]['config'],
$result['tableName'],
$result['databaseRow']['uid'],
$result['databaseRow'][$fieldName]
);
}
$result['databaseRow'][$fieldName] = implode(',', $connectedUids);
$connectedUids = $this->getWorkspacedUids($connectedUids, $childTableName);
// @todo: If inlineCompileExistingChildren must be kept, it might be better to change the data
// @todo: format of databaseRow for this field and separate the child compilation to an own provider?
if ($result['inlineCompileExistingChildren']) {
foreach ($connectedUids as $childUid) {
$result['processedTca']['columns'][$fieldName]['children'][] = $this->compileChild($result, $fieldName, $childUid);
}
}
} elseif ($mode === 'keep') {
// Fetch connected uids of default language record
$connectedUids = $this->resolveConnectedRecordUids(
$connectedUidsOfLocalizedOverlay = [];
if ($result['command'] === 'edit') {
$connectedUidsOfLocalizedOverlay = $this->resolveConnectedRecordUids(
$result['processedTca']['columns'][$fieldName]['config'],
$result['tableName'],
$result['databaseRow']['uid'],
$result['databaseRow'][$fieldName]
);
}
$result['databaseRow'][$fieldName] = implode(',', $connectedUidsOfLocalizedOverlay);
if ($result['inlineCompileExistingChildren']) {
$tableNameWithDefaultRecords = $result['tableName'];
if ($tableNameWithDefaultRecords === 'pages_language_overlay') {
$tableNameWithDefaultRecords = 'pages';
}
$connectedUidsOfDefaultLanguageRecord = $this->resolveConnectedRecordUids(
$result['processedTca']['columns'][$fieldName]['config'],
$tableNameWithDefaultRecords,
$result['defaultLanguageRow']['uid'],
$result['defaultLanguageRow'][$fieldName]
);
$result['databaseRow'][$fieldName] = implode(',', $connectedUids);
$connectedUids = $this->getWorkspacedUids($connectedUids, $childTableName);
if ($result['inlineCompileExistingChildren']) {
foreach ($connectedUids as $childUid) {
$result['processedTca']['columns'][$fieldName]['children'][] = $this->compileChild($result, $fieldName, $childUid);
$showPossible = $result['processedTca']['columns'][$fieldName]['config']['appearance']['showPossibleLocalizationRecords'];
// Find which records are localized, which records are not localized and which are
// localized but miss default language record
$fieldNameWithDefaultLanguageUid = $GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField'];
foreach ($connectedUidsOfLocalizedOverlay as $localizedUid) {
$localizedRecord = $this->getRecordFromDatabase($childTableName, $localizedUid);
$uidOfDefaultLanguageRecord = $localizedRecord[$fieldNameWithDefaultLanguageUid];
if (in_array($uidOfDefaultLanguageRecord, $connectedUidsOfDefaultLanguageRecord)) {
// This localized child has a default language record. Remove this record from list of default language records
$connectedUidsOfDefaultLanguageRecord = array_diff($connectedUidsOfDefaultLanguageRecord, [$uidOfDefaultLanguageRecord]);
}
// Compile localized record
$compiledChild = $this->compileChild($result, $fieldName, $localizedUid);
$result['processedTca']['columns'][$fieldName]['children'][] = $compiledChild;
}
} else {
$connectedUidsOfLocalizedOverlay = [];
if ($result['command'] === 'edit') {
$connectedUidsOfLocalizedOverlay = $this->resolveConnectedRecordUids(
$result['processedTca']['columns'][$fieldName]['config'],
$result['tableName'],
$result['databaseRow']['uid'],
$result['databaseRow'][$fieldName]
);
}
$result['databaseRow'][$fieldName] = implode(',', $connectedUidsOfLocalizedOverlay);
if ($result['inlineCompileExistingChildren']) {
$tableNameWithDefaultRecords = $result['tableName'];
if ($tableNameWithDefaultRecords === 'pages_language_overlay') {
$tableNameWithDefaultRecords = 'pages';
}
$connectedUidsOfDefaultLanguageRecord = $this->resolveConnectedRecordUids(
$result['processedTca']['columns'][$fieldName]['config'],
$tableNameWithDefaultRecords,
$result['defaultLanguageRow']['uid'],
$result['defaultLanguageRow'][$fieldName]
);
$showPossible = $result['processedTca']['columns'][$fieldName]['config']['appearance']['showPossibleLocalizationRecords'];
// Find which records are localized, which records are not localized and which are
// localized but miss default language record
$fieldNameWithDefaultLanguageUid = $GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField'];
foreach ($connectedUidsOfLocalizedOverlay as $localizedUid) {
$localizedRecord = $this->getRecordFromDatabase($childTableName, $localizedUid);
$uidOfDefaultLanguageRecord = $localizedRecord[$fieldNameWithDefaultLanguageUid];
if (in_array($uidOfDefaultLanguageRecord, $connectedUidsOfDefaultLanguageRecord)) {
// This localized child has a default language record. Remove this record from list of default language records
$connectedUidsOfDefaultLanguageRecord = array_diff($connectedUidsOfDefaultLanguageRecord, [$uidOfDefaultLanguageRecord]);
}
// Compile localized record
$compiledChild = $this->compileChild($result, $fieldName, $localizedUid);
if ($showPossible) {
foreach ($connectedUidsOfDefaultLanguageRecord as $defaultLanguageUid) {
// If there are still uids in $connectedUidsOfDefaultLanguageRecord, these are records that
// exist in default language, but are not localized yet. Compile and mark those
$compiledChild = $this->compileChild($result, $fieldName, $defaultLanguageUid);
$compiledChild['isInlineDefaultLanguageRecordInLocalizedParentContext'] = true;
$result['processedTca']['columns'][$fieldName]['children'][] = $compiledChild;
}
if ($showPossible) {
foreach ($connectedUidsOfDefaultLanguageRecord as $defaultLanguageUid) {
// If there are still uids in $connectedUidsOfDefaultLanguageRecord, these are records that
// exist in default language, but are not localized yet. Compile and mark those
$compiledChild = $this->compileChild($result, $fieldName, $defaultLanguageUid);
$compiledChild['isInlineDefaultLanguageRecordInLocalizedParentContext'] = true;
$result['processedTca']['columns'][$fieldName]['children'][] = $compiledChild;
}
}
}
}
......
......@@ -45,7 +45,6 @@ class TcaInlineConfiguration implements FormDataProviderInterface
}
$result = $this->initializeMinMaxItems($result, $fieldName);
$result = $this->initializeLocalizationMode($result, $fieldName);
$result = $this->initializeChildrenLanguage($result, $fieldName);
$result = $this->initializeAppearance($result, $fieldName);
$result = $this->addInlineSelectorAndUniqueConfiguration($result, $fieldName);
......@@ -130,75 +129,6 @@ class TcaInlineConfiguration implements FormDataProviderInterface
return $result;
}
/**
* Set localization mode. This will end up with localizationMode to be set to either 'select', 'keep'
* or 'none' if the handled record is a localized record.
*
* @see TcaInline for a detailed explanation on the meaning of these modes.
*
* @param array $result Result array
* @param string $fieldName Current handle field name
* @return array Modified item array
* @throws \UnexpectedValueException If localizationMode configuration is broken
*/
protected function initializeLocalizationMode(array $result, $fieldName)
{
if ($result['defaultLanguageRow'] === null) {
// Currently handled parent is a localized row if a former provider added the "default" row
// If handled record is not localized, set localizationMode to 'none' and return
// @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9
$result['processedTca']['columns'][$fieldName]['config']['behaviour']['localizationMode'] = 'none';
return $result;
}
$childTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'];
$parentConfig = $result['processedTca']['columns'][$fieldName]['config'];
$isChildTableLocalizable = false;
if (isset($GLOBALS['TCA'][$childTableName]['ctrl']) && is_array($GLOBALS['TCA'][$childTableName]['ctrl'])
&& isset($GLOBALS['TCA'][$childTableName]['ctrl']['languageField'])
&& $GLOBALS['TCA'][$childTableName]['ctrl']['languageField']
&& isset($GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField'])
&& $GLOBALS['TCA'][$childTableName]['ctrl']['transOrigPointerField']
) {
$isChildTableLocalizable = true;
}
$mode = null;
if (isset($parentConfig['behaviour']['localizationMode'])) {
// Use explicit set mode, but validate before use
// Use mode if set, but throw if not set to either 'select' or 'keep'
if ($parentConfig['behaviour']['localizationMode'] !== 'keep' && $parentConfig['behaviour']['localizationMode'] !== 'select') {
throw new \UnexpectedValueException(
'localizationMode of table ' . $result['tableName'] . ' field ' . $fieldName . ' is not valid, set to either \'keep\' or \'select\'',
1443829370
);
}
// Throw if is set to select, but child can not be localized
if ($parentConfig['behaviour']['localizationMode'] === 'select' && !$isChildTableLocalizable) {
throw new \UnexpectedValueException(
'Wrong configuration: localizationMode of table ' . $result['tableName'] . ' field ' . $fieldName . ' is set to \'select\', but table is not localizable.',
1443944274
);
}
$mode = $parentConfig['behaviour']['localizationMode'];
} else {
// Not set explicitly -> use "none"
$mode = 'none';
if ($isChildTableLocalizable) {
// Except if child is localizable, then use "select"
$mode = 'select';
}
}
// @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9
$result['processedTca']['columns'][$fieldName]['config']['behaviour']['localizationMode'] = $mode;
return $result;
}
/**
* Set default value for child records 'sys_language_uid' field. This is relevant if a localized
* parent is edited and a child is added via the ajax call. The child should then have the same
......@@ -223,9 +153,6 @@ class TcaInlineConfiguration implements FormDataProviderInterface
}
$parentConfig = $result['processedTca']['columns'][$fieldName]['config'];
if ($parentConfig['behaviour']['localizationMode'] === 'keep') {
return $result;
}
$parentLanguageField = $result['processedTca']['ctrl']['languageField'];
if (!isset($parentConfig['inline']['parentSysLanguageUid'])
......
......@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Backend\Form;
*/
use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
......@@ -81,7 +80,6 @@ class InlineStackProcessor
if (!$TSconfig['disabled']) {
$unstable['config'] = FormEngineUtility::overrideFieldConf($unstable['config'], $TSconfig);
}
$unstable['localizationMode'] = BackendUtility::getInlineLocalizationMode($unstable['table'], $unstable['config']);
// Extract FlexForm from field part (if any)
if (strpos($unstable['field'], ':') !== false) {
......@@ -119,10 +117,6 @@ class InlineStackProcessor
}
$current = &$this->inlineStructure['stable'][$level];
$current['config'] = $config;
$current['localizationMode'] = BackendUtility::getInlineLocalizationMode(
$current['table'],
$current['config']
);
}
/**
......
......@@ -574,37 +574,6 @@ class BackendUtility
return $isLocalizable;
}
/**
* Returns the value of the property localizationMode in the given $config array ($GLOBALS['TCA'][<table>]['columns'][<field>]['config']).
* If the table is prepared for localization and no localizationMode is set, 'select' is returned by default.
* If the table is not prepared for localization or not defined at all in $GLOBALS['TCA'], FALSE is returned.
*
* @param string $table The name of the table to lookup in TCA
* @param mixed $fieldOrConfig The fieldname (string) or the configuration of the field to check (array)
* @return mixed If table is localizable, the set localizationMode is returned (if property is not set, 'select' is returned by default); if table is not localizable, FALSE is returned
* @deprecated: IRRE 'localizationMode' is deprecated and will be removed in TYPO3 CMS 9, migrate to l10n_mode or allowLanguageSynchronization
*/
public static function getInlineLocalizationMode($table, $fieldOrConfig)
{
$localizationMode = false;
$config = null;
if (is_array($fieldOrConfig) && !empty($fieldOrConfig)) {
$config = $fieldOrConfig;
} elseif (is_string($fieldOrConfig) && isset($GLOBALS['TCA'][$table]['columns'][$fieldOrConfig]['config'])) {
$config = $GLOBALS['TCA'][$table]['columns'][$fieldOrConfig]['config'];
}
if (is_array($config) && isset($config['type']) && $config['type'] === 'inline' && self::isTableLocalizable($table)) {
$localizationMode = isset($config['behaviour']['localizationMode']) && $config['behaviour']['localizationMode']
? $config['behaviour']['localizationMode']
: 'select';
// The mode 'select' is not possible when child table is not localizable at all:
if ($localizationMode === 'select' && !self::isTableLocalizable($config['foreign_table'])) {
$localizationMode = false;
}
}
return $localizationMode;
}
/**
* Returns a page record (of page with $id) with an extra field "_thePath" set to the record path IF the WHERE clause, $perms_clause, selects the record. Thus is works as an access check that returns a page record if access was granted, otherwise not.
* If $id is zero a pseudo root-page with "_thePath" set is returned IF the current BE_USER is admin.
......
......@@ -39,9 +39,6 @@ class TcaInlineConfigurationTest extends \TYPO3\TestingFramework\Core\Unit\UnitT
'foreign_table' => 'aForeignTableName',
'minitems' => 0,
'maxitems' => 99999,
'behaviour' => [
'localizationMode' => 'none',
],
'appearance' => [
'levelLinksPosition' => 'top',
'showPossibleLocalizationRecords' => false,
......@@ -193,169 +190,6 @@ class TcaInlineConfigurationTest extends \TYPO3\TestingFramework\Core\Unit\UnitT
$this->assertEquals($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataThrowsExceptionIfLocalizationModeIsSetButNotToKeepOrSelect()
{
$input = [
'defaultLanguageRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'inline',
'foreign_table' => 'aForeignTableName',
'behaviour' => [
'localizationMode' => 'foo',
]
],
],
],
],
];
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionCode(1443829370);
$this->subject->addData($input);
}
/**
* @test
*/
public function addDataThrowsExceptionIfLocalizationModeIsSetToSelectAndChildIsNotLocalizable()
{
$input = [
'defaultLanguageRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'inline',
'foreign_table' => 'aForeignTableName',
'behaviour' => [
'localizationMode' => 'select',
]
],
],
],
],
];
// not $globals definition for child here -> not localizable
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionCode(1443944274);
$this->subject->addData($input);
}
/**
* @test
*/
public function addDataKeepsLocalizationModeSelectIfChildIsLocalizable()
{
$input = [
'defaultLanguageRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'inline',
'foreign_table' => 'aForeignTableName',
'behaviour' => [
'localizationMode' => 'select',
]
],
],
],
],
];
$GLOBALS['TCA']['aForeignTableName']['ctrl'] = [
'languageField' => 'theLanguageField',
'transOrigPointerField' => 'theTransOrigPointerField',
];
$expected = $input;
$expected['processedTca']['columns']['aField']['config'] = $this->defaultConfig;
$expected['processedTca']['columns']['aField']['config']['behaviour']['localizationMode'] = 'select';
$this->assertEquals($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataKeepsLocalizationModeKeep()
{
$input = [
'defaultLanguageRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'inline',
'foreign_table' => 'aForeignTableName',
'behaviour' => [
'localizationMode' => 'keep',
]
],
],
],
],
];
$expected = $input;
$expected['processedTca']['columns']['aField']['config'] = $this->defaultConfig;
$expected['processedTca']['columns']['aField']['config']['behaviour']['localizationMode'] = 'keep';
$this->assertEquals($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataSetsLocalizationModeToNoneIfNotSetAndChildIsNotLocalizable()
{
$input = [
'defaultLanguageRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'inline',
'foreign_table' => 'aForeignTableName',
],
],
],
],
];
$expected = $input;
$expected['processedTca']['columns']['aField']['config'] = $this->defaultConfig;
$expected['processedTca']['columns']['aField']['config']['behaviour']['localizationMode'] = 'none';
$this->assertEquals($expected, $this->subject->addData($input));
}
/**
* @test
*/
public function addDataSetsLocalizationModeToSelectIfNotSetAndChildIsLocalizable()
{
$input = [
'defaultLanguageRow' => [],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'inline',
'foreign_table' => 'aForeignTableName',
],
],
],
],
];
$GLOBALS['TCA']['aForeignTableName']['ctrl'] = [
'languageField' => 'theLanguageField',
'transOrigPointerField' => 'theTransOrigPointerField',
];
$expected = $input;
$expected['processedTca']['columns']['aField']['config'] = $this->defaultConfig;
$expected['processedTca']['columns']['aField']['config']['behaviour']['localizationMode'] = 'select';
$this->assertEquals($expected, $this->subject->addData($input));
}
/**
* @test
*/
......
......@@ -67,7 +67,6 @@ class InlineStackProcessorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTes
'uid' => 'parentUid',
'field' => 'parentField',
'config' => null,
'localizationMode' => false,
],
],
'unstable' => [
......@@ -88,7 +87,6 @@ class InlineStackProcessorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTes
'uid' => 'parentUid',
'field' => 'parentField',
'config' => null,
'localizationMode' => false,
],
],
'unstable' => [
......@@ -110,7 +108,6 @@ class InlineStackProcessorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTes
'uid' => 'parentUid',
'field' => 'parentField',
'config' => null,
'localizationMode' => false,
],
],
'unstable' => [
......@@ -133,14 +130,12 @@ class InlineStackProcessorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTes
'uid' => 'grandParentUid',
'field' => 'grandParentField',
'config' => null,
'localizationMode' => false,
],
[
'table' => 'parentTable',
'uid' => 'parentUid',
'field' => 'parentField',
'config' => null,
'localizationMode' => false,
],
],
'unstable' => [
......@@ -161,14 +156,12 @@ class InlineStackProcessorTest extends \TYPO3\TestingFramework\Core\Unit\UnitTes
'uid' => 'grandParentUid',
'field' => 'grandParentField',
'config' => null,
'localizationMode' => false,
],