Completed
Push — master ( 67a6a7...de6f2c )
by Vuong
01:19
created

IpVN::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * @link https://github.com/phpviet/validation
4
 * @copyright (c) PHP Viet
5
 * @license [MIT](https://opensource.org/licenses/MIT)
6
 */
7
8
namespace PHPViet\Validation\Rules;
9
10
use IPLib\Factory as IpFactory;
11
use IPLib\Address\Type as IpType;
12
use IPLib\Address\AddressInterface as IpInterface;
13
use Respect\Validation\Rules\AbstractRule;
14
15
/**
16
 * @author Vuong Minh <[email protected]>
17
 * @since 1.0.0
18
 */
19
class IpVN extends AbstractRule
20
{
21
    const IPV4 = IpType::T_IPv4;
22
23
    const IPV6 = IpType::T_IPv6;
24
25
    public $version;
26
27
    public function __construct($version = null)
28
    {
29
        $this->version = $version;
30
    }
31
32
    public function validate($input)
33
    {
34
        if (!$ip = IpFactory::addressFromString($input)) {
35
36
            return false;
37
        }
38
39
        if (($version = $ip->getAddressType()) !== $this->version && null !== $this->version) {
40
41
            return false;
42
        }
43
44
        if (!$ranges = $this->getIpRanges($input, $version)) {
45
46
            return false;
47
        }
48
49
        return $this->validateIpInRange($ip, $ranges);
50
    }
51
52
    protected function getIpRanges(string $ip, int $version): ?array
53
    {
54
        if (self::IPV4 === $version) {
55
            $keys = explode('.', $ip);
56
            $map = static::getIpV4Range();
57
        } else {
58
            $keys = explode(':', $ip);
59
            $map = static::getIpV6Range();
60
        }
61
62
        while (!is_null($key = array_shift($keys))) {
63
64
            if (isset($map[$key])) {
65
                $map = $map[$key];
66
67
                continue;
68
            }
69
70
            if (isset($map['range'])) {
71
72
                return $map['range'];
73
            }
74
75
            return null;
76
        }
77
    }
78
79
    protected function validateIpInRange(IpInterface $ip, array $ranges)
80
    {
81
        foreach ($ranges as $range) {
82
83
            [$begin, $end] = $range;
0 ignored issues
show
Bug introduced by
The variable $begin does not exist. Did you forget to declare it?

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.

Loading history...
Bug introduced by
The variable $end does not exist. Did you forget to declare it?

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.

Loading history...
84
85
            if (($subnet = IpFactory::rangeFromBoundaries($begin, $end)) && $subnet->contains($ip)) {
86
87
                return true;
88
            }
89
        }
90
91
        return false;
92
    }
93
94
    protected static function getIpV4Range(): array
95
    {
96
        static $range = null;
97
98
        if (null === $range) {
99
            $range = require(__DIR__ . '/../../resource/ip-v4-range.php');
100
        }
101
102
        return $range;
103
    }
104
105
    protected static function getIpV6Range(): array
106
    {
107
        static $range = null;
108
109
        if (null === $range) {
110
            $range = require(__DIR__ . '/../../resource/ip-v6-range.php');
111
        }
112
113
        return $range;
114
    }
115
116
}
117