Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
55 / 55 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
IpAddress | |
100.00% |
55 / 55 |
|
100.00% |
3 / 3 |
13 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
validate | |
100.00% |
52 / 52 |
|
100.00% |
1 / 1 |
11 | |||
getInverseError | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace Verja\Validator; |
4 | |
5 | use Verja\Error; |
6 | use Verja\Validator; |
7 | |
8 | class IpAddress extends Validator |
9 | { |
10 | const VERSION_ANY = 'any'; |
11 | const VERSION_4 = 'v4'; |
12 | const VERSION_6 = 'v6'; |
13 | |
14 | const RANGE_ANY = 'any'; |
15 | const RANGE_PUBLIC = 'public'; |
16 | const RANGE_UNRESERVED = 'unreserved'; |
17 | const RANGE_PRIVATE = 'private'; |
18 | |
19 | /** @var string */ |
20 | protected $version; |
21 | |
22 | /** @var string */ |
23 | protected $range; |
24 | |
25 | /** |
26 | * IpAddress constructor. |
27 | * |
28 | * @param string $version 'any' (default), 'v4' or 'v6' |
29 | * @param string $range 'any' (default), 'public', 'public,unreserved' or 'private' |
30 | */ |
31 | public function __construct(string $version = self::VERSION_ANY, string $range = self::RANGE_ANY) |
32 | { |
33 | $this->version = $version; |
34 | $this->range = $range; |
35 | } |
36 | |
37 | /** |
38 | * Validate $value |
39 | * |
40 | * @param mixed $value |
41 | * @param array $context |
42 | * @return bool |
43 | */ |
44 | public function validate($value, array $context = []): bool |
45 | { |
46 | $flags = 0; |
47 | |
48 | $ipName = 'ip address'; |
49 | if ($this->version === self::VERSION_6) { |
50 | $flags = $flags | FILTER_FLAG_IPV6; |
51 | $ipName = 'ip-v6 address'; |
52 | } elseif ($this->version === self::VERSION_4) { |
53 | $flags = $flags | FILTER_FLAG_IPV4; |
54 | $ipName = 'ip-v4 address'; |
55 | } |
56 | |
57 | $parameters = [ |
58 | 'version' => $this->version, |
59 | 'range' => $this->range, |
60 | ]; |
61 | |
62 | if (!filter_var($value, FILTER_VALIDATE_IP, $flags)) { |
63 | // not a valid ip address |
64 | $this->error = new Error( |
65 | 'NO_IP_ADDRESS', |
66 | $value, |
67 | sprintf('value should be an %s', $ipName), |
68 | $parameters |
69 | ); |
70 | return false; |
71 | } |
72 | |
73 | if ($this->range !== self::RANGE_ANY) { |
74 | if (strpos($this->range, self::RANGE_PUBLIC) !== false) { |
75 | $flags = $flags | FILTER_FLAG_NO_PRIV_RANGE; |
76 | if (!filter_var($value, FILTER_VALIDATE_IP, $flags)) { |
77 | // not a public ip address |
78 | $this->error = new Error( |
79 | 'NO_PUBLIC_IP_ADDRESS', |
80 | $value, |
81 | sprintf('value should be a public %s', $ipName), |
82 | $parameters |
83 | ); |
84 | return false; |
85 | } elseif (strpos($this->range, self::RANGE_UNRESERVED) !== false) { |
86 | $flags = $flags | FILTER_FLAG_NO_RES_RANGE; |
87 | if (!filter_var($value, FILTER_VALIDATE_IP, $flags)) { |
88 | // reserved ip address |
89 | $this->error = new Error( |
90 | 'IS_RESERVED_IP_ADDRESS', |
91 | $value, |
92 | sprintf('value should not be a reserved %s', $ipName), |
93 | $parameters |
94 | ); |
95 | return false; |
96 | } |
97 | } |
98 | } |
99 | |
100 | if ($this->range === self::RANGE_PRIVATE) { |
101 | $flags = $flags | FILTER_FLAG_NO_PRIV_RANGE; |
102 | if (filter_var($value, FILTER_VALIDATE_IP, $flags)) { |
103 | // public ip address |
104 | $this->error = new Error( |
105 | 'IS_PUBLIC_IP_ADDRESS', |
106 | $value, |
107 | sprintf('value should not be a public %s', $ipName), |
108 | $parameters |
109 | ); |
110 | return false; |
111 | } |
112 | } |
113 | } |
114 | |
115 | return true; |
116 | } |
117 | |
118 | public function getInverseError($value) |
119 | { |
120 | return new Error('IS_IP_ADDRESS', $value, 'value should not be an ip address'); |
121 | } |
122 | } |