From 29f3d83f2e06f8f914cc74846cf0f6ec9aa68e45 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Mon, 7 Nov 2022 22:40:17 +0100 Subject: [PATCH] [BUGFIX] Keep existing baseVariants for site languages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backend UI does not support handling of baseVariants for languages, however it is possible to define them in the config.yaml of a site configuration. However, when editing and saving a site, the baseVariants manually defined were removed. This has now been changed, as the baseVariants are kept when persisting the site configuratino via the UI. Resolves: #93719 Releases: main, 11.5 Change-Id: I8a0b3be72ddfab46da59b3f8a69ad16121c7246b Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/76460 Tested-by: core-ci <typo3@b13.com> Tested-by: Stefan Bürk <stefan@buerk.tech> Tested-by: Oliver Bartsch <bo@cedev.de> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Benni Mack <benni@typo3.org> --- .../SiteConfigurationController.php | 38 ++++++++++--- .../SiteConfigurationControllerTest.php | 53 +++++++++++++++++++ 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/typo3/sysext/backend/Classes/Controller/SiteConfigurationController.php b/typo3/sysext/backend/Classes/Controller/SiteConfigurationController.php index 9e150da61e1e..53f563c47058 100644 --- a/typo3/sysext/backend/Classes/Controller/SiteConfigurationController.php +++ b/typo3/sysext/backend/Classes/Controller/SiteConfigurationController.php @@ -390,12 +390,9 @@ class SiteConfigurationController } } - // keep root config objects not given via GUI - // this way extension authors are able to use their own objects on root level - // that are not configurable via GUI - // however: we overwrite the full subset of any GUI object to make sure we have a clean state - $newSysSiteData = array_merge($currentSiteConfiguration, $newSysSiteData); - $newSiteConfiguration = $this->validateFullStructure($newSysSiteData); + $newSiteConfiguration = $this->validateFullStructure( + $this->getMergeSiteData($currentSiteConfiguration, $newSysSiteData) + ); // Persist the configuration $siteConfigurationManager = GeneralUtility::makeInstance(SiteConfiguration::class); @@ -808,6 +805,35 @@ class SiteConfigurationController return !empty($value) || $value === '0'; } + /** + * Method keeps root config objects, which are not given via GUI. This way, + * extension authors are able to use their own objects on root level that are + * not configurable via GUI. However: We overwrite the full subset of any GUI + * object to make sure we have a clean state. + * + * Additionally, we also keep the baseVariants of languages, since they + * can't be modified via the GUI, but are part of the public API. + */ + protected function getMergeSiteData(array $currentSiteConfiguration, array $newSysSiteData): array + { + $newSysSiteData = array_merge($currentSiteConfiguration, $newSysSiteData); + + // @todo: this should go away, once base variants for languages are managable via the GUI. + $existingLanguageConfigurationsWithBaseVariants = []; + foreach ($currentSiteConfiguration['languages'] ?? [] as $languageConfiguration) { + if (isset($languageConfiguration['baseVariants'])) { + $existingLanguageConfigurationsWithBaseVariants[$languageConfiguration['languageId']] = $languageConfiguration['baseVariants']; + } + } + foreach ($newSysSiteData['languages'] ?? [] as $key => $languageConfiguration) { + if (isset($existingLanguageConfigurationsWithBaseVariants[$languageConfiguration['languageId']])) { + $newSysSiteData['languages'][$key]['baseVariants'] = $existingLanguageConfigurationsWithBaseVariants[$languageConfiguration['languageId']]; + } + } + + return $newSysSiteData; + } + protected function getLanguageService(): LanguageService { return $GLOBALS['LANG']; diff --git a/typo3/sysext/backend/Tests/Unit/Controller/SiteConfigurationControllerTest.php b/typo3/sysext/backend/Tests/Unit/Controller/SiteConfigurationControllerTest.php index a653f9dfd4e8..25792f1eafb1 100644 --- a/typo3/sysext/backend/Tests/Unit/Controller/SiteConfigurationControllerTest.php +++ b/typo3/sysext/backend/Tests/Unit/Controller/SiteConfigurationControllerTest.php @@ -126,4 +126,57 @@ class SiteConfigurationControllerTest extends UnitTestCase self::assertEquals($expected, $mockedSiteConfigurationController->_call('getDuplicatedEntryPoints', $sites, $rootPages)); } + + /** + * @test + */ + public function languageBaseVariantsAreKept(): void + { + $mockedSiteConfigurationController = $this->getAccessibleMock(SiteConfigurationController::class, ['dummy'], [], '', false); + + $currentSiteConfig = [ + 'base' => '//domain1.tld/', + 'websiteTitle' => 'domain1', + 'languages' => [ + 0 => [ + 'languageId' => 0, + 'title' => 'English', + 'base' => '/', + 'baseVariants' => [ + [ + 'base' => '/en', + ], + ], + ], + ], + ]; + + $newSiteConfig = $currentSiteConfig; + $newSiteConfig['rootPageId'] = 123; + $newSiteConfig['websiteTitle'] = 'domain1 renamed'; + unset($newSiteConfig['languages'][0]['baseVariants']); + + $expected = [ + 'base' => '//domain1.tld/', + 'rootPageId' => 123, + 'websiteTitle' => 'domain1 renamed', + 'languages' => [ + 0 => [ + 'languageId' => 0, + 'title' => 'English', + 'base' => '/', + 'baseVariants' => [ + [ + 'base' => '/en', + ], + ], + ], + ], + ]; + + self::assertEquals( + $expected, + $mockedSiteConfigurationController->_call('getMergeSiteData', $currentSiteConfig, $newSiteConfig) + ); + } } -- GitLab