Completed
Push — master ( 024a26...2b0316 )
by Peter
05:12
created

IPv4NetworkMask::fromIP()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4.1755

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 7
cts 9
cp 0.7778
rs 9.584
c 0
b 0
f 0
cc 4
nc 5
nop 1
crap 4.1755
1
<?php
2
3
/**
4
 * GpsLab component.
5
 *
6
 * @author    Peter Gribanov <[email protected]>
7
 * @copyright Copyright (c) 2016, Peter Gribanov
8
 * @license   http://opensource.org/licenses/MIT
9
 */
10
11
namespace GpsLab\Component\Interval\IPv4Network;
12
13
use GpsLab\Component\Interval\Exception\InvalidPointTypeException;
14
15
class IPv4NetworkMask
16
{
17
    /**
18
     * @var string
19
     */
20
    const CIDR = '(3[0-2]|[1-2]?[0-9])'; // 0-32
21
22
    /**
23
     * @var string
24
     */
25
    private $ip = '';
26
27
    /**
28
     * @var int
29
     */
30
    private $long = 0;
31
32
    /**
33
     * @var int
34
     */
35
    private $cidr = 0;
36
37
    /**
38
     * @param string $ip
39
     * @param int $cidr
40
     */
41 29
    private function __construct($ip, $cidr)
42
    {
43 29
        $this->ip = $ip;
44 29
        $this->long = ip2long($ip);
45 29
        $this->cidr = $cidr;
46 29
    }
47
48
    /**
49
     * @param string $ip
50
     *
51
     * @return self
52
     */
53 3
    public static function fromIP($ip)
54
    {
55 3
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
56
            throw InvalidPointTypeException::point('IPv4', $ip);
57
        }
58
59
        // get CIDR from IP mask
60 3
        $mask = '';
61 3
        foreach (explode('.', $ip) as $octet) {
62 3
            $mask .= str_pad(decbin($octet), 8, '0', STR_PAD_LEFT);
63
        }
64
65
        // check mask
66 3
        if (strpos('01', $mask) !== false) {
67
            // valid   11111111111111111111111100000000 -> 255.255.255.0
68
            // invalid 11111111111111111111111100000001 -> 255.255.255.1
69
            throw InvalidMaskException::ip($ip);
70
        }
71
72 3
        return new self($ip, substr_count($mask, '1'));
73
    }
74
75
    /**
76
     * @param int $cidr
77
     *
78
     * @return self
79
     */
80 26
    public static function fromCIDR($cidr)
81
    {
82 26
        if ($cidr < 0 || $cidr > 32) {
83
            throw InvalidMaskException::cidr($cidr);
84
        }
85
86
        // ip2long('255.255.255.255') == -1
87 26
        return new self(long2ip((-1 << (32 - $cidr)) & -1), $cidr);
88
    }
89
90
    /**
91
     * @return int
92
     */
93 6
    public function ip()
94
    {
95 6
        return $this->long;
96
    }
97
98
    /**
99
     * @return int
100
     */
101 29
    public function cidr()
102
    {
103 29
        return $this->cidr;
104
    }
105
106
    /**
107
     * @param IPv4NetworkMask $mask
108
     *
109
     * @return bool
110
     */
111
    public function equal(IPv4NetworkMask $mask)
112
    {
113
        return $this->long == $mask->ip();
114
    }
115
116
    /**
117
     * @return string
118
     */
119 16
    public function __toString()
120
    {
121 16
        return $this->ip;
122
    }
123
}
124