1 | <?php |
||
22 | class IpVN extends AbstractRule |
||
23 | { |
||
24 | const IPV4 = IpType::T_IPv4; |
||
25 | |||
26 | const IPV6 = IpType::T_IPv6; |
||
27 | |||
28 | public $version; |
||
29 | |||
30 | public function __construct(?int $version = null) |
||
31 | { |
||
32 | if(null !== $version && !$this->isSupportedVersion($version)) { |
||
33 | throw new ComponentException(sprintf('Only versions %d, %d are supported: %d given', self::IPV4, self::IPV6, $version)); |
||
34 | } |
||
35 | |||
36 | $this->version = $version; |
||
37 | } |
||
38 | |||
39 | public function validate($input) |
||
40 | { |
||
41 | if (!$ip = IpFactory::addressFromString($input)) { |
||
42 | return false; |
||
43 | } |
||
44 | |||
45 | if (($version = $ip->getAddressType()) !== $this->version && null !== $this->version) { |
||
46 | return false; |
||
47 | } |
||
48 | |||
49 | if (!$ranges = $this->getIpRanges($input, $version)) { |
||
50 | return false; |
||
51 | } |
||
52 | |||
53 | return $this->validateIpInRange($ip, $ranges); |
||
54 | } |
||
55 | |||
56 | protected function getIpRanges(string $ip, int $version): ?array |
||
57 | { |
||
58 | if (self::IPV4 === $version) { |
||
59 | $keys = explode('.', $ip); |
||
60 | $map = static::getIpV4Range(); |
||
61 | } else { |
||
62 | $keys = explode(':', $ip); |
||
63 | $map = static::getIpV6Range(); |
||
64 | } |
||
65 | |||
66 | while (!is_null($key = array_shift($keys))) { |
||
67 | if (isset($map[$key])) { |
||
68 | $map = $map[$key]; |
||
69 | |||
70 | continue; |
||
71 | } |
||
72 | |||
73 | if (isset($map['range'])) { |
||
74 | return $map['range']; |
||
75 | } |
||
76 | |||
77 | return null; |
||
78 | } |
||
79 | } |
||
80 | |||
81 | protected function validateIpInRange(IpInterface $ip, array $ranges) |
||
82 | { |
||
83 | foreach ($ranges as $range) { |
||
84 | [$begin, $end] = $range; |
||
85 | |||
86 | if (($subnet = IpFactory::rangeFromBoundaries($begin, $end)) && $subnet->contains($ip)) { |
||
87 | return true; |
||
88 | } |
||
89 | } |
||
90 | |||
91 | return false; |
||
92 | } |
||
93 | |||
94 | protected static function getIpV4Range(): array |
||
104 | |||
105 | protected static function getIpV6Range(): array |
||
115 | |||
116 | protected function isSupportedVersion(int $version): bool |
||
117 | { |
||
118 | return self::IPV4 === $version || self::IPV6 === $version; |
||
119 | } |
||
120 | |||
121 | } |
||
122 |
This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.