diff options
Diffstat (limited to 'vendor/commerceguys/intl/src')
29 files changed, 3003 insertions, 1976 deletions
diff --git a/vendor/commerceguys/intl/src/Country/Country.php b/vendor/commerceguys/intl/src/Country/Country.php deleted file mode 100644 index 7063e7d58..000000000 --- a/vendor/commerceguys/intl/src/Country/Country.php +++ /dev/null @@ -1,168 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Country; - -class Country implements CountryEntityInterface -{ - /** - * The two-letter country code. - * - * @var string - */ - protected $countryCode; - - /** - * The country name. - * - * @var string - */ - protected $name; - - /** - * The three-letter country code. - * - * @var string - */ - protected $threeLetterCode; - - /** - * The numeric country code. - * - * @var string - */ - protected $numericCode; - - /** - * The country currency code. - * - * @var string - */ - protected $currencyCode; - - /** - * The country locale (i.e. "en_US"). - * - * The country name is locale specific. - * - * @var string - */ - protected $locale; - - /** - * Returns the string representation of the Country. - * - * @return string - */ - public function __toString() - { - return $this->getCountryCode(); - } - - /** - * {@inheritdoc} - */ - public function getCountryCode() - { - return $this->countryCode; - } - - /** - * {@inheritdoc} - */ - public function setCountryCode($countryCode) - { - $this->countryCode = $countryCode; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getName() - { - return $this->name; - } - - /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getThreeLetterCode() - { - return $this->threeLetterCode; - } - - /** - * {@inheritdoc} - */ - public function setThreeLetterCode($threeLetterCode) - { - $this->threeLetterCode = $threeLetterCode; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getNumericCode() - { - return $this->numericCode; - } - - /** - * {@inheritdoc} - */ - public function setNumericCode($numericCode) - { - $this->numericCode = $numericCode; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getCurrencyCode() - { - return $this->currencyCode; - } - - /** - * {@inheritdoc} - */ - public function setCurrencyCode($currencyCode) - { - $this->currencyCode = $currencyCode; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getLocale() - { - return $this->locale; - } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->locale = $locale; - - return $this; - } -} diff --git a/vendor/commerceguys/intl/src/Country/CountryEntityInterface.php b/vendor/commerceguys/intl/src/Country/CountryEntityInterface.php deleted file mode 100644 index b22bcd42f..000000000 --- a/vendor/commerceguys/intl/src/Country/CountryEntityInterface.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Country; - -interface CountryEntityInterface extends CountryInterface -{ - /** - * Sets the two-letter country code. - * - * @param string $countryCode The two-letter country code. - * - * @return self - */ - public function setCountryCode($countryCode); - - /** - * Sets the country name. - * - * @param string $name The country name. - * - * @return self - */ - public function setName($name); - - /** - * Sets the three-letter country code. - * - * @param string $threeLetterCode The three-letter country code. - * - * @return self - */ - public function setThreeLetterCode($threeLetterCode); - - /** - * Sets the numeric country code. - * - * @param string $numericCode The numeric country code. - * - * @return self - */ - public function setNumericCode($numericCode); - - /** - * Sets the country currency code. - * - * @param string $currencyCode The currency code. - * - * @return self - */ - public function setCurrencyCode($currencyCode); -} diff --git a/vendor/commerceguys/intl/src/Country/CountryInterface.php b/vendor/commerceguys/intl/src/Country/CountryInterface.php deleted file mode 100644 index f6aaf91b2..000000000 --- a/vendor/commerceguys/intl/src/Country/CountryInterface.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Country; - -interface CountryInterface -{ - /** - * Gets the two-letter country code. - * - * @return string - */ - public function getCountryCode(); - - /** - * Gets the country name. - * - * Note that certain locales have incomplete translations, in which - * case the english version of the country name is used instead. - * - * @return string - */ - public function getName(); - - /** - * Gets the three-letter country code. - * - * Note that not every country has a three-letter code. - * CLDR lists "Canary Islands" (IC) and "Ceuta and Melilla" (EA) - * as separate countries, even though they are formally a part of Spain - * and have no three-letter or numeric ISO codes. - * - * @return string|null - */ - public function getThreeLetterCode(); - - /** - * Gets the numeric country code. - * - * The numeric code has three digits, and the first one can be a zero, - * hence the need to pass it around as a string. - * - * Note that not every country has a numeric code. - * CLDR lists "Canary Islands" (IC) and "Ceuta and Melilla" (EA) - * as separate countries, even though they are formally a part of Spain - * and have no three-letter or numeric ISO codes. - * "Ascension Island" (AE) also has no numeric code, even though it has a - * three-letter code. - * - * @return string|null - */ - public function getNumericCode(); - - /** - * Gets the country currency code. - * - * Represents the default currency used in the country, if known. - * - * @return string|null - */ - public function getCurrencyCode(); -} diff --git a/vendor/commerceguys/intl/src/Country/CountryRepository.php b/vendor/commerceguys/intl/src/Country/CountryRepository.php deleted file mode 100644 index fb027dc2f..000000000 --- a/vendor/commerceguys/intl/src/Country/CountryRepository.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Country; - -use CommerceGuys\Intl\LocaleResolverTrait; -use CommerceGuys\Intl\Exception\UnknownCountryException; - -/** - * Manages countries based on JSON definitions. - */ -class CountryRepository implements CountryRepositoryInterface -{ - use LocaleResolverTrait; - - /** - * Base country definitions. - * - * Contains data common to all locales, such as the country numeric, - * three-letter, currency codes. - * - * @var array - */ - protected $baseDefinitions = []; - - /** - * Per-locale country definitions. - * - * @var array - */ - protected $definitions = []; - - /** - * Creates a CountryRepository instance. - * - * @param string $definitionPath The path to the country definitions. - * Defaults to 'resources/country'. - */ - public function __construct($definitionPath = null) - { - $this->definitionPath = $definitionPath ? $definitionPath : __DIR__ . '/../../resources/country/'; - } - - /** - * {@inheritdoc} - */ - public function get($countryCode, $locale = null, $fallbackLocale = null) - { - $locale = $this->resolveLocale($locale, $fallbackLocale); - $definitions = $this->loadDefinitions($locale); - if (!isset($definitions[$countryCode])) { - throw new UnknownCountryException($countryCode); - } - - return $this->createCountryFromDefinition($countryCode, $definitions[$countryCode], $locale); - } - - /** - * {@inheritdoc} - */ - public function getAll($locale = null, $fallbackLocale = null) - { - $locale = $this->resolveLocale($locale, $fallbackLocale); - $definitions = $this->loadDefinitions($locale); - $countries = []; - foreach ($definitions as $countryCode => $definition) { - $countries[$countryCode] = $this->createCountryFromDefinition($countryCode, $definition, $locale); - } - - return $countries; - } - - /** - * {@inheritdoc} - */ - public function getList($locale = null, $fallbackLocale = null) - { - $locale = $this->resolveLocale($locale, $fallbackLocale); - $definitions = $this->loadDefinitions($locale); - $list = []; - foreach ($definitions as $countryCode => $definition) { - $list[$countryCode] = $definition['name']; - } - - return $list; - } - - /** - * Loads the country definitions for the provided locale. - * - * @param string $locale The desired locale. - * - * @return array - */ - protected function loadDefinitions($locale) - { - if (!isset($this->definitions[$locale])) { - $filename = $this->definitionPath . $locale . '.json'; - $this->definitions[$locale] = json_decode(file_get_contents($filename), true); - - // Make sure the base definitions have been loaded. - if (empty($this->baseDefinitions)) { - $this->baseDefinitions = json_decode(file_get_contents($this->definitionPath . 'base.json'), true); - } - // Merge-in base definitions. - foreach ($this->definitions[$locale] as $countryCode => $definition) { - $this->definitions[$locale][$countryCode] += $this->baseDefinitions[$countryCode]; - } - } - - return $this->definitions[$locale]; - } - - /** - * Creates a country object from the provided definition. - * - * @param string $countryCode The country code. - * @param array $definition The country definition. - * @param string $locale The locale of the country definition. - * - * @return Country - */ - protected function createCountryFromDefinition($countryCode, array $definition, $locale) - { - $country = new Country(); - $setValues = \Closure::bind(function ($countryCode, $definition, $locale) { - $this->countryCode = $countryCode; - $this->name = $definition['name']; - $this->locale = $locale; - if (isset($definition['three_letter_code'])) { - $this->threeLetterCode = $definition['three_letter_code']; - } - if (isset($definition['numeric_code'])) { - $this->numericCode = $definition['numeric_code']; - } - if (isset($definition['currency_code'])) { - $this->currencyCode = $definition['currency_code']; - } - }, $country, '\CommerceGuys\Intl\Country\Country'); - $setValues($countryCode, $definition, $locale); - - return $country; - } -} diff --git a/vendor/commerceguys/intl/src/Country/CountryRepositoryInterface.php b/vendor/commerceguys/intl/src/Country/CountryRepositoryInterface.php deleted file mode 100644 index fbcd5551e..000000000 --- a/vendor/commerceguys/intl/src/Country/CountryRepositoryInterface.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Country; - -/** - * Country repository interface. - */ -interface CountryRepositoryInterface -{ - /** - * Returns a country instance matching the provided country code. - * - * @param string $countryCode The country code. - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). - * - * @return CountryInterface - */ - public function get($countryCode, $locale = null, $fallbackLocale = null); - - /** - * Returns all country instances. - * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). - * - * @return array An array of countries implementing the CountryInterface, - * keyed by country code. - */ - public function getAll($locale = null, $fallbackLocale = null); - - /** - * Returns a list of countries. - * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). - * - * @return array An array of country names, keyed by country code. - */ - public function getList($locale = null, $fallbackLocale = null); -} diff --git a/vendor/commerceguys/intl/src/Currency/Currency.php b/vendor/commerceguys/intl/src/Currency/Currency.php index 6f9256bf0..28329795c 100644 --- a/vendor/commerceguys/intl/src/Currency/Currency.php +++ b/vendor/commerceguys/intl/src/Currency/Currency.php @@ -2,7 +2,10 @@ namespace CommerceGuys\Intl\Currency; -class Currency implements CurrencyEntityInterface +/** + * Represents a currency. + */ +final class Currency { /** * The alphanumeric currency code. @@ -37,47 +40,67 @@ class Currency implements CurrencyEntityInterface * * @var int */ - protected $fractionDigits; + protected $fractionDigits = 2; /** - * The currency locale (i.e. "en_US"). - * - * The currency name and symbol are locale specific. + * The locale (i.e. "en_US"). * * @var string */ protected $locale; /** - * Returns the string representation of the currency. + * Creates a new Currency instance. * - * @return string + * @param array $definition The definition array. */ - public function __toString() + public function __construct(array $definition) { - return $this->getCurrencyCode(); + foreach (['currency_code', 'name', 'numeric_code', 'locale'] as $requiredProperty) { + if (empty($definition[$requiredProperty])) { + throw new \InvalidArgumentException(sprintf('Missing required property "%s".', $requiredProperty)); + } + } + if (!isset($definition['symbol'])) { + $definition['symbol'] = $definition['currency_code']; + } + + $this->currencyCode = $definition['currency_code']; + $this->name = $definition['name']; + $this->numericCode = $definition['numeric_code']; + $this->symbol = $definition['symbol']; + if (isset($definition['fraction_digits'])) { + $this->fractionDigits = $definition['fraction_digits']; + } + $this->locale = $definition['locale']; } /** - * {@inheritdoc} + * Gets the string representation of the currency. + * + * @return string */ - public function getCurrencyCode() + public function __toString() { return $this->currencyCode; } /** - * {@inheritdoc} + * Gets the alphabetic currency code. + * + * @return string */ - public function setCurrencyCode($currencyCode) + public function getCurrencyCode() { - $this->currencyCode = $currencyCode; - - return $this; + return $this->currencyCode; } /** - * {@inheritdoc} + * Gets the currency name. + * + * This value is locale specific. + * + * @return string */ public function getName() { @@ -85,17 +108,12 @@ class Currency implements CurrencyEntityInterface } /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} + * Gets the numeric currency code. + * + * The numeric code has three digits, and the first one can be a zero, + * hence the need to pass it around as a string. + * + * @return string */ public function getNumericCode() { @@ -103,17 +121,11 @@ class Currency implements CurrencyEntityInterface } /** - * {@inheritdoc} - */ - public function setNumericCode($numericCode) - { - $this->numericCode = $numericCode; - - return $this; - } - - /** - * {@inheritdoc} + * Gets the currency symbol. + * + * This value is locale specific. + * + * @return string */ public function getSymbol() { @@ -121,17 +133,12 @@ class Currency implements CurrencyEntityInterface } /** - * {@inheritdoc} - */ - public function setSymbol($symbol) - { - $this->symbol = $symbol; - - return $this; - } - - /** - * {@inheritdoc} + * Gets the number of fraction digits. + * + * Used when rounding or formatting an amount for display. + * Actual storage precision can be greater. + * + * @return int */ public function getFractionDigits() { @@ -139,30 +146,14 @@ class Currency implements CurrencyEntityInterface } /** - * {@inheritdoc} - */ - public function setFractionDigits($fractionDigits) - { - $this->fractionDigits = $fractionDigits; - - return $this; - } - - /** - * {@inheritdoc} + * Gets the locale. + * + * The currency name and symbol are locale specific. + * + * @return string */ public function getLocale() { return $this->locale; } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->locale = $locale; - - return $this; - } } diff --git a/vendor/commerceguys/intl/src/Currency/CurrencyEntityInterface.php b/vendor/commerceguys/intl/src/Currency/CurrencyEntityInterface.php deleted file mode 100644 index 85d4ab83d..000000000 --- a/vendor/commerceguys/intl/src/Currency/CurrencyEntityInterface.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Currency; - -interface CurrencyEntityInterface extends CurrencyInterface -{ - /** - * Sets the alphabetic currency code. - * - * @param string $currencyCode The alphabetic currency code. - * - * @return self - */ - public function setCurrencyCode($currencyCode); - - /** - * Sets the currency name. - * - * @param string $name The currency name. - * - * @return self - */ - public function setName($name); - - /** - * Sets the numeric currency code. - * - * @param string $numericCode The numeric currency code. - * - * @return self - */ - public function setNumericCode($numericCode); - - /** - * Sets the currency symbol. - * - * @param string $symbol The currency symbol. - * - * @return self - */ - public function setSymbol($symbol); - - /** - * Sets the number of fraction digits. - * - * @param int $fractionDigits The number of fraction digits. - * - * @return self - */ - public function setFractionDigits($fractionDigits); -} diff --git a/vendor/commerceguys/intl/src/Currency/CurrencyInterface.php b/vendor/commerceguys/intl/src/Currency/CurrencyInterface.php deleted file mode 100644 index 8aa709ca0..000000000 --- a/vendor/commerceguys/intl/src/Currency/CurrencyInterface.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Currency; - -interface CurrencyInterface -{ - /** - * Gets the alphabetic currency code. - * - * @return string - */ - public function getCurrencyCode(); - - /** - * Gets the currency name. - * - * @return string - */ - public function getName(); - - /** - * Gets the numeric currency code. - * - * The numeric code has three digits, and the first one can be a zero, - * hence the need to pass it around as a string. - * - * @return string - */ - public function getNumericCode(); - - /** - * Gets the currency symbol. - * - * @return string - */ - public function getSymbol(); - - /** - * Gets the number of fraction digits. - * - * Used when rounding or formatting an amount for display. - * Actual storage precision can be greater. - * - * @return int - */ - public function getFractionDigits(); -} diff --git a/vendor/commerceguys/intl/src/Currency/CurrencyRepository.php b/vendor/commerceguys/intl/src/Currency/CurrencyRepository.php index 5fdfce216..5a8dc2163 100644 --- a/vendor/commerceguys/intl/src/Currency/CurrencyRepository.php +++ b/vendor/commerceguys/intl/src/Currency/CurrencyRepository.php @@ -2,7 +2,7 @@ namespace CommerceGuys\Intl\Currency; -use CommerceGuys\Intl\LocaleResolverTrait; +use CommerceGuys\Intl\Locale; use CommerceGuys\Intl\Exception\UnknownCurrencyException; /** @@ -10,17 +10,26 @@ use CommerceGuys\Intl\Exception\UnknownCurrencyException; */ class CurrencyRepository implements CurrencyRepositoryInterface { - use LocaleResolverTrait; + /** + * The default locale. + * + * @var string + */ + protected $defaultLocale; /** - * Base currency definitions. + * The fallback locale. * - * Contains data common to all locales, such as the currency numeric - * code, number of fraction digits. + * @var string + */ + protected $fallbackLocale; + + /** + * The path where per-locale definitions are stored. * - * @var array + * @var string */ - protected $baseDefinitions = []; + protected $definitionPath; /** * Per-locale currency definitions. @@ -30,40 +39,87 @@ class CurrencyRepository implements CurrencyRepositoryInterface protected $definitions = []; /** + * The available locales. + * + * @var array + */ + protected $availableLocales = [ + 'af', 'agq', 'ak', 'am', 'ar', 'as', 'asa', 'ast', 'az', 'bas', 'be', + 'bez', 'bg', 'bm', 'bn', 'br', 'brx', 'bs', 'bs-Cyrl', 'ca', 'ccp', + 'ce', 'ceb', 'cgg', 'chr', 'cs', 'cy', 'da', 'dav', 'de', 'de-CH', + 'dje', 'dsb', 'dz', 'ebu', 'ee', 'el', 'en', 'en-001', 'en-AU', 'en-GG', + 'en-IM', 'en-JE', 'es', 'es-419', 'es-CL', 'es-GT', 'es-MX', 'es-US', + 'es-VE', 'et', 'eu', 'ewo', 'fa', 'fa-AF', 'ff', 'fi', 'fil', 'fo', + 'fr', 'fr-CA', 'fur', 'fy', 'ga', 'gd', 'gl', 'gsw', 'gu', 'guz', 'ha', + 'he', 'hi', 'hr', 'hsb', 'hu', 'hy', 'id', 'is', 'it', 'ja', 'jmc', + 'jv', 'ka', 'kab', 'kam', 'kde', 'kea', 'khq', 'ki', 'kk', 'kln', 'km', + 'kn', 'ko', 'kok', 'ks', 'ksb', 'ksf', 'ksh', 'ky', 'lag', 'lb', 'lg', + 'ln', 'lo', 'lt', 'lu', 'luo', 'luy', 'lv', 'mas', 'mer', 'mfe', 'mg', + 'mk', 'ml', 'mn', 'mr', 'ms', 'mua', 'my', 'mzn', 'naq', 'nb', 'nd', + 'ne', 'nl', 'nmg', 'nn', 'nyn', 'or', 'pa', 'pl', 'ps', 'pt', 'pt-PT', + 'qu', 'rm', 'rn', 'ro', 'rof', 'ru', 'rwk', 'saq', 'sbp', 'sd', 'seh', + 'ses', 'sg', 'shi', 'shi-Latn', 'si', 'sk', 'sl', 'sn', 'so', 'sq', + 'sr', 'sr-Latn', 'sv', 'sw', 'sw-CD', 'sw-KE', 'ta', 'te', 'teo', 'th', + 'tk', 'tr', 'twq', 'tzm', 'ug', 'uk', 'ur', 'ur-IN', 'uz', 'uz-Cyrl', + 'vai', 'vai-Latn', 'vi', 'vun', 'xog', 'yo', 'yo-BJ', 'yue', 'yue-Hans', + 'zgh', 'zh', 'zh-Hans-HK', 'zh-Hant', 'zh-Hant-HK', 'zu', + ]; + + /** * Creates a CurrencyRepository instance. * + * @param string $defaultLocale The default locale. Defaults to 'en'. + * @param string $fallbackLocale The fallback locale. Defaults to 'en'. * @param string $definitionPath The path to the currency definitions. * Defaults to 'resources/currency'. */ - public function __construct($definitionPath = null) + public function __construct($defaultLocale = 'en', $fallbackLocale = 'en', $definitionPath = null) { + $this->defaultLocale = $defaultLocale; + $this->fallbackLocale = $fallbackLocale; $this->definitionPath = $definitionPath ? $definitionPath : __DIR__ . '/../../resources/currency/'; } /** * {@inheritdoc} */ - public function get($currencyCode, $locale = null, $fallbackLocale = null) + public function get($currencyCode, $locale = null) { - $locale = $this->resolveLocale($locale, $fallbackLocale); - $definitions = $this->loadDefinitions($locale); - if (!isset($definitions[$currencyCode])) { + $currencyCode = strtoupper($currencyCode); + $baseDefinitions = $this->getBaseDefinitions(); + if (!isset($baseDefinitions[$currencyCode])) { throw new UnknownCurrencyException($currencyCode); } + $locale = $locale ?: $this->defaultLocale; + $locale = Locale::resolve($this->availableLocales, $locale, $this->fallbackLocale); + $definitions = $this->loadDefinitions($locale); + $currency = new Currency([ + 'currency_code' => $currencyCode, + 'numeric_code' => $baseDefinitions[$currencyCode][0], + 'fraction_digits' => $baseDefinitions[$currencyCode][1], + 'locale' => $locale, + ] + $definitions[$currencyCode]); - return $this->createCurrencyFromDefinition($currencyCode, $definitions[$currencyCode], $locale); + return $currency; } /** * {@inheritdoc} */ - public function getAll($locale = null, $fallbackLocale = null) + public function getAll($locale = null) { - $locale = $this->resolveLocale($locale, $fallbackLocale); + $locale = $locale ?: $this->defaultLocale; + $locale = Locale::resolve($this->availableLocales, $locale, $this->fallbackLocale); + $baseDefinitions = $this->getBaseDefinitions(); $definitions = $this->loadDefinitions($locale); $currencies = []; foreach ($definitions as $currencyCode => $definition) { - $currencies[$currencyCode] = $this->createCurrencyFromDefinition($currencyCode, $definition, $locale); + $currencies[$currencyCode] = new Currency([ + 'currency_code' => $currencyCode, + 'numeric_code' => $baseDefinitions[$currencyCode][0], + 'fraction_digits' => $baseDefinitions[$currencyCode][1], + 'locale' => $locale, + ] + $definition); } return $currencies; @@ -72,9 +128,10 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** * {@inheritdoc} */ - public function getList($locale = null, $fallbackLocale = null) + public function getList($locale = null) { - $locale = $this->resolveLocale($locale, $fallbackLocale); + $locale = $locale ?: $this->defaultLocale; + $locale = Locale::resolve($this->availableLocales, $locale, $this->fallbackLocale); $definitions = $this->loadDefinitions($locale); $list = []; foreach ($definitions as $currencyCode => $definition) { @@ -96,49 +153,183 @@ class CurrencyRepository implements CurrencyRepositoryInterface if (!isset($this->definitions[$locale])) { $filename = $this->definitionPath . $locale . '.json'; $this->definitions[$locale] = json_decode(file_get_contents($filename), true); - - // Make sure the base definitions have been loaded. - if (empty($this->baseDefinitions)) { - $this->baseDefinitions = json_decode(file_get_contents($this->definitionPath . 'base.json'), true); - } - // Merge-in base definitions. - foreach ($this->definitions[$locale] as $currencyCode => $definition) { - $this->definitions[$locale][$currencyCode] += $this->baseDefinitions[$currencyCode]; - } } return $this->definitions[$locale]; } /** - * Creates a currency object from the provided definition. + * Gets the base currency definitions. * - * @param string $currencyCode The currency code. - * @param array $definition The currency definition. - * @param string $locale The locale of the currency definition. + * Contains data common to all locales: numeric code, fraction digits. * - * @return Currency + * @return array + * An array of definitions, keyed by currency code. + * Each definition is a numerically indexed array containing: + * - The numeric code. + * - The fraction digits. */ - protected function createCurrencyFromDefinition($currencyCode, array $definition, $locale) + protected function getBaseDefinitions() { - if (!isset($definition['symbol'])) { - $definition['symbol'] = $currencyCode; - } - if (!isset($definition['fraction_digits'])) { - $definition['fraction_digits'] = 2; - } - - $currency = new Currency(); - $setValues = \Closure::bind(function ($currencyCode, $definition, $locale) { - $this->currencyCode = $currencyCode; - $this->name = $definition['name']; - $this->numericCode = $definition['numeric_code']; - $this->symbol = $definition['symbol']; - $this->fractionDigits = $definition['fraction_digits']; - $this->locale = $locale; - }, $currency, '\CommerceGuys\Intl\Currency\Currency'); - $setValues($currencyCode, $definition, $locale); - - return $currency; + return [ + 'AED' => ['784', 2], + 'AFN' => ['971', 0], + 'ALL' => ['008', 0], + 'AMD' => ['051', 2], + 'ANG' => ['532', 2], + 'AOA' => ['973', 2], + 'ARS' => ['032', 2], + 'AUD' => ['036', 2], + 'AWG' => ['533', 2], + 'AZN' => ['944', 2], + 'BAM' => ['977', 2], + 'BBD' => ['052', 2], + 'BDT' => ['050', 2], + 'BGN' => ['975', 2], + 'BHD' => ['048', 3], + 'BIF' => ['108', 0], + 'BMD' => ['060', 2], + 'BND' => ['096', 2], + 'BOB' => ['068', 2], + 'BRL' => ['986', 2], + 'BSD' => ['044', 2], + 'BTN' => ['064', 2], + 'BWP' => ['072', 2], + 'BYN' => ['933', 2], + 'BZD' => ['084', 2], + 'CAD' => ['124', 2], + 'CDF' => ['976', 2], + 'CHF' => ['756', 2], + 'CLP' => ['152', 0], + 'CNY' => ['156', 2], + 'COP' => ['170', 2], + 'CRC' => ['188', 2], + 'CUC' => ['931', 2], + 'CUP' => ['192', 2], + 'CVE' => ['132', 2], + 'CZK' => ['203', 2], + 'DJF' => ['262', 0], + 'DKK' => ['208', 2], + 'DOP' => ['214', 2], + 'DZD' => ['012', 2], + 'EGP' => ['818', 2], + 'ERN' => ['232', 2], + 'ETB' => ['230', 2], + 'EUR' => ['978', 2], + 'FJD' => ['242', 2], + 'FKP' => ['238', 2], + 'GBP' => ['826', 2], + 'GEL' => ['981', 2], + 'GHS' => ['936', 2], + 'GIP' => ['292', 2], + 'GMD' => ['270', 2], + 'GNF' => ['324', 0], + 'GTQ' => ['320', 2], + 'GYD' => ['328', 2], + 'HKD' => ['344', 2], + 'HNL' => ['340', 2], + 'HRK' => ['191', 2], + 'HTG' => ['332', 2], + 'HUF' => ['348', 2], + 'IDR' => ['360', 2], + 'ILS' => ['376', 2], + 'INR' => ['356', 2], + 'IQD' => ['368', 0], + 'IRR' => ['364', 0], + 'ISK' => ['352', 0], + 'JMD' => ['388', 2], + 'JOD' => ['400', 3], + 'JPY' => ['392', 0], + 'KES' => ['404', 2], + 'KGS' => ['417', 2], + 'KHR' => ['116', 2], + 'KMF' => ['174', 0], + 'KPW' => ['408', 0], + 'KRW' => ['410', 0], + 'KWD' => ['414', 3], + 'KYD' => ['136', 2], + 'KZT' => ['398', 2], + 'LAK' => ['418', 0], + 'LBP' => ['422', 0], + 'LKR' => ['144', 2], + 'LRD' => ['430', 2], + 'LSL' => ['426', 2], + 'LYD' => ['434', 3], + 'MAD' => ['504', 2], + 'MDL' => ['498', 2], + 'MGA' => ['969', 0], + 'MKD' => ['807', 2], + 'MMK' => ['104', 0], + 'MNT' => ['496', 2], + 'MOP' => ['446', 2], + 'MRU' => ['929', 2], + 'MUR' => ['480', 2], + 'MVR' => ['462', 2], + 'MWK' => ['454', 2], + 'MXN' => ['484', 2], + 'MYR' => ['458', 2], + 'MZN' => ['943', 2], + 'NAD' => ['516', 2], + 'NGN' => ['566', 2], + 'NIO' => ['558', 2], + 'NOK' => ['578', 2], + 'NPR' => ['524', 2], + 'NZD' => ['554', 2], + 'OMR' => ['512', 3], + 'PAB' => ['590', 2], + 'PEN' => ['604', 2], + 'PGK' => ['598', 2], + 'PHP' => ['608', 2], + 'PKR' => ['586', 2], + 'PLN' => ['985', 2], + 'PYG' => ['600', 0], + 'QAR' => ['634', 2], + 'RON' => ['946', 2], + 'RSD' => ['941', 0], + 'RUB' => ['643', 2], + 'RWF' => ['646', 0], + 'SAR' => ['682', 2], + 'SBD' => ['090', 2], + 'SCR' => ['690', 2], + 'SDG' => ['938', 2], + 'SEK' => ['752', 2], + 'SGD' => ['702', 2], + 'SHP' => ['654', 2], + 'SLL' => ['694', 0], + 'SOS' => ['706', 0], + 'SRD' => ['968', 2], + 'SSP' => ['728', 2], + 'STN' => ['930', 2], + 'SVC' => ['222', 2], + 'SYP' => ['760', 0], + 'SZL' => ['748', 2], + 'THB' => ['764', 2], + 'TJS' => ['972', 2], + 'TMT' => ['934', 2], + 'TND' => ['788', 3], + 'TOP' => ['776', 2], + 'TRY' => ['949', 2], + 'TTD' => ['780', 2], + 'TWD' => ['901', 2], + 'TZS' => ['834', 2], + 'UAH' => ['980', 2], + 'UGX' => ['800', 0], + 'USD' => ['840', 2], + 'UYU' => ['858', 2], + 'UYW' => ['927', 4], + 'UZS' => ['860', 2], + 'VES' => ['928', 2], + 'VND' => ['704', 0], + 'VUV' => ['548', 0], + 'WST' => ['882', 2], + 'XAF' => ['950', 0], + 'XCD' => ['951', 2], + 'XOF' => ['952', 0], + 'XPF' => ['953', 0], + 'YER' => ['886', 0], + 'ZAR' => ['710', 2], + 'ZMW' => ['967', 2], + 'ZWL' => ['932', 2], + ]; } } diff --git a/vendor/commerceguys/intl/src/Currency/CurrencyRepositoryInterface.php b/vendor/commerceguys/intl/src/Currency/CurrencyRepositoryInterface.php index f0a091969..eb726ddb8 100644 --- a/vendor/commerceguys/intl/src/Currency/CurrencyRepositoryInterface.php +++ b/vendor/commerceguys/intl/src/Currency/CurrencyRepositoryInterface.php @@ -8,34 +8,30 @@ namespace CommerceGuys\Intl\Currency; interface CurrencyRepositoryInterface { /** - * Returns a currency instance matching the provided currency code. + * Gets a currency matching the provided currency code. * - * @param string $currencyCode The currency code. - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $currencyCode The currency code. + * @param string $locale The locale (i.e. fr-FR). * - * @return CurrencyInterface + * @return Currency */ - public function get($currencyCode, $locale = null, $fallbackLocale = null); + public function get($currencyCode, $locale = null); /** - * Returns all currency instances. + * Gets all currencies. * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $locale The locale (i.e. fr-FR). * - * @return array An array of currencies implementing the CurrencyInterface, - * keyed by currency code. + * @return Currency[] An array of currencies, keyed by currency code. */ - public function getAll($locale = null, $fallbackLocale = null); + public function getAll($locale = null); /** - * Returns a list of currencies. + * Gets a list of currencies. * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $locale The locale (i.e. fr-FR). * - * @return array An array of currency names, keyed by currency code. + * @return string[] An array of currency names, keyed by currency code. */ - public function getList($locale = null, $fallbackLocale = null); + public function getList($locale = null); } diff --git a/vendor/commerceguys/intl/src/Exception/UnknownCountryException.php b/vendor/commerceguys/intl/src/Exception/UnknownCountryException.php deleted file mode 100644 index c89845b23..000000000 --- a/vendor/commerceguys/intl/src/Exception/UnknownCountryException.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Exception; - -/** - * This exception is thrown when an unknown country code is passed to the - * CountryRepository. - */ -class UnknownCountryException extends InvalidArgumentException implements ExceptionInterface -{ -} diff --git a/vendor/commerceguys/intl/src/Formatter/CurrencyFormatter.php b/vendor/commerceguys/intl/src/Formatter/CurrencyFormatter.php new file mode 100644 index 000000000..8d4d11f27 --- /dev/null +++ b/vendor/commerceguys/intl/src/Formatter/CurrencyFormatter.php @@ -0,0 +1,241 @@ +<?php + +namespace CommerceGuys\Intl\Formatter; + +use CommerceGuys\Intl\Currency\Currency; +use CommerceGuys\Intl\Currency\CurrencyRepositoryInterface; +use CommerceGuys\Intl\Exception\InvalidArgumentException; +use CommerceGuys\Intl\Exception\UnknownCurrencyException; +use CommerceGuys\Intl\NumberFormat\NumberFormat; +use CommerceGuys\Intl\NumberFormat\NumberFormatRepositoryInterface; + +/** + * Formats currency amounts using locale-specific patterns. + */ +class CurrencyFormatter implements CurrencyFormatterInterface +{ + use FormatterTrait; + + /** + * The number format repository. + * + * @var NumberFormatRepositoryInterface + */ + protected $numberFormatRepository; + + /** + * The currency repository. + * + * @var CurrencyRepositoryInterface + */ + protected $currencyRepository; + + /** + * The default locale. + * + * @var string + */ + protected $defaultLocale; + + /** + * The loaded number formats. + * + * @var NumberFormat[] + */ + protected $numberFormats = []; + + /** + * The loaded currencies. + * + * @var Currency[] + */ + protected $currencies = []; + + /** + * The default options. + * + * @var array + */ + protected $defaultOptions = [ + 'locale' => 'en', + 'use_grouping' => true, + 'minimum_fraction_digits' => null, + 'maximum_fraction_digits' => null, + 'rounding_mode' => PHP_ROUND_HALF_UP, + 'style' => 'standard', + 'currency_display' => 'symbol', + ]; + + /** + * Creates a CurrencyFormatter instance. + * + * @param NumberFormatRepositoryInterface $numberFormatRepository The number format repository. + * @param CurrencyRepositoryInterface $currencyRepository The currency repository. + * @param array $defaultOptions The default options. + * + * @throws \RuntimeException + */ + public function __construct(NumberFormatRepositoryInterface $numberFormatRepository, CurrencyRepositoryInterface $currencyRepository, array $defaultOptions = []) + { + if (!extension_loaded('bcmath')) { + throw new \RuntimeException('The bcmath extension is required by CurrencyFormatter.'); + } + $this->validateOptions($defaultOptions); + + $this->numberFormatRepository = $numberFormatRepository; + $this->currencyRepository = $currencyRepository; + $this->defaultOptions = array_replace($this->defaultOptions, $defaultOptions); + } + + /** + * {@inheritdoc} + */ + public function format($number, $currencyCode, array $options = []) + { + if (!is_numeric($number)) { + $message = sprintf('The provided value "%s" is not a valid number or numeric string.', $number); + throw new InvalidArgumentException($message); + } + + $this->validateOptions($options); + $options = array_replace($this->defaultOptions, $options); + $numberFormat = $this->getNumberFormat($options['locale']); + $currency = $this->getCurrency($currencyCode, $options['locale']); + // Use the currency defaults if the values weren't set by the caller. + if (!isset($options['minimum_fraction_digits'])) { + $options['minimum_fraction_digits'] = $currency->getFractionDigits(); + } + if (!isset($options['maximum_fraction_digits'])) { + $options['maximum_fraction_digits'] = $currency->getFractionDigits(); + } + + $number = (string) $number; + $number = $this->formatNumber($number, $numberFormat, $options); + if ($options['currency_display'] == 'symbol') { + $number = str_replace('¤', $currency->getSymbol(), $number); + } elseif ($options['currency_display'] == 'code') { + $number = str_replace('¤', $currency->getCurrencyCode(), $number); + } else { + // No symbol should be displayed. Remove leftover whitespace. + $number = str_replace('¤', '', $number); + $number = trim($number, " \xC2\xA0"); + } + + return $number; + } + + /** + * {@inheritdoc} + */ + public function parse($number, $currencyCode, array $options = []) + { + $this->validateOptions($options); + $options = array_replace($this->defaultOptions, $options); + $numberFormat = $this->getNumberFormat($options['locale']); + $currency = $this->getCurrency($currencyCode, $options['locale']); + $replacements = [ + // Strip the currency code or symbol. + $currency->getCurrencyCode() => '', + $currency->getSymbol() => '', + ]; + $number = strtr($number, $replacements); + $number = $this->parseNumber($number, $numberFormat); + + return $number; + } + + /** + * Gets the number format for the provided locale. + * + * @param string $locale The locale. + * + * @return NumberFormat + */ + protected function getNumberFormat($locale) + { + if (!isset($this->numberFormats[$locale])) { + $this->numberFormats[$locale] = $this->numberFormatRepository->get($locale); + } + + return $this->numberFormats[$locale]; + } + + /** + * Gets the currency for the provided currency code and locale. + * + * @param string $currencyCode The currency code. + * @param string $locale The locale. + * + * @return Currency + */ + protected function getCurrency($currencyCode, $locale) + { + if (!isset($this->currencies[$currencyCode][$locale])) { + try { + $currency = $this->currencyRepository->get($currencyCode, $locale); + } catch (UnknownCurrencyException $e) { + // The requested currency was not found. Fall back + // to a dummy object to show just the currency code. + $currency = new Currency([ + 'currency_code' => $currencyCode, + 'name' => $currencyCode, + 'numeric_code' => '000', + 'locale' => $locale, + ]); + } + $this->currencies[$currencyCode][$locale] = $currency; + } + + return $this->currencies[$currencyCode][$locale]; + } + + /** + * {@inheritdoc} + */ + protected function getAvailablePatterns(NumberFormat $numberFormat) + { + return [ + 'standard' => $numberFormat->getCurrencyPattern(), + 'accounting' => $numberFormat->getAccountingCurrencyPattern(), + ]; + } + + /** + * Validates the provided options. + * + * Ensures the absence of unknown keys, correct data types and values. + * + * @param array $options The options. + * + * @throws \InvalidArgumentException + */ + protected function validateOptions(array $options) + { + foreach ($options as $option => $value) { + if (!array_key_exists($option, $this->defaultOptions)) { + throw new InvalidArgumentException(sprintf('Unrecognized option "%s".', $option)); + } + } + if (isset($options['use_grouping']) && !is_bool($options['use_grouping'])) { + throw new InvalidArgumentException('The option "use_grouping" must be a boolean.'); + } + foreach (['minimum_fraction_digits', 'maximum_fraction_digits'] as $option) { + if (array_key_exists($option, $options) && !is_numeric($options[$option])) { + throw new InvalidArgumentException(sprintf('The option "%s" must be numeric.', $option)); + } + } + $roundingModes = [ + PHP_ROUND_HALF_UP, PHP_ROUND_HALF_DOWN, + PHP_ROUND_HALF_EVEN, PHP_ROUND_HALF_ODD, 'none', + ]; + if (!empty($options['rounding_mode']) && !in_array($options['rounding_mode'], $roundingModes)) { + throw new InvalidArgumentException(sprintf('Unrecognized rounding mode "%s".', $options['rounding_mode'])); + } + if (!empty($options['style']) && !in_array($options['style'], ['standard', 'accounting'])) { + throw new InvalidArgumentException(sprintf('Unrecognized style "%s".', $options['style'])); + } + if (!empty($options['currency_display']) && !in_array($options['currency_display'], ['code', 'symbol', 'none'])) { + throw new InvalidArgumentException(sprintf('Unrecognized currency display "%s".', $options['currency_display'])); + } + } +} diff --git a/vendor/commerceguys/intl/src/Formatter/CurrencyFormatterInterface.php b/vendor/commerceguys/intl/src/Formatter/CurrencyFormatterInterface.php new file mode 100644 index 000000000..3fc25fcc6 --- /dev/null +++ b/vendor/commerceguys/intl/src/Formatter/CurrencyFormatterInterface.php @@ -0,0 +1,54 @@ +<?php + +namespace CommerceGuys\Intl\Formatter; + +interface CurrencyFormatterInterface +{ + /** + * Formats a currency amount. + * + * Supported options: + * - locale: The locale. Default: 'en'. + * - use_grouping: Whether to use grouping separators, + * such as thousands separators. + * Default: true. + * - minimum_fraction_digits: Minimum fraction digits. + * - maximum_fraction_digits: Minimum fraction digits. + * - rounding_mode: The rounding mode. + * A PHP_ROUND_ constant or 'none' to skip + * rounding. Default: PHP_ROUND_HALF_UP. + * - style: The style. + * One of: 'standard', 'accounting'. + * Default: 'standard'. + * - currency_display: How the currency should be displayed. + * One of: 'code', 'symbol', 'none'. + * Default: 'symbol'. + * + * Both minimum_fraction_digits and maximum_fraction_digits default + * to the currency's number of fraction digits. + * + * @param string $number The number. + * @param string $currencyCode The currency code. + * @param array $options The formatting options. + * + * @return string The formatted number. + */ + public function format($number, $currencyCode, array $options = []); + + /** + * Parses a formatted currency amount. + * + * Commonly used in input widgets where the end-user might input + * a number using digits and symbols common to their locale. + * + * Supported options: + * - locale: The locale. Default: 'en'. + * + * @param string $number The formatted number. + * @param string $currencyCode The currency code. + * @param array $options The parsing options. + * + * @return string|false The parsed number or FALSE on error. + */ + public function parse($number, $currencyCode, array $options = []); +} diff --git a/vendor/commerceguys/intl/src/Formatter/FormatterTrait.php b/vendor/commerceguys/intl/src/Formatter/FormatterTrait.php new file mode 100644 index 000000000..aa63c1f5f --- /dev/null +++ b/vendor/commerceguys/intl/src/Formatter/FormatterTrait.php @@ -0,0 +1,215 @@ +<?php + +namespace CommerceGuys\Intl\Formatter; + +use CommerceGuys\Intl\Calculator; +use CommerceGuys\Intl\Exception\InvalidArgumentException; +use CommerceGuys\Intl\NumberFormat\NumberFormat; + +trait FormatterTrait +{ + /** + * The parsed number patterns, keyed by locale and style. + * + * @var ParsedPattern[] + */ + protected $parsedPatterns = []; + + /** + * Localized digits. + * + * @var array + */ + protected $digits = [ + NumberFormat::NUMBERING_SYSTEM_ARABIC => [ + 0 => '٠', 1 => '١', 2 => '٢', 3 => '٣', 4 => '٤', + 5 => '٥', 6 => '٦', 7 => '٧', 8 => '٨', 9 => '٩', + ], + NumberFormat::NUMBERING_SYSTEM_ARABIC_EXTENDED => [ + 0 => '۰', 1 => '۱', 2 => '۲', 3 => '۳', 4 => '۴', + 5 => '۵', 6 => '۶', 7 => '۷', 8 => '۸', 9 => '۹', + ], + NumberFormat::NUMBERING_SYSTEM_BENGALI => [ + 0 => '০', 1 => '১', 2 => '২', 3 => '৩', 4 => '৪', + 5 => '৫', 6 => '৬', 7 => '৭', 8 => '৮', 9 => '৯', + ], + NumberFormat::NUMBERING_SYSTEM_DEVANAGARI => [ + 0 => '०', 1 => '१', 2 => '२', 3 => '३', 4 => '४', + 5 => '५', 6 => '६', 7 => '७', 8 => '८', 9 => '९', + ], + ]; + + /** + * Formats the number according to the number format. + * + * @param string $number The number. + * @param NumberFormat $numberFormat The number format. + * + * @return string The formatted number. + */ + protected function formatNumber($number, NumberFormat $numberFormat, array $options = []) + { + $parsedPattern = $this->getParsedPattern($numberFormat, $options['style']); + // Start by rounding the number, if rounding is enabled. + if (is_int($options['rounding_mode'])) { + $number = Calculator::round($number, $options['maximum_fraction_digits'], $options['rounding_mode']); + } + $negative = (Calculator::compare('0', $number, 12) == 1); + // Ensure that the value is positive and has the right number of digits. + $signMultiplier = $negative ? '-1' : '1'; + $number = bcdiv($number, $signMultiplier, $options['maximum_fraction_digits']); + // Split the number into major and minor digits. + $numberParts = explode('.', $number); + $majorDigits = $numberParts[0]; + // Account for maximumFractionDigits = 0, where the number won't + // have a decimal point, and $numberParts[1] won't be set. + $minorDigits = isset($numberParts[1]) ? $numberParts[1] : ''; + + if ($options['use_grouping'] && $parsedPattern->isGroupingUsed()) { + // Reverse the major digits, since they are grouped from the right. + $majorDigits = array_reverse(str_split($majorDigits)); + // Group the major digits. + $groups = []; + $groups[] = array_splice($majorDigits, 0, $parsedPattern->getPrimaryGroupSize()); + while (!empty($majorDigits)) { + $groups[] = array_splice($majorDigits, 0, $parsedPattern->getSecondaryGroupSize()); + } + // Reverse the groups and the digits inside of them. + $groups = array_reverse($groups); + foreach ($groups as &$group) { + $group = implode(array_reverse($group)); + } + // Reconstruct the major digits. + $majorDigits = implode(',', $groups); + } + + if ($options['minimum_fraction_digits'] < $options['maximum_fraction_digits']) { + // Strip any trailing zeroes. + $minorDigits = rtrim($minorDigits, '0'); + if (strlen($minorDigits) < $options['minimum_fraction_digits']) { + // Now there are too few digits, re-add trailing zeroes + // until the desired length is reached. + $neededZeroes = $options['minimum_fraction_digits'] - strlen($minorDigits); + $minorDigits .= str_repeat('0', $neededZeroes); + } + } + + // Assemble the final number and insert it into the pattern. + $number = strlen($minorDigits) ? $majorDigits . '.' . $minorDigits : $majorDigits; + $pattern = $negative ? $parsedPattern->getNegativePattern() : $parsedPattern->getPositivePattern(); + $number = preg_replace('/#(?:[\.,]#+)*0(?:[,\.][0#]+)*/', $number, $pattern); + $number = $this->localizeNumber($number, $numberFormat); + + return $number; + } + + /** + * Localizes the number according to the number format. + * + * Both the digits and the symbols are replaced + * with their localized equivalents. + * + * @param string $number The number. + * @param NumberFormat $numberFormat The number format. + * + * @return string The localized number. + * + * @see http://cldr.unicode.org/translation/number-symbols + */ + protected function localizeNumber($number, NumberFormat $numberFormat) + { + // Localize digits. + $numberingSystem = $numberFormat->getNumberingSystem(); + if (isset($this->digits[$numberingSystem])) { + $number = strtr($number, $this->digits[$numberingSystem]); + } + // Localize symbols. + $replacements = [ + '.' => $numberFormat->getDecimalSeparator(), + ',' => $numberFormat->getGroupingSeparator(), + '+' => $numberFormat->getPlusSign(), + '-' => $numberFormat->getMinusSign(), + '%' => $numberFormat->getPercentSign(), + ]; + $number = strtr($number, $replacements); + + return $number; + } + + /** + * Parses the number according to the number format. + * + * Both the digits and the symbols are replaced + * with their non-localized equivalents. + * + * @param string $number The number. + * @param NumberFormat $numberFormat The number format. + * + * @return string The localized number. + */ + protected function parseNumber($number, NumberFormat $numberFormat) + { + $replacements = [ + $numberFormat->getGroupingSeparator() => '', + // Convert the localized symbols back to their original form. + $numberFormat->getDecimalSeparator() => '.', + $numberFormat->getPlusSign() => '+', + $numberFormat->getMinusSign() => '-', + $numberFormat->getPercentSign() => '%', + + // Strip whitespace (spaces and non-breaking spaces). + ' ' => '', + chr(0xC2) . chr(0xA0) => '', + ]; + $numberingSystem = $numberFormat->getNumberingSystem(); + if (isset($this->digits[$numberingSystem])) { + // Convert the localized digits back to latin. + $replacements += array_flip($this->digits[$numberingSystem]); + } + $number = strtr($number, $replacements); + + // Convert the accounting format for negative numbers. + if (substr($number, 0, 1) == '(' && substr($number, -1, 1) == ')') { + $number = '-' . str_replace(['(', ')'], '', $number); + } + // Convert percentages back to their decimal form. + if (strpos($number, '%') !== false) { + $number = str_replace('%', '', $number); + $number = Calculator::divide($number, '100'); + } + + return is_numeric($number) ? $number : false; + } + + /** + * Gets the pattern for the provided number format. + * + * @param NumberFormat $numberFormat The number format. + * @param string $style The formatter style. + * + * @return ParsedPattern + */ + protected function getParsedPattern(NumberFormat $numberFormat, $style) + { + $locale = $numberFormat->getLocale(); + if (!isset($this->parsedPatterns[$locale][$style])) { + $availablePatterns = $this->getAvailablePatterns($numberFormat); + if (!isset($availablePatterns[$style])) { + throw new InvalidArgumentException(sprintf('Unrecognized style "%s".', $style)); + } + + $this->parsedPatterns[$locale][$style] = new ParsedPattern($availablePatterns[$style]); + } + + return $this->parsedPatterns[$locale][$style]; + } + + /** + * Gets the available patterns for the provided number format. + * + * @param NumberFormat $numberFormat The number format. + * + * @return string[] The patterns, keyed by style. + */ + abstract protected function getAvailablePatterns(NumberFormat $numberFormat); +} diff --git a/vendor/commerceguys/intl/src/Formatter/NumberFormatter.php b/vendor/commerceguys/intl/src/Formatter/NumberFormatter.php index 9c8979043..95c9a0020 100644 --- a/vendor/commerceguys/intl/src/Formatter/NumberFormatter.php +++ b/vendor/commerceguys/intl/src/Formatter/NumberFormatter.php @@ -2,420 +2,162 @@ namespace CommerceGuys\Intl\Formatter; -use CommerceGuys\Intl\Currency\CurrencyInterface; +use CommerceGuys\Intl\Calculator; use CommerceGuys\Intl\Exception\InvalidArgumentException; -use CommerceGuys\Intl\NumberFormat\NumberFormatInterface; +use CommerceGuys\Intl\NumberFormat\NumberFormat; +use CommerceGuys\Intl\NumberFormat\NumberFormatRepositoryInterface; /** * Formats numbers using locale-specific patterns. */ class NumberFormatter implements NumberFormatterInterface { - /** - * The number format. - * - * @var NumberFormatInterface - */ - protected $numberFormat; - - /** - * The number pattern used to format positive numbers. - * - * @var string - */ - protected $positivePattern; - - /** - * The number pattern used to format negative numbers. - * - * @var string - */ - protected $negativePattern; + use FormatterTrait; /** - * Whether grouping is used. + * The number format repository. * - * @var bool + * @var NumberFormatRepositoryInterface */ - protected $groupingUsed; + protected $numberFormatRepository; /** - * The size of the group of digits closest to the decimal point. + * The default options. * - * @var int - */ - protected $primaryGroupSize; - - /** - * The size of every group of digits after the primary group. - * - * @var int - */ - protected $secondaryGroupSize; - - /** - * The minimum number of fraction digits to show. - * - * @var int - */ - protected $minimumFractionDigits; - - /** - * The maximum number of fraction digits to show. - * - * @var int - */ - protected $maximumFractionDigits; - - /** - * The currency display style. - * - * @var int + * @var array */ - protected $currencyDisplay; + protected $defaultOptions = [ + 'locale' => 'en', + 'use_grouping' => true, + 'minimum_fraction_digits' => 0, + 'maximum_fraction_digits' => 3, + 'rounding_mode' => PHP_ROUND_HALF_UP, + 'style' => 'decimal', + ]; /** - * Localized digits. + * The loaded number formats. * - * @var array + * @var NumberFormat[] */ - protected $digits = [ - NumberFormatInterface::NUMBERING_SYSTEM_ARABIC => [ - 0 => '٠', 1 => '١', 2 => '٢', 3 => '٣', 4 => '٤', - 5 => '٥', 6 => '٦', 7 => '٧', 8 => '٨', 9 => '٩', - ], - NumberFormatInterface::NUMBERING_SYSTEM_ARABIC_EXTENDED => [ - 0 => '۰', 1 => '۱', 2 => '۲', 3 => '۳', 4 => '۴', - 5 => '۵', 6 => '۶', 7 => '۷', 8 => '۸', 9 => '۹', - ], - NumberFormatInterface::NUMBERING_SYSTEM_BENGALI => [ - 0 => '০', 1 => '১', 2 => '২', 3 => '৩', 4 => '৪', - 5 => '৫', 6 => '৬', 7 => '৭', 8 => '৮', 9 => '৯', - ], - NumberFormatInterface::NUMBERING_SYSTEM_DEVANAGARI => [ - 0 => '०', 1 => '१', 2 => '२', 3 => '३', 4 => '४', - 5 => '५', 6 => '६', 7 => '७', 8 => '८', 9 => '९', - ], - ]; + protected $numberFormats = []; /** * Creates a NumberFormatter instance. * - * @param NumberFormatInterface $numberFormat The number format. - * @param int $style The formatting style. + * @param NumberFormatRepositoryInterface $numberFormatRepository The number format repository. + * @param array $defaultOptions The default options. * * @throws \InvalidArgumentException * @throws \RuntimeException */ - public function __construct(NumberFormatInterface $numberFormat, $style = self::DECIMAL) + public function __construct(NumberFormatRepositoryInterface $numberFormatRepository, array $defaultOptions = []) { if (!extension_loaded('bcmath')) { throw new \RuntimeException('The bcmath extension is required by NumberFormatter.'); } - $availablePatterns = [ - self::DECIMAL => $numberFormat->getDecimalPattern(), - self::PERCENT => $numberFormat->getPercentPattern(), - self::CURRENCY => $numberFormat->getCurrencyPattern(), - self::CURRENCY_ACCOUNTING => $numberFormat->getAccountingCurrencyPattern(), - ]; - if (!array_key_exists($style, $availablePatterns)) { - // Unknown type. - throw new InvalidArgumentException('Unknown format style provided to NumberFormatter::__construct().'); - } - - // Split the selected pattern into positive and negative patterns. - $patterns = explode(';', $availablePatterns[$style]); - if (!isset($patterns[1])) { - // No explicit negative pattern was provided, construct it. - $patterns[1] = '-' . $patterns[0]; - } + $this->validateOptions($defaultOptions); - $this->numberFormat = $numberFormat; - $this->positivePattern = $patterns[0]; - $this->negativePattern = $patterns[1]; - $this->groupingUsed = (strpos($this->positivePattern, ',') !== false); - // This pattern has number groups, parse them. - if ($this->groupingUsed) { - preg_match('/#+0/', $this->positivePattern, $primaryGroupMatches); - $this->primaryGroupSize = $this->secondaryGroupSize = strlen($primaryGroupMatches[0]); - $numberGroups = explode(',', $this->positivePattern); - if (count($numberGroups) > 2) { - // This pattern has a distinct secondary group size. - $this->secondaryGroupSize = strlen($numberGroups[1]); - } - } - - // Initialize the fraction digit settings for decimal and percent - // styles only. The currency ones will default to the currency values. - if (in_array($style, [self::DECIMAL, self::PERCENT])) { - $this->minimumFractionDigits = 0; - $this->maximumFractionDigits = 3; - } - $this->currencyDisplay = self::CURRENCY_DISPLAY_SYMBOL; + $this->numberFormatRepository = $numberFormatRepository; + $this->defaultOptions = array_replace($this->defaultOptions, $defaultOptions); } /** * {@inheritdoc} */ - public function format($value) + public function format($number, array $options = []) { - if (!is_numeric($value)) { - $message = sprintf('The provided value "%s" must be a valid number or numeric string.', $value); + if (!is_numeric($number)) { + $message = sprintf('The provided value "%s" is not a valid number or numeric string.', $number); throw new InvalidArgumentException($message); } + $this->validateOptions($options); + $options = array_replace($this->defaultOptions, $options); - // Ensure that the value is positive and has the right number of digits. - $negative = (bccomp('0', $value, 12) == 1); - $signMultiplier = $negative ? '-1' : '1'; - $value = bcdiv($value, $signMultiplier, $this->maximumFractionDigits); - // Split the number into major and minor digits. - $valueParts = explode('.', $value); - $majorDigits = $valueParts[0]; - // Account for maximumFractionDigits = 0, where the number won't - // have a decimal point, and $valueParts[1] won't be set. - $minorDigits = isset($valueParts[1]) ? $valueParts[1] : ''; - - if ($this->groupingUsed) { - // Reverse the major digits, since they are grouped from the right. - $majorDigits = array_reverse(str_split($majorDigits)); - // Group the major digits. - $groups = []; - $groups[] = array_splice($majorDigits, 0, $this->primaryGroupSize); - while (!empty($majorDigits)) { - $groups[] = array_splice($majorDigits, 0, $this->secondaryGroupSize); - } - // Reverse the groups and the digits inside of them. - $groups = array_reverse($groups); - foreach ($groups as &$group) { - $group = implode(array_reverse($group)); - } - // Reconstruct the major digits. - $majorDigits = implode(',', $groups); - } - - if ($this->minimumFractionDigits < $this->maximumFractionDigits) { - // Strip any trailing zeroes. - $minorDigits = rtrim($minorDigits, '0'); - if (strlen($minorDigits) < $this->minimumFractionDigits) { - // Now there are too few digits, re-add trailing zeroes - // until the desired length is reached. - $neededZeroes = $this->minimumFractionDigits - strlen($minorDigits); - $minorDigits .= str_repeat('0', $neededZeroes); - } + $number = (string) $number; + // Percentages are passed as decimals (e.g. 0.2 for 20%). + if ($options['style'] == 'percent') { + $number = Calculator::multiply($number, '100'); } + $numberFormat = $this->getNumberFormat($options['locale']); + $number = $this->formatNumber($number, $numberFormat, $options); - // Assemble the final number and insert it into the pattern. - $value = strlen($minorDigits) ? $majorDigits . '.' . $minorDigits : $majorDigits; - $pattern = $negative ? $this->negativePattern : $this->positivePattern; - $value = preg_replace('/#(?:[\.,]#+)*0(?:[,\.][0#]+)*/', $value, $pattern); - - // Localize the number. - $value = $this->replaceDigits($value); - $value = $this->replaceSymbols($value); - - return $value; + return $number; } /** * {@inheritdoc} */ - public function formatCurrency($value, CurrencyInterface $currency) + public function parse($number, array $options = []) { - // Use the currency defaults if the values weren't set by the caller. - $resetMinimumFractionDigits = $resetMaximumFractionDigits = false; - if (!isset($this->minimumFractionDigits)) { - $this->minimumFractionDigits = $currency->getFractionDigits(); - $resetMinimumFractionDigits = true; - } - if (!isset($this->maximumFractionDigits)) { - $this->maximumFractionDigits = $currency->getFractionDigits(); - $resetMaximumFractionDigits = true; - } - - // Format the decimal part of the value first. - $value = $this->format($value); - - // Reset the fraction digit settings, so that they don't affect - // future formattings with different currencies. - if ($resetMinimumFractionDigits) { - $this->minimumFractionDigits = null; - } - if ($resetMaximumFractionDigits) { - $this->maximumFractionDigits = null; - } + $this->validateOptions($options); + $options = array_replace($this->defaultOptions, $options); + $numberFormat = $this->getNumberFormat($options['locale']); + $number = $this->parseNumber($number, $numberFormat); - // Determine whether to show the currency symbol or the currency code. - if ($this->currencyDisplay == self::CURRENCY_DISPLAY_SYMBOL) { - $symbol = $currency->getSymbol(); - } else { - $symbol = $currency->getCurrencyCode(); - } - - return str_replace('¤', $symbol, $value); + return $number; } /** - * {@inheritdoc} + * Gets the number format for the provided locale. + * + * @param string $locale The locale. + * + * @return NumberFormat */ - public function parse($value) + protected function getNumberFormat($locale) { - $replacements = [ - $this->numberFormat->getGroupingSeparator() => '', - // Convert the localized symbols back to their original form. - $this->numberFormat->getDecimalSeparator() => '.', - $this->numberFormat->getPlusSign() => '+', - $this->numberFormat->getMinusSign() => '-', - - // Strip whitespace (spaces and non-breaking spaces). - ' ' => '', - chr(0xC2) . chr(0xA0) => '', - ]; - $numberingSystem = $this->numberFormat->getNumberingSystem(); - if (isset($this->digits[$numberingSystem])) { - // Convert the localized digits back to latin. - $replacements += array_flip($this->digits[$numberingSystem]); - } - - $value = strtr($value, $replacements); - if (substr($value, 0, 1) == '(' && substr($value, -1, 1) == ')') { - // This is an accounting formatted negative number. - $value = '-' . str_replace(['(', ')'], '', $value); + if (!isset($this->numberFormats[$locale])) { + $this->numberFormats[$locale] = $this->numberFormatRepository->get($locale); } - return is_numeric($value) ? $value : false; + return $this->numberFormats[$locale]; } /** * {@inheritdoc} */ - public function parseCurrency($value, CurrencyInterface $currency) + protected function getAvailablePatterns(NumberFormat $numberFormat) { - $replacements = [ - // Strip the currency code or symbol. - $currency->getCurrencyCode() => '', - $currency->getSymbol() => '', + return [ + 'decimal' => $numberFormat->getDecimalPattern(), + 'percent' => $numberFormat->getPercentPattern(), ]; - $value = strtr($value, $replacements); - - return $this->parse($value); } /** - * Replaces digits with their localized equivalents. + * Validates the provided options. * - * @param string $value The value being formatted. + * Ensures the absence of unknown keys, correct data types and values. * - * @return string - */ - protected function replaceDigits($value) - { - $numberingSystem = $this->numberFormat->getNumberingSystem(); - if (isset($this->digits[$numberingSystem])) { - $value = strtr($value, $this->digits[$numberingSystem]); - } - - return $value; - } - - /** - * Replaces number symbols with their localized equivalents. + * @param array $options The options. * - * @param string $value The value being formatted. - * - * @return string - * - * @see http://cldr.unicode.org/translation/number-symbols + * @throws \InvalidArgumentException */ - protected function replaceSymbols($value) + protected function validateOptions(array $options) { - $replacements = [ - '.' => $this->numberFormat->getDecimalSeparator(), - ',' => $this->numberFormat->getGroupingSeparator(), - '+' => $this->numberFormat->getPlusSign(), - '-' => $this->numberFormat->getMinusSign(), - '%' => $this->numberFormat->getPercentSign(), + foreach ($options as $option => $value) { + if (!array_key_exists($option, $this->defaultOptions)) { + throw new InvalidArgumentException(sprintf('Unrecognized option "%s".', $option)); + } + } + if (isset($options['use_grouping']) && !is_bool($options['use_grouping'])) { + throw new InvalidArgumentException('The option "use_grouping" must be a boolean.'); + } + foreach (['minimum_fraction_digits', 'maximum_fraction_digits'] as $option) { + if (array_key_exists($option, $options) && !is_numeric($options[$option])) { + throw new InvalidArgumentException(sprintf('The option "%s" must be numeric.', $option)); + } + } + $roundingModes = [ + PHP_ROUND_HALF_UP, PHP_ROUND_HALF_DOWN, + PHP_ROUND_HALF_EVEN, PHP_ROUND_HALF_ODD, 'none', ]; - - return strtr($value, $replacements); - } - - /** - * {@inheritdoc} - */ - public function getNumberFormat() - { - return $this->numberFormat; - } - - /** - * {@inheritdoc} - */ - public function getMinimumFractionDigits() - { - return $this->minimumFractionDigits; - } - - /** - * {@inheritdoc} - */ - public function setMinimumFractionDigits($minimumFractionDigits) - { - $this->minimumFractionDigits = $minimumFractionDigits; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getMaximumFractionDigits() - { - return $this->maximumFractionDigits; - } - - /** - * {@inheritdoc} - */ - public function setMaximumFractionDigits($maximumFractionDigits) - { - $this->maximumFractionDigits = $maximumFractionDigits; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function isGroupingUsed() - { - return $this->groupingUsed; - } - - /** - * {@inheritdoc} - */ - public function setGroupingUsed($groupingUsed) - { - $this->groupingUsed = $groupingUsed; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getCurrencyDisplay() - { - return $this->currencyDisplay; - } - - /** - * {@inheritdoc} - */ - public function setCurrencyDisplay($currencyDisplay) - { - $this->currencyDisplay = $currencyDisplay; - - return $this; + if (!empty($options['rounding_mode']) && !in_array($options['rounding_mode'], $roundingModes)) { + throw new InvalidArgumentException(sprintf('Unrecognized rounding mode "%s".', $options['rounding_mode'])); + } + if (!empty($options['style']) && !in_array($options['style'], ['decimal', 'percent'])) { + throw new InvalidArgumentException(sprintf('Unrecognized style "%s".', $options['style'])); + } } } diff --git a/vendor/commerceguys/intl/src/Formatter/NumberFormatterInterface.php b/vendor/commerceguys/intl/src/Formatter/NumberFormatterInterface.php index 3a510be2a..ce6207f52 100644 --- a/vendor/commerceguys/intl/src/Formatter/NumberFormatterInterface.php +++ b/vendor/commerceguys/intl/src/Formatter/NumberFormatterInterface.php @@ -2,150 +2,48 @@ namespace CommerceGuys\Intl\Formatter; -use CommerceGuys\Intl\Currency\CurrencyInterface; -use CommerceGuys\Intl\NumberFormat\NumberFormatInterface; +use CommerceGuys\Intl\Currency\Currency; +use CommerceGuys\Intl\NumberFormat\NumberFormat; interface NumberFormatterInterface { - /* Format style constants */ - const DECIMAL = 1; - const PERCENT = 2; - const CURRENCY = 3; - const CURRENCY_ACCOUNTING = 4; - - /* Currency display style constants */ - const CURRENCY_DISPLAY_SYMBOL = 1; - const CURRENCY_DISPLAY_CODE = 2; - /** * Formats a number. * - * Please note that the provided value should already be rounded. - * This formatter doesn't do any rounding of its own, and will simply - * truncate extra digits. - * - * @param string $value The value to format. - * - * @return string - */ - public function format($value); - - /** - * Formats a currency value. - * - * Please note that the provided value should already be rounded. - * This formatter doesn't do any rounding of its own, and will simply - * truncate extra digits. + * Supported options: + * - locale: The locale. Default: 'en'. + * - use_grouping: Whether to use grouping separators, + * such as thousands separators. + * Default: true. + * - minimum_fraction_digits: Minimum fraction digits. Default: 0. + * - maximum_fraction_digits: Minimum fraction digits. Default: 3. + * - rounding_mode: The rounding mode. + * A PHP_ROUND_ constant or 'none' to skip + * rounding. Default: PHP_ROUND_HALF_UP. + * - style: The style. + * One of: 'decimal', 'percent'. + * Default: 'decimal'. * - * @param string $value The value to format. - * @param CurrencyInterface $currency The currency. + * @param string $number The number. + * @param array $options The formatting options. * - * @return string + * @return string The formatted number. */ - public function formatCurrency($value, CurrencyInterface $currency); + public function format($number, array $options = []); /** * Parses a number. * * Commonly used in input widgets where the end-user might input - * a value using digits and symbols common to their locale. - * - * @param string $value The value to parse. - * - * @return string|false The parsed numeric value or FALSE on error. - */ - public function parse($value); - - /** - * Parses a formatted currency value. - * - * @param string $value The value to parse. - * @param CurrencyInterface $currency The currency. - * - * @return string|false The parsed numeric value or FALSE on error. - */ - public function parseCurrency($value, CurrencyInterface $currency); - - /** - * Gets the number format. - * - * @return NumberFormatInterface - */ - public function getNumberFormat(); - - /** - * Gets the minimum number of fraction digits. - * - * Defaults to 0 for decimal and percentage styles. - * Defaults to null for currency styles, since the currency number of - * fraction digits is used as the default in that case. - * - * @return int - */ - public function getMinimumFractionDigits(); - - /** - * Sets the minimum number of fraction digits. - * - * @param int $minimumFractionDigits + * a number using digits and symbols common to their locale. * - * @return self - */ - public function setMinimumFractionDigits($minimumFractionDigits); - - /** - * Gets the maximum number of fraction digits. - * - * Defaults to 3 for decimal and percentage styles. - * Defaults to null for currency styles, since the currency number of - * fraction digits is used as the default in that case. - * - * @return int - */ - public function getMaximumFractionDigits(); - - /** - * Sets the maximum number of fraction digits. - * - * @param int $maximumFractionDigits - * - * @return self - */ - public function setMaximumFractionDigits($maximumFractionDigits); - - /** - * Returns whether the major digits will be grouped. - * - * @return bool - */ - public function isGroupingUsed(); - - /** - * Sets whether or not major digits should be grouped. - * - * @param bool $groupingUsed - * - * @return self - */ - public function setGroupingUsed($groupingUsed); - - /** - * Gets the currency display style. - * - * Controls whether a currency amount will be shown with the - * currency symbol (CURRENCY_DISPLAY_SYMBOL) or the - * currency code (CURRENCY_DISPLAY_CODE). - * - * @return int - */ - public function getCurrencyDisplay(); - - /** - * Sets the currency display style. + * Supported options: + * - locale: The locale. Default: 'en'. * - * @param int $currencyDisplay One of the CURRENCY_DISPLAY_ constants. + * @param string $number The formatted number. + * @param array $options The parsing options. * - * @return self + * @return string|false The parsed number or FALSE on error. */ - public function setCurrencyDisplay($currencyDisplay); + public function parse($number, array $options = []); } diff --git a/vendor/commerceguys/intl/src/Formatter/ParsedPattern.php b/vendor/commerceguys/intl/src/Formatter/ParsedPattern.php new file mode 100644 index 000000000..aa6e5f43e --- /dev/null +++ b/vendor/commerceguys/intl/src/Formatter/ParsedPattern.php @@ -0,0 +1,129 @@ +<?php + +namespace CommerceGuys\Intl\Formatter; + +/** + * Represents a parsed number pattern. + */ +final class ParsedPattern +{ + /** + * The positive number pattern. + * + * @var string + */ + protected $positivePattern; + + /** + * The negative number pattern. + * + * @var string + */ + protected $negativePattern; + + /** + * Whether grouping is used. + * + * @var bool + */ + protected $groupingUsed; + + /** + * The primary group size. + * + * @var int + */ + protected $primaryGroupSize; + + /** + * The secondary group size. + * + * @var int + */ + protected $secondaryGroupSize; + + /** + * Creates a new ParsedPattern instance. + * + * @param string $pattern The raw pattern. + */ + public function __construct($pattern) + { + // Split the pattern into positive and negative patterns. + $patternList = explode(';', $pattern); + if (!isset($patternList[1])) { + // No explicit negative pattern was provided, construct it. + $patternList[1] = '-' . $patternList[0]; + } + + $this->positivePattern = $patternList[0]; + $this->negativePattern = $patternList[1]; + $this->groupingUsed = (strpos($patternList[0], ',') !== false); + if ($this->groupingUsed) { + preg_match('/#+0/', $patternList[0], $primaryGroupMatches); + $this->primaryGroupSize = $this->secondaryGroupSize = strlen($primaryGroupMatches[0]); + $numberGroups = explode(',', $patternList[0]); + if (count($numberGroups) > 2) { + // This pattern has a distinct secondary group size. + $this->secondaryGroupSize = strlen($numberGroups[1]); + } + } + } + + /** + * Gets the positive number pattern. + * + * Used to format positive numbers. + * + * @return string + */ + public function getPositivePattern() + { + return $this->positivePattern; + } + + /** + * Gets the negative number pattern. + * + * Used to format negative numbers. + * + * @return string + */ + public function getNegativePattern() + { + return $this->negativePattern; + } + + /** + * Gets whether grouping is used. + * + * Indicates that major digits should be grouped according to + * group sizes, right-to-left. + * + * @return bool + */ + public function isGroupingUsed() + { + return $this->groupingUsed; + } + + /** + * Gets the primary group size. + * + * @return int|null + */ + public function getPrimaryGroupSize() + { + return $this->primaryGroupSize; + } + + /** + * Gets the secondary group size. + * + * @return int|null + */ + public function getSecondaryGroupSize() + { + return $this->secondaryGroupSize; + } +} diff --git a/vendor/commerceguys/intl/src/Language/Language.php b/vendor/commerceguys/intl/src/Language/Language.php index 9958d5481..d8196f26c 100644 --- a/vendor/commerceguys/intl/src/Language/Language.php +++ b/vendor/commerceguys/intl/src/Language/Language.php @@ -2,7 +2,10 @@ namespace CommerceGuys\Intl\Language; -class Language implements LanguageEntityInterface +/** + * Represents a language. + */ +final class Language { /** * The two-letter language code. @@ -19,42 +22,56 @@ class Language implements LanguageEntityInterface protected $name; /** - * The language locale (i.e. "en-US"). + * The locale (i.e. "en-US"). * * @var string */ protected $locale; /** - * Returns the string representation of the Language. + * Creates a new Language instance. * - * @return string + * @param array $definition The definition array. */ - public function __toString() + public function __construct(array $definition) { - return $this->getLanguageCode(); + foreach (['language_code', 'name', 'locale'] as $requiredProperty) { + if (empty($definition[$requiredProperty])) { + throw new \InvalidArgumentException(sprintf('Missing required property "%s".', $requiredProperty)); + } + } + + $this->languageCode = $definition['language_code']; + $this->name = $definition['name']; + $this->locale = $definition['locale']; } /** - * {@inheritdoc} + * Returns the string representation of the Language. + * + * @return string */ - public function getLanguageCode() + public function __toString() { return $this->languageCode; } /** - * {@inheritdoc} + * Gets the two-letter language code. + * + * @return string */ - public function setLanguageCode($languageCode) + public function getLanguageCode() { - $this->languageCode = $languageCode; - - return $this; + return $this->languageCode; } /** - * {@inheritdoc} + * Gets the language name. + * + * This value is locale specific. + * + * @return string */ public function getName() { @@ -62,30 +79,14 @@ class Language implements LanguageEntityInterface } /** - * {@inheritdoc} - */ - public function setName($name) - { - $this->name = $name; - - return $this; - } - - /** - * {@inheritdoc} + * Gets the locale. + * + * The language name is locale specific. + * + * @return string */ public function getLocale() { return $this->locale; } - - /** - * {@inheritdoc} - */ - public function setLocale($locale) - { - $this->locale = $locale; - - return $this; - } } diff --git a/vendor/commerceguys/intl/src/Language/LanguageEntityInterface.php b/vendor/commerceguys/intl/src/Language/LanguageEntityInterface.php deleted file mode 100644 index e36e0bf77..000000000 --- a/vendor/commerceguys/intl/src/Language/LanguageEntityInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Language; - -interface LanguageEntityInterface extends LanguageInterface -{ - /** - * Sets the two-letter language code. - * - * @param string $languageCode The two-letter language code. - * - * @return self - */ - public function setLanguageCode($languageCode); - - /** - * Sets the language name. - * - * @param string $name The language name. - * - * @return self - */ - public function setName($name); -} diff --git a/vendor/commerceguys/intl/src/Language/LanguageInterface.php b/vendor/commerceguys/intl/src/Language/LanguageInterface.php deleted file mode 100644 index 14c603dfd..000000000 --- a/vendor/commerceguys/intl/src/Language/LanguageInterface.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\Language; - -interface LanguageInterface -{ - /** - * Gets the two-letter language code. - * - * @return string - */ - public function getLanguageCode(); - - /** - * Gets the language name. - * - * Note that certain locales have incomplete translations, in which - * case the english version of the language name is used instead. - * - * @return string - */ - public function getName(); -} diff --git a/vendor/commerceguys/intl/src/Language/LanguageRepository.php b/vendor/commerceguys/intl/src/Language/LanguageRepository.php index 4fc02f2ff..151619e1d 100644 --- a/vendor/commerceguys/intl/src/Language/LanguageRepository.php +++ b/vendor/commerceguys/intl/src/Language/LanguageRepository.php @@ -2,7 +2,7 @@ namespace CommerceGuys\Intl\Language; -use CommerceGuys\Intl\LocaleResolverTrait; +use CommerceGuys\Intl\Locale; use CommerceGuys\Intl\Exception\UnknownLanguageException; /** @@ -10,7 +10,26 @@ use CommerceGuys\Intl\Exception\UnknownLanguageException; */ class LanguageRepository implements LanguageRepositoryInterface { - use LocaleResolverTrait; + /** + * The default locale. + * + * @var string + */ + protected $defaultLocale; + + /** + * The fallback locale. + * + * @var string + */ + protected $fallbackLocale; + + /** + * The path where per-locale definitions are stored. + * + * @var string + */ + protected $definitionPath; /** * Per-locale language definitions. @@ -20,40 +39,90 @@ class LanguageRepository implements LanguageRepositoryInterface protected $definitions = []; /** + * The available locales. + * + * @var array + */ + protected $availableLocales = [ + 'af', 'agq', 'ak', 'am', 'ar', 'ar-EG', 'ar-LY', 'ar-SA', 'as', 'asa', + 'ast', 'az', 'az-Cyrl', 'bas', 'be', 'bem', 'bez', 'bg', 'bm', 'bn', + 'bn-IN', 'br', 'brx', 'bs', 'bs-Cyrl', 'ca', 'ccp', 'ce', 'cgg', 'chr', + 'ckb', 'cs', 'cy', 'da', 'dav', 'de', 'de-AT', 'de-CH', 'de-LU', 'dje', + 'dsb', 'dyo', 'dz', 'ebu', 'ee', 'el', 'en', 'en-001', 'en-AU', 'en-CA', + 'en-IN', 'en-NZ', 'eo', 'es', 'es-419', 'es-AR', 'es-BO', 'es-CL', + 'es-CO', 'es-CR', 'es-DO', 'es-EC', 'es-GT', 'es-HN', 'es-MX', 'es-NI', + 'es-PA', 'es-PE', 'es-PR', 'es-PY', 'es-SV', 'es-US', 'es-VE', 'et', + 'eu', 'ewo', 'fa', 'fa-AF', 'ff', 'fi', 'fil', 'fo', 'fr', 'fr-BE', + 'fr-CA', 'fr-CH', 'fur', 'fy', 'ga', 'gd', 'gl', 'gsw', 'gu', 'guz', + 'ha', 'ha-NE', 'he', 'hi', 'hr', 'hsb', 'hu', 'hy', 'id', 'ig', 'is', + 'it', 'ja', 'jmc', 'jv', 'ka', 'kab', 'kam', 'kde', 'kea', 'khq', 'ki', + 'kk', 'kln', 'km', 'kn', 'ko', 'kok', 'ks', 'ksb', 'ksf', 'ksh', 'ku', + 'ky', 'lag', 'lb', 'lg', 'lkt', 'ln', 'lo', 'lrc', 'lt', 'lu', 'luo', + 'luy', 'lv', 'mas', 'mer', 'mfe', 'mg', 'mgh', 'mk', 'ml', 'mn', 'mr', + 'ms', 'mt', 'mua', 'my', 'mzn', 'naq', 'nb', 'nd', 'ne', 'nl', 'nmg', + 'nn', 'nus', 'nyn', 'om', 'or', 'os', 'pa', 'pl', 'ps', 'ps-PK', 'pt', + 'pt-PT', 'qu', 'rm', 'rn', 'ro', 'ro-MD', 'rof', 'ru', 'rw', 'rwk', + 'sah', 'saq', 'sbp', 'sd', 'se', 'se-FI', 'seh', 'ses', 'sg', 'shi', + 'shi-Latn', 'si', 'sk', 'sl', 'smn', 'sn', 'so', 'sq', 'sr', + 'sr-Cyrl-BA', 'sr-Cyrl-ME', 'sr-Cyrl-XK', 'sr-Latn', 'sr-Latn-BA', + 'sr-Latn-ME', 'sr-Latn-XK', 'sv', 'sw', 'sw-CD', 'sw-KE', 'ta', 'te', + 'teo', 'tg', 'th', 'ti', 'tk', 'to', 'tr', 'tt', 'twq', 'tzm', 'ug', + 'uk', 'ur', 'ur-IN', 'uz', 'uz-Cyrl', 'vai', 'vai-Latn', 'vi', 'vun', + 'wae', 'wo', 'xog', 'yav', 'yi', 'yo', 'yo-BJ', 'yue', 'yue-Hans', + 'zgh', 'zh', 'zh-Hant', 'zh-Hant-HK', 'zu', + ]; + + /** * Creates a LanguageRepository instance. * + * @param string $defaultLocale The default locale. Defaults to 'en'. + * @param string $fallbackLocale The fallback locale. Defaults to 'en'. * @param string $definitionPath The path to the currency definitions. * Defaults to 'resources/language'. */ - public function __construct($definitionPath = null) + public function __construct($defaultLocale = 'en', $fallbackLocale = 'en', $definitionPath = null) { + $this->defaultLocale = $defaultLocale; + $this->fallbackLocale = $fallbackLocale; $this->definitionPath = $definitionPath ? $definitionPath : __DIR__ . '/../../resources/language/'; } /** * {@inheritdoc} */ - public function get($languageCode, $locale = null, $fallbackLocale = null) + public function get($languageCode, $locale = null) { - $locale = $this->resolveLocale($locale, $fallbackLocale); + $locale = $locale ?: $this->defaultLocale; + $locale = Locale::resolve($this->availableLocales, $locale, $this->fallbackLocale); $definitions = $this->loadDefinitions($locale); + $languageCode = Locale::canonicalize($languageCode); if (!isset($definitions[$languageCode])) { throw new UnknownLanguageException($languageCode); } + $language = new Language([ + 'language_code' => $languageCode, + 'name' => $definitions[$languageCode], + 'locale' => $locale, + ]); - return $this->createLanguageFromDefinition($languageCode, $definitions[$languageCode], $locale); + return $language; } /** * {@inheritdoc} */ - public function getAll($locale = null, $fallbackLocale = null) + public function getAll($locale = null) { - $locale = $this->resolveLocale($locale, $fallbackLocale); + $locale = $locale ?: $this->defaultLocale; + $locale = Locale::resolve($this->availableLocales, $locale, $this->fallbackLocale); $definitions = $this->loadDefinitions($locale); $languages = []; - foreach ($definitions as $languageCode => $definition) { - $languages[$languageCode] = $this->createLanguageFromDefinition($languageCode, $definition, $locale); + foreach ($definitions as $languageCode => $languageName) { + $languages[$languageCode] = new Language([ + 'language_code' => $languageCode, + 'name' => $languageName, + 'locale' => $locale, + ]); } return $languages; @@ -62,13 +131,14 @@ class LanguageRepository implements LanguageRepositoryInterface /** * {@inheritdoc} */ - public function getList($locale = null, $fallbackLocale = null) + public function getList($locale = null) { - $locale = $this->resolveLocale($locale, $fallbackLocale); + $locale = $locale ?: $this->defaultLocale; + $locale = Locale::resolve($this->availableLocales, $locale, $this->fallbackLocale); $definitions = $this->loadDefinitions($locale); $list = []; - foreach ($definitions as $languageCode => $definition) { - $list[$languageCode] = $definition['name']; + foreach ($definitions as $languageCode => $languageName) { + $list[$languageCode] = $languageName; } return $list; @@ -90,26 +160,4 @@ class LanguageRepository implements LanguageRepositoryInterface return $this->definitions[$locale]; } - - /** - * Creates a language object from the provided definition. - * - * @param string $languageCode The language code. - * @param array $definition The language definition. - * @param string $locale The locale of the language definition. - * - * @return Language - */ - protected function createLanguageFromDefinition($languageCode, array $definition, $locale) - { - $language = new Language(); - $setValues = \Closure::bind(function ($languageCode, $definition, $locale) { - $this->languageCode = $languageCode; - $this->name = $definition['name']; - $this->locale = $locale; - }, $language, '\CommerceGuys\Intl\Language\Language'); - $setValues($languageCode, $definition, $locale); - - return $language; - } } diff --git a/vendor/commerceguys/intl/src/Language/LanguageRepositoryInterface.php b/vendor/commerceguys/intl/src/Language/LanguageRepositoryInterface.php index dd14250e0..12480fc1b 100644 --- a/vendor/commerceguys/intl/src/Language/LanguageRepositoryInterface.php +++ b/vendor/commerceguys/intl/src/Language/LanguageRepositoryInterface.php @@ -8,34 +8,30 @@ namespace CommerceGuys\Intl\Language; interface LanguageRepositoryInterface { /** - * Returns a language instance matching the provided language code. + * Gets a language matching the provided language code. * - * @param string $languageCode The language code. - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $languageCode The language code. + * @param string $locale The locale (i.e. fr-FR). * - * @return LanguageInterface + * @return Language */ - public function get($languageCode, $locale = null, $fallbackLocale = null); + public function get($languageCode, $locale = null); /** - * Returns all language instances. + * Gets all languages. * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $locale The locale (i.e. fr-FR). * - * @return array An array of languages implementing the LanguageInterface, - * keyed by language code. + * @return Language[] An array of languages, keyed by language code. */ - public function getAll($locale = null, $fallbackLocale = null); + public function getAll($locale = null); /** - * Returns a list of languages. + * Gets a list of languages. * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $locale The locale (i.e. fr-FR). * * @return array An array of language names, keyed by language code. */ - public function getList($locale = null, $fallbackLocale = null); + public function getList($locale = null); } diff --git a/vendor/commerceguys/intl/src/Locale.php b/vendor/commerceguys/intl/src/Locale.php new file mode 100644 index 000000000..f8f3f7cb8 --- /dev/null +++ b/vendor/commerceguys/intl/src/Locale.php @@ -0,0 +1,432 @@ +<?php + +namespace CommerceGuys\Intl; + +use CommerceGuys\Intl\Exception\UnknownLocaleException; + +final class Locale +{ + /** + * Locale aliases. + * + * @var array + */ + protected static $aliases = [ + 'az-AZ' => 'az-Latn-AZ', + 'bs-BA' => 'bs-Latn-BA', + 'ha-GH' => 'ha-Latn-GH', + 'ha-NE' => 'ha-Latn-NE', + 'ha-NG' => 'ha-Latn-NG', + 'in' => 'id', + 'in-ID' => 'id-ID', + 'iw' => 'he', + 'iw-IL' => 'he-IL', + 'kk-KZ' => 'kk-Cyrl-KZ', + 'ks-IN' => 'ks-Arab-IN', + 'ky-KG' => 'ky-Cyrl-KG', + 'mn-MN' => 'mn-Cyrl-MN', + 'mo' => 'ro-MD', + 'ms-BN' => 'ms-Latn-BN', + 'ms-MY' => 'ms-Latn-MY', + 'ms-SG' => 'ms-Latn-SG', + 'no' => 'nb', + 'no-NO' => 'nb-NO', + 'no-NO-NY' => 'nn-NO', + 'pa-IN' => 'pa-Guru-IN', + 'pa-PK' => 'pa-Arab-PK', + 'sh' => 'sr-Latn', + 'sh-BA' => 'sr-Latn-BA', + 'sh-CS' => 'sr-Latn-RS', + 'sh-YU' => 'sr-Latn-RS', + 'shi-MA' => 'shi-Tfng-MA', + 'sr-BA' => 'sr-Cyrl-BA', + 'sr-ME' => 'sr-Latn-ME', + 'sr-RS' => 'sr-Cyrl-RS', + 'sr-XK' => 'sr-Cyrl-XK', + 'tl' => 'fil', + 'tl-PH' => 'fil-PH', + 'tzm-MA' => 'tzm-Latn-MA', + 'ug-CN' => 'ug-Arab-CN', + 'uz-AF' => 'uz-Arab-AF', + 'uz-UZ' => 'uz-Latn-UZ', + 'vai-LR' => 'vai-Vaii-LR', + 'zh-CN' => 'zh-Hans-CN', + 'zh-HK' => 'zh-Hant-HK', + 'zh-MO' => 'zh-Hant-MO', + 'zh-SG' => 'zh-Hans-SG', + 'zh-TW' => 'zh-Hant-TW', + ]; + + /** + * Locale parents. + * + * @var array + */ + protected static $parents = [ + 'en-150' => 'en-001', + 'en-AG' => 'en-001', + 'en-AI' => 'en-001', + 'en-AU' => 'en-001', + 'en-BB' => 'en-001', + 'en-BM' => 'en-001', + 'en-BS' => 'en-001', + 'en-BW' => 'en-001', + 'en-BZ' => 'en-001', + 'en-CA' => 'en-001', + 'en-CC' => 'en-001', + 'en-CK' => 'en-001', + 'en-CM' => 'en-001', + 'en-CX' => 'en-001', + 'en-CY' => 'en-001', + 'en-DG' => 'en-001', + 'en-DM' => 'en-001', + 'en-ER' => 'en-001', + 'en-FJ' => 'en-001', + 'en-FK' => 'en-001', + 'en-FM' => 'en-001', + 'en-GB' => 'en-001', + 'en-GD' => 'en-001', + 'en-GG' => 'en-001', + 'en-GH' => 'en-001', + 'en-GI' => 'en-001', + 'en-GM' => 'en-001', + 'en-GY' => 'en-001', + 'en-HK' => 'en-001', + 'en-IE' => 'en-001', + 'en-IL' => 'en-001', + 'en-IM' => 'en-001', + 'en-IN' => 'en-001', + 'en-IO' => 'en-001', + 'en-JE' => 'en-001', + 'en-JM' => 'en-001', + 'en-KE' => 'en-001', + 'en-KI' => 'en-001', + 'en-KN' => 'en-001', + 'en-KY' => 'en-001', + 'en-LC' => 'en-001', + 'en-LR' => 'en-001', + 'en-LS' => 'en-001', + 'en-MG' => 'en-001', + 'en-MO' => 'en-001', + 'en-MS' => 'en-001', + 'en-MT' => 'en-001', + 'en-MU' => 'en-001', + 'en-MW' => 'en-001', + 'en-MY' => 'en-001', + 'en-NA' => 'en-001', + 'en-NF' => 'en-001', + 'en-NG' => 'en-001', + 'en-NR' => 'en-001', + 'en-NU' => 'en-001', + 'en-NZ' => 'en-001', + 'en-PG' => 'en-001', + 'en-PH' => 'en-001', + 'en-PK' => 'en-001', + 'en-PN' => 'en-001', + 'en-PW' => 'en-001', + 'en-RW' => 'en-001', + 'en-SB' => 'en-001', + 'en-SC' => 'en-001', + 'en-SD' => 'en-001', + 'en-SG' => 'en-001', + 'en-SH' => 'en-001', + 'en-SL' => 'en-001', + 'en-SS' => 'en-001', + 'en-SX' => 'en-001', + 'en-SZ' => 'en-001', + 'en-TC' => 'en-001', + 'en-TK' => 'en-001', + 'en-TO' => 'en-001', + 'en-TT' => 'en-001', + 'en-TV' => 'en-001', + 'en-TZ' => 'en-001', + 'en-UG' => 'en-001', + 'en-VC' => 'en-001', + 'en-VG' => 'en-001', + 'en-VU' => 'en-001', + 'en-WS' => 'en-001', + 'en-ZA' => 'en-001', + 'en-ZM' => 'en-001', + 'en-ZW' => 'en-001', + 'en-AT' => 'en-150', + 'en-BE' => 'en-150', + 'en-CH' => 'en-150', + 'en-DE' => 'en-150', + 'en-DK' => 'en-150', + 'en-FI' => 'en-150', + 'en-NL' => 'en-150', + 'en-SE' => 'en-150', + 'en-SI' => 'en-150', + 'es-AR' => 'es-419', + 'es-BO' => 'es-419', + 'es-BR' => 'es-419', + 'es-BZ' => 'es-419', + 'es-CL' => 'es-419', + 'es-CO' => 'es-419', + 'es-CR' => 'es-419', + 'es-CU' => 'es-419', + 'es-DO' => 'es-419', + 'es-EC' => 'es-419', + 'es-GT' => 'es-419', + 'es-HN' => 'es-419', + 'es-MX' => 'es-419', + 'es-NI' => 'es-419', + 'es-PA' => 'es-419', + 'es-PE' => 'es-419', + 'es-PR' => 'es-419', + 'es-PY' => 'es-419', + 'es-SV' => 'es-419', + 'es-US' => 'es-419', + 'es-UY' => 'es-419', + 'es-VE' => 'es-419', + 'pt-AO' => 'pt-PT', + 'pt-CH' => 'pt-PT', + 'pt-CV' => 'pt-PT', + 'pt-FR' => 'pt-PT', + 'pt-GQ' => 'pt-PT', + 'pt-GW' => 'pt-PT', + 'pt-LU' => 'pt-PT', + 'pt-MO' => 'pt-PT', + 'pt-MZ' => 'pt-PT', + 'pt-ST' => 'pt-PT', + 'pt-TL' => 'pt-PT', + 'az-Arab' => 'root', + 'az-Cyrl' => 'root', + 'blt-Latn' => 'root', + 'bm-Nkoo' => 'root', + 'bs-Cyrl' => 'root', + 'byn-Latn' => 'root', + 'cu-Glag' => 'root', + 'dje-Arab' => 'root', + 'dyo-Arab' => 'root', + 'en-Dsrt' => 'root', + 'en-Shaw' => 'root', + 'ff-Adlm' => 'root', + 'ff-Arab' => 'root', + 'ha-Arab' => 'root', + 'iu-Latn' => 'root', + 'kk-Arab' => 'root', + 'ku-Arab' => 'root', + 'ky-Arab' => 'root', + 'ky-Latn' => 'root', + 'ml-Arab' => 'root', + 'mn-Mong' => 'root', + 'ms-Arab' => 'root', + 'pa-Arab' => 'root', + 'sd-Deva' => 'root', + 'sd-Khoj' => 'root', + 'sd-Sind' => 'root', + 'shi-Latn' => 'root', + 'so-Arab' => 'root', + 'sr-Latn' => 'root', + 'sw-Arab' => 'root', + 'tg-Arab' => 'root', + 'ug-Cyrl' => 'root', + 'uz-Arab' => 'root', + 'uz-Cyrl' => 'root', + 'vai-Latn' => 'root', + 'wo-Arab' => 'root', + 'yo-Arab' => 'root', + 'yue-Hans' => 'root', + 'zh-Hant' => 'root', + 'zh-Hant-MO' => 'zh-Hant-HK', + ]; + + /** + * Checks whether two locales match. + * + * @param string $firstLocale The first locale. + * @param string $secondLocale The second locale. + * + * @return bool TRUE if the locales match, FALSE otherwise. + */ + public static function match($firstLocale, $secondLocale) + { + if (empty($firstLocale) || empty($secondLocale)) { + return false; + } + + return self::canonicalize($firstLocale) === self::canonicalize($secondLocale); + } + + /** + * Checks whether two locales have at least one common candidate. + * + * For example, "de" and "de-AT" will match because they both have + * "de" in common. This is useful for partial locale matching. + * + * @see self::getCandidates + * + * @param string $firstLocale The first locale. + * @param string $secondLocale The second locale. + * + * @return bool TRUE if there is a common candidate, FALSE otherwise. + */ + public static function matchCandidates($firstLocale, $secondLocale) + { + if (empty($firstLocale) || empty($secondLocale)) { + return false; + } + + $firstLocale = self::canonicalize($firstLocale); + $secondLocale = self::canonicalize($secondLocale); + $firstLocaleCandidates = self::getCandidates($firstLocale); + $secondLocaleCandidates = self::getCandidates($secondLocale); + + return (bool) array_intersect($firstLocaleCandidates, $secondLocaleCandidates); + } + + /** + * Resolves the locale from the available locales. + * + * Takes all locale candidates for the requested locale + * and fallback locale, searches for them in the available + * locale list. The first found locale is returned. + * If no candidate is found in the list, an exception is thrown. + * + * @see self::getCandidates + * + * @param array $availableLocales The available locales. + * @param string $locale The requested locale (i.e. fr-FR). + * @param string $fallbackLocale A fallback locale (i.e "en"). + * + * @return string + * + * @throws UnknownLocaleException + */ + public static function resolve(array $availableLocales, $locale, $fallbackLocale = null) + { + $locale = self::canonicalize($locale); + $resolvedLocale = null; + foreach (self::getCandidates($locale, $fallbackLocale) as $candidate) { + if (in_array($candidate, $availableLocales)) { + $resolvedLocale = $candidate; + break; + } + } + // No locale could be resolved, stop here. + if (!$resolvedLocale) { + throw new UnknownLocaleException($locale); + } + + return $resolvedLocale; + } + + /** + * Canonicalizes the given locale. + * + * Standardizes separators and capitalization, turning + * a locale such as "sr_rs_latn" into "sr-RS-Latn". + * + * @param string $locale The locale. + * + * @return string The canonicalized locale. + */ + public static function canonicalize($locale) + { + if (empty($locale)) { + return $locale; + } + + $locale = str_replace('_', '-', strtolower($locale)); + $localeParts = explode('-', $locale); + foreach ($localeParts as $index => $part) { + if ($index === 0) { + // The language code should stay lowercase. + continue; + } + + if (strlen($part) == 4) { + // Script code. + $localeParts[$index] = ucfirst($part); + } else { + // Country or variant code. + $localeParts[$index] = strtoupper($part); + } + } + + return implode('-', $localeParts); + } + + /** + * Gets locale candidates. + * + * For example, "bs-Cyrl-BA" has the following candidates: + * 1) bs-Cyrl-BA + * 2) bs-Cyrl + * 3) bs + * + * The locale is de-aliased, e.g. the candidates for "sh" are: + * 1) sr-Latn + * 2) sr + * + * @param string $locale The locale (i.e. fr-FR). + * @param string $fallbackLocale A fallback locale (i.e "en"). + * + * @return array An array of all variants of a locale. + */ + public static function getCandidates($locale, $fallbackLocale = null) + { + $locale = self::replaceAlias($locale); + $candidates = [$locale]; + while ($parent = self::getParent($locale)) { + $candidates[] = $parent; + $locale = $parent; + } + if (isset($fallbackLocale)) { + $candidates[] = $fallbackLocale; + while ($parent = self::getParent($fallbackLocale)) { + $candidates[] = $parent; + $fallbackLocale = $parent; + } + } + + return array_unique($candidates); + } + + /** + * Gets the parent for the given locale. + * + * @param string $locale + * The locale. + * + * @return string|null + * The parent, or null if none found. + */ + public static function getParent($locale) + { + $parent = null; + if (isset(self::$parents[$locale])) { + $parent = self::$parents[$locale]; + } elseif (strpos($locale, '-') !== false) { + $localeParts = explode('-', $locale); + array_pop($localeParts); + $parent = implode('-', $localeParts); + } + // The library doesn't have data for the empty 'root' locale, it + // is more user friendly to use the configured fallback instead. + if ($parent == 'root') { + $parent = null; + } + + return $parent; + } + + /** + * Replaces a locale alias with the real locale. + * + * For example, "zh-CN" is replaced with "zh-Hans-CN". + * + * @param string $locale The locale. + * + * @return string The locale. + */ + public static function replaceAlias($locale) + { + if (!empty($locale) && isset(self::$aliases[$locale])) { + $locale = self::$aliases[$locale]; + } + + return $locale; + } +} diff --git a/vendor/commerceguys/intl/src/LocaleResolverTrait.php b/vendor/commerceguys/intl/src/LocaleResolverTrait.php deleted file mode 100644 index 797e5abaf..000000000 --- a/vendor/commerceguys/intl/src/LocaleResolverTrait.php +++ /dev/null @@ -1,244 +0,0 @@ -<?php - -namespace CommerceGuys\Intl; - -use CommerceGuys\Intl\Exception\UnknownLocaleException; - -trait LocaleResolverTrait -{ - /** - * The path where per-locale definitions are stored. - * - * @var string - */ - protected $definitionPath; - - /** - * The default locale. - * - * @var string - */ - protected $defaultLocale = 'en'; - - /** - * The fallback locale. - * - * @var string - */ - protected $fallbackLocale = null; - - /** - * Common locale aliases. - * - * @var array - */ - protected $localeAliases = [ - 'az-AZ' => 'az-Latn-AZ', - 'bs-BA' => 'bs-Latn-BA', - 'ha-GH' => 'ha-Latn-GH', - 'ha-NE' => 'ha-Latn-NE', - 'ha-NG' => 'ha-Latn-NG', - 'in' => 'id', - 'in-ID' => 'id-ID', - 'iw' => 'he', - 'iw-IL' => 'he-IL', - 'kk-KZ' => 'kk-Cyrl-KZ', - 'ks-IN' => 'ks-Arab-IN', - 'ky-KG' => 'ky-Cyrl-KG', - 'mn-MN' => 'mn-Cyrl-MN', - 'mo' => 'ro-MD', - 'ms-BN' => 'ms-Latn-BN', - 'ms-MY' => 'ms-Latn-MY', - 'ms-SG' => 'ms-Latn-SG', - 'no' => 'nb', - 'no-NO' => 'nb-NO', - 'no-NO-NY' => 'nn-NO', - 'pa-IN' => 'pa-Guru-IN', - 'pa-PK' => 'pa-Arab-PK', - 'sh' => 'sr-Latn', - 'sh-BA' => 'sr-Latn-BA', - 'sh-CS' => 'sr-Latn-RS', - 'sh-YU' => 'sr-Latn-RS', - 'shi-MA' => 'shi-Tfng-MA', - 'sr-BA' => 'sr-Cyrl-BA', - 'sr-ME' => 'sr-Latn-ME', - 'sr-RS' => 'sr-Cyrl-RS', - 'sr-XK' => 'sr-Cyrl-XK', - 'tl' => 'fil', - 'tl-PH' => 'fil-PH', - 'tzm-MA' => 'tzm-Latn-MA', - 'ug-CN' => 'ug-Arab-CN', - 'uz-AF' => 'uz-Arab-AF', - 'uz-UZ' => 'uz-Latn-UZ', - 'vai-LR' => 'vai-Vaii-LR', - 'zh-CN' => 'zh-Hans-CN', - 'zh-HK' => 'zh-Hant-HK', - 'zh-MO' => 'zh-Hant-MO', - 'zh-SG' => 'zh-Hans-SG', - 'zh-TW' => 'zh-Hant-TW', - ]; - - /** - * Determines which locale should be used for loading definitions. - * - * If the "bs-Cyrl-BA" locale is requested, with an "en" fallback, - * the system will try to find the definitions for: - * 1) bs-Cyrl-BA - * 2) bs-Cyrl - * 3) bs - * 4) en - * The first locale for which a definition file is found, wins. - * Otherwise, an exception is thrown. - * - * @param string $locale The desired locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). - * - * @return string - * - * @throws UnknownLocaleException - */ - protected function resolveLocale($locale = null, $fallbackLocale = null) - { - $locale = $locale ?: $this->getDefaultLocale(); - $locale = $this->canonicalizeLocale($locale); - $locale = $this->resolveLocaleAlias($locale); - // List all possible variants (i.e. en-US gives "en-US" and "en"). - $localeVariants = $this->getLocaleVariants($locale); - // A fallback locale was provided, add it to the end of the chain. - $fallbackLocale = $fallbackLocale ?: $this->getFallbackLocale(); - if (isset($fallbackLocale)) { - $localeVariants[] = $fallbackLocale; - } - - // Try to resolve a locale by finding a matching definition file. - $resolvedLocale = null; - foreach ($localeVariants as $localeVariant) { - $path = $this->definitionPath . $localeVariant . '.json'; - if (file_exists($path)) { - $resolvedLocale = $localeVariant; - break; - } - } - // No locale could be resolved, stop here. - if (!$resolvedLocale) { - throw new UnknownLocaleException($locale); - } - - return $resolvedLocale; - } - - /** - * Resolves known locale aliases. - * - * For example, "zh-CN" is resolved to "zh-Hans-CN". - * - * @param string $locale The locale. - * - * @return string The locale. - */ - protected function resolveLocaleAlias($locale = null) - { - if ($locale && isset($this->localeAliases[$locale])) { - $locale = $this->localeAliases[$locale]; - } - - return $locale; - } - - /** - * Canonicalize the given locale. - * - * @param string $locale The locale. - * - * @return string The canonicalized locale. - */ - protected function canonicalizeLocale($locale = null) - { - if (is_null($locale)) { - return $locale; - } - - $locale = str_replace('-', '_', strtolower($locale)); - $localeParts = explode('_', $locale); - foreach ($localeParts as $index => $part) { - if ($index === 0) { - // The language code should stay lowercase. - continue; - } - - if (strlen($part) == 4) { - // Script code. - $localeParts[$index] = ucfirst($part); - } else { - // Country or variant code. - $localeParts[$index] = strtoupper($part); - } - } - - return implode('-', $localeParts); - } - - /** - * Gets the default locale. - * - * @return string The default locale. - */ - public function getDefaultLocale() - { - return $this->defaultLocale; - } - - /** - * Sets the default locale. - * - * @return void - */ - public function setDefaultLocale($locale) - { - $this->defaultLocale = $locale; - } - - /** - * Gets the fallback locale. - * - * @return string The fallback locale. - */ - public function getFallbackLocale() - { - return $this->fallbackLocale; - } - - /** - * Sets the fallback locale. - * - * @return void - */ - public function setFallbackLocale($locale) - { - $this->fallbackLocale = $locale; - } - - /** - * Gets all variants of a locale. - * - * For example, "bs-Cyrl-BA" has the following variants: - * 1) bs-Cyrl-BA - * 2) bs-Cyrl - * 3) bs - * - * @param string $locale The locale (i.e. fr-FR). - * - * @return array An array of all variants of a locale. - */ - protected function getLocaleVariants($locale) - { - $localeVariants = []; - $localeParts = explode('-', $locale); - while (!empty($localeParts)) { - $localeVariants[] = implode('-', $localeParts); - array_pop($localeParts); - } - - return $localeVariants; - } -} diff --git a/vendor/commerceguys/intl/src/NumberFormat/NumberFormat.php b/vendor/commerceguys/intl/src/NumberFormat/NumberFormat.php index 077f6721f..156470eee 100644 --- a/vendor/commerceguys/intl/src/NumberFormat/NumberFormat.php +++ b/vendor/commerceguys/intl/src/NumberFormat/NumberFormat.php @@ -2,8 +2,22 @@ namespace CommerceGuys\Intl\NumberFormat; -class NumberFormat implements NumberFormatEntityInterface +/** + * Provides metadata for number formatting. + */ +final class NumberFormat { + // Arabic-Indic digits. + const NUMBERING_SYSTEM_ARABIC = 'arab'; + // Extended Arabic-Indic digits. + const NUMBERING_SYSTEM_ARABIC_EXTENDED = 'arabext'; + // Bengali digits. + const NUMBERING_SYSTEM_BENGALI = 'beng'; + // Devanagari digits. + const NUMBERING_SYSTEM_DEVANAGARI = 'deva'; + // Latin digits + const NUMBERING_SYSTEM_LATIN = 'latn'; + /** * The locale (i.e. "en_US"). * @@ -12,159 +26,230 @@ class NumberFormat implements NumberFormatEntityInterface protected $locale; /** - * The numbering system. + * The number pattern used to format decimal numbers. * * @var string */ - protected $numberingSystem = []; + protected $decimalPattern; /** - * The decimal separator. + * The number pattern used to format percentages. * * @var string */ - protected $decimalSeparator = []; + protected $percentPattern; /** - * The grouping separator. + * The number pattern used to format currency amounts. * * @var string */ - protected $groupingSeparator = []; + protected $currencyPattern; /** - * The plus sign. + * The number pattern used to format accounting currency amounts. * * @var string */ - protected $plusSign = []; + protected $accountingCurrencyPattern; /** - * The number symbols. + * The numbering system. * * @var string */ - protected $minusSign = []; + protected $numberingSystem = self::NUMBERING_SYSTEM_LATIN; /** - * The percent sign. + * The decimal separator. * * @var string */ - protected $percentSign = []; + protected $decimalSeparator = '.'; /** - * The number pattern used to format decimal numbers. + * The grouping separator. * * @var string */ - protected $decimalPattern; + protected $groupingSeparator = ','; /** - * The number pattern used to format percentages. + * The plus sign. * * @var string */ - protected $percentPattern; + protected $plusSign = '+'; /** - * The number pattern used to format currency amounts. + * The number symbols. * * @var string */ - protected $currencyPattern; + protected $minusSign = '-'; /** - * The number pattern used to format accounting currency amounts. + * The percent sign. * * @var string */ - protected $accountingCurrencyPattern; + protected $percentSign = '%'; /** - * {@inheritdoc} + * Creates a new NumberFormat instance. + * + * @param array $definition The definition array. */ - public function getLocale() + public function __construct(array $definition) { - return $this->locale; + // Validate the presence of required properties. + $requiredProperties = [ + 'locale', 'decimal_pattern', 'percent_pattern', + 'currency_pattern', 'accounting_currency_pattern', + ]; + foreach ($requiredProperties as $requiredProperty) { + if (empty($definition[$requiredProperty])) { + throw new \InvalidArgumentException(sprintf('Missing required property "%s".', $requiredProperty)); + } + } + // Validate the numbering system. + if (isset($definition['numbering_system'])) { + if (!in_array($definition['numbering_system'], ['arab', 'arabext', 'beng', 'deva', 'latn'])) { + throw new \InvalidArgumentException(sprintf('Invalid numbering system "%s".', $definition['numbering_system'])); + } + } + + $this->locale = $definition['locale']; + $this->decimalPattern = $definition['decimal_pattern']; + $this->percentPattern = $definition['percent_pattern']; + $this->currencyPattern = $definition['currency_pattern']; + $this->accountingCurrencyPattern = $definition['accounting_currency_pattern']; + if (isset($definition['numbering_system'])) { + $this->numberingSystem = $definition['numbering_system']; + } + if (isset($definition['decimal_separator'])) { + $this->decimalSeparator = $definition['decimal_separator']; + } + if (isset($definition['grouping_separator'])) { + $this->groupingSeparator = $definition['grouping_separator']; + } + if (isset($definition['plus_sign'])) { + $this->plusSign = $definition['plus_sign']; + } + if (isset($definition['minus_sign'])) { + $this->minusSign = $definition['minus_sign']; + } + if (isset($definition['percent_sign'])) { + $this->percentSign = $definition['percent_sign']; + } } /** - * {@inheritdoc} + * Gets the locale. + * + * @return string */ - public function setLocale($locale) + public function getLocale() { - $this->locale = $locale; - - return $this; + return $this->locale; } /** - * {@inheritdoc} + * Gets the number pattern used to format decimal numbers. + * + * @return string + * + * @see http://cldr.unicode.org/translation/number-patterns */ - public function getNumberingSystem() + public function getDecimalPattern() { - return $this->numberingSystem; + return $this->decimalPattern; } /** - * {@inheritdoc} + * Gets the number pattern used to format percentages. + * + * @return string + * + * @see http://cldr.unicode.org/translation/number-patterns */ - public function setNumberingSystem($numberingSystem) + public function getPercentPattern() { - $this->numberingSystem = $numberingSystem; + return $this->percentPattern; } /** - * {@inheritdoc} + * Gets the number pattern used to format currency amounts. + * + * @return string + * + * @see http://cldr.unicode.org/translation/number-patterns */ - public function getDecimalSeparator() + public function getCurrencyPattern() { - return $this->decimalSeparator; + return $this->currencyPattern; } /** - * {@inheritdoc} + * Gets the number pattern used to format accounting currency amounts. + * + * Most commonly used when formatting amounts on invoices. + * + * @return string + * + * @see http://cldr.unicode.org/translation/number-patterns */ - public function setDecimalSeparator($decimalSeparator) + public function getAccountingCurrencyPattern() { - $this->decimalSeparator = $decimalSeparator; + return $this->accountingCurrencyPattern; } /** - * {@inheritdoc} + * Gets the numbering system. + * + * The value is one of the NUMBERING_SYSTEM_ constants. + * + * @return string */ - public function getGroupingSeparator() + public function getNumberingSystem() { - return $this->groupingSeparator; + return $this->numberingSystem; } /** - * {@inheritdoc} + * Gets the decimal separator. + * + * @return string */ - public function setGroupingSeparator($groupingSeparator) + public function getDecimalSeparator() { - $this->groupingSeparator = $groupingSeparator; + return $this->decimalSeparator; } /** - * {@inheritdoc} + * Gets the grouping separator. + * + * @return string */ - public function getPlusSign() + public function getGroupingSeparator() { - return $this->plusSign; + return $this->groupingSeparator; } /** - * {@inheritdoc} + * Gets the plus sign. + * + * @return string */ - public function setPlusSign($plusSign) + public function getPlusSign() { - $this->plusSign = $plusSign; + return $this->plusSign; } /** - * {@inheritdoc} + * Gets the minus sign. + * + * @return string */ public function getMinusSign() { @@ -172,98 +257,12 @@ class NumberFormat implements NumberFormatEntityInterface } /** - * {@inheritdoc} - */ - public function setMinusSign($minusSign) - { - $this->minusSign = $minusSign; - } - - /** - * {@inheritdoc} + * Gets the percent sign. + * + * @return string */ public function getPercentSign() { return $this->percentSign; } - - /** - * {@inheritdoc} - */ - public function setPercentSign($percentSign) - { - $this->percentSign = $percentSign; - } - - /** - * {@inheritdoc} - */ - public function getDecimalPattern() - { - return $this->decimalPattern; - } - - /** - * {@inheritdoc} - */ - public function setDecimalPattern($decimalPattern) - { - $this->decimalPattern = $decimalPattern; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getPercentPattern() - { - return $this->percentPattern; - } - - /** - * {@inheritdoc} - */ - public function setPercentPattern($percentPattern) - { - $this->percentPattern = $percentPattern; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getCurrencyPattern() - { - return $this->currencyPattern; - } - - /** - * {@inheritdoc} - */ - public function setCurrencyPattern($currencyPattern) - { - $this->currencyPattern = $currencyPattern; - - return $this; - } - - /** - * {@inheritdoc} - */ - public function getAccountingCurrencyPattern() - { - return $this->accountingCurrencyPattern; - } - - /** - * {@inheritdoc} - */ - public function setAccountingCurrencyPattern($accountingCurrencyPattern) - { - $this->accountingCurrencyPattern = $accountingCurrencyPattern; - - return $this; - } } diff --git a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatEntityInterface.php b/vendor/commerceguys/intl/src/NumberFormat/NumberFormatEntityInterface.php deleted file mode 100644 index debafd6ba..000000000 --- a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatEntityInterface.php +++ /dev/null @@ -1,107 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\NumberFormat; - -interface NumberFormatEntityInterface extends NumberFormatInterface -{ - /** - * Sets the locale. - * - * @param string $locale The locale (i.e. "en_US"). - * - * @return self - */ - public function setLocale($locale); - - /** - * Sets the numbering system. - * - * @param string $numberingSystem One of the NUMBERING_SYSTEM_ constants. - * - * @return self - */ - public function setNumberingSystem($numberingSystem); - - /** - * Sets the decimal separator. - * - * @param string $decimalSeparator - * - * @return self - */ - public function setDecimalSeparator($decimalSeparator); - - /** - * Sets the grouping separator. - * - * @param string $groupingSeparator - * - * @return self - */ - public function setGroupingSeparator($groupingSeparator); - - /** - * Sets the plus sign. - * - * @param string $plusSign - * - * @return self - */ - public function setPlusSign($plusSign); - - /** - * Sets the minus sign. - * - * @param string $minusSign - * - * @return self - */ - public function setMinusSign($minusSign); - - /** - * Sets the percent sign. - * - * @param string $percentSign - * - * @return self - */ - public function setPercentSign($percentSign); - - /** - * Sets the number pattern used to format decimal numbers. - * - * @param string $decimalPattern The decimal pattern. - * - * @return self - */ - public function setDecimalPattern($decimalPattern); - - /** - * Sets the number pattern used to format percentages. - * - * @param string $percentPattern The percent pattern. - * - * @return self - */ - public function setPercentPattern($percentPattern); - - /** - * Sets the number pattern used to format currency amounts. - * - * @param string $currencyPattern The currency pattern. - * - * @return self - */ - public function setCurrencyPattern($currencyPattern); - - /** - * Sets the number pattern used to format accounting currency amounts. - * - * Most commonly used when formatting amounts on invoices. - * - * @param string $accountingCurrencyPattern The accounting currency pattern. - * - * @return self - */ - public function setAccountingCurrencyPattern($accountingCurrencyPattern); -} diff --git a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php b/vendor/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php deleted file mode 100644 index bb343f366..000000000 --- a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatInterface.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php - -namespace CommerceGuys\Intl\NumberFormat; - -interface NumberFormatInterface -{ - // Arabic-Indic digits. - const NUMBERING_SYSTEM_ARABIC = 'arab'; - // Extended Arabic-Indic digits. - const NUMBERING_SYSTEM_ARABIC_EXTENDED = 'arabext'; - // Bengali digits. - const NUMBERING_SYSTEM_BENGALI = 'beng'; - // Devanagari digits. - const NUMBERING_SYSTEM_DEVANAGARI = 'deva'; - // Latin digits - const NUMBERING_SYSTEM_LATIN = 'latn'; - - /** - * Gets the locale. - * - * @return string - */ - public function getLocale(); - - /** - * Gets the numbering system. - * - * The value is one of the NUMBERING_SYSTEM_ constants. - * - * @return string - */ - public function getNumberingSystem(); - - /** - * Gets the decimal separator. - * - * @return string - */ - public function getDecimalSeparator(); - - /** - * Gets the grouping separator. - * - * @return string - */ - public function getGroupingSeparator(); - - /** - * Gets the plus sign. - * - * @return string - */ - public function getPlusSign(); - - /** - * Gets the minus sign. - * - * @return string - */ - public function getMinusSign(); - - /** - * Gets the percent sign. - * - * @return string - */ - public function getPercentSign(); - - /** - * Gets the number pattern used to format decimal numbers. - * - * @return string - * - * @see http://cldr.unicode.org/translation/number-patterns - */ - public function getDecimalPattern(); - - /** - * Gets the number pattern used to format percentages. - * - * @return string - * - * @see http://cldr.unicode.org/translation/number-patterns - */ - public function getPercentPattern(); - - /** - * Gets the number pattern used to format currency amounts. - * - * @return string - * - * @see http://cldr.unicode.org/translation/number-patterns - */ - public function getCurrencyPattern(); - - /** - * Gets the number pattern used to format accounting currency amounts. - * - * Most commonly used when formatting amounts on invoices. - * - * @return string - * - * @see http://cldr.unicode.org/translation/number-patterns - */ - public function getAccountingCurrencyPattern(); -} diff --git a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php b/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php index 368eb7e2b..887bc43e0 100644 --- a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php +++ b/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepository.php @@ -2,90 +2,1262 @@ namespace CommerceGuys\Intl\NumberFormat; -use CommerceGuys\Intl\LocaleResolverTrait; +use CommerceGuys\Intl\Locale; /** - * Repository for number formats based on JSON definitions. + * Provides number formats. */ class NumberFormatRepository implements NumberFormatRepositoryInterface { - use LocaleResolverTrait; - /** - * Number formats. + * The fallback locale. * - * @var array + * @var string */ - protected $numberFormats = []; + protected $fallbackLocale; /** * Creates a NumberFormatRepository instance. * - * @param string $definitionPath The path to the number format definitions. - * Defaults to 'resources/number_format'. + * @param string $fallbackLocale The fallback locale. Defaults to 'en'. */ - public function __construct($definitionPath = null) + public function __construct($fallbackLocale = 'en') { - $this->definitionPath = $definitionPath ? $definitionPath : __DIR__ . '/../../resources/number_format/'; + $this->fallbackLocale = $fallbackLocale; } /** * {@inheritdoc} */ - public function get($locale, $fallbackLocale = null) + public function get($locale) { - $locale = $this->resolveLocale($locale, $fallbackLocale); - if (!isset($this->numberFormats[$locale])) { - $filename = $this->definitionPath . $locale . '.json'; - $definition = json_decode(file_get_contents($filename), true); - $this->numberFormats[$locale] = $this->createNumberFormatFromDefinition($definition, $locale); - } + $definitions = $this->getDefinitions(); + $availableLocales = array_keys($definitions); + $locale = Locale::resolve($availableLocales, $locale, $this->fallbackLocale); + $definition = $this->processDefinition($locale, $definitions[$locale]); - return $this->numberFormats[$locale]; + return new NumberFormat($definition); } /** - * Creates a number format object from the provided definition. + * Processes the number format definition for the provided locale. * - * @param array $definition The number format definition. - * @param string $locale The locale of the number format definition. + * @param string $locale The locale. + * @param array $definition The definition * - * @return NumberFormat + * @return array The processed definition. */ - protected function createNumberFormatFromDefinition(array $definition, $locale) + protected function processDefinition($locale, array $definition) { - if (!isset($definition['decimal_separator'])) { - $definition['decimal_separator'] = '.'; - } - if (!isset($definition['grouping_separator'])) { - $definition['grouping_separator'] = ','; - } - if (!isset($definition['plus_sign'])) { - $definition['plus_sign'] = '+'; - } - if (!isset($definition['minus_sign'])) { - $definition['minus_sign'] = '-'; - } - if (!isset($definition['percent_sign'])) { - $definition['percent_sign'] = '%'; + $definition['locale'] = $locale; + // The generation script strips all keys that have the same values + // as the ones in 'en'. + if ($definition['locale'] != 'en') { + $definitions = $this->getDefinitions(); + $definition += $definitions['en']; } - $numberFormat = new NumberFormat(); - $setValues = \Closure::bind(function ($definition, $locale) { - $this->locale = $locale; - $this->numberingSystem = $definition['numbering_system']; - $this->decimalSeparator = $definition['decimal_separator']; - $this->groupingSeparator = $definition['grouping_separator']; - $this->plusSign = $definition['plus_sign']; - $this->minusSign = $definition['minus_sign']; - $this->percentSign = $definition['percent_sign']; - $this->decimalPattern = $definition['decimal_pattern']; - $this->percentPattern = $definition['percent_pattern']; - $this->currencyPattern = $definition['currency_pattern']; - $this->accountingCurrencyPattern = $definition['accounting_currency_pattern']; - }, $numberFormat, '\CommerceGuys\Intl\NumberFormat\NumberFormat'); - $setValues($definition, $locale); + return $definition; + } - return $numberFormat; + /** + * Gets the number format definitions. + * + * @return array + * The number format definitions, keyed by locale. + */ + protected function getDefinitions() + { + return [ + 'af' => [ + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'agq' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'ak' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'am' => [], + 'ar' => [ + 'numbering_system' => 'arab', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'ar-DZ' => [ + 'currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '%', + ], + 'ar-EH' => [ + 'currency_pattern' => '¤ #,##0.00', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '%', + ], + 'ar-LY' => [ + 'currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '%', + ], + 'ar-MA' => [ + 'currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '%', + ], + 'ar-TN' => [ + 'currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '%', + ], + 'ast' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'az' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'az-Cyrl' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'bas' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'be' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'bez' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + ], + 'bg' => [ + 'currency_pattern' => '#0.00 ¤', + 'accounting_currency_pattern' => '#0.00 ¤;(#0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'bm' => [], + 'bn' => [ + 'numbering_system' => 'beng', + 'decimal_pattern' => '#,##,##0.###', + 'currency_pattern' => '#,##,##0.00¤', + 'accounting_currency_pattern' => '#,##,##0.00¤;(#,##,##0.00¤)', + ], + 'bo' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'br' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'brx' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤ #,##,##0.00', + 'accounting_currency_pattern' => '¤ #,##,##0.00', + ], + 'bs' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'bs-Cyrl' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ca' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ca-ES-VALENCIA' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ce' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + ], + 'ceb' => [ + 'percent_pattern' => '#,#0%', + ], + 'cgg' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'ckb' => [ + 'numbering_system' => 'arab', + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'cs' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'cu' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'cy' => [], + 'da' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'de' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'de-AT' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'de-CH' => [ + 'currency_pattern' => '¤ #,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'grouping_separator' => '’', + ], + 'de-LI' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'grouping_separator' => '’', + ], + 'dje' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'grouping_separator' => ' ', + ], + 'dsb' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'dyo' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'dz' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0 %', + 'currency_pattern' => '¤#,##,##0.00', + 'accounting_currency_pattern' => '¤#,##,##0.00', + ], + 'ee' => [], + 'el' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en' => [ + 'numbering_system' => 'latn', + 'decimal_pattern' => '#,##0.###', + 'percent_pattern' => '#,##0%', + 'currency_pattern' => '¤#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00;(¤#,##0.00)', + ], + 'en-150' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + ], + 'en-AT' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en-BE' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en-CH' => [ + 'currency_pattern' => '¤ #,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;¤-#,##0.00', + 'grouping_separator' => '’', + ], + 'en-DE' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en-DK' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en-FI' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'en-IN' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤#,##,##0.00', + ], + 'en-NL' => [ + 'currency_pattern' => '¤ #,##0.00;¤ -#,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en-SE' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'en-SI' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'en-ZA' => [ + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'eo' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'es' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-419' => [ + 'percent_pattern' => '#,##0 %', + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'es-AR' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-BO' => [ + 'percent_pattern' => '#,##0 %', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-CL' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-CO' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-CR' => [ + 'percent_pattern' => '#,##0 %', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'es-DO' => [ + 'percent_pattern' => '#,##0 %', + ], + 'es-EC' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-GQ' => [ + 'percent_pattern' => '#,##0 %', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-PE' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'es-PY' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00;¤ -#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-UY' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'es-VE' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'et' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'eu' => [ + 'percent_pattern' => '% #,##0', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'minus_sign' => '−', + ], + 'fa' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤#,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '−', + 'percent_sign' => '٪', + ], + 'fa-AF' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '−', + 'percent_sign' => '٪', + ], + 'ff' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'fi' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'fil' => [], + 'fo' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'minus_sign' => '−', + ], + 'fr' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'fr-CA' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'fr-CH' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'fr-LU' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'fr-MA' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'fur' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'fy' => [ + 'currency_pattern' => '¤ #,##0.00;¤ #,##0.00-', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ga' => [], + 'gd' => [], + 'gl' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'gsw' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'grouping_separator' => '’', + 'minus_sign' => '−', + ], + 'gu' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤#,##,##0.00', + 'accounting_currency_pattern' => '¤#,##,##0.00;(¤#,##,##0.00)', + ], + 'ha' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'haw' => [], + 'he' => [ + 'currency_pattern' => '#,##0.00 ¤;-#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'plus_sign' => '+', + 'minus_sign' => '-', + ], + 'hi' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤#,##,##0.00', + 'accounting_currency_pattern' => '¤#,##,##0.00', + ], + 'hr' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'hsb' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'hu' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'hy' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'id' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ig' => [], + 'is' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'it' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'it-CH' => [ + 'currency_pattern' => '¤ #,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'grouping_separator' => '’', + ], + 'ja' => [], + 'jv' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ka' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'kab' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'kea' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'khq' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'grouping_separator' => ' ', + ], + 'kk' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'km' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤;(#,##0.00¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'kn' => [], + 'ko' => [], + 'kok' => [ + 'currency_pattern' => '¤ #,##0.00', + ], + 'ks' => [ + 'numbering_system' => 'arabext', + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤ #,##,##0.00', + 'accounting_currency_pattern' => '¤ #,##,##0.00', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'ksf' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'ksh' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'ku' => [ + 'percent_pattern' => '%#,##0', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ky' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'lb' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'lg' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + ], + 'lkt' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'lo' => [ + 'currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'lrc' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'lt' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'lu' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'luo' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + ], + 'luy' => [ + 'currency_pattern' => '¤#,##0.00;¤- #,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00;¤- #,##0.00', + ], + 'lv' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'mas' => [], + 'mfe' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'grouping_separator' => ' ', + ], + 'mg' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'mgh' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'mi' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'mk' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ml' => [ + 'decimal_pattern' => '#,##,##0.###', + ], + 'mn' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'mr' => [ + 'numbering_system' => 'deva', + 'decimal_pattern' => '#,##,##0.###', + ], + 'ms' => [], + 'ms-BN' => [ + 'currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'mt' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'mua' => [ + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'my' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'mzn' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'naq' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'nb' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'nds' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'ne' => [ + 'numbering_system' => 'deva', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'nl' => [ + 'currency_pattern' => '¤ #,##0.00;¤ -#,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00;(¤ #,##0.00)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'nn' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'nyn' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'om' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'or' => [ + 'decimal_pattern' => '#,##,##0.###', + ], + 'pa' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤ #,##,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'pa-Arab' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'pl' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'prg' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'pt' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'pt-PT' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'qu' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'qu-BO' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'rm' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'grouping_separator' => '’', + 'minus_sign' => '−', + ], + 'rn' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ro' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'rof' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'ru' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'rw' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'sd' => [ + 'numbering_system' => 'arab', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'se' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'seh' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ses' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'grouping_separator' => ' ', + ], + 'sg' => [ + 'currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'accounting_currency_pattern' => '¤#,##0.00;¤-#,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'si' => [], + 'sk' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'sl' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + 'minus_sign' => '−', + ], + 'smn' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'so' => [], + 'sq' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'sr' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'sr-Latn' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'sv' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + 'minus_sign' => '−', + ], + 'sw' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'sw-CD' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'ta' => [ + 'decimal_pattern' => '#,##,##0.###', + 'percent_pattern' => '#,##,##0%', + 'currency_pattern' => '¤ #,##,##0.00', + ], + 'ta-MY' => [ + 'currency_pattern' => '¤ #,##0.00', + ], + 'ta-SG' => [ + 'currency_pattern' => '¤ #,##0.00', + ], + 'te' => [ + 'decimal_pattern' => '#,##,##0.###', + 'currency_pattern' => '¤#,##,##0.00', + ], + 'tg' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'th' => [], + 'ti' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + ], + 'tk' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'to' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'tr' => [ + 'percent_pattern' => '%#,##0', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'tt' => [ + 'percent_pattern' => '#,##0 %', + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'twq' => [ + 'currency_pattern' => '#,##0.00¤', + 'accounting_currency_pattern' => '#,##0.00¤', + 'grouping_separator' => ' ', + ], + 'tzm' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'ug' => [], + 'uk' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'ur' => [ + 'currency_pattern' => '¤ #,##0.00', + 'plus_sign' => '+', + 'minus_sign' => '-', + ], + 'ur-IN' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤ #,##,##0.00', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + ], + 'uz' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'uz-Arab' => [ + 'numbering_system' => 'arabext', + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => '٫', + 'grouping_separator' => '٬', + 'plus_sign' => '+', + 'minus_sign' => '-', + 'percent_sign' => '٪', + ], + 'uz-Cyrl' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'vi' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'vo' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'wae' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '’', + ], + 'wo' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + 'decimal_separator' => ',', + 'grouping_separator' => '.', + ], + 'xh' => [ + 'accounting_currency_pattern' => '¤#,##0.00', + 'grouping_separator' => ' ', + ], + 'yav' => [ + 'currency_pattern' => '#,##0.00 ¤', + 'accounting_currency_pattern' => '#,##0.00 ¤;(#,##0.00 ¤)', + 'decimal_separator' => ',', + 'grouping_separator' => ' ', + ], + 'yi' => [ + 'currency_pattern' => '¤ #,##0.00', + 'accounting_currency_pattern' => '¤ #,##0.00', + ], + 'yo' => [], + 'yue' => [], + 'yue-Hans' => [], + 'zh' => [], + 'zh-Hant' => [], + 'zu' => [], + ]; } } diff --git a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php b/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php index ff162b522..b8f7facc4 100644 --- a/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php +++ b/vendor/commerceguys/intl/src/NumberFormat/NumberFormatRepositoryInterface.php @@ -8,12 +8,11 @@ namespace CommerceGuys\Intl\NumberFormat; interface NumberFormatRepositoryInterface { /** - * Returns a number format instance for the provided locale. + * Gets a number format for the provided locale. * - * @param string $locale The locale (i.e. fr-FR). - * @param string $fallbackLocale A fallback locale (i.e "en"). + * @param string $locale The locale (i.e. fr-FR). * - * @return NumberFormatInterface + * @return NumberFormat */ - public function get($locale, $fallbackLocale = null); + public function get($locale); } |