Completed
Push — master ( 59b106...2838f8 )
by Peter
03:34
created

IPv4NetworkMask::fromIP()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 21
Code Lines 9

Duplication

Lines 3
Ratio 14.29 %

Code Coverage

Tests 8
CRAP Score 4.128

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 3
loc 21
ccs 8
cts 10
cp 0.8
rs 9.0534
cc 4
eloc 9
nc 5
nop 1
crap 4.128
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
    private $ip = '';
21
22
    /**
23
     * @var int
24
     */
25
    private $long = 0;
26
27
    /**
28
     * @var int
29
     */
30
    private $cidr = 0;
31
32
    /**
33
     * @param string $ip
34
     * @param int $cidr
35
     */
36 27
    private function __construct($ip, $cidr)
37
    {
38 27
        $this->ip = $ip;
39 27
        $this->long = ip2long($ip);
40 27
        $this->cidr = $cidr;
41 27
    }
42
43
    /**
44
     * @param string $ip
45
     *
46
     * @return self
47
     */
48 3
    public static function fromIP($ip)
49
    {
50 3 View Code Duplication
        if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
51
            throw InvalidPointTypeException::create('IPv4', $ip);
52
        }
53
54
        // get CIDR from IP mask
55 3
        $mask = '';
56 3
        foreach (explode('.', $ip) as $octet) {
57 3
            $mask .= str_pad(decbin($octet), 8, '0', STR_PAD_LEFT);
58 3
        }
59
60
        // check mask
61 3
        if (strpos('01', $mask) !== false) {
62
            // valid   11111111111111111111111100000000 -> 255.255.255.0
63
            // invalid 11111111111111111111111100000001 -> 255.255.255.1
64
            throw InvalidMaskException::ip($ip);
65
        }
66
67 3
        return new self($ip, substr_count($mask, '1'));
68
    }
69
70
    /**
71
     * @param int $cidr
72
     *
73
     * @return self
74
     */
75 24
    public static function fromCIDR($cidr)
76
    {
77 24
        if ($cidr < 0 || $cidr > 32) {
78
            throw InvalidMaskException::cidr($cidr);
79
        }
80
81 24
        return new self(long2ip((-1 << (32 - $cidr)) & ip2long('255.255.255.255')), $cidr);
82
    }
83
84
    /**
85
     * @return int
86
     */
87 6
    public function ip()
88
    {
89 6
        return $this->long;
90
    }
91
92
    /**
93
     * @return int
94
     */
95 27
    public function cidr()
96
    {
97 27
        return $this->cidr;
98
    }
99
100
    /**
101
     * @param IPv4NetworkMask $mask
102
     *
103
     * @return bool
104
     */
105
    public function equal(IPv4NetworkMask $mask)
106
    {
107
        return $this->long == $mask->ip();
108
    }
109
110
    /**
111
     * @return string
112
     */
113 16
    public function __toString()
114
    {
115 16
        return $this->ip;
116
    }
117
}
118