From f7563bcafbd5ab3d2d11079631f3d4f1ac22c3da Mon Sep 17 00:00:00 2001 From: Nico Hoffmann Date: Sun, 11 Aug 2024 20:28:26 +0200 Subject: [PATCH] Fix error pages in multilang Fixes #4834 --- src/Cms/Language.php | 20 +++++++++++++++++--- tests/Cms/Languages/LanguageTest.php | 27 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/Cms/Language.php b/src/Cms/Language.php index 592186722a..b8040bab16 100644 --- a/src/Cms/Language.php +++ b/src/Cms/Language.php @@ -7,6 +7,7 @@ use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\LogicException; use Kirby\Filesystem\F; +use Kirby\Toolkit\A; use Kirby\Toolkit\Locale; use Kirby\Toolkit\Str; use Throwable; @@ -203,7 +204,7 @@ public static function create(array $props): static */ public function delete(): bool { - $kirby = App::instance(); + $kirby = $this->kirby(); $code = $this->code(); if ($this->isDeletable() === false) { @@ -364,7 +365,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?)'; @@ -503,7 +517,7 @@ public function update(array $props = null): static // make sure the slug is nice and clean $props['slug'] = Str::slug($props['slug'] ?? null); - $kirby = App::instance(); + $kirby = $this->kirby(); $updated = $this->clone($props); if (isset($props['translations']) === true) { diff --git a/tests/Cms/Languages/LanguageTest.php b/tests/Cms/Languages/LanguageTest.php index 75d800c110..c7a02b3ae7 100644 --- a/tests/Cms/Languages/LanguageTest.php +++ b/tests/Cms/Languages/LanguageTest.php @@ -461,6 +461,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 */