Commit 5a8b7f2a authored by Oliver Hader's avatar Oliver Hader Committed by Benni Mack
Browse files

[BUGFIX] MM language synchronization is ignored on initial localization

The language synchronization of many-to-many fields (MM) is ignored for
the initial localization command, but is considered again when further
changes happen to source/parent elements of a localized element.

Besides fixing the missing 'config' segment on resolving the foreign
table name of the field to be synchronized, the special handling for
language assignments has been added - albeit it might not been used
in fields different to sys_language_uid.

Change-Id: I8bf02ee117fa41cf5b0425d0e535fced84fb72ca
Resolves: #80211
Releases: master
Reviewed-on: https://review.typo3.org/52004


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog's avatarSusanne Moog <susanne.moog@typo3.org>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarChristian Müllenhagen <christianmuellenhagen@yahoo.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent f1fbc80f
......@@ -417,13 +417,14 @@ class DataMapProcessor
$fromId = $fromRecord['uid'];
$fromValue = $this->allDataMap[$item->getFromTableName()][$fromId][$fieldName] ?? $fromRecord[$fieldName];
$configuration = $GLOBALS['TCA'][$item->getFromTableName()]['columns'][$fieldName];
$isSpecialLanguageField = ($configuration['config']['special'] ?? null) === 'languages';
// non-MM relations are stored as comma separated values, just use them
// if values are available in data-map already, just use them as well
if (
empty($configuration['config']['MM'])
|| isset($this->allDataMap[$item->getFromTableName()][$fromId][$fieldName])
|| ($configuration['config']['special'] ?? null) === 'languages'
|| $isSpecialLanguageField
) {
$this->modifyDataMap(
$item->getTableName(),
......@@ -432,14 +433,17 @@ class DataMapProcessor
);
return;
}
// resolve the language special table name
if ($isSpecialLanguageField) {
$specialTableName = 'sys_language';
}
// fetch MM relations from storage
$type = $configuration['config']['type'];
$manyToManyTable = $configuration['config']['MM'];
if ($type === 'group' && $configuration['config']['internal_type'] === 'db') {
$tableNames = trim($configuration['config']['allowed'] ?? '');
} elseif ($configuration['config']['type'] === 'select') {
$tableNames = ($configuration['foreign_table'] ?? '');
$tableNames = ($specialTableName ?? $configuration['config']['foreign_table'] ?? '');
} else {
return;
}
......
......@@ -24,14 +24,19 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
const VALUE_ContentIdFirst = 297;
const VALUE_ContentIdLast = 298;
const VALUE_LanguageId = 1;
const VALUE_LanguageIdSecond = 2;
const VALUE_CategoryIdFirst = 28;
const VALUE_CategoryIdSecond = 29;
const VALUE_CategoryIdThird = 30;
const VALUE_CategoryIdFourth = 31;
const TABLE_Page = 'pages';
const TABLE_Content = 'tt_content';
const TABLE_Category = 'sys_category';
const TABLE_ContentCategory_ManyToMany = 'sys_category_record_mm';
const FIELD_Categories = 'categories';
/**
* @var string
*/
......@@ -178,6 +183,42 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
$this->recordIds['localizedContentId'] = $localizedTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
}
public function localizeContentOfRelationWithLanguageSynchronization()
{
$GLOBALS['TCA'][self::TABLE_Content]['columns'][self::FIELD_Categories]['config']['behaviour']['allowLanguageSynchronization'] = true;
$localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, self::VALUE_ContentIdLast, self::VALUE_LanguageId);
$this->recordIds['localizedContentId'] = $localizedTableIds[self::TABLE_Content][self::VALUE_ContentIdLast];
}
public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization()
{
self::localizeContentOfRelationWithLanguageSynchronization();
$this->actionService->modifyReferences(
self::TABLE_Content,
self::VALUE_ContentIdLast,
self::FIELD_Categories,
[self::VALUE_CategoryIdSecond, self::VALUE_CategoryIdThird, self::VALUE_CategoryIdFourth]
);
}
public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization()
{
self::localizeContentOfRelationWithLanguageSynchronization();
$localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Content, $this->recordIds['localizedContentId'], self::VALUE_LanguageIdSecond);
$this->recordIds['localizedContentIdSecond'] = $localizedTableIds[self::TABLE_Content][$this->recordIds['localizedContentId']];
$this->actionService->modifyRecord(
self::TABLE_Content,
$this->recordIds['localizedContentIdSecond'],
['l10n_state' => [self::FIELD_Categories => 'source']]
);
$this->actionService->modifyReferences(
self::TABLE_Content,
self::VALUE_ContentIdLast,
self::FIELD_Categories,
[self::VALUE_CategoryIdSecond, self::VALUE_CategoryIdThird, self::VALUE_CategoryIdFourth]
);
}
/**
* @test
* @see DataSet/localizeCategoryRecordOfCategoryRelation.csv
......
......@@ -227,6 +227,51 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\ManyToMan
->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
}
/**
* @test
* @see DataSet/localizeContentOfRelationWSynchronization.csv
*/
public function localizeContentOfRelationWithLanguageSynchronization()
{
parent::localizeContentOfRelationWithLanguageSynchronization();
$this->assertAssertionDataSet('localizeContentOfRelationWSynchronization');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField('categories')
->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C'));
}
/**
* @test
* @see DataSet/localizeContentOfRelationNAddCategoryWSynchronization.csv
*/
public function localizeContentOfRelationAndAddCategoryWithLanguageSynchronization()
{
parent::localizeContentOfRelationAndAddCategoryWithLanguageSynchronization();
$this->assertAssertionDataSet('localizeContentOfRelationNAddCategoryWSynchronization');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField('categories')
->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
}
/**
* @test
* @see DataSet/localizeContentChainOfRelationNAddCategoryWSynchronization.csv
*/
public function localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization()
{
parent::localizeContentChainOfRelationAndAddCategoryWithLanguageSynchronization();
$this->assertAssertionDataSet('localizeContentChainOfRelationNAddCategoryWSynchronization');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageIdSecond)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
->setRecordIdentifier(self::TABLE_Content . ':' . self::VALUE_ContentIdLast)->setRecordField('categories')
->setTable(self::TABLE_Category)->setField('title')->setValues('Category B', 'Category C', 'Category A.A'));
}
/**
* @test
* @see DataSet/localizeCategoryRecordOfCategoryRelation.csv
......
sys_category
,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parent,items
,28,0,256,0,0,0,0,0,0,0,0,0,"Category A",0,0
,29,0,512,0,0,0,0,0,0,0,0,0,"Category B",0,0
,30,0,768,0,0,0,0,0,0,0,0,0,"Category C",0,0
,31,0,1024,0,0,0,0,0,0,0,0,0,"Category A.A",28,0
sys_category_record_mm
,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
,28,297,tt_content,0,1,categories
,29,297,tt_content,0,2,categories
,29,298,tt_content,0,1,categories
,30,298,tt_content,0,2,categories
,29,299,tt_content,0,1,categories
,30,299,tt_content,0,2,categories
,29,300,tt_content,0,1,categories
,30,300,tt_content,0,2,categories
,31,298,tt_content,0,3,categories
,31,299,tt_content,0,3,categories
,31,300,tt_content,0,3,categories
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",0,2,\NULL
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",0,3,\NULL
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",0,3,"{""categories"":""parent""}"
,300,89,1024,0,2,298,299,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #2",0,3,"{""categories"":""source""}"
sys_category
,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parent,items
,28,0,256,0,0,0,0,0,0,0,0,0,"Category A",0,0
,29,0,512,0,0,0,0,0,0,0,0,0,"Category B",0,0
,30,0,768,0,0,0,0,0,0,0,0,0,"Category C",0,0
,31,0,1024,0,0,0,0,0,0,0,0,0,"Category A.A",28,0
sys_category_record_mm
,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
,28,297,tt_content,0,1,categories
,29,297,tt_content,0,2,categories
,29,298,tt_content,0,1,categories
,30,298,tt_content,0,2,categories
,31,298,tt_content,0,3,categories
,29,299,tt_content,0,1,categories
,30,299,tt_content,0,2,categories
,31,299,tt_content,0,3,categories
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",0,2,\NULL
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",0,3,\NULL
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",0,3,"{""categories"":""parent""}"
sys_category
,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parent,items
,28,0,256,0,0,0,0,0,0,0,0,0,"Category A",0,0
,29,0,512,0,0,0,0,0,0,0,0,0,"Category B",0,0
,30,0,768,0,0,0,0,0,0,0,0,0,"Category C",0,0
,31,0,1024,0,0,0,0,0,0,0,0,0,"Category A.A",28,0
sys_category_record_mm
,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
,28,297,tt_content,0,1,categories
,29,297,tt_content,0,2,categories
,29,298,tt_content,0,1,categories
,30,298,tt_content,0,2,categories
,29,299,tt_content,0,1,categories
,30,299,tt_content,0,2,categories
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",0,2,\NULL
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",0,2,\NULL
,299,89,768,0,1,298,298,0,0,0,0,0,"[Translate to Dansk:] Regular Element #2",0,2,"{""categories"":""parent""}"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment