瀏覽代碼

[GENERIC, ZF-9488] Zend_Locale:

- added new feature for currency localization

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@21745 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 年之前
父節點
當前提交
2bea29d053

+ 31 - 0
documentation/manual/en/module_specs/Zend_Currency-Usage.xml

@@ -93,4 +93,35 @@ Zend_Registry::set('Zend_Locale', $locale);
 $currency = new Zend_Currency();
 ]]></programlisting>
     </sect2>
+
+    <sect2 id="zend.currency.usage.territory">
+        <title>Currency creation based on a country</title>
+
+        <para>
+            <classname>Zend_Currency</classname> is also able to work on a given country by using
+            <classname>Zend_Locale</classname> internally.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$currency = new Zend_Currency('US');
+
+// See the actual settings which are fixed to 'en_US'
+// var_dump($currency);
+]]></programlisting>
+
+        <note>
+            <title>Uppercase territories</title>
+
+            <para>
+                When you know that you are using a territory, then you should uppercase it.
+                Otherwise you could get an in your eyes false locale in return. For example,
+                when you give "om" then you could expect "ar_OM" to be returned. But in fact it
+                returns "om", as it's also a language.
+            </para>
+
+            <para>
+                Therefor always uppercase the input when you know that a territory is meant.
+            </para>
+        <note>
+    </sect2>
 </sect1>

+ 46 - 0
documentation/manual/en/module_specs/Zend_Locale-Functions.xml

@@ -177,6 +177,46 @@ print $locale->getRegion();
         </example>
     </sect2>
 
+    <sect2 id="zend.locale.getlocaletoterritory">
+        <title>Get the locale by giving a territory</title>
+
+        <para>
+            When you only have the territory or country then it's also possible to get a locale
+            from that information. You can manually search if there is a locale for this territory
+            by using <methodname>getLocaleToTerritory()</methodname>. This method returns a
+            locale for the given territory or <constant>NULL</constant> when there was has no locale
+            been found.
+        </para>
+
+        <example id="zend.locale.setlocale.example-1">
+            <title>getLocaleToTerritory</title>
+
+            <programlisting language="php"><![CDATA[
+$locale = Zend_Locale::getLocaleToTerritory('US');
+// returns 'en_US'
+]]></programlisting>
+        </example>
+
+        <note>
+            <title>Uppercase territories</title>
+
+            <para>
+                When you know that you are using a territory, then you should uppercase it.
+                Otherwise you could get an in your eyes false locale in return when you use other
+                methods. For example: When you give "om" then
+                <methodname>getLocaleToTerritory()</methodname> returns you "ar_OM" as it knows that
+                you mean a territory. But all other methods will return "om", as it's also a
+                language.
+            </para>
+
+            <para>
+                So when you know that the given string is a territory, eighter use
+                <methodname>getLocaleToTerritory()</methodname> yourself before creating a locale,
+                or uppercase the input.
+            </para>
+        </note>
+    </sect2>
+
     <sect2 id="zend.locale.getdata">
         <title>Obtaining localized strings</title>
 
@@ -1920,6 +1960,12 @@ if ($locale instanceof Zend_Locale) {
 
             <listitem>
                 <para>
+                    Upgrades the locale when it is detected as region without language
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
                     Returns a previous set application wide locale if no input is given
                 </para>
             </listitem>

+ 46 - 0
documentation/manual/en/module_specs/Zend_Translate-Additional.xml

@@ -451,6 +451,52 @@ if (!$translate->isAvailable($locale->getLanguage())) {
 $translate->getLocale();
 ]]></programlisting>
         </sect3>
