diff --git a/src/Php85/Php85.php b/src/Php85/Php85.php index b6619d5b..a95db4be 100644 --- a/src/Php85/Php85.php +++ b/src/Php85/Php85.php @@ -13,6 +13,7 @@ /** * @author Pierre Ambroise + * @author Alexander Schranz * * @internal */ @@ -47,4 +48,54 @@ public static function array_last(array $array) { return $array ? current(array_slice($array, -1)) : null; } + + public static function locale_is_right_to_left(string $locale): bool { + 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); + } } diff --git a/src/Php85/bootstrap.php b/src/Php85/bootstrap.php index 44e872b1..45405c17 100644 --- a/src/Php85/bootstrap.php +++ b/src/Php85/bootstrap.php @@ -30,3 +30,7 @@ function array_first(array $array) { return p\Php85::array_first($array); } if (!function_exists('array_last')) { function array_last(array $array) { return p\Php85::array_last($array); } } + +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); } +} \ No newline at end of file diff --git a/tests/Php85/Php85Test.php b/tests/Php85/Php85Test.php index 727fc289..26d6ab29 100644 --- a/tests/Php85/Php85Test.php +++ b/tests/Php85/Php85Test.php @@ -116,6 +116,25 @@ public function testArrayFirstArrayLast() $this->assertTrue(array_first([true, new \stdClass])); $this->assertEquals(new \stdClass(), array_last([true, new \stdClass])); } + + 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