From f9c28d48f72632eaeba9e9d5ae6f6584e8b31bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BCrk?= <stefan@buerk.tech> Date: Sat, 20 Nov 2021 15:50:14 +0100 Subject: [PATCH] [BUGFIX] Respect '_language' argument for typoLink and LinkHandler This patch fixes a bug where a t3 page URI with _language != 0 was resolved to a page in the default language. This caused automatically generated redirects to translated pages to redirect to the page in the default language. We now use the same override handling for the '_language' parameter (as already existed for 'L') when t3 page URIs are resolved. Also, we ensure that both parameters are always removed when the final URL is generated. Furthermore, this patch adds tests to cover these cases. Using the historical 'L' parameter still works and has been added to be handled as language override. Background information: The '_language parameter' is the preferred parameter to be used to specify the language in a t3 URI, not 'L'. The behaviour of creating auto redirects on slug changes was changed previously: The target was added as LinkHandler URI (instead of the path). Along with this change, the '_language' parameter was used to ensure the target URL is generated in the needed language (#89327). This introduced a problem where a redirect always redirected to the page in default language if a t3: page URI was used with '_language'. Resolves: #96043 Related: #89327 Releases: master, 11.5, 10.4 Change-Id: I95bdeff4827eed3be30528c02331b9c9ff2836b1 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/72242 Tested-by: core-ci <typo3@b13.com> Tested-by: Oliver Bartsch <bo@cedev.de> Tested-by: Sybille Peters <sypets@gmx.de> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Sybille Peters <sypets@gmx.de> Reviewed-by: Benni Mack <benni@typo3.org> --- .../Classes/Typolink/PageLinkBuilder.php | 15 ++++-- .../Fixtures/TypoLinkScenario.yaml | 12 +++++ .../SiteHandling/TypoLinkGeneratorTest.php | 52 +++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php index a34ea386f8a5..1f72cfe8fbcb 100644 --- a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php +++ b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php @@ -163,9 +163,18 @@ class PageLinkBuilder extends AbstractTypolinkBuilder // Disable "?id=", for pages with no site configuration, this is added later-on anyway unset($queryParameters['id']); - // Override language property if not being set already - if (isset($queryParameters['L']) && !isset($conf['language'])) { - $conf['language'] = (int)$queryParameters['L']; + // Override language property if not being set already, supporting historically 'L' and + // modern '_language' arguments, giving '_language' the precedence. + if (isset($queryParameters['_language'])) { + if (!isset($conf['language'])) { + $conf['language'] = (int)$queryParameters['_language']; + } + unset($queryParameters['_language']); + } + if (isset($queryParameters['L'])) { + if (!isset($conf['language'])) { + $conf['language'] = (int)$queryParameters['L']; + } unset($queryParameters['L']); } diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/TypoLinkScenario.yaml b/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/TypoLinkScenario.yaml index 2a8118593127..1a44af4419b2 100644 --- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/TypoLinkScenario.yaml +++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/TypoLinkScenario.yaml @@ -23,17 +23,29 @@ entitySettings: languageColumnNames: ['l18n_parent', 'l10n_source'] columnNames: {title: 'header', type: 'CType'} defaultValues: {hidden: 0, CType: 'text'} + language: + tableName: 'sys_language' + columnNames: {code: 'language_isocode'} entities: + language: + - self: {id: 1, title: 'French', code: 'fr'} + - self: {id: 2, title: 'Franco-Canadian', code: 'fr'} page: - self: {id: 1000, title: 'ACME Inc', type: *pageShortcut, shortcut: 'first', root: true, slug: '/'} children: - self: {id: 1100, title: 'EN: Welcome', slug: '/welcome', subtitle: 'hello-and-welcome'} + languageVariants: + - self: {id: 1101, title: 'FR: Bienvenue', language: 1, slug: '/bienvenue', subtitle: 'salut-et-bienvenue'} + - self: {id: 1102, title: 'FR-CA: Bienvenue', language: 2, slug: '/bienvenue', subtitle: 'salut-et-bienvenue'} entities: content: - self: {title: 'EN: Content Element #1'} - self: {title: 'EN: Content Element #2'} - self: {id: 1200, title: 'EN: Features', slug: '/features'} + languageVariants: + - self: {id: 1201, title: 'FR: Features', slug: '/features-fr', language: 1} + - self: {id: 1202, title: 'FR-CA: Features', slug: '/features-ca', language: 2} - self: {id: 1300, title: 'Go to TYPO3.org', type: *pageLink, slug: '/external', url: 'typo3.org' } - self: {id: 9911, title: '<good>', slug: '/test/good'} - self: {id: 9912, title: '<good a="a/" b="thing(1)">', slug: '/test/good-a-b-spaced'} diff --git a/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php b/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php index 47a0ef757671..7e0129849286 100644 --- a/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php +++ b/typo3/sysext/frontend/Tests/Functional/SiteHandling/TypoLinkGeneratorTest.php @@ -200,6 +200,58 @@ class TypoLinkGeneratorTest extends AbstractTestCase 'user@example.org target class title &other=other', '<a href="mailto:user@example.org" title="title" target="target" class="class">user@example.org</a>', ], + // check link with language parameters + [ + 't3://page?uid=1200&L=0', + '<a href="/features">EN: Features</a>', + ], + [ + 't3://page?uid=1200&_language=0', + '<a href="/features">EN: Features</a>', + ], + [ + 't3://page?uid=1200&L=1', + '<a href="https://acme.fr/features-fr">FR: Features</a>', + ], + [ + 't3://page?uid=1200&_language=1', + '<a href="https://acme.fr/features-fr">FR: Features</a>', + ], + [ + 't3://page?uid=1201&L=1', + '<a href="https://acme.fr/features-fr">FR: Features</a>', + ], + [ + 't3://page?uid=1201&_language=1', + '<a href="https://acme.fr/features-fr">FR: Features</a>', + ], + // localized page language overrule language arguments (new and old). + // This has also test coverage through SlugGeneratorTests. + [ + 't3://page?uid=1202&L=1', + '<a href="https://acme.ca/features-ca">FR-CA: Features</a>', + ], + [ + 't3://page?uid=1202&_language=1', + '<a href="https://acme.ca/features-ca">FR-CA: Features</a>', + ], + // check precedence order correctness if old and modern are provided + [ + 't3://page?uid=1200&L=2&_language=1', + '<a href="https://acme.fr/features-fr">FR: Features</a>', + ], + [ + 't3://page?uid=1200&_language=1&L=2', + '<a href="https://acme.fr/features-fr">FR: Features</a>', + ], + [ + 't3://page?uid=1200&L=1&_language=2', + '<a href="https://acme.ca/features-ca">FR-CA: Features</a>', + ], + [ + 't3://page?uid=1200&_language=2&L=1', + '<a href="https://acme.ca/features-ca">FR-CA: Features</a>', + ], ]; return $this->keysFromTemplate($instructions, '%1$s;'); } -- GitLab