From fc4e8fd2230d316dd75d133f04d60412c85e6e87 Mon Sep 17 00:00:00 2001 From: Nico Hoffmann Date: Sun, 11 Aug 2024 20:28:26 +0200 Subject: [PATCH 1/3] Fix error pages in multilang Fixes #4834 --- src/Cms/Language.php | 18 ++++++++++++++++-- tests/Cms/Languages/LanguageTest.php | 27 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/Cms/Language.php b/src/Cms/Language.php index d9e3ebac24..eb8c63100b 100644 --- a/src/Cms/Language.php +++ b/src/Cms/Language.php @@ -8,6 +8,7 @@ use Kirby\Exception\LogicException; use Kirby\Exception\PermissionException; use Kirby\Filesystem\F; +use Kirby\Toolkit\A; use Kirby\Toolkit\Locale; use Kirby\Toolkit\Str; use Throwable; @@ -213,7 +214,7 @@ public static function create(array $props): static */ public function delete(): bool { - $kirby = App::instance(); + $kirby = $this->kirby(); $user = $kirby->user(); $code = $this->code(); @@ -382,7 +383,20 @@ public function pattern(): string $path = $this->path(); if (empty($path) === true) { - return '(:all)'; + $pattern = '(:all)'; + + // match anything except paths that begin with the prefix + // of any other language + $languages = $this->kirby()->languages()->not($this)->values( + fn ($language) => $language->path() + ); + + if (count($languages) > 0) { + $pattern = '^(?!(?:' . A::join($languages, '|') . ')\/)' . $pattern; + } + + + return $pattern; } return $path . '/(:all?)'; diff --git a/tests/Cms/Languages/LanguageTest.php b/tests/Cms/Languages/LanguageTest.php index d0b587dddf..8885f369e8 100644 --- a/tests/Cms/Languages/LanguageTest.php +++ b/tests/Cms/Languages/LanguageTest.php @@ -556,6 +556,33 @@ public function testPattern($input, $expected) $this->assertSame($expected, $language->pattern()); } + /** + * @covers ::pattern + */ + public function testPatternWithNoPathPrefixButOtherLanguages() + { + $app = $this->app->clone([ + 'languages' => [ + [ + 'code' => 'en', + 'name' => 'English', + 'default' => true, + 'url' => '/' + ], + [ + 'code' => 'de', + 'name' => 'Deutsch', + ], + [ + 'code' => 'fr', + 'name' => 'Frances', + ] + ] + ]); + + $this->assertSame('^(?!(?:de|fr)\/)(:all)', $app->language('en')->pattern()); + } + /** * @covers ::root */ From 6689e5791b9f17b9dd725325913e7e0782309f17 Mon Sep 17 00:00:00 2001 From: Bastian Allgeier Date: Mon, 12 Aug 2024 12:43:41 +0200 Subject: [PATCH 2/3] Use test case from issue --- tests/Cms/Languages/LanguageRoutesTest.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/tests/Cms/Languages/LanguageRoutesTest.php b/tests/Cms/Languages/LanguageRoutesTest.php index 83c58d7105..d2eb5e8d29 100644 --- a/tests/Cms/Languages/LanguageRoutesTest.php +++ b/tests/Cms/Languages/LanguageRoutesTest.php @@ -37,6 +37,19 @@ public function setUp(): void public function testFallback() { $app = $this->app->clone([ + 'languages' => [ + [ + 'code' => 'fr', + 'name' => 'French', + 'default' => true, + 'url' => '/', + ], + [ + 'code' => 'en', + 'name' => 'English', + 'url' => '/en', + ], + ], 'site' => [ 'children' => [ [ @@ -48,10 +61,10 @@ public function testFallback() ]); $app->call('notes'); - $this->assertSame($app->language()->code(), 'en'); + $this->assertSame($app->language()->code(), 'fr'); - $app->call('de/notes'); - $this->assertSame($app->language()->code(), 'de'); + $app->call('en/notes'); + $this->assertSame($app->language()->code(), 'en'); } public function testNotNextWhenFalsyReturn() From cbdd71ef1f224e0de75270ef3e5519d11085f7dd Mon Sep 17 00:00:00 2001 From: Ahmet Bora Date: Tue, 13 Aug 2024 21:05:15 +0300 Subject: [PATCH 3/3] Unit test for the exact case --- tests/Cms/Languages/LanguageRoutesTest.php | 47 +++++++++++++++++++ tests/Cms/Languages/fixtures/languages/en.php | 15 ++++++ tests/Cms/Languages/fixtures/languages/fr.php | 15 ++++++ .../Languages/fixtures/templates/default.php | 1 + 4 files changed, 78 insertions(+) create mode 100644 tests/Cms/Languages/fixtures/languages/en.php create mode 100644 tests/Cms/Languages/fixtures/languages/fr.php create mode 100644 tests/Cms/Languages/fixtures/templates/default.php diff --git a/tests/Cms/Languages/LanguageRoutesTest.php b/tests/Cms/Languages/LanguageRoutesTest.php index d2eb5e8d29..f464bb2944 100644 --- a/tests/Cms/Languages/LanguageRoutesTest.php +++ b/tests/Cms/Languages/LanguageRoutesTest.php @@ -7,6 +7,7 @@ class LanguageRoutesTest extends TestCase { protected $app; + public const FIXTURES = __DIR__ . '/fixtures'; public function setUp(): void { @@ -67,6 +68,52 @@ public function testFallback() $this->assertSame($app->language()->code(), 'en'); } + public static function languagePrefixProvider(): array { + return [ + ['not-exists', 'Erreur'], + ['en/not-exists', 'Error'] + ]; + } + + /** + * @dataProvider languagePrefixProvider + */ + public function testLanguagePrefix($path, $body) + { + $app = new App([ + 'roots' => [ + 'index' => static::FIXTURES, + 'languages' => static::FIXTURES . '/languages', + 'templates' => static::FIXTURES . '/templates' + ], + 'site' => [ + 'children' => [ + [ + 'slug' => 'error', + 'template' => 'error', + 'translations' => [ + [ + 'code' => 'fr', + 'content' => [ + 'title' => 'Erreur' + ] + ], + [ + 'code' => 'en', + 'content' => [ + 'title' => 'Error' + ] + ] + ] + ] + ] + ] + ]); + + + $this->assertSame($body, $app->render($path)->body()); + } + public function testNotNextWhenFalsyReturn() { $a = $b = $c = $d = $e = 0; diff --git a/tests/Cms/Languages/fixtures/languages/en.php b/tests/Cms/Languages/fixtures/languages/en.php new file mode 100644 index 0000000000..097abd45bf --- /dev/null +++ b/tests/Cms/Languages/fixtures/languages/en.php @@ -0,0 +1,15 @@ + 'en', + 'default' => false, + 'direction' => 'ltr', + 'locale' => [ + 'LC_ALL' => 'en_US' + ], + 'name' => 'English', + 'translations' => [ + + ], + 'url' => NULL +]; diff --git a/tests/Cms/Languages/fixtures/languages/fr.php b/tests/Cms/Languages/fixtures/languages/fr.php new file mode 100644 index 0000000000..8547f2857f --- /dev/null +++ b/tests/Cms/Languages/fixtures/languages/fr.php @@ -0,0 +1,15 @@ + 'fr', + 'default' => true, + 'direction' => 'ltr', + 'locale' => [ + 'LC_ALL' => 'fr_FR' + ], + 'name' => 'French', + 'translations' => [ + + ], + 'url' => '/' +]; diff --git a/tests/Cms/Languages/fixtures/templates/default.php b/tests/Cms/Languages/fixtures/templates/default.php new file mode 100644 index 0000000000..739b706af7 --- /dev/null +++ b/tests/Cms/Languages/fixtures/templates/default.php @@ -0,0 +1 @@ +title();