Passed
Push — master ( 69e8b8...9399e3 )
by Joe
03:24
created

Validator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 324
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Test Coverage

Coverage 69.23%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 12
c 4
b 0
f 0
lcom 2
cbo 1
dl 0
loc 324
ccs 18
cts 26
cp 0.6923
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
B isValid() 0 19 5
A getFormats() 0 7 2
A hasCountry() 0 3 1
A getFormatPattern() 0 11 2
A getZipName() 0 7 2
1
<?php
2
/*
3
 * This file is part of the postal-code-validator package
4
 *
5
 * @author Joe Huss <[email protected]>
6
 */
7
8
namespace Detain\ZipZapper;
9
10
/**
11
 * Validator.
12
 *
13
 * @author Joe Huss <[email protected]>
14
 */
15
class Validator {
0 ignored issues
show
Coding Style introduced by
The property $zip_names is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
16
	protected $zip_names = array(
17
		'BR' => array('name' => 'CEP', 'acronym_text' => 'Código de endereçamento postal (Postal Addressing Code)'),
18
		'CA' => array('name' => 'Postal Code', 'acronym_text' => ''),
19
		'CH' => array('name' => 'NPA', 'acronym_text' => "numéro postal d'acheminement in French-speaking Switzerland and numéro postal d'acheminement in Italian-speaking Switzerland"),
20
		'DE' => array('name' => 'PLZ', 'acronym_text' => 'Postleitzahl (Postal Routing Number)'),
21
		'IE' => array('name' => 'Eircode', 'acronym_text' => ''),
22
		'IN' => array('name' => 'PIN code', 'acronym_text' => 'postal index number.'),
23
		'IT' => array('name' => 'CAP', 'acronym_text' => 'Codice di Avviamento Postale (Postal Expedition Code)'),
24
		'NL' => array('name' => 'Postcode', 'acronym_text' => ''),
25
		'US' => array('name' => 'ZIP code', 'acronym_text' => 'Zone Improvement Plan'),
26
	);
27
28
	/*
29
	 * country code: ISO 3166 2-letter code
30
	 * format:
31
	 *     # - numberic 0-9
32
	 *     @ - alpha a-zA-Z
33
	 */
34
	protected $formats = array(
35
		'AD' => array('CC###'), // Andorra, Notes: Each Parishes of Andorra|parish now has its own post code.
36
		'AE' => array(), // United Arab Emirates
37
		'AF' => array('####'), // Afghanistan, Notes: The first two digits (ranging from 10–43) correspond to the province, while the last two digits correspond either to the city/delivery zone (range 01–50) or to the district/delivery zone (range 51–99). (http://postalcode.afghanpost.gov.af/ Afghanistan Postal code lookup)
38
		'AG' => array(), // Antigua and Barbuda
39
		'AI' => array('@I-2640'), // Anguilla, Notes: Single code used for all addresses.
40
		'AL' => array('####'), // Albania, Notes: Introduced in 2006, gradually implemented throughout 2007.
41
		'AM' => array('####'), // Armenia, Notes: Previously used '''NNNNNN''' system inherited from former Soviet Union.
42
		'AO' => array(), // Angola
43
		'AQ' => array('BIQQ 1ZZ'), // British Antarctic Territory, Notes: One code for all addresses (AAAA NAA). UK territory, but not UK postcode.
44
		'AR' => array('####', '@####@@@'), // Argentina, Notes: 1974-1998 NNNN, and from 1999 ANNNNAAA. Codigo Postal Argentino (CPA), where the first A is the province code as in ISO 3166-2:AR, the four numbers are the old postal codes, the three last letters indicate a side of the block. Previously '''NNNN''' which is the minimum requirement as of 2006.
45
		'AS' => array('#####', '#####-####'), // American Samoa, Notes: U.S. ZIP codes (range '''96799''')
46
		'AT' => array('####'), // Austria, Notes: The first digit denotes regions, which are partly identical to one of the nine provinces—called ''Bundesländer''; the last the nearest post office in the area.
47
		'AU' => array('####'), // Australia, Notes: In general, the first digit identifies the state or territory.
48
		'AW' => array(), // Aruba
49
		'AX' => array('#####', 'CC-#####'), // Åland Islands, Notes: With Finland, first two numbers are 22. CC-NNNNN used from abroad
50
		'AZ' => array('CC####'), // Azerbaijan, Notes: Previously used '''NNNNNN''' system inherited from former Soviet Union.
51
		'BA' => array('#####'), // Bosnia and Herzegovina
52
		'BB' => array('CC#####'), // Barbados, Notes: Only one postal code currently assigned. '''11000''' applies to the General Post Office building in Cheapside, Bridgetown, to enable delivery to Barbados by global package delivery companies whose software requires a postal code.
53
		'BD' => array('####'), // | List of postal codes in Bangladesh|Bangladesh
54
		'BE' => array('####'), // Belgium, Notes: In general, the first digit gives the province.
55
		'BF' => array(), // Burkina Faso
56
		'BG' => array('####'), // Bulgaria
57
		'BH' => array('###', '####'), // Bahrain, Notes: Valid post code numbers are '''101''' to '''1216''' with gaps in the range. Known as ''block number'' ({{lang-ar|رقم المجمع}}) formally. The first digit in NNN format and the first two digits in NNNN format refer to one of the 12 municipalities of the country. PO Box address doesn't need a block number or city name, just the PO Box number followed by the name of the country, Bahrain.
58
		'BI' => array(), // Burundi
59
		'BJ' => array(), // Benin
60
		'BL' => array('97133'), // Saint Barthélemy, Notes: Overseas Collectivity of France. French codes used.
61
		'BM' => array('@@ ##', '@@ @@'), // Bermuda, Notes: AA NN for street addresses, AA AA for P.O. Box addresses. The second half of the postcode identifies the street delivery walk (e.g.: Hamilton HM 12) or the PO Box number range (e.g.: Hamilton HM BX).  See Postal codes in Bermuda.
62
		'BN' => array('@@####'), // Brunei
63
		'BO' => array(), // Bolivia
64
		'BQ' => array(), // Bonaire, Sint Eustatius and Saba
65
		'BR' => array('#####-###'), // Brazil, Notes: NNNNN only from 1971 to 1992. Código de Endereçamento Postal (CEP): -000 to -899 are used for streets, roads, avenues, boulevards; -900 to -959 are used for buildings with a high postal use; -960 to -969 are for promotional use; -970 to -989 are post offices and regular P.O. boxes; and -990 to -998 are used for community P.O. boxes. -999 is used for special services.
66
		'BS' => array(), // Bahamas
67
		'BT' => array('#####'), // Bhutan
68
		'BV' => array(), // Bouvet Island
69
		'BW' => array(), // Botswana
70
		'BY' => array('######'), // Belarus, Notes: Retained system inherited from former Soviet Union.
71
		'BZ' => array(), // Belize
72
		'CA' => array('@#@ #@#'), // Canada, Notes: The system was gradually introduced starting in April 1971 in Ottawa. The letters D, F, I, O, Q, and U are not used to avoid confusion with other letters or numbers.
73
		'CC' => array('####'), // Cocos (Keeling) Island, Notes: Part of the Australian postal code system.
74
		'CD' => array(), // Congo, Democratic Republic
75
		'CF' => array(), // Central African Republic
76
		'CG' => array(), // Congo (Brazzaville)
77
		'CH' => array('####'), // Switzerland, Notes: With Liechtenstein, ordered from west to east. In Geneva and other big cities, like Basel, Bern, Zurich, there may be one or two digits after the name of the city when the generic City code (1211) is used instead of the area-specific code (1201, 1202...), e.g.: 1211 Geneva 13. The digit identifies the post office. This addressing is generally used for P.O. box deliveries. Büsingen (Germany) and Campione (Italy) have also a Swiss postal code.
78
		'CI' => array(), // Côte d'Ivoire (Ivory Coast)
79
		'CK' => array(), // Cook Islands
80
		'CL' => array('#######', '###-####'), // Chile, Notes: May only be required for bulk mail.
81
		'CM' => array(), // Cameroon
82
		'CN' => array('######'), // China, Notes: A postal code or ''youbian'' (邮编) in a subordinate division will have the same first two digits as its governing one (see Administrative divisions of the People's Republic of China#Levels|Political divisions of China. The postal services in Macau or Hong Kong Special Administrative Region of the People's Republic of China|Special Administrative Regions remain separate from Mainland China, with no post code system currently used.
83
		'CO' => array('######'), // Colombia, Notes: First NN = 32 departments of Colombia|departments&lt;ref&gt;{{cite web|url=http://english.4-72.com.co/?q=content/postal-codes |title=Postal Codes |publisher=Colombian Postal Network 4-72 |accessdate=2010-03-04 }}&lt;/ref&gt; [http://www.codigopostal4-72.com.co/codigosPostales/ Códigos Postales | 4-72]
84
		'CR' => array('#####', '#####-####'), // Costa Rica, Notes: Was NNNN until 2007. First codes the provinces, next two the canton, last two the district.
85
		'CU' => array('#####'), // Cuba, Notes: May only be required for bulk mail. The letters CP are frequently used before the postal code. This is not a country code, but an abbreviation for &quot;codigo postal&quot; or postal code.
86
		'CV' => array('####'), // Cape Verde, Notes: The first digit indicates the island.
87
		'CW' => array(), // Curaçao
88
		'CX' => array('####'), // Christmas Island, Notes: Part of the Australian postal code system.
89
		'CY' => array('####'), // Cyprus, Notes: The postal code system covers the whole island, but is not used on mail to Northern Cyprus. Northern Cyprus uses a 5-digit code commencing 99, introduced in 2013. For mail sent there from abroad, the line &quot;Mersin 10&quot; is written on the line above that containing the postal code, and the country name used is &quot;Turkey&quot;.
90
		'CZ' => array('### ##'), // Czech Republic, Notes: With Slovak Republic, Poštovní směrovací číslo (PSČ) - postal routing number.
91
		'DE' => array('#####'), // Germany, Notes: Known as Postleitzahl (PLZ), introduced after the German reunification. Between 1989 and 1993 the old separate 4-digit postal codes of former West-Germany|West- and East-Germany were distinguished by preceding &quot;W-&quot; ('West') or &quot;O-&quot; ({{lang|de|'Ost'}} for East).
92
		'DJ' => array(), // Djibouti
93
		'DK' => array('####'), // Denmark, Notes: Numbering follows the dispatch of postal trains from Copenhagen.&lt;ref&gt;http://www.denstoredanske.dk/It,_teknik_og_naturvidenskab/Elektronik,_teletrafik_og_kommunikation/Postforsendelser/postnummer?highlight=postnummer&lt;/ref&gt; Also used by Greenland, e.g.: Nuuk|DK-3900 Nuuk.
94
		'DM' => array(), // Dominica
95
		'DO' => array('#####'), // Dominican Republic
96
		'DZ' => array('#####'), // Algeria, Notes: First two as in ISO 3166-2:DZ
97
		'EC' => array('######'), // Ecuador
98
		'EE' => array('#####'), // Estonia
99
		'EG' => array('#####'), // Egypt
100
		'EH' => array(), // Western Sahara
101
		'ER' => array(), // Eritrea
102
		'ES' => array('#####'), // Spain, Notes: First two indicate the province, range 01-52
103
		'ET' => array('####'), // Ethiopia, Notes: The code is only used on a trial basis for Addis Ababa addresses.
104
		'FI' => array('#####'), // Finland, Notes: A lower first digit indicates a place in south (for example 00100 Helsinki), a higher indicates a place further to north (99800 in Ivalo). The last digit is usually 0, except for postal codes for PO Box number ranges, in which case it is 1. Country code for Finland: &quot;FI&quot;. In the Åland Islands, the postal code is prefixed with &quot;AX&quot;, not &quot;FI&quot;. Some postal codes for rural settlements may end with 5, and there are some unique postal codes for large companies and institutions, e.g. 00014 HELSINGIN YLIOPISTO (university), 00102 EDUSKUNTA (parliament), 00020 NORDEA (a major Scandinavian bank).
105
		'FJ' => array(), // Fiji
106
		'FK' => array('FIQQ 1ZZ'), // Falkland Islands, Notes: Single code (AAAA NAA). UK territory, but not UK postcode
107
		'FM' => array('#####', '#####-####'), // Micronesia, Notes: U.S. ZIP codes. Range '''96941''' - '''96944'''.
108
		'FO' => array('###'), // Faroe Islands, Notes: Self-governing territory within the Kingdom of Denmark, but not Danish postcode.
109
		'FR' => array('#####'), // France, Notes: The first two digits give the ''département in France|département'' number, while in Paris, Lyon and Marseille, the last two digits of the postal code indicates the Municipal arrondissement in France|arrondissement. Both of the 2 Corsican départements use &quot;20&quot; as the first two digits. Also used by French overseas departments and territories. Monaco is also part of the French postal code system, but the country code MC- is used for Monegasque addresses.
110
		'GA' => array(), // Gabon
111
		'GB' => array('@#', '@##', '@@#', '@@##', '@#@', '@@#@', '@@@', '@# #@@', '@## #@@', '@@# #@@', '@@## #@@', '@#@ #@@', '@@#@ #@@', '@@@ #@@'), // | Postcodes in the United Kingdom|United Kingdom, Notes: Known as the UK postcodes|postcode. The first letter(s) indicate the List of postcode areas in the United Kingdom|postal area, such as the town or part of London. Placed on a separate line below the city (or county, if used). The UK postcode is made up of two parts separated by a space.  These are known as the '''outward postcode''' and the '''inward postcode'''. The outward postcode is always one of the following formats: AN, ANN, AAN, AANN, ANA, AANA, AAA.  The inward postcode is always formatted as NAA.  A valid inward postcode never contains the letters: C, I, K, M, O or V.  The British Forces Post Office has a different system, but as of 2012 has also adopted UK-style postcodes that begin with &quot;BF1&quot; for electronic compatibility.
112
		'GD' => array(), // Grenada
113
		'GE' => array('####'), // Georgia
114
		'GF' => array('973##'), // French Guiana, Notes: Overseas Department of France. French codes used. Range '''97300''' - '''97390'''.
115
		'GG' => array('@@# #@@', '@@## #@@'), // | GY postcode area|Guernsey, Notes: UK-format postcode (first two letters are always GY)
116
		'GH' => array(), // Ghana, Notes: {{citation needed|date=January 2011}}
117
		'GI' => array('GX11 1@@'), // Gibraltar, Notes: Single code used for all addresses.
118
		'GL' => array('####'), // Greenland, Notes: Part of the Danish postal code system.
119
		'GM' => array(), // Gambia
120
		'GN' => array('###'), // Guinea
121
		'GP' => array('971##'), // Guadeloupe, Notes: Overseas Department of France. French codes used. Range '''97100''' - '''97190'''.
122
		'GQ' => array(), // Equatorial Guinea
123
		'GR' => array('### ##'), // Greece
124
		'GS' => array('SIQQ 1ZZ'), // South Georgia and the South Sandwich Islands, Notes: One code for all addresses.
125
		'GT' => array('#####'), // Guatemala, Notes: The first two numbers identify the department, the third number the route and the last two the office.
126
		'GU' => array('#####', '#####-####'), // Guam, Notes: U.S. ZIP codes. Range '''96910''' - '''96932'''.
127
		'GW' => array('####'), // Guinea Bissau
128
		'GY' => array(), // Guyana
129
		'HK' => array(), // Hong Kong, Notes: [http://www.upu.int/fileadmin/documentsFiles/activities/addressingUnit/hkgEn.pdf] The dummy postal code of Hong Kong is 999077.
130
		'HM' => array(), // Heard and McDonald Islands
131
		'HN' => array('CC#####'), // Honduras
132
		'HR' => array('#####'), // Croatia
133
		'HT' => array('####'), // Haiti
134
		'HU' => array('####'), // Hungary, Notes: The code defines an area, usually one code per settlement except the six largest towns. One code can identify more (usually) small settlements as well.
135
		'ID' => array('#####'), // Indonesia, Notes: Kode Pos. Included East Timor (ranges 88xxx and 89xxx) until 1999, no longer used. For Indonesia postal code information visit [http://kodepos.posindonesia.co.id &lt;nowiki&gt;[2]&lt;/nowiki&gt;]
136
		'IE' => array('@## @#@#', '@## @@##', '@## @#@@', '@#W @#@#', '@#W @@##', '@#W @#@@'), // Ireland, Notes: Ireland's postcode system (called Eircode) refers to individual properties - not to streets/areas. The first 3 characters are a routing key referring to an area's postal district, and the second 4 characters are an individual property identifier. &quot;see www.eircode.ie for more information&quot;'' See also Republic of Ireland postal addresses.''
137
		'IL' => array('#######'), // Israel, Notes: In 2013, after the introduction of the 7 digit codes, 5 digit codes were still being used widely.
138
		'IM' => array('CC# #@@', 'CC## #@@'), // | IM postcode area|Isle of Man, Notes: UK-format postcode. The first two letters are always IM.
139
		'IN' => array('######', '## ###'), // India
140
		'IO' => array('BB#D 1ZZ'), // British Indian Ocean Territory, Notes: One code for all addresses (AAAA NAA). UK territory, but not UK postcode.
141
		'IQ' => array('#####'), // Iraq
142
		'IR' => array('##########'), // Iran, Notes: (Persian language|Persian: کد پستی)
143
		'IS' => array('###'), // Iceland
144
		'IT' => array('#####'), // Italy, Notes: Codice di Avviamento Postale (CAP). Also used by San Marino and Vatican City. First two digits identify province with some exceptions, because there are more than 100 provinces.
145
		'JE' => array('CC# #@@', 'CC## #@@'), // | JE postcode area|Jersey, Notes: UK-format postcode. The first two letters are always JE.
146
		'JM' => array('##'), // Jamaica, Notes: Before suspension: CCAAANN. Jamaica currently has no national postal code system, except for Kingston and Lower St. Andrew, which are divided into postal districts numbered '''1'''-'''20'''&lt;ref&gt;[http://www.jamaicapost.gov.jm/corporate_news/pressrelease_07.htm Postal Corporation of Jamaica Press Releases 2007 - POST CODE PROJECT SUSPENDED INDEFINITELY (12 February 2007)]&lt;/ref&gt;
147
		'JO' => array('#####'), // Jordan, Notes: Deliveries to PO Boxes only.
148
		'JP' => array('###-####'), // Japan, Notes: See also Japanese addressing system.
149
		'KE' => array('#####'), // Kenya, Notes: Deliveries to PO Boxes only. The postal code refers to the post office at which the receiver's P. O. Box is located.
150
		'KG' => array('######'), // Kyrgyzstan
151
		'KH' => array('#####'), // Cambodia
152
		'KI' => array(), // Kiribati
153
		'KM' => array(), // Comoros
154
		'KN' => array(), // Saint Kitts and Nevis
155
		'KP' => array(), // Korea, North
156
		'KR' => array('#####'), // | List of postal codes in South Korea|Korea, South, Notes: Previously NNN-NNN (1988~2015), NNN-NN (1970~1988)
157
		'KW' => array('#####'), // Kuwait, Notes: The first two digits represent the sector and the last three digits represents the post office.
158
		'KY' => array('CC#-####'), // Cayman Islands
159
		'KZ' => array('######'), // Kazakhstan, Notes: &lt;ref&gt;[http://eshop.kazpost.kz/QueryForm.php Kazakhstan's postal codes]&lt;/ref&gt;
160
		'LA' => array('#####'), // Laos
161
		'LB' => array('#####', '#### ####'), // Lebanon, Notes: The first four digits represent the region or postal zone,the last four digits represent the building see also [http://postal-codes.net/lebanon_postal_codes/ Lebanon Postal code website].
162
		'LC' => array('LC##  ###'), // Saint Lucia, Notes: The first two letters are always LC. There are two spaces between the second and third digits.
163
		'LI' => array('####'), // Liechtenstein, Notes: With Switzerland, ordered from west to east. Range '''9485''' - '''9498'''.
164
		'LK' => array('#####'), // Sri Lanka, Notes: Reference: http://mohanjith.net/ZIPLook/ Incorporates Colombo postal districts, e.g.: Colombo 1 is &quot;00100&quot;. You can search for specific postal codes [http://www.slpost.gov.lk here].
165
		'LR' => array('####'), // Liberia, Notes: Two digit postal zone after city name.
166
		'LS' => array('###'), // Lesotho
167
		'LT' => array('CC-#####'), // Lithuania, Notes: References: http://www.post.lt/en/help/postal-code-search. Previously '''9999''' which was actually the old Soviet Union|Soviet '''999999''' format code with the first 2 digits dropped.
168
		'LU' => array('####'), // Luxembourg, Notes: References: http://www.upu.int/post_code/en/countries/LUX.pdf
169
		'LV' => array('CC-####'), // Latvia
170
		'LY' => array(), // Libya
171
		'MA' => array('#####'), // Morocco
172
		'MC' => array('980##'), // Monaco, Notes: Uses the French Postal System, but with an &quot;MC&quot; Prefix for Monaco. Code range 98000-98099
173
		'MD' => array('CC####', 'CC-####'), // Moldova
174
		'ME' => array('#####'), // Montenegro
175
		'MF' => array('97150'), // Saint Martin, Notes: Overseas Collectivity of France. French codes used.
176
		'MG' => array('###'), // Madagascar
177
		'MH' => array('#####', '#####-####'), // Marshall Islands, Notes: U.S. ZIP codes. Range '''96960''' - '''96970'''.
178
		'MK' => array('####'), // Macedonia
179
		'ML' => array(), // Mali
180
		'MM' => array('#####'), // Myanmar
181
		'MN' => array('######'), // Mongolia, Notes: First digit: region / zone, Second digit: province / district, Last three digits: locality / delivery block&lt;ref&gt;http://en.youbianku.com/Mongolia&lt;/ref&gt;
182
		'MO' => array(), // Macau, Notes: [http://www.upu.int/fileadmin/userUpload/damFileSystem/universalPostalUnion/activities/addressing/postalAddressingSystemsInMemberCountries/sheetsEn/MAC.pdf]&lt;!-- Please DON'T add any post code information. ALL postcode sources are WRONG, and Macau doesn't use postcodes. See the addressing guide from Universal Postal Union (link above) BEFORE editing. --&gt;
183
		'MP' => array('#####', '#####-####'), // Northern Mariana Islands, Notes: U.S. ZIP codes. Range '''96950''' - '''96952'''.
184
		'MQ' => array('972##'), // Martinique, Notes: Overseas Department of France. French codes used. Range '''97200''' - '''97290'''.
185
		'MR' => array(), // Mauritania
186
		'MS' => array('MSR 1110-1350'), // Montserrat
187
		'MT' => array('@@@ ####'), // Malta, Notes: Kodiċi Postali
188
		'MU' => array('#####'), // Mauritius
189
		'MV' => array('#####'), // Maldives
190
		'MW' => array(), // Malawi
191
		'MX' => array('#####'), // Mexico, Notes: The first two digits identify the States of Mexico|state (or a part thereof), except for Nos. 00 to 16, which indicate ''delegaciones'' (boroughs) of the Mexican Federal District|Federal District (Mexico City).
192
		'MY' => array('#####'), // Malaysia
193
		'MZ' => array('####'), // Mozambique
194
		'NA' => array(), // Namibia, Notes: Formerly used South African postal code ranges from 9000-9299.&lt;ref name=&quot;panorama&quot;&gt;[https://books.google.co.uk/books?id=rMtBAAAAYAAJ&amp;dq=Post+Codes+introduced+in+South+Africa+in+1973&amp;focus=searchwithinvolume&amp;q=9000 ''South African Panorama'' – Volume 22), South African Information Service, 1977, page 9&lt;/ref&gt;  Withdrawn from use after independence in 1990.&lt;ref&gt;[https://books.google.co.uk/books?id=1c63AAAAIAAJ&amp;dq=Postal+codes+in+Namibia&amp;focus=searchwithinvolume&amp;q=%22postal+codes%22 ''The comprehensive handbook of the postmarks of German South West Africa, South West Africa, Namibia''), Ralph F. Putzel, R.F. Putzel, 1991, page 173&lt;/ref&gt; A five-digit postal code system is under consideration.&lt;ref&gt;[http://www.upu.int/fileadmin/documentsFiles/activities/addressingUnit/namEn.pdf Namibia), Universal Postal Union, May 2014&lt;/ref&gt;
195
		'NC' => array('988##'), // New Caledonia, Notes: Overseas Collectivity of France. French codes used. Range '''98800''' - '''98890'''.
196
		'NE' => array('####'), // Niger
197
		'NF' => array('####'), // Norfolk Island, Notes: Part of the Australian postal code system.
198
		'NG' => array('######'), // Nigeria
199
		'NI' => array('#####'), // Nicaragua
200
		'NL' => array('#### @@'), // Netherlands, Notes: The combination of the postal code and the house number gives a unique identifier of the address. The four numbers indicate an area, the two letters indicate a group of some 25 habitations, offices, factories or post office boxes.
201
		'NO' => array('####'), // Norway, Notes: From south to north
202
		'NP' => array('#####'), // | List of postal codes in Nepal|Nepal
203
		'NR' => array(), // Nauru
204
		'NU' => array(), // Niue
205
		'NZ' => array('####'), // New Zealand, Notes: Postcodes were originally intended for bulk mailing and were not needed for addressing individual items. However, new post codes for general use were phased in from June 2006 and came into force by July 2008.
206
		'OM' => array('###'), // Oman, Notes: Deliveries to P.O. Boxes only.
207
		'PA' => array('####'), // Panama
208
		'PE' => array('#####', 'CC ####'), // | List of postal codes in Peru|Peru
209
		'PF' => array('987##'), // French Polynesia, Notes: Overseas Collectivity of France. French codes used. Range '''98700''' - '''98790'''.
210
		'PG' => array('###'), // Papua New Guinea
211
		'PH' => array('####'), // Philippines
212
		'PK' => array('#####'), // | List of postal codes of Pakistan|Pakistan, Notes: [https://trackpost.org/ Pakistan postal codes list]
213
		'PL' => array('##-###'), // Poland
214
		'PM' => array('97500'), // Saint Pierre and Miquelon, Notes: Overseas Collectivity of France. French codes used.
215
		'PN' => array('PCR# 1ZZ'), // Pitcairn Islands, Notes: Single code used(AAAA NAA). UK territory, but not UK postcode
216
		'PR' => array('#####', '#####-####'), // Puerto Rico, Notes: U.S. ZIP codes. ZIP codes 006XX for NW PR, 007XX for SE PR, in which XX designates the town or post office and 009XX for the San Juan Metropolitan Area, in which XX designates the area or borough of San Juan. The last four digits identify an area within the post office. For example 00716-2604: 00716-for the east section of the city of Ponce and 2604 for Aceitillo St. in the neighborhood of Los Caobos. US Post office is changing the PR address format to the American one: 1234 No Name Avenue, San Juan, PR 00901.
217
		'PS' => array('###'), // Palestine, Notes: not yet implemented in practice. Codes '''100-899''' are in the Westbank, '''900-999''' in the Gaza Strip
218
		'PT' => array('####-###', '####'), // Portugal
219
		'PW' => array('#####', '#####-####'), // Palau, Notes: U.S. ZIP codes. All locations '''96940'''.
220
		'PY' => array('####'), // | List of postal codes of Paraguay|Paraguay
221
		'QA' => array(), // Qatar
222
		'RE' => array('974##'), // Réunion, Notes: Overseas Department of France. French codes used. Range '''97400''' - '''97490'''.
223
		'RO' => array('######'), // Romania, Notes: Previously '''99999''' in Bucharest and '''9999''' in rest of country.
224
		'RS' => array('#####'), // Serbia, Notes: Poštanski adresni kod (PAK)
225
		'RU' => array('######'), // Russia, Notes: Placed on a line of its own.
226
		'RW' => array(), // Rwanda
227
		'SA' => array('#####-####', '#####'), // Saudi Arabia, Notes: NNNNN for PO Boxes. NNNNN-NNNN for home delivery. A complete 13-digit code has 5-digit number representing region, sector, city, and zone; 4-digit X between 2000 and 5999; 4-digit Y between 6000 and 9999 [http://www.esri.com/news/arcnews/winter1011articles/saudi-arabia.html]. Digits of 5-digit code may represent postal region, sector, branch,  section, and block respectively [http://youbianku.com/files/upu/SAU.pdf].
228
		'SB' => array(), // Solomon Islands
229
		'SC' => array(), // Seychelles
230
		'SD' => array('#####'), // Sudan
231
		'SE' => array('### ##'), // Sweden, Notes: The lowest number is '''100 00''' and the highest number is '''984 99'''.
232
		'SG' => array('######'), // Singapore, Notes: Each building has its own unique postcode.
233
		'SH' => array('@@@@ 1ZZ'), // Saint Helena, Ascension and Tristan da Cunha, Notes: Part of UK system (AAAA NAA). Saint Helena, Ascension and Tristan da Cunha|Saint Helena uses one code STHL 1ZZ, Ascension Island|Ascension uses one code ASCN 1ZZ, Tristan da Cunha uses one code TDCU 1ZZ.
234
		'SI' => array('####', 'CC-####'), // Slovenia
235
		'SJ' => array('####'), // | Svalbard and Jan Mayen, Notes: Norway postal codes
236
		'SK' => array('### ##'), // Slovakia, Notes: with Czech Republic from west to east, Poštové smerovacie číslo (PSČ) - postal routing number.
237
		'SL' => array(), // Sierra Leone
238
		'SM' => array('4789#'), // San Marino, Notes: With Italy, uses a five-digit numeric CAP of Emilia Romagna. Range 47890 and 47899
239
		'SN' => array('#####'), // Senegal, Notes: The letters CP or C.P. are often written in front of the postcode. This is not a country code, but simply an abbreviation for &quot;code postal&quot;.
240
		'SO' => array('@@ #####'), // Somalia, Notes: Two letter postal codes for each of the nation's 18 Administrative divisions of Somalia|administrative regions (e.g. AW for Awdal, BN for Banaadir, BR for Bari, Somalia|Bari and SL for Sool, Somalia|Sool).&lt;ref name=&quot;Wsptsg&quot;&gt;{{cite news|title=Weekly Statement: Progress of the Somali Government|url=http://diplomat.so/2014/10/11/weekly-statement-progress-of-the-somali-government-3/|accessdate=12 October 2014|agency=Diplomat News Network|date=11 October 2014}}&lt;/ref&gt;
241
		'SR' => array(), // Suriname
242
		'SS' => array(), // South Sudan
243
		'ST' => array(), // Sao Tome and Principe
244
		'SV' => array('####'), // El Salvador
245
		'SX' => array(), // Sint Maarten
246
		'SY' => array(), // Syria, Notes: A 4-digit system has been announced. Status unknown.
247
		'SZ' => array('@###'), // Swaziland, Notes: The letter identifies one of the country's four districts.
248
		'TC' => array('TKC@ 1ZZ'), // Turks and Caicos Islands, Notes: Single code used for all addresses.
249
		'TD' => array(), // Chad
250
		'TF' => array(), // French Southern and Antarctic Territories, Notes: French codes in the '''98400''' range have been reserved.
251
		'TG' => array(), // Togo
252
		'TH' => array('#####'), // Thailand, Notes: The first two specify the province, numbers as in ISO 3166-2:TH, the third and fourth digits specify a district (amphoe)
253
		'TJ' => array('######'), // Tajikistan, Notes: Retained system from former Soviet Union.
254
		'TK' => array(), // Tokelau
255
		'TL' => array(), // East Timor, Notes: No postal code system in use since Indonesian withdrawal in 1999.
256
		'TM' => array('######'), // Turkmenistan, Notes: Retained system from former Soviet Union.
257
		'TN' => array('####'), // Tunisia
258
		'TO' => array(), // Tonga
259
		'TR' => array('#####'), // Turkey, Notes: First two digits are the city numbers.&lt;ref&gt;http://www.postakodumne.com | Posta Kodum Ne - Postal Code Reference for Turkey&lt;/ref&gt;
260
		'TT' => array('######'), // Trinidad and Tobago, Notes: First two digits specify a postal district (one of 72), next two digits a carrier route, last two digits a building or zone along that route
261
		'TV' => array(), // Tuvalu
262
		'TW' => array('###', '###-##'), // Taiwan, Notes: The first three digits of the postal code are required; the last two digits are optional. Codes are known as ''youdi quhao'' (郵遞區號), and are also assigned to Senkaku Islands (''Diaoyutai''), though Japanese-administered,  the Pratas Islands and the Spratly Islands. See List of postal codes in Taiwan.
263
		'TZ' => array('#####'), // Tanzania
264
		'UA' => array('#####'), // Ukraine
265
		'UG' => array(), // Uganda
266
		'UM' => array(), // United States Minor Outlying Islands
267
		'US' => array('#####', '#####-####'), // | ZIP code|United States, Notes: Known as the ZIP Code with five digits '''99999*''' or the ZIP+4 Code with nine digits '''99999-9999*''' (while the minimum requirement is the first five digits, the U.S. Postal Service encourages everyone to use all nine). Also used by the former US Pacific Territories: Federated States of Micronesia; Palau; and the Marshall Islands, as well as in current US territories American Samoa, Guam, Northern Mariana Islands, Puerto Rico, and the United States Virgin Islands.  An individual delivery point may be represented as an 11-digit number, but these are usually represented by Intelligent Mail barcode or formerly POSTNET bar code.
268
		'UY' => array('#####'), // Uruguay
269
		'UZ' => array('######'), // Uzbekistan, Notes: [http://www.aci.uz/ru/online_services/postal_indexes/ Почтовые индексы]
270
		'VA' => array('00120'), // Vatican, Notes: Single code used for all addresses. Part of the Italian postal code system.
271
		'VC' => array('CC####'), // Saint Vincent and the Grenadines
272
		'VE' => array('####', '####-@'), // Venezuela
273
		'VG' => array('CC####'), // British Virgin Islands, Notes: Specifically, VG1110 through VG1160&lt;ref&gt;http://www.finance.gov.vg/AboutUs/Departments/BVIPostOffice.aspx&lt;/ref&gt;
274
		'VI' => array('#####', '#####-####'), // U.S. Virgin Islands, Notes: U.S. ZIP codes. Range '''00801''' - '''00851'''.
275
		'VN' => array('######'), // Vietnam, Notes: First two indicate a provinces of Vietnam|province.
276
		'VU' => array(), // Vanuatu
277
		'WF' => array('986##'), // Wallis and Futuna, Notes: Overseas Collectivity of France. French codes used. Range '''98600''' - '''98690'''.
278
		'WS' => array('CC####'), // Samoa
279
		'XK' => array('#####'), // Kosovo, Notes: A separate postal code for Kosovo was introduced by the UNMIK postal administration in 2004. Serbian postcodes are still widely used in the Serbian enclaves. No country code has been assigned.
280
		'YE' => array(), // Yemen, Notes: System for Sana'a Governorate using geocoding &quot;عنواني&quot; based on the Postal addresses in the Republic of Ireland#OpenPostcode|OpenPostcode algorithm is inaugurated in 2014.&lt;ref&gt;http://www.althawranews.net/pdf/main/2014-01-02/02.pdf&lt;/ref&gt;
281
		'YT' => array('976##'), // Mayotte, Notes: Overseas Department of France. French codes used. Range '''97600''' - '''97690'''.
282
		'ZA' => array('####'), // South Africa, Notes: Postal codes are allocated to individual Post Office branches, some have two codes to differentiate between P.O. Boxes and street delivery addresses. Included Namibia (ranges 9000-9299) until 1992, no longer used.
283
		'ZM' => array('#####'), // Zambia
284
		'ZW' => array(), // Zimbabwe, Notes: System is being planned.
285
	);
286
287 14
	public function isValid($countryCode, $postalCode, $ignoreSpaces = false) {
288
		//$postalCode = str_replace('-', '', $postalCode);
289 14
		if (!isset($this->formats[$countryCode])) {
290 1
			throw new ValidationException(sprintf('Invalid country code: "%s"', $countryCode));
291
		}
292
293 13
		foreach ($this->formats[$countryCode] as $format) {
294
			#echo $postalCode . ' - ' . $this->getFormatPattern($format)."\n";
0 ignored issues
show
Coding Style introduced by
Perl-style comments are not allowed. Use "// Comment." or "/* comment */" instead.
Loading history...
295 13
			if (preg_match($this->getFormatPattern($format, $ignoreSpaces), $postalCode)) {
296 13
				return true;
297
			}
298
		}
299
300 1
		if (!count($this->formats[$countryCode])) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return !count($this->formats[$countryCode]);.
Loading history...
301
			return true;
302
		}
303
304 1
		return false;
305
	}
306
307
	public function getFormats($countryCode) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
308
		if (!isset($this->formats[$countryCode])) {
309
			throw new ValidationException(sprintf('Invalid country code: "%s"', $countryCode));
310
		}
311
312
		return $this->formats[$countryCode];
313
	}
314
315
	public function hasCountry($countryCode) {
316
		return (isset($this->formats[$countryCode]));
317
	}
318
319 13
	protected function getFormatPattern($format, $ignoreSpaces = false) {
320
		//$format = str_replace('-', '', $format);
321 13
		$pattern = str_replace('#', '\d', $format);
322 13
		$pattern = str_replace('@', '[a-zA-Z]', $pattern);
323
324 13
		if ($ignoreSpaces) {
325 1
			$pattern = str_replace(' ', ' ?', $pattern);
326
		}
327
328 13
		return '/^'.$pattern.'$/';
329
	}
330
331 1
	public function getZipName($countryCode) {
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
332 1
		if (isset($this->zip_names[$countryCode]))
333 1
			$name = $this->zip_names[$countryCode]['name'];
334
		else
335
			$name = 'Postal Code';
336 1
		return $name;
337
	}
338
}
339