From beacebd04d42e940f4fc96eca85c59b75125a4eb Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Mon, 26 May 2025 13:33:24 +0200 Subject: [PATCH 1/2] Add locale_is_right_to_left polyfill --- src/Php85/Php85.php | 5 +++++ src/Php85/bootstrap.php | 4 ++++ tests/Php85/Php85Test.php | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/Php85/Php85.php b/src/Php85/Php85.php index a406fe0e..3e96492f 100644 --- a/src/Php85/Php85.php +++ b/src/Php85/Php85.php @@ -13,6 +13,7 @@ /** * @author Pierre Ambroise + * @author Alexander Schranz * * @internal */ @@ -33,4 +34,8 @@ public static function get_exception_handler(): ?callable return $handler; } + + public static function locale_is_right_to_left(string $locale): bool { + return (bool) preg_match('/^(?:ar|he|fa|ur|ps|sd|ug|ckb|yi|dv|ku_arab|ku-arab)(?:[_-].*)?$/i', $locale); + } } diff --git a/src/Php85/bootstrap.php b/src/Php85/bootstrap.php index 0da63eb9..1e4a83c4 100644 --- a/src/Php85/bootstrap.php +++ b/src/Php85/bootstrap.php @@ -22,3 +22,7 @@ function get_error_handler(): ?callable { return p\Php85::get_error_handler(); } if (!function_exists('get_exception_handler')) { function get_exception_handler(): ?callable { return p\Php85::get_exception_handler(); } } + +if (!function_exists('locale_is_right_to_left')) { + function locale_is_right_to_left(string $locale): bool { return p\Php85::locale_is_right_to_left($locale); } +} diff --git a/tests/Php85/Php85Test.php b/tests/Php85/Php85Test.php index fc4c7163..cdcfcd5b 100644 --- a/tests/Php85/Php85Test.php +++ b/tests/Php85/Php85Test.php @@ -78,6 +78,25 @@ public static function provideHandler() $handler = new TestHandlerInvokable(); yield [$handler, $handler]; } + + public function testLocaleIsRightToLeft(): void + { + $this->assertTrue(locale_is_right_to_left('ar')); + $this->assertTrue(locale_is_right_to_left('he')); + $this->assertTrue(locale_is_right_to_left('fa')); + $this->assertTrue(locale_is_right_to_left('ur')); + $this->assertTrue(locale_is_right_to_left('ps')); + $this->assertTrue(locale_is_right_to_left('sd')); + $this->assertTrue(locale_is_right_to_left('ug')); + $this->assertTrue(locale_is_right_to_left('ckb')); + $this->assertTrue(locale_is_right_to_left('yi')); + $this->assertTrue(locale_is_right_to_left('dv')); + $this->assertTrue(locale_is_right_to_left('ku_arab')); + $this->assertTrue(locale_is_right_to_left('ku-arab')); + + $this->assertFalse(locale_is_right_to_left('en')); + $this->assertFalse(locale_is_right_to_left('fr')); + } } class TestHandler From 667130e51a3854a015c72a09feb89f677758f8a5 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 24 Jun 2025 16:01:07 +0200 Subject: [PATCH 2/2] Update Php85.php --- src/Php85/Php85.php | 48 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Php85/Php85.php b/src/Php85/Php85.php index 3e96492f..d861b76c 100644 --- a/src/Php85/Php85.php +++ b/src/Php85/Php85.php @@ -36,6 +36,52 @@ public static function get_exception_handler(): ?callable } public static function locale_is_right_to_left(string $locale): bool { - return (bool) preg_match('/^(?:ar|he|fa|ur|ps|sd|ug|ckb|yi|dv|ku_arab|ku-arab)(?:[_-].*)?$/i', $locale); + static $rtlScripts = [ + 'Adlm', 'Arab', 'Armi', 'Hebr', 'Mani', 'Mend', 'Nkoo', + 'Phnx', 'Rohg', 'Samr', 'Syrc', 'Thaa', + ]; + + static $languageToLikelyRtlScript = [ + 'ar' => 'Arab', // Arabic + 'fa' => 'Arab', // Persian (Farsi) + 'ur' => 'Arab', // Urdu + 'ps' => 'Arab', // Pashto + 'sd' => 'Arab', // Sindhi + 'ug' => 'Arab', // Uyghur + 'ckb' => 'Arab', // Sorani Kurdish + 'he' => 'Hebr', // Hebrew + 'yi' => 'Hebr', // Yiddish + 'dv' => 'Thaa', // Dhivehi + 'nqo' => 'Nkoo', // N'Ko + ]; + + if (empty($locale)) { + return false; + } + + $localeParts = preg_split('/[_-]/', $locale); + $language = strtolower($localeParts[0] ?? ''); + $script = null; + + foreach ($localeParts as $part) { + if (strlen($part) === 4 && ctype_alpha($part)) { + $script = ucfirst(strtolower($part)); + break; + } + } + + if ($script === null) { + $script = $languageToLikelyScript[$language] ?? null; + } + + if ($script === null) { + if (in_array($language, ['ar', 'he', 'fa', 'ur', 'ps', 'sd', 'ug', 'ckb', 'yi', 'dv'])) { + return true; + } + + return false; + } + + return in_array($script, $rtlScripts, true); } }