1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the php-epp2 library. |
5
|
|
|
* |
6
|
|
|
* (c) Gunter Grodotzki <[email protected]> |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE file |
9
|
|
|
* that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace AfriCC\EPP; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* various validating methods needed to create sane EPP requests |
16
|
|
|
*/ |
17
|
|
|
class Validator |
18
|
|
|
{ |
19
|
|
|
const TYPE_IPV4 = 1; |
20
|
|
|
const TYPE_IPV6 = 2; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* hashmap country-code -> country name (english) |
24
|
|
|
* @link https://gist.github.com/vxnick/380904 |
25
|
|
|
* @var array |
26
|
|
|
*/ |
27
|
|
|
protected static $countries = [ |
28
|
|
|
'AF' => 'Afghanistan', |
29
|
|
|
'AX' => 'Aland Islands', |
30
|
|
|
'AL' => 'Albania', |
31
|
|
|
'DZ' => 'Algeria', |
32
|
|
|
'AS' => 'American Samoa', |
33
|
|
|
'AD' => 'Andorra', |
34
|
|
|
'AO' => 'Angola', |
35
|
|
|
'AI' => 'Anguilla', |
36
|
|
|
'AQ' => 'Antarctica', |
37
|
|
|
'AG' => 'Antigua And Barbuda', |
38
|
|
|
'AR' => 'Argentina', |
39
|
|
|
'AM' => 'Armenia', |
40
|
|
|
'AW' => 'Aruba', |
41
|
|
|
'AU' => 'Australia', |
42
|
|
|
'AT' => 'Austria', |
43
|
|
|
'AZ' => 'Azerbaijan', |
44
|
|
|
'BS' => 'Bahamas', |
45
|
|
|
'BH' => 'Bahrain', |
46
|
|
|
'BD' => 'Bangladesh', |
47
|
|
|
'BB' => 'Barbados', |
48
|
|
|
'BY' => 'Belarus', |
49
|
|
|
'BE' => 'Belgium', |
50
|
|
|
'BZ' => 'Belize', |
51
|
|
|
'BJ' => 'Benin', |
52
|
|
|
'BM' => 'Bermuda', |
53
|
|
|
'BT' => 'Bhutan', |
54
|
|
|
'BO' => 'Bolivia', |
55
|
|
|
'BA' => 'Bosnia And Herzegovina', |
56
|
|
|
'BW' => 'Botswana', |
57
|
|
|
'BV' => 'Bouvet Island', |
58
|
|
|
'BR' => 'Brazil', |
59
|
|
|
'IO' => 'British Indian Ocean Territory', |
60
|
|
|
'BN' => 'Brunei Darussalam', |
61
|
|
|
'BG' => 'Bulgaria', |
62
|
|
|
'BF' => 'Burkina Faso', |
63
|
|
|
'BI' => 'Burundi', |
64
|
|
|
'KH' => 'Cambodia', |
65
|
|
|
'CM' => 'Cameroon', |
66
|
|
|
'CA' => 'Canada', |
67
|
|
|
'CV' => 'Cape Verde', |
68
|
|
|
'KY' => 'Cayman Islands', |
69
|
|
|
'CF' => 'Central African Republic', |
70
|
|
|
'TD' => 'Chad', |
71
|
|
|
'CL' => 'Chile', |
72
|
|
|
'CN' => 'China', |
73
|
|
|
'CX' => 'Christmas Island', |
74
|
|
|
'CC' => 'Cocos (Keeling) Islands', |
75
|
|
|
'CO' => 'Colombia', |
76
|
|
|
'KM' => 'Comoros', |
77
|
|
|
'CG' => 'Congo', |
78
|
|
|
'CD' => 'Congo, Democratic Republic', |
79
|
|
|
'CK' => 'Cook Islands', |
80
|
|
|
'CR' => 'Costa Rica', |
81
|
|
|
'CI' => 'Cote D\'Ivoire', |
82
|
|
|
'HR' => 'Croatia', |
83
|
|
|
'CU' => 'Cuba', |
84
|
|
|
'CY' => 'Cyprus', |
85
|
|
|
'CZ' => 'Czech Republic', |
86
|
|
|
'DK' => 'Denmark', |
87
|
|
|
'DJ' => 'Djibouti', |
88
|
|
|
'DM' => 'Dominica', |
89
|
|
|
'DO' => 'Dominican Republic', |
90
|
|
|
'EC' => 'Ecuador', |
91
|
|
|
'EG' => 'Egypt', |
92
|
|
|
'SV' => 'El Salvador', |
93
|
|
|
'GQ' => 'Equatorial Guinea', |
94
|
|
|
'ER' => 'Eritrea', |
95
|
|
|
'EE' => 'Estonia', |
96
|
|
|
'ET' => 'Ethiopia', |
97
|
|
|
'FK' => 'Falkland Islands (Malvinas)', |
98
|
|
|
'FO' => 'Faroe Islands', |
99
|
|
|
'FJ' => 'Fiji', |
100
|
|
|
'FI' => 'Finland', |
101
|
|
|
'FR' => 'France', |
102
|
|
|
'GF' => 'French Guiana', |
103
|
|
|
'PF' => 'French Polynesia', |
104
|
|
|
'TF' => 'French Southern Territories', |
105
|
|
|
'GA' => 'Gabon', |
106
|
|
|
'GM' => 'Gambia', |
107
|
|
|
'GE' => 'Georgia', |
108
|
|
|
'DE' => 'Germany', |
109
|
|
|
'GH' => 'Ghana', |
110
|
|
|
'GI' => 'Gibraltar', |
111
|
|
|
'GR' => 'Greece', |
112
|
|
|
'GL' => 'Greenland', |
113
|
|
|
'GD' => 'Grenada', |
114
|
|
|
'GP' => 'Guadeloupe', |
115
|
|
|
'GU' => 'Guam', |
116
|
|
|
'GT' => 'Guatemala', |
117
|
|
|
'GG' => 'Guernsey', |
118
|
|
|
'GN' => 'Guinea', |
119
|
|
|
'GW' => 'Guinea-Bissau', |
120
|
|
|
'GY' => 'Guyana', |
121
|
|
|
'HT' => 'Haiti', |
122
|
|
|
'HM' => 'Heard Island & Mcdonald Islands', |
123
|
|
|
'VA' => 'Holy See (Vatican City State)', |
124
|
|
|
'HN' => 'Honduras', |
125
|
|
|
'HK' => 'Hong Kong', |
126
|
|
|
'HU' => 'Hungary', |
127
|
|
|
'IS' => 'Iceland', |
128
|
|
|
'IN' => 'India', |
129
|
|
|
'ID' => 'Indonesia', |
130
|
|
|
'IR' => 'Iran, Islamic Republic Of', |
131
|
|
|
'IQ' => 'Iraq', |
132
|
|
|
'IE' => 'Ireland', |
133
|
|
|
'IM' => 'Isle Of Man', |
134
|
|
|
'IL' => 'Israel', |
135
|
|
|
'IT' => 'Italy', |
136
|
|
|
'JM' => 'Jamaica', |
137
|
|
|
'JP' => 'Japan', |
138
|
|
|
'JE' => 'Jersey', |
139
|
|
|
'JO' => 'Jordan', |
140
|
|
|
'KZ' => 'Kazakhstan', |
141
|
|
|
'KE' => 'Kenya', |
142
|
|
|
'KI' => 'Kiribati', |
143
|
|
|
'KR' => 'Korea', |
144
|
|
|
'KW' => 'Kuwait', |
145
|
|
|
'KG' => 'Kyrgyzstan', |
146
|
|
|
'LA' => 'Lao People\'s Democratic Republic', |
147
|
|
|
'LV' => 'Latvia', |
148
|
|
|
'LB' => 'Lebanon', |
149
|
|
|
'LS' => 'Lesotho', |
150
|
|
|
'LR' => 'Liberia', |
151
|
|
|
'LY' => 'Libyan Arab Jamahiriya', |
152
|
|
|
'LI' => 'Liechtenstein', |
153
|
|
|
'LT' => 'Lithuania', |
154
|
|
|
'LU' => 'Luxembourg', |
155
|
|
|
'MO' => 'Macao', |
156
|
|
|
'MK' => 'Macedonia', |
157
|
|
|
'MG' => 'Madagascar', |
158
|
|
|
'MW' => 'Malawi', |
159
|
|
|
'MY' => 'Malaysia', |
160
|
|
|
'MV' => 'Maldives', |
161
|
|
|
'ML' => 'Mali', |
162
|
|
|
'MT' => 'Malta', |
163
|
|
|
'MH' => 'Marshall Islands', |
164
|
|
|
'MQ' => 'Martinique', |
165
|
|
|
'MR' => 'Mauritania', |
166
|
|
|
'MU' => 'Mauritius', |
167
|
|
|
'YT' => 'Mayotte', |
168
|
|
|
'MX' => 'Mexico', |
169
|
|
|
'FM' => 'Micronesia, Federated States Of', |
170
|
|
|
'MD' => 'Moldova', |
171
|
|
|
'MC' => 'Monaco', |
172
|
|
|
'MN' => 'Mongolia', |
173
|
|
|
'ME' => 'Montenegro', |
174
|
|
|
'MS' => 'Montserrat', |
175
|
|
|
'MA' => 'Morocco', |
176
|
|
|
'MZ' => 'Mozambique', |
177
|
|
|
'MM' => 'Myanmar', |
178
|
|
|
'NA' => 'Namibia', |
179
|
|
|
'NR' => 'Nauru', |
180
|
|
|
'NP' => 'Nepal', |
181
|
|
|
'NL' => 'Netherlands', |
182
|
|
|
'AN' => 'Netherlands Antilles', |
183
|
|
|
'NC' => 'New Caledonia', |
184
|
|
|
'NZ' => 'New Zealand', |
185
|
|
|
'NI' => 'Nicaragua', |
186
|
|
|
'NE' => 'Niger', |
187
|
|
|
'NG' => 'Nigeria', |
188
|
|
|
'NU' => 'Niue', |
189
|
|
|
'NF' => 'Norfolk Island', |
190
|
|
|
'MP' => 'Northern Mariana Islands', |
191
|
|
|
'NO' => 'Norway', |
192
|
|
|
'OM' => 'Oman', |
193
|
|
|
'PK' => 'Pakistan', |
194
|
|
|
'PW' => 'Palau', |
195
|
|
|
'PS' => 'Palestinian Territory, Occupied', |
196
|
|
|
'PA' => 'Panama', |
197
|
|
|
'PG' => 'Papua New Guinea', |
198
|
|
|
'PY' => 'Paraguay', |
199
|
|
|
'PE' => 'Peru', |
200
|
|
|
'PH' => 'Philippines', |
201
|
|
|
'PN' => 'Pitcairn', |
202
|
|
|
'PL' => 'Poland', |
203
|
|
|
'PT' => 'Portugal', |
204
|
|
|
'PR' => 'Puerto Rico', |
205
|
|
|
'QA' => 'Qatar', |
206
|
|
|
'RE' => 'Reunion', |
207
|
|
|
'RO' => 'Romania', |
208
|
|
|
'RU' => 'Russian Federation', |
209
|
|
|
'RW' => 'Rwanda', |
210
|
|
|
'BL' => 'Saint Barthelemy', |
211
|
|
|
'SH' => 'Saint Helena', |
212
|
|
|
'KN' => 'Saint Kitts And Nevis', |
213
|
|
|
'LC' => 'Saint Lucia', |
214
|
|
|
'MF' => 'Saint Martin', |
215
|
|
|
'PM' => 'Saint Pierre And Miquelon', |
216
|
|
|
'VC' => 'Saint Vincent And Grenadines', |
217
|
|
|
'WS' => 'Samoa', |
218
|
|
|
'SM' => 'San Marino', |
219
|
|
|
'ST' => 'Sao Tome And Principe', |
220
|
|
|
'SA' => 'Saudi Arabia', |
221
|
|
|
'SN' => 'Senegal', |
222
|
|
|
'RS' => 'Serbia', |
223
|
|
|
'SC' => 'Seychelles', |
224
|
|
|
'SL' => 'Sierra Leone', |
225
|
|
|
'SG' => 'Singapore', |
226
|
|
|
'SK' => 'Slovakia', |
227
|
|
|
'SI' => 'Slovenia', |
228
|
|
|
'SB' => 'Solomon Islands', |
229
|
|
|
'SO' => 'Somalia', |
230
|
|
|
'ZA' => 'South Africa', |
231
|
|
|
'GS' => 'South Georgia And Sandwich Isl.', |
232
|
|
|
'ES' => 'Spain', |
233
|
|
|
'LK' => 'Sri Lanka', |
234
|
|
|
'SD' => 'Sudan', |
235
|
|
|
'SR' => 'Suriname', |
236
|
|
|
'SJ' => 'Svalbard And Jan Mayen', |
237
|
|
|
'SZ' => 'Swaziland', |
238
|
|
|
'SE' => 'Sweden', |
239
|
|
|
'CH' => 'Switzerland', |
240
|
|
|
'SY' => 'Syrian Arab Republic', |
241
|
|
|
'TW' => 'Taiwan', |
242
|
|
|
'TJ' => 'Tajikistan', |
243
|
|
|
'TZ' => 'Tanzania', |
244
|
|
|
'TH' => 'Thailand', |
245
|
|
|
'TL' => 'Timor-Leste', |
246
|
|
|
'TG' => 'Togo', |
247
|
|
|
'TK' => 'Tokelau', |
248
|
|
|
'TO' => 'Tonga', |
249
|
|
|
'TT' => 'Trinidad And Tobago', |
250
|
|
|
'TN' => 'Tunisia', |
251
|
|
|
'TR' => 'Turkey', |
252
|
|
|
'TM' => 'Turkmenistan', |
253
|
|
|
'TC' => 'Turks And Caicos Islands', |
254
|
|
|
'TV' => 'Tuvalu', |
255
|
|
|
'UG' => 'Uganda', |
256
|
|
|
'UA' => 'Ukraine', |
257
|
|
|
'AE' => 'United Arab Emirates', |
258
|
|
|
'GB' => 'United Kingdom', |
259
|
|
|
'US' => 'United States', |
260
|
|
|
'UM' => 'United States Outlying Islands', |
261
|
|
|
'UY' => 'Uruguay', |
262
|
|
|
'UZ' => 'Uzbekistan', |
263
|
|
|
'VU' => 'Vanuatu', |
264
|
|
|
'VE' => 'Venezuela', |
265
|
|
|
'VN' => 'Viet Nam', |
266
|
|
|
'VG' => 'Virgin Islands, British', |
267
|
|
|
'VI' => 'Virgin Islands, U.S.', |
268
|
|
|
'WF' => 'Wallis And Futuna', |
269
|
|
|
'EH' => 'Western Sahara', |
270
|
|
|
'YE' => 'Yemen', |
271
|
|
|
'ZM' => 'Zambia', |
272
|
|
|
'ZW' => 'Zimbabwe', |
273
|
|
|
]; |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* @var array |
277
|
|
|
*/ |
278
|
|
|
protected static $contact_role = [ |
279
|
|
|
2 => "admin", |
280
|
|
|
3 => "billing", |
281
|
|
|
4 => "tech", |
282
|
|
|
5 => "registrant" |
283
|
|
|
]; |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* @var array |
287
|
|
|
*/ |
288
|
|
|
protected static $contact_type = [ |
289
|
|
|
0 => "private_person", |
290
|
|
|
1 => "company", |
291
|
|
|
2 => "corporation", |
292
|
|
|
3 => "institution", |
293
|
|
|
4 => "political_party", |
294
|
|
|
5 => "township", |
295
|
|
|
6 => "government", |
296
|
|
|
7 => "public_community" |
297
|
|
|
]; |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* returns version of IP address, or false if not an IP |
301
|
|
|
* @param string $ip |
302
|
|
|
* @return bool|int |
303
|
|
|
*/ |
304
|
|
|
public static function getIPType($ip) |
305
|
|
|
{ |
306
|
|
|
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { |
307
|
|
|
return self::TYPE_IPV4; |
308
|
|
|
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { |
309
|
|
|
return self::TYPE_IPV6; |
310
|
|
|
} else { |
311
|
|
|
return false; |
312
|
|
|
} |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* returns true if hostname is usuable |
317
|
|
|
* @author velcrow |
318
|
|
|
* @link http://stackoverflow.com/a/4694816 |
319
|
|
|
* @param string $hostname |
320
|
|
|
* @return bool |
321
|
|
|
*/ |
322
|
|
|
public static function isHostname($hostname) |
323
|
|
|
{ |
324
|
|
|
if (preg_match('/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i', $hostname) && //valid chars check |
325
|
|
|
preg_match('/^.{1,253}$/', $hostname) && //overall length check |
326
|
|
|
preg_match('/^[^\.]{1,63}(\.[^\.]{1,63})*$/', $hostname) && //length of each label |
327
|
|
|
strpos($hostname, '.') // has at least two labels (SLD + TLD) |
328
|
|
|
) { |
329
|
|
|
return true; |
330
|
|
|
} |
331
|
|
|
return false; |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* returns true if email is usuable |
336
|
|
|
* @param string $email |
337
|
|
|
*/ |
338
|
|
|
public static function isEmail($email) |
339
|
|
|
{ |
340
|
|
|
$pos = strrpos($email, '@'); |
341
|
|
|
if ($pos === false) { |
342
|
|
|
return false; |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
$ascii_email = substr($email, 0, $pos) . '@' . idn_to_ascii(substr($email, $pos + 1), 0, INTL_IDNA_VARIANT_2003); |
346
|
|
|
|
347
|
|
|
return filter_var($ascii_email, FILTER_VALIDATE_EMAIL); |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* returns country name if country code is known, false if unknown |
352
|
|
|
* @param string $country_code |
353
|
|
|
* @return bool|string |
354
|
|
|
*/ |
355
|
|
|
public static function isCountryCode($country_code) |
356
|
|
|
{ |
357
|
|
|
// actually we don't need to check for any conventions... |
358
|
|
|
$country_code = strtoupper($country_code); |
359
|
|
|
|
360
|
|
|
if (isset(self::$countries[$country_code])) { |
361
|
|
|
return self::$countries[$country_code]; |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
return false; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* Returns value of key from self::$contact_role |
369
|
|
|
* @param $role |
370
|
|
|
* @return bool |
371
|
|
|
*/ |
372
|
|
|
public static function isValidContactRole($role) |
373
|
|
|
{ |
374
|
|
|
if (is_int($role) && array_key_exists($role, self::$contact_role)) { |
375
|
|
|
return $role; |
|
|
|
|
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
if (is_string($role) && array_key_exists($role, array_flip(self::$contact_role))) { |
379
|
|
|
return array_flip(self::$contact_role)[$role]; |
380
|
|
|
} |
381
|
|
|
|
382
|
|
|
return false; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
/** |
386
|
|
|
* Returns value of key from: self::$contact_type |
387
|
|
|
* @param $type |
388
|
|
|
* @return bool |
389
|
|
|
*/ |
390
|
|
|
public static function isValidContactType($type) |
391
|
|
|
{ |
392
|
|
|
if (is_int($type) && array_key_exists($type, self::$contact_type)) { |
393
|
|
|
return $type; |
|
|
|
|
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
if (is_string($type) && array_key_exists($type, array_flip(self::$contact_type))) { |
397
|
|
|
return array_flip(self::$contact_type)[$type]; |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
return false; |
401
|
|
|
} |
402
|
|
|
} |
403
|
|
|
|
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.