Commit 326ca5d7 authored by Oliver Hader's avatar Oliver Hader Committed by Oliver Hader
Browse files

[FOLLOWUP][TASK] Enhance DataHandler translation and synchronization handling

Copying a page translation having an 1:n monoglot inline relation leads
to an SQL error which is silently put to sys_log in DataHandler. Besides
that, the inline children are superfluously duplicated since there is no
connection between those copied records anymore.

Resolves: #79856
Releases: master
Change-Id: Ife5cfdea1c1d9dff764ea3d28e0a35a83d5919e1
Reviewed-on: https://review.typo3.org/51784


Reviewed-by: default avatarMorton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: default avatarMorton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
parent 54306301
......@@ -51,6 +51,11 @@ class DataMapProcessor
*/
protected $dataMap = [];
/**
* @var array
*/
protected $sanitizationMap = [];
/**
* @var BackendUserAuthentication
*/
......@@ -221,10 +226,17 @@ class DataMapProcessor
$this->getFieldNamesForItemScope($item, DataMapItem::SCOPE_PARENT, !$item->isNew()),
$this->getFieldNamesForItemScope($item, DataMapItem::SCOPE_SOURCE, !$item->isNew())
);
$fieldNameMap = array_combine($fieldNames, $fieldNames);
// separate fields, that are submitted in data-map, but not defined as custom
$this->sanitizationMap[$item->getTableName()][$item->getId()] = array_intersect_key(
$this->dataMap[$item->getTableName()][$item->getId()],
$fieldNameMap
);
// remove fields, that are submitted in data-map, but not defined as custom
$this->dataMap[$item->getTableName()][$item->getId()] = array_diff_key(
$this->dataMap[$item->getTableName()][$item->getId()],
array_combine($fieldNames, $fieldNames)
$fieldNameMap
);
}
......@@ -489,6 +501,22 @@ class DataMapProcessor
);
return;
}
// In case only missing elements shall be created, re-use previously sanitized
// values IF child table cannot be translated, the relation parent item is new
// and the count of missing relations equals the count of previously sanitized
// relations. This is caused during copy processes, when the child relations
// already have been cloned in DataHandler::copyRecord_procBasedOnFieldType()
// without the possibility to resolve the initial connections at this point.
// Otherwise child relations would superfluously be duplicated again here.
// @todo Invalid manually injected child relations cannot be determined here
$sanitizedValue = $this->sanitizationMap[$item->getTableName()][$item->getId()][$fieldName] ?? null;
if (!empty($missingAncestorIds) && $item->isNew()
&& $sanitizedValue !== null && !$isTranslatable
&& count(GeneralUtility::trimExplode(',', $sanitizedValue)) === count($missingAncestorIds)
) {
$this->dataMap[$item->getTableName()][$item->getId()][$fieldName] = $sanitizedValue;
return;
}
$localCommandMap = [];
foreach ($removeIds as $removeId) {
......@@ -753,7 +781,7 @@ class DataMapProcessor
// fetch by origin dependency ("copied from")
} elseif (!empty($fieldNames['origin'])) {
$predicates = [
$queryBuilder->expr()->eq(
$queryBuilder->expr()->in(
$fieldNames['origin'],
$idsParameter
)
......
......@@ -606,4 +606,20 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\IRRE\Fore
->setRecordIdentifier(self::TABLE_Page . ':' . self::VALUE_PageId)->setRecordField(self::FIELD_PageHotel)
->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0'));
}
/**
* @test
* @see DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv
*/
public function localizePageAddMonoglotHotelChildAndCopyPageWithLanguageSynchronization()
{
parent::localizePageAndAddMonoglotHotelChildWithLanguageSynchronization();
parent::copyPage();
$this->assertAssertionDataSet('localizePageAddMonoglotHotelChildNCopyPageWSynchronization');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionStructureHasRecordConstraint()
->setRecordIdentifier(self::TABLE_Page . ':' . self::VALUE_PageId)->setRecordField(self::FIELD_PageHotel)
->setTable(self::TABLE_Hotel)->setField('title')->setValues('Hotel #0', 'Hotel #007'));
}
}
pages
,uid,pid,sorting,deleted,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,tx_irretutorial_hotels
,1,0,256,0,0,0,0,0,0,0,FunctionalTest,0
,88,1,256,0,0,0,0,0,0,0,DataHandlerTest,0
,89,88,256,0,0,0,0,0,0,0,Relations,2
,90,88,512,0,0,0,0,0,0,0,Target,0
,91,90,256,0,89,0,0,0,0,0,Relations,2
pages_language_overlay
,uid,pid,deleted,sys_language_uid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,title,tx_irretutorial_hotels,l10n_state
,1,89,0,1,0,0,0,0,"[Translate to Dansk:] Relations",2,"{""tx_irretutorial_hotels"":""parent""}"
,2,91,0,1,0,0,0,0,"[Translate to Dansk:] Relations",2,"{""tx_irretutorial_hotels"":""parent""}"
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,tx_irretutorial_1nff_hotels
,297,89,256,0,0,0,0,0,0,0,0,0,"Regular Element #1",2
,298,89,512,0,0,0,0,0,0,0,0,0,"Regular Element #2",1
,299,91,256,0,0,0,298,0,0,0,0,0,"Regular Element #2",1
,300,91,128,0,0,0,297,0,0,0,0,0,"Regular Element #1",2
tx_irretutorial_1nff_hotel
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier,offers
,2,89,1,0,0,0,0,0,0,0,0,0,"Hotel #0",89,pages,,0
,3,89,1280,0,0,0,0,0,0,0,0,0,"Hotel #1",297,tt_content,,2
,4,89,1792,0,0,0,0,0,0,0,0,0,"Hotel #2",297,tt_content,,1
,5,89,1536,0,0,0,0,0,0,0,0,0,"Hotel #1",298,tt_content,,1
,6,89,1,0,0,0,2,0,0,0,0,0,"Hotel #0",1,pages_language_overlay,,0
,7,89,2,0,0,0,0,0,0,0,0,0,"Hotel #007",89,pages,,0
,8,89,2,0,0,0,0,0,0,0,0,0,"Hotel #007",1,pages_language_overlay,,0
,9,91,1,0,0,0,2,0,0,0,0,0,"Hotel #0",91,pages,,0
,10,91,2,0,0,0,7,0,0,0,0,0,"Hotel #007",91,pages,,0
,11,91,1,0,0,0,6,0,0,0,0,0,"Hotel #0",2,pages_language_overlay,,0
,12,91,2,0,0,0,8,0,0,0,0,0,"Hotel #007",2,pages_language_overlay,,0
,13,91,1,0,0,0,5,0,0,0,0,0,"Hotel #1",299,tt_content,,1
,14,91,1,0,0,0,3,0,0,0,0,0,"Hotel #1",300,tt_content,,2
,15,91,2,0,0,0,4,0,0,0,0,0,"Hotel #2",300,tt_content,,1
tx_irretutorial_1nff_offer
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier,prices
,5,89,1,0,0,0,0,0,0,0,0,0,"Offer #1.1",3,tx_irretutorial_1nff_hotel,,3
,6,89,2,0,0,0,0,0,0,0,0,0,"Offer #1.2",3,tx_irretutorial_1nff_hotel,,2
,7,89,1,0,0,0,0,0,0,0,0,0,"Offer #2.1",4,tx_irretutorial_1nff_hotel,,1
,8,89,1,0,0,0,0,0,0,0,0,0,"Offer #1.1",5,tx_irretutorial_1nff_hotel,,1
,9,91,1,0,0,0,8,0,0,0,0,0,"Offer #1.1",13,tx_irretutorial_1nff_hotel,,1
,10,91,1,0,0,0,5,0,0,0,0,0,"Offer #1.1",14,tx_irretutorial_1nff_hotel,,3
,11,91,2,0,0,0,6,0,0,0,0,0,"Offer #1.2",14,tx_irretutorial_1nff_hotel,,2
,12,91,1,0,0,0,7,0,0,0,0,0,"Offer #2.1",15,tx_irretutorial_1nff_hotel,,1
tx_irretutorial_1nff_price
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,parentid,parenttable,parentidentifier
,7,89,1,0,0,0,0,0,0,0,0,0,"Price #1.1.1",5,tx_irretutorial_1nff_offer,
,8,89,2,0,0,0,0,0,0,0,0,0,"Price #1.1.2",5,tx_irretutorial_1nff_offer,
,9,89,3,0,0,0,0,0,0,0,0,0,"Price #1.1.3",5,tx_irretutorial_1nff_offer,
,10,89,1,0,0,0,0,0,0,0,0,0,"Price #1.2.1",6,tx_irretutorial_1nff_offer,
,11,89,2,0,0,0,0,0,0,0,0,0,"Price #1.2.2",6,tx_irretutorial_1nff_offer,
,12,89,1,0,0,0,0,0,0,0,0,0,"Price #2.1.1",7,tx_irretutorial_1nff_offer,
,13,89,1,0,0,0,0,0,0,0,0,0,"Price #1.1.1",8,tx_irretutorial_1nff_offer,
,14,91,1,0,0,0,13,0,0,0,0,0,"Price #1.1.1",9,tx_irretutorial_1nff_offer,
,15,91,1,0,0,0,7,0,0,0,0,0,"Price #1.1.1",10,tx_irretutorial_1nff_offer,
,16,91,2,0,0,0,8,0,0,0,0,0,"Price #1.1.2",10,tx_irretutorial_1nff_offer,
,17,91,3,0,0,0,9,0,0,0,0,0,"Price #1.1.3",10,tx_irretutorial_1nff_offer,
,18,91,1,0,0,0,10,0,0,0,0,0,"Price #1.2.1",11,tx_irretutorial_1nff_offer,
,19,91,2,0,0,0,11,0,0,0,0,0,"Price #1.2.2",11,tx_irretutorial_1nff_offer,
,20,91,1,0,0,0,12,0,0,0,0,0,"Price #2.1.1",12,tx_irretutorial_1nff_offer,
......@@ -378,6 +378,21 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular\A
->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
}
/**
* @test
* @see DataSet/localizeNCopyPage.csv
*/
public function localizeAndCopyPage()
{
parent::localizePage();
parent::copyPage();
$this->assertAssertionDataSet('localizeNCopyPage');
$responseSections = $this->getFrontendResponse($this->recordIds['newPageId'], self::VALUE_LanguageId)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionHasRecordConstraint()
->setTable(self::TABLE_Page)->setField('title')->setValues('[Translate to Dansk:] Relations'));
}
/**
* @test
* @see DataSet/localizePageWSynchronization.csv
......@@ -392,6 +407,21 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\Regular\A
->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
}
/**
* @test
* @see DataSet/localizeNCopyPageWSynchronization.csv
*/
public function localizeAndCopyPageWithLanguageSynchronization()
{
parent::localizePageWithLanguageSynchronization();
parent::copyPage();
$this->assertAssertionDataSet('localizeNCopyPageWSynchronization');
$responseSections = $this->getFrontendResponse(self::VALUE_PageId, self::VALUE_LanguageId)->getResponseSections();
$this->assertThat($responseSections, $this->getRequestSectionHasRecordConstraint()
->setTable(self::TABLE_Page)->setField('title')->setValues('Testing #1'));
}
/**
* @test
* @see DataSet/changePageRecordSorting.csv
......
tt_content,,,,,,,,,,,,,,
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,l10n_source,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header
,297,89,256,0,0,0,0,0,0,0,0,0,0,Regular Element #1
,298,89,512,0,0,0,0,0,0,0,0,0,0,Testing #1
,299,89,768,0,0,0,0,0,0,0,0,0,0,Regular Element #3
,300,89,1024,0,1,299,299,299,0,0,0,0,0,[Translate to Dansk:] Regular Element #3
,301,89,384,0,1,297,297,297,0,0,0,0,0,[Translate to Dansk:] Regular Element #1
,302,89,448,0,2,297,301,301,0,0,0,0,0,[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1
,303,89,416,0,1,298,298,298,0,0,0,0,0,Testing #1
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,l10n_source,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,l10n_state
,297,89,256,0,0,0,0,0,0,0,0,0,0,"Regular Element #1",
,298,89,512,0,0,0,0,0,0,0,0,0,0,"Testing #1",\NULL
,299,89,768,0,0,0,0,0,0,0,0,0,0,"Regular Element #3",
,300,89,1024,0,1,299,299,299,0,0,0,0,0,"[Translate to Dansk:] Regular Element #3",
,301,89,384,0,1,297,297,297,0,0,0,0,0,"[Translate to Dansk:] Regular Element #1",
,302,89,448,0,2,297,301,301,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1",
,303,89,416,0,1,298,298,298,0,0,0,0,0,"Testing #1","{""header"":""parent""}"
pages
,uid,pid,sorting,deleted,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title
,1,0,256,0,0,0,0,0,0,0,FunctionalTest
,88,1,256,0,0,0,0,0,0,0,DataHandlerTest
,89,88,256,0,0,0,0,0,0,0,Relations
,90,88,512,0,0,0,0,0,0,0,Target
,91,90,256,0,89,0,0,0,0,0,Relations
pages_language_overlay
,uid,pid,deleted,sys_language_uid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,title
,1,89,0,1,0,0,0,0,"[Translate to Dansk:] Relations"
,2,91,0,1,0,0,0,0,"[Translate to Dansk:] Relations"
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,l10n_source,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header
,297,89,256,0,0,0,0,0,0,0,0,0,0,"Regular Element #1"
,298,89,512,0,0,0,0,0,0,0,0,0,0,"Regular Element #2"
,299,89,768,0,0,0,0,0,0,0,0,0,0,"Regular Element #3"
,300,89,1024,0,1,299,299,299,0,0,0,0,0,"[Translate to Dansk:] Regular Element #3"
,301,89,384,0,1,297,297,297,0,0,0,0,0,"[Translate to Dansk:] Regular Element #1"
,302,89,448,0,2,297,301,301,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1"
,303,91,256,0,0,0,0,299,0,0,0,0,0,"Regular Element #3"
,304,91,128,0,1,303,303,300,0,0,0,0,0,"[Translate to Dansk:] Regular Element #3"
,305,91,64,0,0,0,0,298,0,0,0,0,0,"Regular Element #2"
,306,91,32,0,0,0,0,297,0,0,0,0,0,"Regular Element #1"
,307,91,16,0,1,306,306,301,0,0,0,0,0,"[Translate to Dansk:] Regular Element #1"
,308,91,8,0,2,306,307,302,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1"
pages
,uid,pid,sorting,deleted,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title
,1,0,256,0,0,0,0,0,0,0,FunctionalTest
,88,1,256,0,0,0,0,0,0,0,DataHandlerTest
,89,88,256,0,0,0,0,0,0,0,"Testing #1"
,90,88,512,0,0,0,0,0,0,0,Target
,91,90,256,0,89,0,0,0,0,0,"Testing #1"
pages_language_overlay
,uid,pid,deleted,sys_language_uid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,title,l10n_state
,1,89,0,1,0,0,0,0,"Testing #1","{""title"":""parent""}"
,2,91,0,1,0,0,0,0,"Testing #1","{""title"":""parent""}"
tt_content
,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,l10n_source,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header
,297,89,256,0,0,0,0,0,0,0,0,0,0,"Regular Element #1"
,298,89,512,0,0,0,0,0,0,0,0,0,0,"Regular Element #2"
,299,89,768,0,0,0,0,0,0,0,0,0,0,"Regular Element #3"
,300,89,1024,0,1,299,299,299,0,0,0,0,0,"[Translate to Dansk:] Regular Element #3"
,301,89,384,0,1,297,297,297,0,0,0,0,0,"[Translate to Dansk:] Regular Element #1"
,302,89,448,0,2,297,301,301,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1"
,303,91,256,0,0,0,0,299,0,0,0,0,0,"Regular Element #3"
,304,91,128,0,1,303,303,300,0,0,0,0,0,"[Translate to Dansk:] Regular Element #3"
,305,91,64,0,0,0,0,298,0,0,0,0,0,"Regular Element #2"
,306,91,32,0,0,0,0,297,0,0,0,0,0,"Regular Element #1"
,307,91,16,0,1,306,306,301,0,0,0,0,0,"[Translate to Dansk:] Regular Element #1"
,308,91,8,0,2,306,307,302,0,0,0,0,0,"[Translate to Deutsch:] [Translate to Dansk:] Regular Element #1"
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