+
+        <sect3 id="zend.translate.additional.languages.territory">
+            <title>Using a country as language</title>
+
+            <para>
+                You can also use a country as locale parameter. This could be useful when you
+                provide your user with flags, which represent the country in which he lives, and
+                when he selects his flag, he would automatically get the default language for this
+                country.
+            </para>
+
+            <para>
+                For example, when the user selected <emphasis>US</emphasis> then you would get
+                <emphasis>en_US</emphasis> in return as locale which is being used. This leads
+                automatically to the language <emphasis>en</emphasis> which is the default language
+                for the country <emphasis>US</emphasis>.
+            </para>
+
+            <programlisting language="php"><![CDATA[
+$translate = new Zend_Translate(
+    array(
+        'adapter' => 'gettext',
+        'content' => 'my_de.mo',
+        'locale'  => 'US'
+    )
+);
+]]></programlisting>
+
+            <note>
+                <title>Always uppercase countries</title>
+
+                <para>
+                    Using this syntax you should always uppercase the input when you know that it's
+                    a country. The reason is that there are also languages which have the same
+                    letters as a country. Take for example <emphasis>om</emphasis>. You could expect
+                    to get <emphasis>ar_OM</emphasis> when you mean the country "Oman", or you could
+                    expect the language "Oromo" which is spoken in Kenia for example.
+                </para>
+
+                <para>
+                    As <classname>Zend_Translate</classname> is related to languages it will always
+                    use the language in this case. Therefor always uppercase the locale when you
+                    want it to be recognised as country.
+                </para>
+            </note>
+        </sect3>
     </sect2>
 
     <sect2 id="zend.translate.additional.detection">

+ 85 - 4
library/Zend/Locale.php

