* * For the full copyright and license information, please view the "LICENSE.md" * file that was distributed with this source code. */ declare(strict_types=1); namespace Respect\Validation\Rules; use Respect\Validation\Exceptions\ComponentException; use function array_column; use function array_keys; use function implode; use function sprintf; /** * Validates whether the input is a country code in ISO 3166-1 standard. * * This rule supports the three sets of country codes (alpha-2, alpha-3, and numeric). * * @author Alexandre Gomes Gaigalas * @author Felipe Martins * @author Henrique Moody * @author William Espindola */ final class CountryCode extends AbstractSearcher { /** * The ISO representation of a country code. * */ public const ALPHA2 = 'alpha-2'; /** * The ISO3 representation of a country code. * */ public const ALPHA3 = 'alpha-3'; /** * The ISO-number representation of a country code. * */ public const NUMERIC = 'numeric'; /** * Position of the indexes of each set in the list of country codes. * */ private const SET_INDEXES = [ self::ALPHA2 => 0, self::ALPHA3 => 1, self::NUMERIC => 2, ]; /** * @see http://download.geonames.org/export/dump/countryInfo.txt * */ private const COUNTRY_CODES = [ ['AD', 'AND', '020'], // Andorra ['AE', 'ARE', '784'], // United Arab Emirates ['AF', 'AFG', '004'], // Afghanistan ['AG', 'ATG', '028'], // Antigua and Barbuda ['AI', 'AIA', '660'], // Anguilla ['AL', 'ALB', '008'], // Albania ['AM', 'ARM', '051'], // Armenia ['AN', 'ANT', '530'], // Netherlands Antilles ['AO', 'AGO', '024'], // Angola ['AQ', 'ATA', '010'], // Antarctica ['AR', 'ARG', '032'], // Argentina ['AS', 'ASM', '016'], // American Samoa ['AT', 'AUT', '040'], // Austria ['AU', 'AUS', '036'], // Australia ['AW', 'ABW', '533'], // Aruba ['AX', 'ALA', '248'], // Aland Islands ['AZ', 'AZE', '031'], // Azerbaijan ['BA', 'BIH', '070'], // Bosnia and Herzegovina ['BB', 'BRB', '052'], // Barbados ['BD', 'BGD', '050'], // Bangladesh ['BE', 'BEL', '056'], // Belgium ['BF', 'BFA', '854'], // Burkina Faso ['BG', 'BGR', '100'], // Bulgaria ['BH', 'BHR', '048'], // Bahrain ['BI', 'BDI', '108'], // Burundi ['BJ', 'BEN', '204'], // Benin ['BL', 'BLM', '652'], // Saint Barthelemy ['BM', 'BMU', '060'], // Bermuda ['BN', 'BRN', '096'], // Brunei ['BO', 'BOL', '068'], // Bolivia ['BQ', 'BES', '535'], // Bonaire, Saint Eustatius and Saba ['BR', 'BRA', '076'], // Brazil ['BS', 'BHS', '044'], // Bahamas ['BT', 'BTN', '064'], // Bhutan ['BV', 'BVT', '074'], // Bouvet Island ['BW', 'BWA', '072'], // Botswana ['BY', 'BLR', '112'], // Belarus ['BZ', 'BLZ', '084'], // Belize ['CA', 'CAN', '124'], // Canada ['CC', 'CCK', '166'], // Cocos Islands ['CD', 'COD', '180'], // Democratic Republic of the Congo ['CF', 'CAF', '140'], // Central African Republic ['CG', 'COG', '178'], // Republic of the Congo ['CH', 'CHE', '756'], // Switzerland ['CI', 'CIV', '384'], // Ivory Coast ['CK', 'COK', '184'], // Cook Islands ['CL', 'CHL', '152'], // Chile ['CM', 'CMR', '120'], // Cameroon ['CN', 'CHN', '156'], // China ['CO', 'COL', '170'], // Colombia ['CR', 'CRI', '188'], // Costa Rica ['CS', 'SCG', '891'], // Serbia and Montenegro ['CU', 'CUB', '192'], // Cuba ['CV', 'CPV', '132'], // Cape Verde ['CW', 'CUW', '531'], // Curacao ['CX', 'CXR', '162'], // Christmas Island ['CY', 'CYP', '196'], // Cyprus ['CZ', 'CZE', '203'], // Czech Republic ['DE', 'DEU', '276'], // Germany ['DJ', 'DJI', '262'], // Djibouti ['DK', 'DNK', '208'], // Denmark ['DM', 'DMA', '212'], // Dominica ['DO', 'DOM', '214'], // Dominican Republic ['DZ', 'DZA', '012'], // Algeria ['EC', 'ECU', '218'], // Ecuador ['EE', 'EST', '233'], // Estonia ['EG', 'EGY', '818'], // Egypt ['EH', 'ESH', '732'], // Western Sahara ['ER', 'ERI', '232'], // Eritrea ['ES', 'ESP', '724'], // Spain ['ET', 'ETH', '231'], // Ethiopia ['FI', 'FIN', '246'], // Finland ['FJ', 'FJI', '242'], // Fiji ['FK', 'FLK', '238'], // Falkland Islands ['FM', 'FSM', '583'], // Micronesia ['FO', 'FRO', '234'], // Faroe Islands ['FR', 'FRA', '250'], // France ['GA', 'GAB', '266'], // Gabon ['GB', 'GBR', '826'], // United Kingdom ['GD', 'GRD', '308'], // Grenada ['GE', 'GEO', '268'], // Georgia ['GF', 'GUF', '254'], // French Guiana ['GG', 'GGY', '831'], // Guernsey ['GH', 'GHA', '288'], // Ghana ['GI', 'GIB', '292'], // Gibraltar ['GL', 'GRL', '304'], // Greenland ['GM', 'GMB', '270'], // Gambia ['GN', 'GIN', '324'], // Guinea ['GP', 'GLP', '312'], // Guadeloupe ['GQ', 'GNQ', '226'], // Equatorial Guinea ['GR', 'GRC', '300'], // Greece ['GS', 'SGS', '239'], // South Georgia and the South Sandwich Islands ['GT', 'GTM', '320'], // Guatemala ['GU', 'GUM', '316'], // Guam ['GW', 'GNB', '624'], // Guinea-Bissau ['GY', 'GUY', '328'], // Guyana ['HK', 'HKG', '344'], // Hong Kong ['HM', 'HMD', '334'], // Heard Island and McDonald Islands ['HN', 'HND', '340'], // Honduras ['HR', 'HRV', '191'], // Croatia ['HT', 'HTI', '332'], // Haiti ['HU', 'HUN', '348'], // Hungary ['ID', 'IDN', '360'], // Indonesia ['IE', 'IRL', '372'], // Ireland ['IL', 'ISR', '376'], // Israel ['IM', 'IMN', '833'], // Isle of Man ['IN', 'IND', '356'], // India ['IO', 'IOT', '086'], // British Indian Ocean Territory ['IQ', 'IRQ', '368'], // Iraq ['IR', 'IRN', '364'], // Iran ['IS', 'ISL', '352'], // Iceland ['IT', 'ITA', '380'], // Italy ['JE', 'JEY', '832'], // Jersey ['JM', 'JAM', '388'], // Jamaica ['JO', 'JOR', '400'], // Jordan ['JP', 'JPN', '392'], // Japan ['KE', 'KEN', '404'], // Kenya ['KG', 'KGZ', '417'], // Kyrgyzstan ['KH', 'KHM', '116'], // Cambodia ['KI', 'KIR', '296'], // Kiribati ['KM', 'COM', '174'], // Comoros ['KN', 'KNA', '659'], // Saint Kitts and Nevis ['KP', 'PRK', '408'], // North Korea ['KR', 'KOR', '410'], // South Korea ['KW', 'KWT', '414'], // Kuwait ['KY', 'CYM', '136'], // Cayman Islands ['KZ', 'KAZ', '398'], // Kazakhstan ['LA', 'LAO', '418'], // Laos ['LB', 'LBN', '422'], // Lebanon ['LC', 'LCA', '662'], // Saint Lucia ['LI', 'LIE', '438'], // Liechtenstein ['LK', 'LKA', '144'], // Sri Lanka ['LR', 'LBR', '430'], // Liberia ['LS', 'LSO', '426'], // Lesotho ['LT', 'LTU', '440'], // Lithuania ['LU', 'LUX', '442'], // Luxembourg ['LV', 'LVA', '428'], // Latvia ['LY', 'LBY', '434'], // Libya ['MA', 'MAR', '504'], // Morocco ['MC', 'MCO', '492'], // Monaco ['MD', 'MDA', '498'], // Moldova ['ME', 'MNE', '499'], // Montenegro ['MF', 'MAF', '663'], // Saint Martin ['MG', 'MDG', '450'], // Madagascar ['MH', 'MHL', '584'], // Marshall Islands ['MK', 'MKD', '807'], // Macedonia ['ML', 'MLI', '466'], // Mali ['MM', 'MMR', '104'], // Myanmar ['MN', 'MNG', '496'], // Mongolia ['MO', 'MAC', '446'], // Macao ['MP', 'MNP', '580'], // Northern Mariana Islands ['MQ', 'MTQ', '474'], // Martinique ['MR', 'MRT', '478'], // Mauritania ['MS', 'MSR', '500'], // Montserrat ['MT', 'MLT', '470'], // Malta ['MU', 'MUS', '480'], // Mauritius ['MV', 'MDV', '462'], // Maldives ['MW', 'MWI', '454'], // Malawi ['MX', 'MEX', '484'], // Mexico ['MY', 'MYS', '458'], // Malaysia ['MZ', 'MOZ', '508'], // Mozambique ['NA', 'NAM', '516'], // Namibia ['NC', 'NCL', '540'], // New Caledonia ['NE', 'NER', '562'], // Niger ['NF', 'NFK', '574'], // Norfolk Island ['NG', 'NGA', '566'], // Nigeria ['NI', 'NIC', '558'], // Nicaragua ['NL', 'NLD', '528'], // Netherlands ['NO', 'NOR', '578'], // Norway ['NP', 'NPL', '524'], // Nepal ['NR', 'NRU', '520'], // Nauru ['NU', 'NIU', '570'], // Niue ['NZ', 'NZL', '554'], // New Zealand ['OM', 'OMN', '512'], // Oman ['PA', 'PAN', '591'], // Panama ['PE', 'PER', '604'], // Peru ['PF', 'PYF', '258'], // French Polynesia ['PG', 'PNG', '598'], // Papua New Guinea ['PH', 'PHL', '608'], // Philippines ['PK', 'PAK', '586'], // Pakistan ['PL', 'POL', '616'], // Poland ['PM', 'SPM', '666'], // Saint Pierre and Miquelon ['PN', 'PCN', '612'], // Pitcairn ['PR', 'PRI', '630'], // Puerto Rico ['PS', 'PSE', '275'], // Palestinian Territory ['PT', 'PRT', '620'], // Portugal ['PW', 'PLW', '585'], // Palau ['PY', 'PRY', '600'], // Paraguay ['QA', 'QAT', '634'], // Qatar ['RE', 'REU', '638'], // Reunion ['RO', 'ROU', '642'], // Romania ['RS', 'SRB', '688'], // Serbia ['RU', 'RUS', '643'], // Russia ['RW', 'RWA', '646'], // Rwanda ['SA', 'SAU', '682'], // Saudi Arabia ['SB', 'SLB', '090'], // Solomon Islands ['SC', 'SYC', '690'], // Seychelles ['SD', 'SDN', '729'], // Sudan ['SE', 'SWE', '752'], // Sweden ['SG', 'SGP', '702'], // Singapore ['SH', 'SHN', '654'], // Saint Helena ['SI', 'SVN', '705'], // Slovenia ['SJ', 'SJM', '744'], // Svalbard and Jan Mayen ['SK', 'SVK', '703'], // Slovakia ['SL', 'SLE', '694'], // Sierra Leone ['SM', 'SMR', '674'], // San Marino ['SN', 'SEN', '686'], // Senegal ['SO', 'SOM', '706'], // Somalia ['SR', 'SUR', '740'], // Suriname ['SS', 'SSD', '728'], // South Sudan ['ST', 'STP', '678'], // Sao Tome and Principe ['SV', 'SLV', '222'], // El Salvador ['SX', 'SXM', '534'], // Sint Maarten ['SY', 'SYR', '760'], // Syria ['SZ', 'SWZ', '748'], // Swaziland ['TC', 'TCA', '796'], // Turks and Caicos Islands ['TD', 'TCD', '148'], // Chad ['TF', 'ATF', '260'], // French Southern Territories ['TG', 'TGO', '768'], // Togo ['TH', 'THA', '764'], // Thailand ['TJ', 'TJK', '762'], // Tajikistan ['TK', 'TKL', '772'], // Tokelau ['TL', 'TLS', '626'], // East Timor ['TM', 'TKM', '795'], // Turkmenistan ['TN', 'TUN', '788'], // Tunisia ['TO', 'TON', '776'], // Tonga ['TR', 'TUR', '792'], // Turkey ['TT', 'TTO', '780'], // Trinidad and Tobago ['TV', 'TUV', '798'], // Tuvalu ['TW', 'TWN', '158'], // Taiwan ['TZ', 'TZA', '834'], // Tanzania ['UA', 'UKR', '804'], // Ukraine ['UG', 'UGA', '800'], // Uganda ['UM', 'UMI', '581'], // United States Minor Outlying Islands ['US', 'USA', '840'], // United States ['UY', 'URY', '858'], // Uruguay ['UZ', 'UZB', '860'], // Uzbekistan ['VA', 'VAT', '336'], // Vatican ['VC', 'VCT', '670'], // Saint Vincent and the Grenadines ['VE', 'VEN', '862'], // Venezuela ['VG', 'VGB', '092'], // British Virgin Islands ['VI', 'VIR', '850'], // U.S. Virgin Islands ['VN', 'VNM', '704'], // Vietnam ['VU', 'VUT', '548'], // Vanuatu ['WF', 'WLF', '876'], // Wallis and Futuna ['WS', 'WSM', '882'], // Samoa ['XK', 'XKX', '0'], // Kosovo ['YE', 'YEM', '887'], // Yemen ['YT', 'MYT', '175'], // Mayotte ['ZA', 'ZAF', '710'], // South Africa ['ZM', 'ZMB', '894'], // Zambia ['ZW', 'ZWE', '716'], // Zimbabwe ]; /** * @var string */ private $set; /** * Initializes the rule. * * @throws ComponentException If $set is not a valid set */ public function __construct(string $set = self::ALPHA2) { if (!isset(self::SET_INDEXES[$set])) { throw new ComponentException( sprintf( '"%s" is not a valid set for ISO 3166-1 (Available: %s)', $set, implode(', ', array_keys(self::SET_INDEXES)) ) ); } $this->set = $set; } /** * {@inheritDoc} */ protected function getDataSource(): array { return array_column(self::COUNTRY_CODES, self::SET_INDEXES[$this->set]); } }