Ip::equals()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * Copyright 2016 Alexandru Guzinschi <[email protected]>.
4
 *
5
 * This software may be modified and distributed under the terms
6
 * of the MIT license. See the LICENSE file for details.
7
 */
8
namespace Gentle\Embeddable\Network;
9
10
use Gentle\Embeddable\Embeddable;
11
12
/**
13
 * @author Alexandru Guzinschi <[email protected]>
14
 */
15
final class Ip extends Embeddable
16
{
17
    /** @var int */
18
    private $version = 4;
19
20
    /**
21
     * @param string $value
22
     *
23
     * @throws \InvalidArgumentException
24
     */
25 77
    public function __construct($value)
26
    {
27 77
        if (false === filter_var($value, FILTER_VALIDATE_IP)) {
28 14
            throw new \InvalidArgumentException('Invalid IP address.');
29
        }
30
31 63
        $this->value = (string)$value;
32
33 63
        if (false !== filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
34 45
            $this->version = 6;
35 45
            $this->value = $this->getCondensed();
36
        }
37 63
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42 7
    public function equals(Embeddable $object)
43
    {
44 7
        return get_class($object) === 'Gentle\Embeddable\Network\Ip' && $this->value === (string)$object;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 14
    public function __toString()
51
    {
52 14
        return $this->value;
53
    }
54
55
    /**
56
     * @access public
57
     * @return int
58
     */
59 7
    public function getVersion()
60
    {
61 7
        return $this->version;
62
    }
63
64
    /**
65
     * @access public
66
     * @return string
67
     */
68 47
    public function getExpanded()
69
    {
70 47
        if ($this->version === 4) {
71 2
            return $this->value;
72
        }
73
74 45
        $hex = unpack('H*hex', $this->toBinary());
75
76 45
        return strtolower(substr(preg_replace('/([a-fA-F0-9]{4})/', '$1:', $hex['hex']), 0, -1));
77
    }
78
79
    /**
80
     * All leading zeros are removed.
81
     *
82
     * @access public
83
     * @return string
84
     */
85 7
    public function getAlternate()
86
    {
87 7
        if ($this->version === 4) {
88 2
            return $this->value;
89
        }
90
91 5
        return preg_replace('/(^|:)0+(\d)/', '\1\2', $this->getExpanded());
92
    }
93
94
    /**
95
     * All consecutive sections of zeroes are removed.
96
     *
97
     * @access public
98
     * @return string
99
     */
100 47
    public function getCondensed()
101
    {
102 47
        if ($this->version === 4) {
103 2
            return $this->value;
104
        }
105
106 45
        $addr = preg_replace('/(^|:)0+(\d)/', '\1\2', $this->getExpanded());
107
108 45
        if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $addr, $matches, PREG_OFFSET_CAPTURE)) {
109 45
            $max = 0;
110 45
            $pos = null;
111
112 45
            foreach ($matches[0] as $match) {
113 45
                if (strlen($match[0]) > $max) {
114 45
                    $max = mb_strlen($match[0]);
115 45
                    $pos = $match[1];
116
                }
117
            }
118
119 45
            $addr = substr_replace($addr, '::', $pos, $max);
120
        }
121
122 45
        return $addr;
123
    }
124
125
    /**
126
     * @access public
127
     * @return string
128
     */
129 7
    public function toLong()
130
    {
131 7
        if ($this->version === 4) {
132 2
            return sprintf('%u', ip2long($this->value));
133
        }
134
135 5
        $octet = 16 - 1;
136 5
        $long = 0;
137
138 5
        foreach (unpack('C*', inet_pton($this->value)) as $char) {
139 5
            $long = bcadd($long, bcmul($char, bcpow(256, $octet--)));
140
        }
141
142 5
        return $long;
143
    }
144
145
    /**
146
     * @access public
147
     * @return string
148
     */
149 7
    public function toHex()
150
    {
151 7
        return '0x'.unpack('H*hex', inet_pton($this->value))['hex'];
152
    }
153
154
    /**
155
     * @access public
156
     * @return string
157
     */
158 47
    public function toBinary()
159
    {
160 47
        if ($this->version === 4) {
161 2
            return str_pad(
162 2
                current(unpack('a4', inet_pton($this->value))),
163 2
                16,
164 2
                "\0",
165 2
                STR_PAD_LEFT
166
            );
167
        }
168
169 45
        return current(unpack('a16', inet_pton($this->value)));
170
    }
171
}
172