@@ -119,6 +119,63 @@ class Zend_Locale
     );
 
     /**
+     * Class wide Locale Constants
+     *
+     * @var array $_territoryData
+     */
+    private static $_territoryData = array(
+        'AD' => 'ca_AD', 'AE' => 'ar_AE', 'AF' => 'fa_AF', 'AG' => 'en_AG', 'AI' => 'en_AI',
+        'AL' => 'sq_AL', 'AM' => 'hy_AM', 'AN' => 'pap_AN', 'AO' => 'pt_AO', 'AQ' => 'und_AQ',
+        'AR' => 'es_AR', 'AS' => 'sm_AS', 'AT' => 'de_AT', 'AU' => 'en_AU', 'AW' => 'nl_AW',
+        'AX' => 'sv_AX', 'AZ' => 'az_Latn_AZ', 'BA' => 'bs_BA', 'BB' => 'en_BB', 'BD' => 'bn_BD',
+        'BE' => 'nl_BE', 'BF' => 'mos_BF', 'BG' => 'bg_BG', 'BH' => 'ar_BH', 'BI' => 'rn_BI',
+        'BJ' => 'fr_BJ', 'BL' => 'fr_BL', 'BM' => 'en_BM', 'BN' => 'ms_BN', 'BO' => 'es_BO',
+        'BR' => 'pt_BR', 'BS' => 'en_BS', 'BT' => 'dz_BT', 'BV' => 'und_BV', 'BW' => 'en_BW',
+        'BY' => 'be_BY', 'BZ' => 'en_BZ', 'CA' => 'en_CA', 'CC' => 'ms_CC', 'CD' => 'sw_CD',
+        'CF' => 'fr_CF', 'CG' => 'fr_CG', 'CH' => 'de_CH', 'CI' => 'fr_CI', 'CK' => 'en_CK',
+        'CL' => 'es_CL', 'CM' => 'fr_CM', 'CN' => 'zh_Hans_CN', 'CO' => 'es_CO', 'CR' => 'es_CR',
+        'CU' => 'es_CU', 'CV' => 'kea_CV', 'CX' => 'en_CX', 'CY' => 'el_CY', 'CZ' => 'cs_CZ',
+        'DE' => 'de_DE', 'DJ' => 'aa_DJ', 'DK' => 'da_DK', 'DM' => 'en_DM', 'DO' => 'es_DO',
+        'DZ' => 'ar_DZ', 'EC' => 'es_EC', 'EE' => 'et_EE', 'EG' => 'ar_EG', 'EH' => 'ar_EH',
+        'ER' => 'ti_ER', 'ES' => 'es_ES', 'ET' => 'en_ET', 'FI' => 'fi_FI', 'FJ' => 'hi_FJ',
+        'FK' => 'en_FK', 'FM' => 'chk_FM', 'FO' => 'fo_FO', 'FR' => 'fr_FR', 'GA' => 'fr_GA',
+        'GB' => 'en_GB', 'GD' => 'en_GD', 'GE' => 'ka_GE', 'GF' => 'fr_GF', 'GG' => 'en_GG',
+        'GH' => 'ak_GH', 'GI' => 'en_GI', 'GL' => 'iu_GL', 'GM' => 'en_GM', 'GN' => 'fr_GN',
+        'GP' => 'fr_GP', 'GQ' => 'fan_GQ', 'GR' => 'el_GR', 'GS' => 'und_GS', 'GT' => 'es_GT',
+        'GU' => 'en_GU', 'GW' => 'pt_GW', 'GY' => 'en_GY', 'HK' => 'zh_Hant_HK', 'HM' => 'und_HM',
+        'HN' => 'es_HN', 'HR' => 'hr_HR', 'HT' => 'ht_HT', 'HU' => 'hu_HU', 'ID' => 'id_ID',
+        'IE' => 'en_IE', 'IL' => 'he_IL', 'IM' => 'en_IM', 'IN' => 'hi_IN', 'IO' => 'und_IO',
+        'IQ' => 'ar_IQ', 'IR' => 'fa_IR', 'IS' => 'is_IS', 'IT' => 'it_IT', 'JE' => 'en_JE',
+        'JM' => 'en_JM', 'JO' => 'ar_JO', 'JP' => 'ja_JP', 'KE' => 'en_KE', 'KG' => 'ky_Cyrl_KG',
+        'KH' => 'km_KH', 'KI' => 'en_KI', 'KM' => 'ar_KM', 'KN' => 'en_KN', 'KP' => 'ko_KP',
+        'KR' => 'ko_KR', 'KW' => 'ar_KW', 'KY' => 'en_KY', 'KZ' => 'ru_KZ', 'LA' => 'lo_LA',
+        'LB' => 'ar_LB', 'LC' => 'en_LC', 'LI' => 'de_LI', 'LK' => 'si_LK', 'LR' => 'en_LR',
+        'LS' => 'st_LS', 'LT' => 'lt_LT', 'LU' => 'fr_LU', 'LV' => 'lv_LV', 'LY' => 'ar_LY',
+        'MA' => 'ar_MA', 'MC' => 'fr_MC', 'MD' => 'ro_MD', 'ME' => 'sr_Latn_ME', 'MF' => 'fr_MF',
+        'MG' => 'mg_MG', 'MH' => 'mh_MH', 'MK' => 'mk_MK', 'ML' => 'bm_ML', 'MM' => 'my_MM',
+        'MN' => 'mn_Cyrl_MN', 'MO' => 'zh_Hant_MO', 'MP' => 'en_MP', 'MQ' => 'fr_MQ', 'MR' => 'ar_MR',
+        'MS' => 'en_MS', 'MT' => 'mt_MT', 'MU' => 'mfe_MU', 'MV' => 'dv_MV', 'MW' => 'ny_MW',
+        'MX' => 'es_MX', 'MY' => 'ms_MY', 'MZ' => 'pt_MZ', 'NA' => 'kj_NA', 'NC' => 'fr_NC',
+        'NE' => 'ha_Latn_NE', 'NF' => 'en_NF', 'NG' => 'en_NG', 'NI' => 'es_NI', 'NL' => 'nl_NL',
+        'NO' => 'nb_NO', 'NP' => 'ne_NP', 'NR' => 'en_NR', 'NU' => 'niu_NU', 'NZ' => 'en_NZ',
+        'OM' => 'ar_OM', 'PA' => 'es_PA', 'PE' => 'es_PE', 'PF' => 'fr_PF', 'PG' => 'tpi_PG',
+        'PH' => 'fil_PH', 'PK' => 'ur_PK', 'PL' => 'pl_PL', 'PM' => 'fr_PM', 'PN' => 'en_PN',
+        'PR' => 'es_PR', 'PS' => 'ar_PS', 'PT' => 'pt_PT', 'PW' => 'pau_PW', 'PY' => 'gn_PY',
+        'QA' => 'ar_QA', 'RE' => 'fr_RE', 'RO' => 'ro_RO', 'RS' => 'sr_Cyrl_RS', 'RU' => 'ru_RU',
+        'RW' => 'rw_RW', 'SA' => 'ar_SA', 'SB' => 'en_SB', 'SC' => 'crs_SC', 'SD' => 'ar_SD',
+        'SE' => 'sv_SE', 'SG' => 'en_SG', 'SH' => 'en_SH', 'SI' => 'sl_SI', 'SJ' => 'nb_SJ',
+        'SK' => 'sk_SK', 'SL' => 'kri_SL', 'SM' => 'it_SM', 'SN' => 'fr_SN', 'SO' => 'sw_SO',
+        'SR' => 'srn_SR', 'ST' => 'pt_ST', 'SV' => 'es_SV', 'SY' => 'ar_SY', 'SZ' => 'en_SZ',
+        'TC' => 'en_TC', 'TD' => 'fr_TD', 'TF' => 'und_TF', 'TG' => 'fr_TG', 'TH' => 'th_TH',
+        'TJ' => 'tg_Cyrl_TJ', 'TK' => 'tkl_TK', 'TL' => 'pt_TL', 'TM' => 'tk_TM', 'TN' => 'ar_TN',
+        'TO' => 'to_TO', 'TR' => 'tr_TR', 'TT' => 'en_TT', 'TV' => 'tvl_TV', 'TW' => 'zh_Hant_TW',
+        'TZ' => 'sw_TZ', 'UA' => 'uk_UA', 'UG' => 'sw_UG', 'UM' => 'en_UM', 'US' => 'en_US',
+        'UY' => 'es_UY', 'UZ' => 'uz_Cyrl_UZ', 'VA' => 'it_VA', 'VC' => 'en_VC', 'VE' => 'es_VE',
+        'VG' => 'en_VG', 'VI' => 'en_VI', 'VU' => 'bi_VU', 'WF' => 'wls_WF', 'WS' => 'sm_WS',
+        'YE' => 'ar_YE', 'YT' => 'swb_YT', 'ZA' => 'en_ZA', 'ZM' => 'en_ZM', 'ZW' => 'sn_ZW'
+    );
+
+    /**
      * Autosearch constants
      */
     const BROWSER     = 'browser';
