1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Skrill\ValueObject; |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Class Address |
9
|
|
|
* |
10
|
|
|
* Value object for Customer Verification Service. |
11
|
|
|
* The customer verification service is used to check if one of your customers, identified by an email |
12
|
|
|
* address or customer ID, is registered with Skrill (i.e. the customer already has an active Skrill Digital |
13
|
|
|
* Wallet account).You can also verify information that you hold about the customer against Skrill’s |
14
|
|
|
* registration records. |
15
|
|
|
* |
16
|
|
|
* https://www.skrill.com/fileadmin/content/pdf/Skrill_Customer_Verification_Service_Guide_v1.1__1_.pdf |
17
|
|
|
* |
18
|
|
|
*/ |
19
|
|
|
final class Address |
20
|
|
|
{ |
21
|
|
|
/** |
22
|
|
|
* Length three letter codes |
23
|
|
|
*/ |
24
|
|
|
private const ISO_ALPHA_3 = 3; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Length two-letter codes |
28
|
|
|
*/ |
29
|
|
|
private const ISO_ALPHA_2 = 2; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var string |
33
|
|
|
*/ |
34
|
|
|
private $houseNumber = ''; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var string |
38
|
|
|
*/ |
39
|
|
|
private $postCode = ''; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var string |
43
|
|
|
*/ |
44
|
|
|
private $country = ''; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Address constructor. |
48
|
|
|
* @param string $postCode Customer’s postal code/ZIP Code. |
49
|
|
|
* @param string $country Customer’s country. |
50
|
|
|
* @param string $address Customer’s address (for example: "221b Baker street") |
51
|
|
|
*/ |
52
|
|
|
public function __construct(string $postCode = '', string $country = '', string $address = '') |
53
|
|
|
{ |
54
|
|
|
$postCode = trim(preg_replace('/(\s+)/msi', '', $postCode)); |
55
|
|
|
if ($postCode && $this->validateAlphaNum($postCode)) { |
56
|
|
|
$this->postCode = $postCode; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
$country = trim($country); |
60
|
|
|
if ($country && ($country = $this->validateCountry($country))) { |
61
|
|
|
$this->country = $country; |
|
|
|
|
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
$address = trim($address); |
65
|
|
|
if ($address && $this->validateAddress($address)) { |
66
|
|
|
// Non‐alphanumeric characters such as spaces and commas are not supported and will return NO_MATCH |
67
|
|
|
preg_match('/\S+(?<!\W)/', trim($address), $match); |
68
|
|
|
$this->houseNumber = $match[0]; |
69
|
|
|
} |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Matches an alphanumeric string separated from the rest of the text |
74
|
|
|
* by non‐alphanumeric character in line 1 or 2 of the stored customer address. |
75
|
|
|
* @return string |
76
|
|
|
*/ |
77
|
|
|
public function getHouseNumber(): string |
78
|
|
|
{ |
79
|
|
|
return $this->houseNumber; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Customer’s postal code/ZIP Code. Only alphanumeric values are accepted |
84
|
|
|
* and ignored white space for matches e.g. CR34JP matches CR3 4JP |
85
|
|
|
* @return string |
86
|
|
|
*/ |
87
|
|
|
public function getPostCode(): string |
88
|
|
|
{ |
89
|
|
|
return $this->postCode; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Customer’s country in the 3-digit ISO_3166‐1_alpha‐3 country code e.g. DEU for Germany. |
94
|
|
|
* @return string |
95
|
|
|
*/ |
96
|
|
|
public function getCountry(): string |
97
|
|
|
{ |
98
|
|
|
return $this->country; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Validate that a field contains only alpha-numeric characters, white space or specialized sybmols (.-,). |
103
|
|
|
* @param string $value |
104
|
|
|
* @return bool |
105
|
|
|
*/ |
106
|
|
|
private function validateAddress($value): bool |
107
|
|
|
{ |
108
|
|
|
return (bool)preg_match("/^([a-z0-9\'\.\-\s\,])+$/i", $value); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Customer’s country |
113
|
|
|
* @param string $value |
114
|
|
|
* @return string|bool |
115
|
|
|
*/ |
116
|
|
|
private function validateCountry($value) |
117
|
|
|
{ |
118
|
|
|
if (mb_strlen($value) == self::ISO_ALPHA_3) { |
119
|
|
|
$countries = getSkillSupportsCountries(); |
120
|
|
|
if (array_key_exists($value, $countries)) { |
121
|
|
|
return $value; |
122
|
|
|
} |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
if (mb_strlen($value) == self::ISO_ALPHA_2) { |
126
|
|
|
$countries = convertISO(); |
127
|
|
|
if (array_key_exists($value, $countries)) { |
128
|
|
|
return $countries[$value]; |
129
|
|
|
} |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
if ($country = array_search($value, $countries)) { |
|
|
|
|
133
|
|
|
return $country; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return false; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Validate that a field contains only alpha-numeric characters |
141
|
|
|
* @param string $value |
142
|
|
|
* @return bool |
143
|
|
|
*/ |
144
|
|
|
private function validateAlphaNum($value): bool |
145
|
|
|
{ |
146
|
|
|
return (bool)preg_match('/^([a-z0-9])+$/i', $value); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
} |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.