소스 검색

[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);
 
             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);
 
             self::$languages[$locale] = $languages;
@@ -150,6 +160,11 @@ class Locale extends \Locale
                 $locales[$code] = $name;
             }
 
+            $fallbackLocale = self::getFallbackLocale($locale);
+            if (null !== $fallbackLocale) {
+                $locales = array_merge(self::getDisplayLocales($fallbackLocale), $locales);
+            }
+
             $collator->asort($locales);
 
             self::$locales[$locale] = $locales;
@@ -168,4 +183,23 @@ class Locale extends \Locale
     {
         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');
+    }
+}