diff --git a/Classes/Hooks/Datahandler/CommandMapPostProcessingHook.php b/Classes/Hooks/Datahandler/CommandMapPostProcessingHook.php index b4e80719..6ebb68aa 100644 --- a/Classes/Hooks/Datahandler/CommandMapPostProcessingHook.php +++ b/Classes/Hooks/Datahandler/CommandMapPostProcessingHook.php @@ -75,6 +75,7 @@ protected function copyToLanguageChildren(int $uid, int $language, string $comma if ($newId === null) { continue; } + $this->keepHiddenState($newId, $record, $dataHandler); $cmd = ['tt_content' => [$newId=> [ 'move' => [ 'target' => -$last, @@ -106,12 +107,29 @@ protected function localizeChildren(int $uid, int $language, string $command, Da $localDataHandler->enableLogging = $dataHandler->enableLogging; $localDataHandler->start([], $cmd, $dataHandler->BE_USER); $localDataHandler->process_cmdmap(); + $newId = $localDataHandler->copyMappingArray['tt_content'][$record['uid']] ?? null; + if ($newId !== null) { + $this->keepHiddenState($newId, $record, $dataHandler); + } } } catch (Exception $e) { // nothing todo } } + /** + * Localize/copyToLanguage always hide the new record unless the source was already hidden + * (TcaSchemaCapability::HideRecordsAtCopy), losing the original per-child visibility. Restore it explicitly, + * since neither 'localize' nor 'copyToLanguage' cmdmap commands support an 'update' override array. + */ + protected function keepHiddenState(int $newId, array $record, DataHandler $dataHandler): void + { + $hiddenStateDataHandler = GeneralUtility::makeInstance(DataHandler::class); + $hiddenStateDataHandler->enableLogging = $dataHandler->enableLogging; + $hiddenStateDataHandler->start(['tt_content' => [$newId => ['hidden' => (int)$record['hidden']]]], [], $dataHandler->BE_USER); + $hiddenStateDataHandler->process_datamap(); + } + protected function copyOrMoveChildren(int $origUid, int $newId, int $containerId, string $command, DataHandler $dataHandler): void { try { @@ -144,6 +162,8 @@ protected function copyOrMoveChildren(int $origUid, int $newId, int $containerId 'update' => [ 'tx_container_parent' => $containerId, 'colPos' => $record['colPos'], + // keep the original hidden state instead of DataHandler's hideAtCopy default + 'hidden' => (int)$record['hidden'], ], ], ], diff --git a/Tests/Functional/Datahandler/DefaultLanguage/ContainerTest.php b/Tests/Functional/Datahandler/DefaultLanguage/ContainerTest.php index 29551388..8e79b212 100644 --- a/Tests/Functional/Datahandler/DefaultLanguage/ContainerTest.php +++ b/Tests/Functional/Datahandler/DefaultLanguage/ContainerTest.php @@ -244,6 +244,28 @@ public function copyContainerKeepsSortingOfChildren(): void self::assertCSVDataSet(__DIR__ . '/Fixtures/Container/CopyContainerKeepsSortingOfChildrenResult.csv'); } + #[Test] + public function copyContainerKeepsHiddenStateOfChildren(): void + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildren.csv'); + $cmdmap = [ + 'tt_content' => [ + 1 => [ + 'copy' => [ + 'action' => 'paste', + 'target' => 3, + 'update' => [ + 'colPos' => 0, + ], + ], + ], + ], + ]; + $this->dataHandler->start([], $cmdmap, $this->backendUser); + $this->dataHandler->process_cmdmap(); + self::assertCSVDataSet(__DIR__ . '/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildrenResult.csv'); + } + #[Test] public function moveContainerOtherPageOnTop(): void { diff --git a/Tests/Functional/Datahandler/DefaultLanguage/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildren.csv b/Tests/Functional/Datahandler/DefaultLanguage/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildren.csv new file mode 100644 index 00000000..b5ed6d84 --- /dev/null +++ b/Tests/Functional/Datahandler/DefaultLanguage/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildren.csv @@ -0,0 +1,9 @@ +"pages" +,"uid","pid","title" +,1,0,"page-1" +,3,0,"page-2" +"tt_content" +,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","l18n_parent","hidden" +,1,1,"b13-2cols-with-header-container","container-default",56,0,0,0,0,0 +,2,1,"header","header-default",128,0,200,1,0,1 +,5,1,"header","second element",256,0,200,1,0,0 diff --git a/Tests/Functional/Datahandler/DefaultLanguage/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildrenResult.csv b/Tests/Functional/Datahandler/DefaultLanguage/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildrenResult.csv new file mode 100644 index 00000000..fb9269cf --- /dev/null +++ b/Tests/Functional/Datahandler/DefaultLanguage/Fixtures/Container/CopyContainerKeepsHiddenStateOfChildrenResult.csv @@ -0,0 +1,12 @@ +"pages" +,"uid","pid","title" +,1,0,"page-1" +,3,0,"page-2" +"tt_content" +,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","l18n_parent","hidden" +,1,1,"b13-2cols-with-header-container","container-default",56,0,0,0,0,0 +,2,1,"header","header-default",128,0,200,1,0,1 +,5,1,"header","second element",256,0,200,1,0,0 +,6,3,"b13-2cols-with-header-container","container-default",256,0,0,0,0,1 +,7,3,"header","second element",512,0,200,6,0,0 +,8,3,"header","header-default",384,0,200,6,0,1 diff --git a/Tests/Functional/Datahandler/Localization/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildren.csv b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildren.csv new file mode 100644 index 00000000..efc7a365 --- /dev/null +++ b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildren.csv @@ -0,0 +1,8 @@ +"pages" +,"uid","pid","title","slug","sys_language_uid","l10n_parent","l10n_source" +,1,0,"page-1","/",,, +,2,0,"page-1-language-1","/",1,1,1 +"tt_content" +,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","hidden" +,1,1,"b13-2cols-with-header-container","container-language-1",128,0,0,0,0 +,2,1,"header","header-language-1",256,0,200,1,0 diff --git a/Tests/Functional/Datahandler/Localization/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildrenResult.csv b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildrenResult.csv new file mode 100644 index 00000000..409065b2 --- /dev/null +++ b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildrenResult.csv @@ -0,0 +1,10 @@ +"pages" +,"uid","pid","title" +,1,0,"page-1" +,2,0,"page-1-language-1" +"tt_content" +,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","l18n_parent","l10n_source","hidden" +,1,1,"b13-2cols-with-header-container","container-language-1",128,0,0,0,0,0,0 +,2,1,"header","header-language-1",256,0,200,1,0,0,0 +,3,1,"b13-2cols-with-header-container","[Translate to german:] container-language-1",512,1,0,0,0,1,1 +,4,1,"header","[Translate to german:] header-language-1",640,1,200,3,0,2,0 diff --git a/Tests/Functional/Datahandler/Localization/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildren.csv b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildren.csv new file mode 100644 index 00000000..efc7a365 --- /dev/null +++ b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildren.csv @@ -0,0 +1,8 @@ +"pages" +,"uid","pid","title","slug","sys_language_uid","l10n_parent","l10n_source" +,1,0,"page-1","/",,, +,2,0,"page-1-language-1","/",1,1,1 +"tt_content" +,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","hidden" +,1,1,"b13-2cols-with-header-container","container-language-1",128,0,0,0,0 +,2,1,"header","header-language-1",256,0,200,1,0 diff --git a/Tests/Functional/Datahandler/Localization/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildrenResult.csv b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildrenResult.csv new file mode 100644 index 00000000..45a075a3 --- /dev/null +++ b/Tests/Functional/Datahandler/Localization/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildrenResult.csv @@ -0,0 +1,10 @@ +"pages" +,"uid","pid","title" +,1,0,"page-1" +,2,0,"page-1-language-1" +"tt_content" +,"uid","pid","CType","header","sorting","sys_language_uid","colPos","tx_container_parent","l18n_parent","l10n_source","hidden" +,1,1,"b13-2cols-with-header-container","container-language-1",128,0,0,0,0,0,0 +,2,1,"header","header-language-1",256,0,200,1,0,0,0 +,3,1,"b13-2cols-with-header-container","[Translate to german:] container-language-1",192,1,0,0,1,1,1 +,4,1,"header","[Translate to german:] header-language-1",512,1,200,1,2,2,0 diff --git a/Tests/Functional/Datahandler/Localization/LocalizeTest.php b/Tests/Functional/Datahandler/Localization/LocalizeTest.php index 13711dcd..deae19dd 100644 --- a/Tests/Functional/Datahandler/Localization/LocalizeTest.php +++ b/Tests/Functional/Datahandler/Localization/LocalizeTest.php @@ -69,6 +69,38 @@ public function localizeContainerLocalizeChildren(): void self::assertCSVDataSet(__DIR__ . '/Fixtures/Localize/LocalizeContainerLocalizeChildrenResult.csv'); } + #[Test] + public function localizeContainerKeepsHiddenStateOfChildren(): void + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildren.csv'); + $cmdmap = [ + 'tt_content' => [ + 1 => [ + 'localize' => 1, + ], + ], + ]; + $this->dataHandler->start([], $cmdmap, $this->backendUser); + $this->dataHandler->process_cmdmap(); + self::assertCSVDataSet(__DIR__ . '/Fixtures/Localize/LocalizeContainerKeepsHiddenStateOfChildrenResult.csv'); + } + + #[Test] + public function copyContainerToLanguageKeepsHiddenStateOfChildren(): void + { + $this->importCSVDataSet(__DIR__ . '/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildren.csv'); + $cmdmap = [ + 'tt_content' => [ + 1 => [ + 'copyToLanguage' => 1, + ], + ], + ]; + $this->dataHandler->start([], $cmdmap, $this->backendUser); + $this->dataHandler->process_cmdmap(); + self::assertCSVDataSet(__DIR__ . '/Fixtures/Localize/CopyContainerToLanguageKeepsHiddenStateOfChildrenResult.csv'); + } + #[Test] public function localizeNestedContainerKeepsDefaultLanguageParent(): void {