浏览代码

[Bugfix][Locale] Fixed incomplete Locale data loading

Sublocales like de_CH returned only incomplete results for
getDisplayCountries(), getDisplayLanguages() and getDisplayLocales(),
consisting only of results specific for this sublocale, but without the
results of their respective parent locale
Manuel Kiessling 13 年之前
父节点
当前提交
cacc880929
共有 2 个文件被更改,包括 81 次插入0 次删除
  1. 34 0
      src/Symfony/Component/Locale/Locale.php
  2. 47 0
      tests/Symfony/Tests/Component/Locale/LocaleTest.php

+ 34 - 0
src/Symfony/Component/Locale/Locale.php

@@ -61,6 +61,11 @@ class Locale extends \Locale
                 }
                 }
             }
             }
 
 
+            $fallbackLocale = self::getFallbackLocale($locale);
+            if (null !== $fallbackLocale) {
+                $countries = array_merge(self::getDisplayCountries($fallbackLocale), $countries);
+            }
+
             $collator->asort($countries);
             $collator->asort($countries);
 
 
             self::$countries[$locale] = $countries;
             self::$countries[$locale] = $countries;
@@ -108,6 +113,11 @@ class Locale extends \Locale
                 }
                 }
             }
             }
 
 
+            $fallbackLocale = self::getFallbackLocale($locale);
+            if (null !== $fallbackLocale) {
+                $languages = array_merge(self::getDisplayLanguages($fallbackLocale), $languages);
+            }
+
             $collator->asort($languages);
             $collator->asort($languages);
 
 
             self::$languages[$locale] = $languages;
             self::$languages[$locale] = $languages;
@@ -150,6 +160,11 @@ class Locale extends \Locale
                 $locales[$code] = $name;
                 $locales[$code] = $name;
             }
             }
 
 
+            $fallbackLocale = self::getFallbackLocale($locale);
+            if (null !== $fallbackLocale) {
+                $locales = array_merge(self::getDisplayLocales($fallbackLocale), $locales);
+            }
+
             $collator->asort($locales);
             $collator->asort($locales);
 
 
             self::$locales[$locale] = $locales;
             self::$locales[$locale] = $locales;
@@ -168,4 +183,23 @@ class Locale extends \Locale
     {
     {
         return array_keys(self::getDisplayLocales(self::getDefault()));
         return array_keys(self::getDisplayLocales(self::getDefault()));
     }
     }
+
+    /**
+     * Returns the fallback locale for a given locale, if any
+     *
+     * @param $locale             The locale to find the fallback for
+     * @return string|null        The fallback locale, or null if no parent exists
+     */
+    static protected function getFallbackLocale($locale)
+    {
+        if ($locale === self::getDefault()) {
+            return null;
+        }
+
+        if (false === $pos = strrpos($locale, '_')) {
+            return self::getDefault();
+        };
+
+        return substr($locale, 0, $pos);
+    }
 }
 }

+ 47 - 0
tests/Symfony/Tests/Component/Locale/LocaleTest.php

@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Tests\Component\Locale;
+
+use Symfony\Component\Locale\Locale;
+
+class LocaleTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetDisplayCountriesReturnsFullListForSubLocale()
+    {
+        $countriesDe = Locale::getDisplayCountries('de');
+        $countriesDeCh = Locale::getDisplayCountries('de_CH');
+
+        $this->assertEquals(count($countriesDe), count($countriesDeCh));
+        $this->assertEquals($countriesDe['BD'], 'Bangladesch');
+        $this->assertEquals($countriesDeCh['BD'], 'Bangladesh');
+    }
+
+    public function testGetDisplayLanguagesReturnsFullListForSubLocale()
+    {
+        $languagesDe = Locale::getDisplayLanguages('de');
+        $languagesDeCh = Locale::getDisplayLanguages('de_CH');
+
+        $this->assertEquals(count($languagesDe), count($languagesDeCh));
+        $this->assertEquals($languagesDe['be'], 'Weißrussisch');
+        $this->assertEquals($languagesDeCh['be'], 'Weissrussisch');
+    }
+
+    public function testGetDisplayLocalesReturnsFullListForSubLocale()
+    {
+        $localesDe = Locale::getDisplayLocales('de');
+        $localesDeCh = Locale::getDisplayLocales('de_CH');
+
+        $this->assertEquals(count($localesDe), count($localesDeCh));
+        $this->assertEquals($localesDe['be'], 'Weißrussisch');
+        $this->assertEquals($localesDeCh['be'], 'Weissrussisch');
+    }
+}