@@ -813,11 +870,15 @@ class Zend_Locale
 
         if (!Zend_Locale::isLocale($locale, true, false)) {
             if (!Zend_Locale::isLocale($locale, false, false)) {
-                require_once 'Zend/Locale/Exception.php';
-                throw new Zend_Locale_Exception("The locale '$locale' is no known locale");
-            }
+                $locale = Zend_Locale::getLocaleToTerritory($locale);
 
-            $locale = new Zend_Locale($locale);
+                if (empty($locale)) {
+                    require_once 'Zend/Locale/Exception.php';
+                    throw new Zend_Locale_Exception("The locale '$locale' is no known locale");
+                }
+            } else {
+                $locale = new Zend_Locale($locale);
+            }
         }
 
         $locale = self::_prepareLocale($locale);
@@ -825,6 +886,22 @@ class Zend_Locale
     }
 
     /**
+     * Returns the expected locale for a given territory
+     *
+     * @param string $territory Territory for which the locale is being searched
+     * @return string|null Locale string or null when no locale has been found
+     */
+    public static function getLocaleToTerritory($territory)
+    {
+        $territory = strtoupper($territory);
+        if (array_key_exists($territory, self::$_territoryData)) {
+            return self::$_territoryData[$territory];
+        }
+
+        return null;
+    }
+
+    /**
      * Returns a list of all known locales where the locale is the key
      * Only real locales are returned, the internal locales 'root', 'auto', 'browser'
      * and 'environment' are suppressed
@@ -970,6 +1047,10 @@ class Zend_Locale
 
         $parts = explode('_', $locale);
         if (!isset(self::$_localeData[$parts[0]])) {
+            if ((count($parts) == 1) && array_key_exists($parts[0], self::$_territoryData)) {
+                return self::$_territoryData[$parts[0]];
+            }
+
             return '';
         }
 

+ 14 - 0
tests/Zend/LocaleTest.php

@@ -839,6 +839,20 @@ class Zend_LocaleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * @ZF-9488
+     */
+    public function testTerritoryToGetLocale() {
+        $value = Zend_Locale::findLocale('US');
+        $this->assertEquals('en_US', $value);
+
+        $value = new Zend_Locale('US');
+        $this->assertEquals('en_US', $value->toString());
+
+        $value = new Zend_Locale('TR');
+        $this->assertEquals('tr_TR', $value->toString());
+    }
+
+    /**
      * Ignores a raised PHP error when in effect, but throws a flag to indicate an error occurred
      *
      * @param  integer $errno