diff --git a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php index a2e2b57023049f7a8cfda647b93d0b316c61fcd7..f26f031cee58e50acbb3bb1228bfc77417d8815f 100644 --- a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php +++ b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php @@ -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 ) diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php index a8cde508c53acee1e0f440ce0f6b753061a8e1a2..71f47a7e213ef3acd37a41e6e79040614f3d56cc 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php +++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/ActionTest.php @@ -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')); + } } diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv new file mode 100644 index 0000000000000000000000000000000000000000..12f915614868bb0cd76c413a2b75ad60fc547e54 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv @@ -0,0 +1,59 @@ +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, diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php index c5e9f5be6eeef65da5a45e70a4a64e693a1332e6..ca0219b1b72bfb9060aa775a0ab7ed8734035292 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php +++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/ActionTest.php @@ -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 diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeContentWSynchronization.csv b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeContentWSynchronization.csv index 741cfaa28b39c5d7c72a4e9dd400b3871ea55ace..4d65cc969638033ef7b4e30245fa475b2f6af5f5 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeContentWSynchronization.csv +++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeContentWSynchronization.csv @@ -1,9 +1,9 @@ -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""}" diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeNCopyPage.csv b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeNCopyPage.csv new file mode 100644 index 0000000000000000000000000000000000000000..a28e910acca6ac86af6e5adc75d7e4d206ae0dfb --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeNCopyPage.csv @@ -0,0 +1,25 @@ +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" diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeNCopyPageWSynchronization.csv b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeNCopyPageWSynchronization.csv new file mode 100644 index 0000000000000000000000000000000000000000..fbd4291c864afd1c4eaf1e2a8d64de5ec83aed93 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/DataHandling/Regular/Modify/DataSet/localizeNCopyPageWSynchronization.csv @@ -0,0 +1,25 @@ +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"