From 4770e0b787682dd5d3f18326834604dad370604b Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Mon, 13 Nov 2017 20:33:53 +0100 Subject: [PATCH] [BUGFIX] Ensure "pid" and "parentid" of pages - inline fields are correct When doing translations with pages and inline elements (e.g. pages.media), there is an inconsistency when an additional inline element is added to the TRANSLATED page (e.g. language=1). Current (wrong) when adding a translation to a page - localized IRRE children get pid = default page ID (correct) - localized IRRE children only localization get parentid = default page ID (should be translated page ID) Current (wrong) behaviour when adding a IRRE child only available in a translation: - parentid gets localized page => correct - pid gets set to localized page => must be default language The patch corrects this behaviour by always set - the relation (parentid) to the localized page ID - the page ID (pid) to the default language page ID Additionally, when adding an Inline element (IRRE) via AJAX on page properties, the PID gets resolved correctly to be sent to DataHandler. Resolves: #82983 Releases: master Change-Id: Id8bf39524ee608acf452e2b7103087d4299c1e28 Reviewed-on: https://review.typo3.org/54632 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Daniel Gorges <daniel.gorges@b13.de> Tested-by: Daniel Gorges <daniel.gorges@b13.de> Reviewed-by: Susanne Moog <susanne.moog@typo3.org> Tested-by: Susanne Moog <susanne.moog@typo3.org> --- .../Form/FormDataProvider/TcaInline.php | 4 ++++ .../core/Classes/DataHandling/DataHandler.php | 13 ++++++++++++- .../ForeignField/AbstractActionTestCase.php | 18 ++++++++++++++++++ .../IRRE/ForeignField/Modify/ActionTest.php | 18 ++++++++++++++++++ ...hSynchronizationAndCustomLocalizedHotel.csv | 15 +++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php index 18401cfb6885..6fc3d6dd50e8 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php @@ -106,6 +106,10 @@ class TcaInline extends AbstractDatabaseRecordProvider implements FormDataProvid } else { $pid = $row['pid']; } + $pageRecord = BackendUtility::getRecord('pages', $pid); + if ((int)$pageRecord['l10n_parent'] > 0) { + $pid = (int)$pageRecord['l10n_parent']; + } $result['inlineFirstPid'] = (int)$pid; } return $result; diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index 53c95637e4bf..90446007b082 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -1316,6 +1316,11 @@ class DataHandler implements LoggerAwareInterface $sortRow = $GLOBALS['TCA'][$table]['ctrl']['sortby']; // Points to a page on which to insert the element, possibly in the top of the page if ($pid >= 0) { + // Ensure that the "pid" is not a translated page ID, but the default page ID + $localizationParent = $this->recordInfo('pages', $pid, 'l10n_parent'); + if ($localizationParent['l10n_parent'] > 0) { + $pid = (int)$localizationParent['l10n_parent']; + } // The numerical pid is inserted in the data array $fieldArray['pid'] = $pid; // If this table is sorted we better find the top sorting number @@ -1332,7 +1337,13 @@ class DataHandler implements LoggerAwareInterface } else { // Here we fetch the PID of the record that we point to $record = $this->recordInfo($table, abs($pid), 'pid'); - $fieldArray['pid'] = $record['pid']; + $pid = $record['pid']; + // Ensure that the "pid" is not a translated page ID, but the default page ID + $localizationParent = $this->recordInfo('pages', $pid, 'l10n_parent'); + if ($localizationParent['l10n_parent'] > 0) { + $pid = (int)$localizationParent['l10n_parent']; + } + $fieldArray['pid'] = $pid; } return $fieldArray; } diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php index caf26096f77d..c4599ca0bea1 100644 --- a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php +++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php @@ -493,4 +493,22 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D $newTableIds = $this->actionService->copyRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_PageIdTarget); $this->recordIds['newPageId'] = $newTableIds[self::TABLE_Page][self::VALUE_PageId]; } + + public function localizePageWithSynchronizationAndCustomLocalizedHotel() + { + // in these test cases we expect new pages not to be hidden in order to + // verify proper overlaying behavior during the frontend render process + $GLOBALS['TCA'][self::TABLE_Page]['columns']['hidden']['config']['default'] = 0; + $GLOBALS['TCA'][self::TABLE_Page]['columns'][self::FIELD_PageHotel]['config']['behaviour']['allowLanguageSynchronization'] = true; + $localizedTableIds = $this->actionService->localizeRecord(self::TABLE_Page, self::VALUE_PageId, self::VALUE_LanguageId); + $this->recordIds['localizedPageId'] = $localizedTableIds[self::TABLE_Page][self::VALUE_PageId]; + // Using "localized page ID" on purpose because BE editing uses a "page" record and data handler + $this->actionService->modifyRecords( + $this->recordIds['localizedPageId'], + [ + self::TABLE_Page => ['uid' => $this->recordIds['localizedPageId'], self::FIELD_PageHotel => '6,__nextUid'], + self::TABLE_Hotel => ['uid' => '__NEW', 'sys_language_uid' => self::VALUE_LanguageId, 'title' => 'Hotel in dansk page only'], + ] + ); + } } 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 5b60ba9d8f7a..626e87e2d7d5 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 @@ -547,6 +547,24 @@ class ActionTest extends \TYPO3\CMS\Core\Tests\Functional\DataHandling\IRRE\Fore ->setTable(self::TABLE_Hotel)->setField('title')->setValues('[Translate to Dansk:] Hotel #0')); } + /** + * Checks for a page having a IRRE record. The page is then localized and + * an IRRE record is then added to the localized page + * + * @test + * @see DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv + */ + public function localizePageWithSynchronizationAndCustomLocalizedHotel() + { + parent::localizePageWithSynchronizationAndCustomLocalizedHotel(); + $this->assertAssertionDataSet('localizePageWithSynchronizationAndCustomLocalizedHotel'); + + $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('[Translate to Dansk:] Hotel #0')); + } + /** * @test * @see DataSet/localizePageAddMonoglotHotelChildNCopyPageWSynchronization.csv diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv new file mode 100644 index 000000000000..57676d2e07d3 --- /dev/null +++ b/typo3/sysext/core/Tests/Functional/DataHandling/IRRE/ForeignField/Modify/DataSet/localizePageWithSynchronizationAndCustomLocalizedHotel.csv @@ -0,0 +1,15 @@ +pages +,uid,pid,sorting,deleted,sys_language_uid,l10n_parent,t3_origuid,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,title,tx_irretutorial_hotels,l10n_state +,1,0,256,0,0,0,0,0,0,0,0,0,FunctionalTest,0, +,88,1,256,0,0,0,0,0,0,0,0,0,DataHandlerTest,0, +,89,88,256,0,0,0,0,0,0,0,0,0,Relations,1, +,90,88,512,0,0,0,0,0,0,0,0,0,Target,0, +,91,88,256,0,1,89,0,0,0,0,0,0,"[Translate to Dansk:] Relations",2,"{""url"":""parent"",""lastUpdated"":""parent"",""newUntil"":""parent"",""no_search"":""parent"",""shortcut"":""parent"",""shortcut_mode"":""parent"",""author"":""parent"",""author_email"":""parent"",""media"":""parent"",""tx_irretutorial_hotels"":""parent""}" +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,512,0,0,0,0,0,0,0,0,0,"Hotel #0",89,pages,,0 +,3,89,1024,0,0,0,0,0,0,0,0,0,"Hotel #1",297,tt_content,,2 +,4,89,1536,0,0,0,0,0,0,0,0,0,"Hotel #2",297,tt_content,,1 +,5,89,1280,0,0,0,0,0,0,0,0,0,"Hotel #1",298,tt_content,,1 +,6,89,1,0,1,2,2,0,0,0,0,0,"[Translate to Dansk:] Hotel #0",91,pages,,0 +,7,89,2,0,1,0,0,0,0,0,0,0,"Hotel in dansk page only",91,pages,,0 -- GitLab