10 const POSTCODE_FORMATS = [
12 'BE' => [
'(\\d{4})',[],
'$1',
"* #\n% @@\nBELGIUM"],
13 'BG' => [
'(\\d{4})',[],
'$1',
"* #\n% @@\nBULGARIA"],
14 'CZ' => [
'(\\d{3})-?(\\d{2})',[],
'$1 $2',
"* #\n% @@\nCZECH REPUBLIC"],
15 'DK' => [
'(\\d{4})',[],
'$1',
"* #\n% @@\nDENMARK"],
16 'DE' => [
'(?:DE?-?)?(\\d{5})',[],
'$1',
"* #\n% @@\nGERMANY"],
17 'EE' => [
'(\\d{5})',[],
'$1',
"* #\n% @\NESTONIA"],
18 'IE' => [
'(\\w{7})',[],
'$1',
"* #\n@@\n%\nIRELAND"],
19 'GR' => [
'(\\d{3})-?(\\d{2})',[],
'$1 $2',
"* #\n% @@\nGREECE"],
20 'ES' => [
'(\\d{5})',[],
'$1',
"* #\n% @@\n&\nSPAIN"],
21 'FR' => [
'(\\d{5})',[],
'$1',
"* #\n% @@\nFRANCE"],
22 'HR' => [
'(HR)?-*(\\d{5})',[
'HR'],
'$1-$2',
"* #\n% @\nCROATIA"],
23 'IT' => [
'(\\d{5})',[],
'$1',
"* #\n% @@ &&\nITALY"],
24 'CY' => [
'(\\d{4})',[],
'$1',
"* #\n% @\nCYPRUS"],
25 'LV' => [
'(LV)?-?(\\d{4})',[
'LV'],
'$1-$2',
"* #\n@, %\nLATVIA"],
26 'LT' => [
'(LT)?-?(\\d{5})',[
'LT'],
'$1-$2',
"* #\n% @\nLITHUANIA"],
27 'LU' => [
'(L)?-?(\\d{4})',[
'L'],
'$1-$2',
"* #\n% @@\nLUXEMBOURG"],
28 'HU' => [
'(\\d{4})',[],
'$1',
"@\n* #\n%\nHUNGARY"],
29 'MT' => [
'([A-Z]{3})-*(\\d{4})',[],
'$1 $2',
"* #\n@\n%\nMALTA"],
30 'NL' => [
'(\\d{4})-?([A-Z]{2})',[],
'$1 $2',
"* #\n% @@\nTHE NETHERLANDS"],
31 'AT' => [
'(\\d{4})',[],
'$1',
"* #\n% @@\nAUSTRIA"],
32 'PL' => [
'(\\d{2})-?(\\d{3})',[],
'$1-$2',
"* #\n% @@\nPOLAND"],
33 'PT' => [
'(\\d{4})-?(\\d{5})',[],
'$1-$2',
"* #\n% @@\nPORTUGAL"],
34 'RO' => [
'(\\d{6})',[],
'$1',
"* #\n% @\nROMANIA"],
35 'SI' => [
'(SI)?-?(\\d{4})',[
'SI'],
'$1-$2',
"* #\n@, %\nSLOVENIA"],
36 'SK' => [
'(\\d{3})-?(\\d{2})',[],
'$1 $2',
"* #\n% @@\nSLOVAK REPUBLIC"],
37 'FI' => [
'(FI|AX)?-?(\\d{5})',[
'FI'],
'$1-$2',
"* #\n% @@\nFINLAND"],
38 'SE' => [
'(SE)?-?(\\d{5})',[
'SE'],
'$1-$2',
"* #\n@@, %\nSWEDEN"],
39 'GB' => [
'(\\w{2,4})-?(\\d[A-Z]{2})',[],
'$1 $2',
"# *\n@\n%\nUNITED KINGDOM"],
41 'AU' => [
'(\\d{4})',[],
'$1',
"# *\n@@ && %\nAUSTRALIA"],
42 'CA' => [
'(\\w{3})-?(\\w{3})',[],
'$1 $2',
"# *\n@@ && %\nCANADA"],
43 'US' => [
'(\\d{5})(-\\d{4})?',[],
'$1$2',
"# *\n@@ && %\nUNITED STATES OF AMERICA"]
45 const IBAN_FORMATS = [
46 'AL' =>
'\\d{8}\\w{16}',
47 'AD' =>
'\\d{8}\\w{12}',
49 'AZ' =>
'\\w{4}\\d{20}',
50 'BH' =>
'[A-Z]{4}\\w{14}',
53 'BR' =>
'\\d{23}[A-Z]{1}\\w{1}',
54 'BG' =>
'[A-Z]{4}\\d{6}\\w{8}',
57 'CY' =>
'\\d{8}\\w{16}',
60 'DO' =>
'[A-Z]{4}\\d{20}',
65 'FR' =>
'\\d{10}\\w{11}\\d{2}',
66 'GE' =>
'\\w{2}\\d{16}',
68 'GI' =>
'[A-Z]{4}\\w{15}',
69 'GR' =>
'\\d{7}\\w{16}',
71 'GT' =>
'\\w{4}\\w{20}',
74 'IE' =>
'\\w{4}\\d{14}',
76 'IT' =>
'[A-Z]{1}\\d{10}\\w{12}',
77 'JO' =>
'[A-Z]{4}\\d{22}',
78 'KZ' =>
'\\d{3}\\w{13}',
79 'XK' =>
'\\d{4}\\d{10}\\d{2}',
80 'KW' =>
'[A-Z]{4}\\w{22}',
81 'LV' =>
'[A-Z]{4}\\w{13}',
82 'LB' =>
'\\d{4}\\w{20}',
83 'LI' =>
'\\d{5}\\w{12}',
85 'LU' =>
'\\d{3}\\w{13}',
86 'MK' =>
'\\d{3}\\w{10}\\d{2}',
87 'MT' =>
'[A-Z]{4}\\d{5}\\w{18}',
89 'MU' =>
'[A-Z]{4}\\d{19}[A-Z]{3}',
90 'MC' =>
'\\d{10}\\w{11}\\d{2}',
91 'MD' =>
'\\w{2}\\w{18}',
93 'NL' =>
'[A-Z]{4}\\d{10}',
95 'PK' =>
'\\w{4}\\d{16}',
96 'PS' =>
'\\w{4}\\d{21}',
99 'QA' =>
'[A-Z]{4}\\w{21}',
100 'RO' =>
'[A-Z]{4}\\w{16}',
101 'SM' =>
'[A-Z]{1}\\d{10}\\w{12}',
102 'SA' =>
'\\d{2}\\w{18}',
108 'CH' =>
'\\d{5}\\w{12}',
110 'TR' =>
'\\d{5}\\w{17}',
111 'AE' =>
'\\d{3}\\d{16}',
112 'GB' =>
'[A-Z]{4}\\d{14}',
113 'VG' =>
'\\w{4}\\d{16}',
121 public static function email($value){
122 return filter_var($value,FILTER_VALIDATE_EMAIL) && checkdnsrr(substr(strrchr($value,
'@'),1));
131 $value = trim(preg_replace(
'/[^\\dA-Z]+/',
'-',strtoupper($value)),
'-');
132 if(($format = Record::get(self::POSTCODE_FORMATS,strtoupper($country))) && ($value = (
bool)preg_match(
'/^' . array_shift($format) .
'$/',$value,$matches))){
133 foreach(array_shift($format) as $index => $default)
if(!$matches[++$index]) $matches[$index] = $default;
134 $value = array_shift($format);
135 foreach($matches as $index => $match) $value = str_replace(
'$' . $index,$match,$value);
149 public static function address($country,$street,$number,$postcode,$town,$state = null){
152 ($format = Record::get(self::POSTCODE_FORMATS,strtoupper($country))) &&
153 $street && $number && ($postcode = self::postcode($country,$postcode)) && $town
155 $value = array_pop($format);
156 foreach([
'*' => $street,
'#' => $number,
'%' => $postcode,
'@' => $town,
'&' => $state] as $k => $v)
157 $value = strtr($value,[$k . $k => mb_strtoupper($v),$k => $v]);
166 public static function iban($value){
167 $value = strtoupper(preg_replace(
'/[\\W_]/',
'',$value));
168 if(!preg_match(
'/^[A-Z]{2}(0[2-9]|[1-8]\d|9[0-8])' . Record::get(self::IBAN_FORMATS,substr($value,0,2),
'\\w{10,30}') .
'$/',$value))
return false;
169 $check = substr($value,4) . substr($value,0,4);
170 for($c =
'A'; $c <=
'Z'; $c++) $check = str_replace($c,ord($c) - 55,$check);
171 return bcmod($check,97) == 1 ? $value :
false;
180 public static function vatNo($value,&$info = null){
181 $value = strtoupper(preg_replace(
'/\\W/',
'',$value));
183 $soap = @new \SoapClient(
'http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl',[
'exceptions' => 1]);
184 $info = (array)$soap->checkVat([
'countryCode' => substr($value,0,2),
'vatNumber' => substr($value,2)]);
185 return $info[
'valid'];
187 catch(\SoapFault $e){
188 $info = [
'error' => $e->faultstring];
static postcode($country, $value)
Check a postal code for syntax.
static iban($value)
Check if an International Bank Account Number (IBAN) is valid.
static address($country, $street, $number, $postcode, $town, $state=null)
Check all parts of an address for syntax.
static vatNo($value, &$info=null)
Check if an European VAT number is valid.
const n const static email($value)
Check an e-mail address for syntax and host.