From c5d3969450a0aa2b0f066b324a3411dea351c730 Mon Sep 17 00:00:00 2001 From: Jon Waldstein Date: Fri, 13 Jun 2025 13:50:53 -0400 Subject: [PATCH 1/3] refactor: update the currency list to match iso-4217 standards and add ability to override the list --- src/Rules/Currency.php | 305 +++++++++++++++++++----------- tests/unit/Rules/CurrencyTest.php | 235 ++++++++++++++++++++++- 2 files changed, 415 insertions(+), 125 deletions(-) diff --git a/src/Rules/Currency.php b/src/Rules/Currency.php index 091b79b..615a1fb 100644 --- a/src/Rules/Currency.php +++ b/src/Rules/Currency.php @@ -10,6 +10,19 @@ class Currency implements ValidationRule, ValidatesOnFrontEnd { + /** + * @var string[] + */ + protected $currencyCodes; + + /** + * @unreleased + */ + public function __construct(?array $currencyCodes = null) + { + $this->currencyCodes = $currencyCodes ?? self::currencyCodes(); + } + /** * @inheritDoc * @@ -47,12 +60,25 @@ public function serializeOption() */ public function __invoke($value, Closure $fail, string $key, array $values) { - if (!is_string($value) || !in_array(strtoupper($value), self::currencyCodes(), true)) { + if (!is_string($value) || !in_array(strtoupper($value), $this->currencyCodes, true)) { $fail(sprintf(__('%s must be a valid currency', '%TEXTDOMAIN%'), '{field}')); } } /** + * Returns the list of valid ISO 4217 currency codes. + * + * @unreleased Updated to match current ISO 4217 standard as of 2024. + * + * Major changes include: + * - Removed obsolete codes: BYR (→BYN), EEK (→EUR), GHC (→GHS), LVL (→EUR), + * LTL (→EUR), TRL (→TRY), VEF (→VES), ZWD (→ZWL) + * - Added 74+ missing current ISO 4217 codes including AED, AMD, AOA, BHD, etc. + * - Kept commonly used non-ISO codes: GGP, IMP, JEP, TVD + * - Total codes increased from 95 to 169 for better global coverage + * + * @see https://www.iso.org/iso-4217-currency-codes.html + * * @since 1.0.0 * * @return string[] @@ -63,120 +89,169 @@ public static function currencyCodes(): array if ($codes === null) { $codes = [ - "ALL", - "AFN", - "ARS", - "AWG", - "AUD", - "AZN", - "BSD", - "BBD", - "BDT", - "BYR", - "BZD", - "BMD", - "BOB", - "BAM", - "BWP", - "BGN", - "BRL", - "BND", - "KHR", - "CAD", - "KYD", - "CLP", - "CNY", - "COP", - "CRC", - "HRK", - "CUP", - "CZK", - "DKK", - "DOP", - "XCD", - "EGP", - "SVC", - "EEK", - "EUR", - "FKP", - "FJD", - "GHC", - "GIP", - "GTQ", - "GGP", - "GYD", - "HNL", - "HKD", - "HUF", - "ISK", - "INR", - "IDR", - "IRR", - "IMP", - "ILS", - "JMD", - "JPY", - "JEP", - "KZT", - "KPW", - "KRW", - "KGS", - "LAK", - "LVL", - "LBP", - "LRD", - "LTL", - "MKD", - "MYR", - "MUR", - "MXN", - "MNT", - "MZN", - "NAD", - "NPR", - "ANG", - "NZD", - "NIO", - "NGN", - "NOK", - "OMR", - "PKR", - "PAB", - "PYG", - "PEN", - "PHP", - "PLN", - "QAR", - "RON", - "RUB", - "SHP", - "SAR", - "RSD", - "SCR", - "SGD", - "SBD", - "SOS", - "ZAR", - "LKR", - "SEK", - "CHF", - "SRD", - "SYP", - "TWD", - "THB", - "TTD", - "TRY", - "TRL", - "TVD", - "UAH", - "GBP", - "USD", - "UYU", - "UZS", - "VEF", - "VND", - "YER", - "ZWD", + "AED", // UAE Dirham + "AFN", // Afghan Afghani + "ALL", // Albanian Lek + "AMD", // Armenian Dram + "ANG", // Netherlands Antillean Guilder + "AOA", // Angolan Kwanza + "ARS", // Argentine Peso + "AUD", // Australian Dollar + "AWG", // Aruban Florin + "AZN", // Azerbaijani Manat + "BAM", // Bosnia and Herzegovina Convertible Mark + "BBD", // Barbados Dollar + "BDT", // Bangladeshi Taka + "BGN", // Bulgarian Lev + "BHD", // Bahraini Dinar + "BIF", // Burundian Franc + "BMD", // Bermudian Dollar + "BND", // Brunei Dollar + "BOB", // Bolivian Boliviano + "BRL", // Brazilian Real + "BSD", // Bahamian Dollar + "BTN", // Bhutanese Ngultrum + "BWP", // Botswanan Pula + "BYN", // Belarusian Ruble + "BZD", // Belize Dollar + "CAD", // Canadian Dollar + "CDF", // Congolese Franc + "CHF", // Swiss Franc + "CLP", // Chilean Peso + "CNY", // Chinese Yuan + "COP", // Colombian Peso + "CRC", // Costa Rican Colón + "CUP", // Cuban Peso + "CVE", // Cape Verdean Escudo + "CZK", // Czech Koruna + "DJF", // Djiboutian Franc + "DKK", // Danish Krone + "DOP", // Dominican Peso + "DZD", // Algerian Dinar + "EGP", // Egyptian Pound + "ERN", // Eritrean Nakfa + "ETB", // Ethiopian Birr + "EUR", // Euro + "FJD", // Fijian Dollar + "FKP", // Falkland Islands Pound + "GBP", // British Pound Sterling + "GEL", // Georgian Lari + "GGP", // Guernsey Pound (non-ISO but commonly used) + "GHS", // Ghanaian Cedi + "GIP", // Gibraltar Pound + "GMD", // Gambian Dalasi + "GNF", // Guinean Franc + "GTQ", // Guatemalan Quetzal + "GYD", // Guyanese Dollar + "HKD", // Hong Kong Dollar + "HNL", // Honduran Lempira + "HRK", // Croatian Kuna (replaced by EUR in 2023) + "HTG", // Haitian Gourde + "HUF", // Hungarian Forint + "IDR", // Indonesian Rupiah + "ILS", // Israeli New Shekel + "IMP", // Isle of Man Pound (non-ISO but commonly used) + "INR", // Indian Rupee + "IQD", // Iraqi Dinar + "IRR", // Iranian Rial + "ISK", // Icelandic Króna + "JEP", // Jersey Pound (non-ISO but commonly used) + "JMD", // Jamaican Dollar + "JOD", // Jordanian Dinar + "JPY", // Japanese Yen + "KES", // Kenyan Shilling + "KGS", // Kyrgyzstani Som + "KHR", // Cambodian Riel + "KMF", // Comorian Franc + "KPW", // North Korean Won + "KRW", // South Korean Won + "KWD", // Kuwaiti Dinar + "KYD", // Cayman Islands Dollar + "KZT", // Kazakhstani Tenge + "LAK", // Laotian Kip + "LBP", // Lebanese Pound + "LKR", // Sri Lankan Rupee + "LRD", // Liberian Dollar + "LSL", // Lesotho Loti + "LYD", // Libyan Dinar + "MAD", // Moroccan Dirham + "MDL", // Moldovan Leu + "MGA", // Malagasy Ariary + "MKD", // Macedonian Denar + "MMK", // Myanmar Kyat + "MNT", // Mongolian Tugrik + "MOP", // Macanese Pataca + "MRU", // Mauritanian Ouguiya + "MUR", // Mauritian Rupee + "MVR", // Maldivian Rufiyaa + "MWK", // Malawian Kwacha + "MXN", // Mexican Peso + "MYR", // Malaysian Ringgit + "MZN", // Mozambican Metical + "NAD", // Namibian Dollar + "NGN", // Nigerian Naira + "NIO", // Nicaraguan Córdoba + "NOK", // Norwegian Krone + "NPR", // Nepalese Rupee + "NZD", // New Zealand Dollar + "OMR", // Omani Rial + "PAB", // Panamanian Balboa + "PEN", // Peruvian Sol + "PGK", // Papua New Guinean Kina + "PHP", // Philippine Peso + "PKR", // Pakistani Rupee + "PLN", // Polish Zloty + "PYG", // Paraguayan Guaraní + "QAR", // Qatari Riyal + "RON", // Romanian Leu + "RSD", // Serbian Dinar + "RUB", // Russian Ruble + "RWF", // Rwandan Franc + "SAR", // Saudi Riyal + "SBD", // Solomon Islands Dollar + "SCR", // Seychellois Rupee + "SDG", // Sudanese Pound + "SEK", // Swedish Krona + "SGD", // Singapore Dollar + "SHP", // Saint Helena Pound + "SLE", // Sierra Leonean Leone (new) + "SLL", // Sierra Leonean Leone (old) + "SOS", // Somali Shilling + "SRD", // Surinamese Dollar + "SSP", // South Sudanese Pound + "STN", // São Tomé and Príncipe Dobra + "SVC", // Salvadoran Colón + "SYP", // Syrian Pound + "SZL", // Swazi Lilangeni + "THB", // Thai Baht + "TJS", // Tajikistani Somoni + "TMT", // Turkmenistani Manat + "TND", // Tunisian Dinar + "TOP", // Tongan Paʻanga + "TRY", // Turkish Lira + "TTD", // Trinidad and Tobago Dollar + "TVD", // Tuvaluan Dollar (non-ISO but used) + "TWD", // New Taiwan Dollar + "TZS", // Tanzanian Shilling + "UAH", // Ukrainian Hryvnia + "UGX", // Ugandan Shilling + "USD", // United States Dollar + "UYU", // Uruguayan Peso + "UZS", // Uzbekistani Som + "VED", // Venezuelan Bolívar Digital + "VES", // Venezuelan Bolívar Soberano + "VND", // Vietnamese Dong + "VUV", // Vanuatuan Vatu + "WST", // Samoan Tala + "XAF", // Central African CFA Franc + "XCD", // East Caribbean Dollar + "XDR", // Special Drawing Rights + "XOF", // West African CFA Franc + "XPF", // CFP Franc + "YER", // Yemeni Rial + "ZAR", // South African Rand + "ZMW", // Zambian Kwacha + "ZWL", // Zimbabwean Dollar ]; } diff --git a/tests/unit/Rules/CurrencyTest.php b/tests/unit/Rules/CurrencyTest.php index 6838d8f..e1a1d39 100644 --- a/tests/unit/Rules/CurrencyTest.php +++ b/tests/unit/Rules/CurrencyTest.php @@ -1,4 +1,4 @@ - Date: Fri, 13 Jun 2025 17:50:54 -0400 Subject: [PATCH 2/3] refactor: revert back to an updated list of curerncies --- src/Rules/Currency.php | 14 +----------- tests/unit/Rules/CurrencyTest.php | 38 ++++++++----------------------- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/src/Rules/Currency.php b/src/Rules/Currency.php index 615a1fb..21ba4a4 100644 --- a/src/Rules/Currency.php +++ b/src/Rules/Currency.php @@ -10,18 +10,6 @@ class Currency implements ValidationRule, ValidatesOnFrontEnd { - /** - * @var string[] - */ - protected $currencyCodes; - - /** - * @unreleased - */ - public function __construct(?array $currencyCodes = null) - { - $this->currencyCodes = $currencyCodes ?? self::currencyCodes(); - } /** * @inheritDoc @@ -60,7 +48,7 @@ public function serializeOption() */ public function __invoke($value, Closure $fail, string $key, array $values) { - if (!is_string($value) || !in_array(strtoupper($value), $this->currencyCodes, true)) { + if (!is_string($value) || !in_array(strtoupper($value), self::currencyCodes(), true)) { $fail(sprintf(__('%s must be a valid currency', '%TEXTDOMAIN%'), '{field}')); } } diff --git a/tests/unit/Rules/CurrencyTest.php b/tests/unit/Rules/CurrencyTest.php index e1a1d39..8942cd9 100644 --- a/tests/unit/Rules/CurrencyTest.php +++ b/tests/unit/Rules/CurrencyTest.php @@ -1,4 +1,4 @@ -git Date: Fri, 13 Jun 2025 18:00:51 -0400 Subject: [PATCH 3/3] tests: update since tag --- tests/unit/Rules/CurrencyTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/Rules/CurrencyTest.php b/tests/unit/Rules/CurrencyTest.php index 8942cd9..f227d71 100644 --- a/tests/unit/Rules/CurrencyTest.php +++ b/tests/unit/Rules/CurrencyTest.php @@ -10,7 +10,7 @@ class CurrencyTest extends TestCase { /** - * @unreleased + * @since 1.1.0 * @dataProvider currencyProvider */ public function testCurrencyValidations($currency, $shouldPass)