PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Core/Cldr/Localize.php

https://gitlab.com/jslee1/PrestaShop
PHP | 261 lines | 143 code | 42 blank | 76 comment | 30 complexity | 159ff27e6d8e67cc418bcad5d0414d6a MD5 | raw file
  1. <?php
  2. /**
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. namespace PrestaShop\PrestaShop\Core\Cldr;
  27. /**
  28. * Class Localize
  29. * @package PrestaShop\PrestaShop\Core\Cldr
  30. */
  31. class Localize
  32. {
  33. const DEFAULT_LOCALE = 'en';
  34. protected static $filters = array(
  35. 'language' => array('filter' => 'strtolower'),
  36. 'script' => array('filter' => array('strtolower', 'ucfirst')),
  37. 'territory' => array('filter' => 'strtoupper'),
  38. 'variant' => array('filter' => 'strtoupper')
  39. );
  40. private static $browserLocales;
  41. private static $environmentLocale;
  42. private static $locale;
  43. /**
  44. * {@inheritdoc}
  45. */
  46. public function __toString()
  47. {
  48. return self::toString();
  49. }
  50. /**
  51. * Get the Browser locales (checking the HTTP header 'accept language')
  52. *
  53. * @return array The accepted locales
  54. */
  55. public static function getBrowserLocales()
  56. {
  57. if (self::$browserLocales !== null) {
  58. return self::$browserLocales;
  59. }
  60. $regex = '(?P<locale>[\w\-]+)+(?:;q=(?P<quality>[0-9]+\.[0-9]+))?';
  61. $result = array();
  62. $httpLanguages = getenv('HTTP_ACCEPT_LANGUAGE');
  63. if (empty($httpLanguages)) {
  64. if (array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
  65. $httpLanguages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
  66. } else {
  67. return $result;
  68. }
  69. }
  70. foreach (explode(',', $httpLanguages) as $language) {
  71. if (preg_match("/{$regex}/", $language, $matches)) {
  72. $quality = isset($matches['quality']) ? $matches['quality'] : 1;
  73. $result[self::canonicalize($matches['locale'])] = $quality;
  74. }
  75. }
  76. arsort($result);
  77. $result = array_keys($result);
  78. self::$browserLocales = $result;
  79. return $result;
  80. }
  81. public static function getEnvironmentLocale()
  82. {
  83. if (self::$environmentLocale !== null) {
  84. return self::$environmentLocale;
  85. }
  86. $regex = '(?P<locale>[\w\_]+)(\.|@|$)+';
  87. $result = array();
  88. $value = setlocale(LC_ALL, 0);
  89. if ($value != 'C' && $value != 'POSIX' && preg_match("/{$regex}/", $value, $matches)) {
  90. $result = (array) $matches['locale'];
  91. // TODO: Add region handle
  92. }
  93. self::$environmentLocale = $result;
  94. return $result;
  95. }
  96. /**
  97. * Parse the language part of a given locale string
  98. *
  99. * @param null|string $locale The local to parse
  100. * @return string The language parsed from the $locale input
  101. */
  102. public static function getLanguage($locale = null)
  103. {
  104. if (!isset($locale)) {
  105. $locale = self::getLocale();
  106. }
  107. $locale = explode('_', $locale);
  108. return $locale[0];
  109. }
  110. /**
  111. * Sets a locale value as a singleton
  112. *
  113. * @param string $value The local to set
  114. */
  115. public static function setLocale($value)
  116. {
  117. if (!is_string($value)) {
  118. throw new \InvalidArgumentException('Invalid type for setLocale function');
  119. }
  120. self::$locale = self::canonicalize($value);
  121. }
  122. /**
  123. * Gets the locale value (singleton)
  124. *
  125. * @return string The locale singleton
  126. */
  127. public static function getLocale()
  128. {
  129. if (!isset(self::$locale)) {
  130. self::$locale = self::getPreferedLocale();
  131. }
  132. return self::$locale;
  133. }
  134. /**
  135. * Gets the best locale value, looking after the input, the browser and the environment locales.
  136. *
  137. * @param null|string|Localize $locale
  138. * @return string The best fitting locale
  139. */
  140. public static function getPreferedLocale($locale = null)
  141. {
  142. if ($locale instanceof self) {
  143. $locale = $locale->toString();
  144. }
  145. if ($locale === 'browser') {
  146. $locale = self::getBrowserLocales();
  147. }
  148. if ($locale === 'environment') {
  149. $locale = self::getEnvironmentLocale();
  150. }
  151. if (($locale === 'auto') || ($locale === null)) {
  152. $locale = self::getBrowserLocales();
  153. $locale += self::getEnvironmentLocale();
  154. }
  155. if (is_array($locale) === true) {
  156. reset($locale);
  157. $locale = current($locale);
  158. }
  159. if ($locale === null || trim($locale) == '') {
  160. $locale = self::DEFAULT_LOCALE;
  161. }
  162. return (string)self::canonicalize($locale);
  163. }
  164. /**
  165. * Parse the region part of the given locale string.
  166. *
  167. * @param null|string $locale The locale value to parse
  168. * @return string The region parsed from the input
  169. */
  170. public static function getRegion($locale = null)
  171. {
  172. if (!isset($locale)) {
  173. $locale = self::getLocale();
  174. }
  175. $locale = explode('_', strtoupper($locale));
  176. if (isset($locale[1]) === true) {
  177. return $locale[1];
  178. }
  179. return $locale[0];
  180. }
  181. /**
  182. * Cast the current Localize instance into a string.
  183. *
  184. * @return string The locale of the current Localize instance, in a string format.
  185. */
  186. public static function toString()
  187. {
  188. return (string)self::getLocale();
  189. }
  190. /**
  191. * Parse and fix the given locale to ensure format.
  192. *
  193. * @param $locale The locale to fix.
  194. * @return array|null|string The fixed locale format.
  195. */
  196. private static function canonicalize($locale)
  197. {
  198. if (empty($locale) || $locale == '') {
  199. return null;
  200. }
  201. $regex = '(?P<language>[a-z]{2,3})(?:[_-](?P<script>[a-z]{4}))?(?:[_-](?P<territory>[a-z]{2}))?(?:[_-](?P<variant>[a-z]{5,}))?';
  202. if (!preg_match("/^{$regex}$/i", $locale, $matches)) {
  203. throw new \InvalidArgumentException('Locale "'.$locale.'" could not be parsed');
  204. }
  205. $tags = array_filter(array_intersect_key($matches, static::$filters));
  206. foreach ($tags as $name => &$tag) {
  207. foreach ((array)static::$filters[$name]['filter'] as $filter) {
  208. $tag = $filter($tag);
  209. }
  210. }
  211. $result = array();
  212. foreach (static::$filters as $name => $value) {
  213. if (isset($tags[$name])) {
  214. $result[] = $tags[$name];
  215. }
  216. }
  217. return $result ? implode('_', $result) : $result;
  218. }
  219. }