Textpattern PHP Cross Reference Content Management Systems

Source: /textpattern/vendors/Textpattern/L10n/Locale.php - 325 lines - 13568 bytes - Summary - Text - Print

Description: Handles locales.

   1  <?php
   2  
   3  /*
   4   * Textpattern Content Management System
   5   * http://textpattern.com
   6   *
   7   * Copyright (C) 2016 The Textpattern Development Team
   8   *
   9   * This file is part of Textpattern.
  10   *
  11   * Textpattern is free software; you can redistribute it and/or
  12   * modify it under the terms of the GNU General Public License
  13   * as published by the Free Software Foundation, version 2.
  14   *
  15   * Textpattern is distributed in the hope that it will be useful,
  16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18   * GNU General Public License for more details.
  19   *
  20   * You should have received a copy of the GNU General Public License
  21   * along with Textpattern. If not, see <http://www.gnu.org/licenses/>.
  22   */
  23  
  24  /**
  25   * Handles locales.
  26   *
  27   * <code>
  28   * echo Txp::get('Textpattern\L10n\Locale')->setLocale(LC_ALL, 'da-dk')->getLocale();
  29   * </code>
  30   *
  31   * @since   4.6.0
  32   * @package L10n
  33   */
  34  
  35  namespace Textpattern\L10n;
  36  
  37  class Locale
  38  {
  39      /**
  40       * An array of locale identifiers.
  41       *
  42       * @var array
  43       */
  44  
  45      protected $locales = array(
  46          'ar-dz' => array('ar_DZ.UTF-8', 'ar_DZ', 'ara', 'ar', 'arabic', 'ar_DZ.ISO_8859-6', 'Arabic_Saudi Arabia.1256'),
  47          'bg-bg' => array('bg_BG.UTF-8', 'bg_BG', 'bg', 'bul', 'bulgarian', 'bg_BG.ISO_8859-5', 'Bulgarian_Bulgaria.1251'),
  48          'bs-ba' => array('bs_BA.UTF-8', 'bs_BA', 'bs', 'bos', 'bosnian'),
  49          'ca-es' => array('ca_ES.UTF-8', 'ca_ES', 'cat', 'ca', 'catalan', 'ca_ES.ISO_8859-1', 'Catalan_Spain.1252'),
  50          'cs-cz' => array('cs_CZ.UTF-8', 'cs_CZ', 'ces', 'cze', 'cs', 'csy', 'czech', 'cs_CZ.ISO_8859-2', 'Czech_Czech Republic.1250'),
  51          'da-dk' => array('da_DK.UTF-8', 'da_DK', 'da', 'dan', 'danish', 'da_DK.ISO_8859-1', 'Danish_Denmark.1252'),
  52          'de-de' => array('de_DE.UTF-8', 'de_DE', 'de', 'deu', 'german', 'de_DE.ISO_8859-1', 'de_DE.ISO_8859-16', 'German_Germany.1252'),
  53          'el-gr' => array('el_GR.UTF-8', 'el_GR', 'el', 'gre', 'greek', 'el_GR.ISO_8859-7', 'Greek_Greece.1253'),
  54          'en-gb' => array('en_GB.UTF-8', 'en_GB', 'en_UK', 'eng', 'en', 'english-uk', 'english', 'en_GB.ISO_8859-1', 'C', 'English_UK.1252'),
  55          'en-us' => array('en_US.UTF-8', 'en_US', 'english-us', 'eng', 'en', 'english', 'en_US.ISO_8859-1', 'English_USA.1252'),
  56          'es-es' => array('es_ES.UTF-8', 'es_ES', 'esp', 'spanish', 'es_ES.ISO_8859-1', 'Spanish_Spain.1252'),
  57          'et-ee' => array('et_EE.UTF-8', 'et_EE', 'et', 'est', 'estonian', 'et_EE.ISO_8859-1', 'et_EE.ISO_8859-15', 'Estonian_Estonia.1257'),
  58          'fa-ir' => array('fa_IR.UTF-8', 'fa_IR', 'fa', 'persian', 'per', 'fas', 'farsi', 'Farsi_Iran.1256'),
  59          'fi-fi' => array('fi_FI.UTF-8', 'fi_FI', 'fin', 'fi', 'finnish', 'fi_FI.ISO_8859-1', 'fi_FI.ISO-8859-15', 'fi_FI.ISO_8859-16', 'Finnish_Finland.1252'),
  60          'fr-fr' => array('fr_FR.UTF-8', 'fr_FR', 'fra', 'fre', 'fr', 'french', 'fr_FR.ISO_8859-1', 'fr_FR.ISO-8859-15', 'fr_FR.ISO_8859-16', 'French_France.1252'),
  61          'gl-gz' => array('gl_GZ.UTF-8', 'gl_GZ', 'glg', 'gl'),
  62          'gl-es' => array('gl_ES.UTF-8', 'gl_ES', 'gle', 'gl', 'galician', 'galleco', 'gl_ES.ISO_8859-1', 'Galician_Spain.1252'),
  63          'he-il' => array('he_IL.UTF-8', 'he_IL', 'heb', 'he', 'hebrew', 'he_IL.ISO_8859-8', 'Hebrew_Israel.1255'),
  64          'hr-hr' => array('hr_HR.UTF-8', 'hr_HR', 'hr', 'hrv', 'croatian', 'hr_HR.ISO_8859-2', 'hr_HR.ISO_8859-16', 'Croatian_Croatia.1250'),
  65          'hu-hu' => array('hu_HU.UTF-8', 'hu_HU', 'hun', 'hu', 'hungarian', 'hu_HU.ISO_8859-2', 'hu_HU.ISO_8859-16', 'Hungarian_Hungary.1250'),
  66          'id-id' => array('id_ID.UTF-8', 'id_ID', 'id', 'ind', 'indonesian', 'id_ID.ISO_8859-1', 'Indonesian_indonesia.1252'),
  67          'is-is' => array('is_IS.UTF-8', 'is_IS', 'is', 'ice', 'isl', 'icelandic', 'is_IS.ISO_8859-1', 'Icelandic_Iceland.1252'),
  68          'it-it' => array('it_IT.UTF-8', 'it_IT', 'it', 'ita', 'italian', 'it_IT.ISO_8859-1', 'it_IT.ISO_8859-16', 'Italian_Italy.1252'),
  69          'ja-jp' => array('ja_JP.UTF-8', 'ja_JP', 'ja', 'jpn', 'japanese', 'Japanese_Japan.932'),
  70          'ko-kr' => array('ko_KR.UTF-8', 'ko_KR', 'ko', 'kor', 'korean', 'Korean_Korea.949'),
  71          'lt-lt' => array('lt_LT.UTF-8', 'lt_LT', 'lt', 'lit', 'lithuanian', 'lt_LT.ISO_8859-4', 'Lithuanian_Lithuania.1257'),
  72          'lv-lv' => array('lv_LV.UTF-8', 'lv_LV', 'lv', 'lav', 'latvian', 'lv_LV.ISO_8859-4', 'Latvian_Latvia.1257'),
  73          'nl-nl' => array('nl_NL.UTF-8', 'nl_NL', 'dut', 'nla', 'nl', 'nld', 'dutch', 'nl_NL.ISO_8859-1', 'Dutch_Netherlands.1252'),
  74          'nn-no' => array('nn_NO.UTF-8', 'nn_NO', 'no', 'nn', 'nor', 'nno', 'nb', 'nob', 'norwegian', 'no_NO.ISO_8859-1', 'Norwegian_Norway.1252'),
  75          'no-no' => array('no_NO.UTF-8', 'no_NO', 'no', 'nor', 'norwegian', 'no_NO.ISO_8859-1', 'Norwegian_Norway.1252'),
  76          'pl-pl' => array('pl_PL.UTF-8', 'pl_PL', 'pl', 'pol', 'polish', 'po_PO.ISO_8859-2', 'Polish_Poland.1250'),
  77          'pt-br' => array('pt_BR.UTF-8', 'pt_BR', 'pt', 'ptb', 'portuguese-brazil', 'Portuguese_Brazil.1252'),
  78          'pt-pt' => array('pt_PT.UTF-8', 'pt_PT', 'por', 'portuguese', 'pt_PT.ISO_8859-1', 'Portuguese_Portugal.1252'),
  79          'ro-ro' => array('ro_RO.UTF-8', 'ro_RO', 'ron', 'rum', 'ro', 'romanian', 'ro_RO.ISO_8859-2', 'ro_RO.ISO_8859-16', 'Romanian_Romania.1250'),
  80          'ru-ru' => array('ru_RU.UTF-8', 'ru_RU', 'ru', 'rus', 'russian', 'ru_RU.ISO_8859-5', 'Russian_Russia.1251'),
  81          'sk-sk' => array('sk_SK.UTF-8', 'sk_SK', 'sk', 'slo', 'slk', 'slovak', 'sk_SK.ISO_8859-1', 'Slovak_Slovakia.1250'),
  82          'sr-rs' => array('sr-RS.UTF-8', 'sr_RS', 'sr', 'sp', 'srb', 'serbian', 'Serbian (Cyrillic)_Serbia and Montenegro.1251'),
  83          'sr-sp' => array('sr-SP.UTF-8', 'sr_SP', 'sr', 'sp', 'srb', 'serbian', 'Serbian (Cyrillic)_Serbia and Montenegro.1251'),
  84          'sv-se' => array('sv_SE.UTF-8', 'sv_SE', 'sv', 'swe', 'sve', 'swedish', 'sv_SE.ISO_8859-1', 'Swedish_Sweden.1252'),
  85          'th-th' => array('th_TH.UTF-8', 'th_TH', 'th', 'tha', 'thai', 'th_TH.ISO_8859-11', 'Thai_Thailand.874'),
  86          'tr-tr' => array('tr_TR.UTF-8', 'tr_TR', 'tr', 'tur', 'turkish', 'tr_TR.ISO_8859-3', 'tr_TR.ISO_8859-9', 'Turkish_Turkey.1254'),
  87          'uk-ua' => array('uk_UA.UTF-8', 'uk_UA', 'uk', 'ukr', 'ukrainian', 'uk_UA.ISO_8859-5', 'Ukrainian_Ukraine.1251'),
  88          'ur-in' => array('ur_IN.UTF-8', 'ur_IN', 'ur', 'urd', 'urdu'),
  89          'vi-vn' => array('vi_VN.UTF-8', 'vi_VN', 'vi', 'vie', 'vietnamese', 'Vietnamese_Viet Nam.1258'),
  90          'zh-cn' => array('zh_CN.UTF-8', 'zh_CN', 'chinese-simplified', 'Chinese_China.936'),
  91          'zh-tw' => array('zh_TW.UTF-8', 'zh_TW', 'chinese-traditional', 'Chinese_Taiwan.950'),
  92      );
  93  
  94      /**
  95       * Sets the locale.
  96       *
  97       * This method wraps around system setlocale. It takes an IETF language code
  98       * and sets the locale accordingly.
  99       *
 100       * The following would set the locale to English:
 101       *
 102       * <code>
 103       * Txp::get('Textpattern\L10n\Locale')->setLocale(LC_ALL, 'en-GB');
 104       * </code>
 105       *
 106       * This would format currencies according to the French localisation:
 107       *
 108       * <code>
 109       * Txp::get('Textpattern\L10n\Locale')->setLocale(LC_MONETARY, 'fr-FR');
 110       * echo money_format('%i', 51.99);
 111       * </code>
 112       *
 113       * The '51.99' would be returned as '51,99 EUR' if you have up to date
 114       * French locale installed on your system.
 115       *
 116       * If an array of locales is provided, the first one that works is used.
 117       *
 118       * @param  int          $category The localisation category to change
 119       * @param  string|array $locale   The language code
 120       * @return Locale
 121       * @throws \Exception
 122       * @see    setlocale()
 123       */
 124  
 125      public function setLocale($category, $locale)
 126      {
 127          foreach ((array)$locale as $name) {
 128              $code = strtolower($name);
 129  
 130              if (isset($this->locales[$code])) {
 131                  if (@setlocale($category, $this->locales[$code])) {
 132                      return $this;
 133                  }
 134              }
 135          }
 136  
 137          if (@setlocale($category, $name)) {
 138              return $this;
 139          }
 140  
 141          throw new \Exception(gTxt('invalid_argument', array('{name}' => 'locale')));
 142      }
 143  
 144      /**
 145       * Gets the current locale.
 146       *
 147       * <code>
 148       * echo Txp::get('Textpattern\L10n\Locale')->getLocale(LC_ALL);
 149       * </code>
 150       *
 151       * @param  int $category The localisation category
 152       * @return mixed
 153       */
 154  
 155      public function getLocale($category = LC_ALL)
 156      {
 157          return @setlocale($category, '0');
 158      }
 159  
 160      /**
 161       * Gets a locale identifier for the given language code.
 162       *
 163       * This method takes an IETF language code and returns a locale for it that
 164       * works on the current system.
 165       *
 166       * The following returns 'en_GB.UTF-8':
 167       *
 168       * <code>
 169       * echo Txp::get('Textpattern\L10n\Locale')->getLanguageLocale('en-GB');
 170       * </code>
 171       *
 172       * Returns the current locale name if the system doesn't have anything
 173       * more appropriate.
 174       *
 175       * @param  string $language The language
 176       * @return string|bool Locale code, or FALSE on error
 177       */
 178  
 179      public function getLanguageLocale($language)
 180      {
 181          $locale = false;
 182  
 183          if ($original = $this->getLocale(LC_TIME)) {
 184              $locale = $original;
 185  
 186              try {
 187                  $locale = $this->setLocale(LC_TIME, $language)->getLocale(LC_TIME);
 188                  $this->setLocale(LC_TIME, $original);
 189              } catch (\Exception $e) {
 190              }
 191          }
 192  
 193          return $locale;
 194      }
 195  
 196      /**
 197       * Gets a language code for the given locale identifier.
 198       *
 199       * This method supports various different formats used by different host
 200       * platform. These formats include IETF language tag, POSIX locale name and
 201       * language name in English.
 202       *
 203       * All these will return 'en-GB':
 204       *
 205       * <code>
 206       * echo Txp::get('Textpattern\L10n\Locale')->getLocaleLanguage('en_GB.UTF-8');
 207       * echo Txp::get('Textpattern\L10n\Locale')->getLocaleLanguage('en-gb');
 208       * echo Txp::get('Textpattern\L10n\Locale')->getLocaleLanguage('english');
 209       * echo Txp::get('Textpattern\L10n\Locale')->getLocaleLanguage('c');
 210       * echo Txp::get('Textpattern\L10n\Locale')->getLocaleLanguage('English_UK.1252');
 211       * </code>
 212       *
 213       * If the specified locale isn't supported, FALSE will be returned.
 214       *
 215       * @param  string $locale The locale identifier
 216       * @return string|bool The language code, or FALSE on failure
 217       */
 218  
 219      public function getLocaleLanguage($locale)
 220      {
 221          $code = strtolower($locale);
 222  
 223          foreach ($this->locales as $lang => $data) {
 224              if ($lang === $code || in_array($code, array_map('strtolower', $data), true)) {
 225                  return $lang;
 226              }
 227          }
 228  
 229          if (strpos($locale, '.')) {
 230              return join('.', array_slice(explode('.', $locale), 0, 1));
 231          }
 232  
 233          return false;
 234      }
 235  
 236      /**
 237       * Gets the character set from the current locale.
 238       *
 239       * This method exports the character set from the current locale string as
 240       * returned by the OS.
 241       *
 242       * <code>
 243       * echo Txp::get('Textpattern\L10n\Locale')->getCharset();
 244       * </code>
 245       *
 246       * @param  int $category The localisation category
 247       * @return string|bool The character set, or FALSE on failure
 248       */
 249  
 250      public function getCharset($category = LC_ALL)
 251      {
 252          if (($locale = $this->getLocale($category)) && strpos($locale, '.')) {
 253              list($language, $charset) = explode('.', $locale);
 254  
 255              if (IS_WIN && is_numeric($charset)) {
 256                  return 'Windows-'.$charset;
 257              }
 258  
 259              return $charset;
 260          }
 261  
 262          return false;
 263      }
 264  
 265      /**
 266       * Gets the language from the current locale.
 267       *
 268       * <code>
 269       * echo Txp::get('Textpattern\L10n\Locale')->getLanguage();
 270       * </code>
 271       *
 272       * @param  int $category The localisation category
 273       * @return string|bool The language code, or FALSE on failure
 274       */
 275  
 276      public function getLanguage($category = LC_ALL)
 277      {
 278          if ($locale = $this->getLocale($category)) {
 279              if (($lang = $this->getLocaleLanguage($locale)) !== false) {
 280                  return $lang;
 281              }
 282          }
 283  
 284          return false;
 285      }
 286  
 287      /**
 288       * Gets locale identifiers mapped to the given language.
 289       *
 290       * Returns all locale identifiers that match the given language or locale
 291       * code. For instance providing 'en', will return both en-US and en-GB
 292       * locale identifiers.
 293       *
 294       * <code>
 295       * print_r(Txp::get('Textpattern\L10n\Locale')->getLocaleIdentifiers('english'));
 296       * print_r(Txp::get('Textpattern\L10n\Locale')->getLocaleIdentifiers('en'));
 297       * print_r(Txp::get('Textpattern\L10n\Locale')->getLocaleIdentifiers('en-gb'));
 298       * </code>
 299       *
 300       * @param  string $locale The locale or language code
 301       * @return array|bool An array of identifiers, or FALSE if not supported
 302       */
 303  
 304      public function getLocaleIdentifiers($locale)
 305      {
 306          if (isset($this->locales[strtolower($locale)])) {
 307              return array_merge($this->locales[$locale], array($locale));
 308          }
 309  
 310          $code = strtolower($locale);
 311          $matches = array();
 312  
 313          foreach ($this->locales as $lang => $data) {
 314              if ($lang === $code || in_array($code, array_map('strtolower', $data), true)) {
 315                  $matches = array_merge($matches, $data, array($lang, $locale));
 316              }
 317          }
 318  
 319          if ($matches) {
 320              return array_unique($matches);
 321          }
 322  
 323          return false;
 324      }
 325  }

title

Description

title

Description

title

Description

title

title

Body