Просмотр исходного кода

use intl functions if possible, but beware of ICU < 67 and unsupported locales

El RIDO 17 часов назад
Родитель
Сommit
9be8ee7026
3 измененных файлов с 23 добавлено и 14 удалено
  1. 1 1
      Makefile
  2. 19 9
      lib/I18n.php
  3. 3 4
      tst/I18nTest.php

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 .PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help
 
 CURRENT_VERSION = 2.1.1
-VERSION ?= 2.1.1
+VERSION ?= 2.1.2
 VERSION_FILES = README.md SECURITY.md doc/Installation.md js/package.json lib/Controller.php Makefile
 REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g")
 REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g")

+ 19 - 9
lib/I18n.php

@@ -205,17 +205,27 @@ class I18n
             return self::$_languageFallback;
         }
 
-        /* TODO: Once https://github.com/php/php-src/issues/24074 makes it into
-         * all supported PHP releases, we can use the intl module like so:
-        if (function_exists('locale_accept_from_http')) {
-            $detectedBestLanguage = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE'], $availableLanguages);
-            if ($detectedBestLanguage !== false) {
-                return $detectedBestLanguage;
+        // ICU < 67 returns equivalent matches in alphabetical order instead of
+        // the order passed, causing test inconsistencies (unicode-org/icu#1022).
+        // Also, ICU doesn't properly handle some of our languages (co, jbo) or
+        // regional zh variants (zh_TW, zh_HK) even in recent versions.
+        if (
+            function_exists('locale_accept_from_http') &&
+            defined('INTL_ICU_VERSION') &&
+            version_compare(INTL_ICU_VERSION, '67', '>=') &&
+            !preg_match('/(co|jbo|zh-)/', $_SERVER['HTTP_ACCEPT_LANGUAGE'])
+        ) {
+            $detectedBestLocale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+            if (
+                $detectedBestLocale !== false &&
+                function_exists('locale_get_primary_language')
+            ) {
+                $detectedBestLanguage = locale_get_primary_language($detectedBestLocale);
+                if (in_array($detectedBestLanguage, $availableLanguages)) {
+                    return $detectedBestLanguage;
+                }
             }
         }
-        * disabled for now as it's order depends on the ICU version installed
-        * and showed large inconsistencies between different test environments
-        */
 
         return self::_getMatchingLanguage(
             self::_normalizeBrowserLanguages(self::getBrowserLanguages(), $availableLanguages),

+ 3 - 4
tst/I18nTest.php

@@ -95,7 +95,7 @@ class I18nTest extends TestCase
         // ICU before version 67 sorts languages of equal quality alphabetically
         return [
             'fr;q=0.8,de;q=0.8' => ['fr;q=0.8,de;q=0.8', 'fr'],
-            'fr,de' => ['fr,de', 'fr'],
+            'fr,de'             => ['fr,de', 'fr'],
         ];
     }
 
@@ -113,9 +113,8 @@ class I18nTest extends TestCase
     {
         // ICU has no locale data for these languages, so it can only match the next one in the header
         return [
-            'co,fr;q=0.8' => ['co,fr;q=0.8', 'co'],
+            'co,fr;q=0.8'  => ['co,fr;q=0.8', 'co'],
             'jbo,de;q=0.8' => ['jbo,de;q=0.8', 'jbo'],
-            'la,it;q=0.8' => ['la,it;q=0.8', 'la'],
         ];
     }
 
@@ -215,7 +214,7 @@ class I18nTest extends TestCase
         // has zh_TW and zh_HK only as aliases, skips them and returns zh instead
         return [
             'zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7' => ['zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7', 'zh-tw'],
-            'zh-HK,zh;q=0.9,en;q=0.8' => ['zh-HK,zh;q=0.9,en;q=0.8', 'zh-tw'],
+            'zh-HK,zh;q=0.9,en;q=0.8'             => ['zh-HK,zh;q=0.9,en;q=0.8', 'zh-tw'],
         ];
     }