IpList::fromParser()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace BramR\TorExits;
4
5
use BramR\TorExits\Parser\ParserInterface;
6
use BramR\TorExits\Cache\IpListCacheInterface;
7
8
/**
9
 * Class IpList, contains a list of IPv4 addresses
10
 */
11
class IpList implements \Countable, \Iterator, \Serializable, \JsonSerializable
12
{
13
    protected $position = 0;
14
    protected $addresses = array();
15
    protected $addressInList = array();
16
17
    /**
18
     * @param array $addresses of IPv4 addresses as string
19
     */
20 31
    public function __construct(array $addresses = array())
21
    {
22 31
        $this->position = 0;
23 31
        if (!empty($addresses)) {
24 21
            $this->add($addresses);
25 21
        }
26 31
    }
27
28
    /**
29
     * fromParser, factory method for creating an ipList from parser
30
     *
31
     * @param ParserInterface $parser
32
     * @return IpList
33
     */
34 3
    public static function fromParser(ParserInterface $parser)
35
    {
36 3
        return $parser->parse();
37
    }
38
39
    /**
40
     * fromParserWithCache, factory method for creating an ipList from parser while
41
     * checking a cache layer first.
42
     * If the cache layer is not filled and a nonempty list is returned by parser then
43
     * the cache is set with that list
44
     *
45
     * @param ParserInterface $parser
46
     * @param IpListCacheInterface $cache
47
     * @return IpList
48
     */
49 3
    public static function fromParserWithCache(ParserInterface $parser, IpListCacheInterface $cache)
50
    {
51 3
        $ipList = $cache->fetch();
52 3
        if (!is_null($ipList)) {
53 1
            return $ipList;
54
        } else {
55 2
            $ipList = self::fromParser($parser);
56 2
            if (!empty($ipList)) {
57 2
                if (!$cache->store($ipList)) {
58 1
                    throw new \RuntimeException('Failed storing new tor exit node list in cache.');
59
                }
60 1
            }
61 1
            return $ipList;
62
        }
63
    }
64
65
66
    /**
67
     * add addresses to an IpList
68
     * Ignores invalid IPv4 Addresses
69
     *
70
     * @param mixed $addresses (array|string)
71
     * @return IpList
72
     */
73 27
    public function add($addresses)
74
    {
75 27
        if (!is_array($addresses)) {
76 1
            $addresses = (array) $addresses;
77 1
        }
78
79 27
        foreach ($addresses as $address) {
80 26
            $ip = ip2long($address);
81 26
            if ($ip && !isset($this->addressInList[$ip])) {
82 26
                $this->addresses[] = $ip;
83 26
                $this->addressInList[$ip] = true;
84 26
            }
85 27
        }
86 27
        return $this;
87
    }
88
89
    /**
90
     * fromArray load an IpList from an array
91
     * Ignores invalid IPv4 Addresses
92
     *
93
     * @param mixed $addresses (array|string)
94
     * @return IpList
95
     */
96 2
    public function remove($addresses)
97
    {
98 2
        if (!is_array($addresses)) {
99 1
            $addresses = (array) $addresses;
100 1
        }
101
102 2
        foreach ($addresses as $address) {
103 2
            $ip = ip2long($address);
104 2
            if ($ip && isset($this->addressInList[$ip])) {
105 2
                unset($this->addressInList[$ip]);
106 2
                if (false !== $key = array_search($ip, $this->addresses)) {
107 2
                    unset($this->addresses[$key]);
108 2
                }
109 2
            }
110 2
        }
111 2
        return $this;
112
    }
113
114
    /**
115
     * toArray, convert to array
116
     * @return array (with IPv4 addresses as strings)
117
     */
118 15
    public function toArray()
119
    {
120 15
        $result = array();
121 15
        foreach ($this->addresses as $ip) {
122 13
            $result[] = long2ip($ip);
123 15
        }
124 15
        return $result;
125
    }
126
127
    /**
128
     * contains, an ip address
129
     * @param string $address ip
130
     * @return boolean
131
     */
132 2
    public function contains($address)
133
    {
134 2
        $ip = ip2long($address);
135 2
        return $ip ? isset($this->addressInList[$ip]) : false;
136
    }
137
138
    /**
139
     * doesNotContain, an ip address (for semantics)
140
     * @param string $address ip
141
     * @return boolean
142
     */
143 1
    public function doesNotContain($address)
144
    {
145 1
        return !$this->contains($address);
146
    }
147
148
    /**
149
     * isEmpty
150
     * @return boolean
151
     */
152 2
    public function isEmpty()
153
    {
154 2
        return empty($this->addresses);
155
    }
156
157
158 1
    public function clear()
159
    {
160 1
        $this->position = 0;
161 1
        $this->addresses = array();
162 1
        $this->addressInList = array();
163 1
        return $this;
164
    }
165
166
    //Implement Countable
167 5
    public function count()
168
    {
169 5
        return count($this->addresses);
170
    }
171
172
    //Implement Iterator
173 2
    public function rewind()
174
    {
175 2
        $this->position = 0;
176 2
    }
177
178 1
    public function current()
179
    {
180 1
        return long2ip($this->addresses[$this->position]);
181
    }
182
183 1
    public function key()
184
    {
185 1
        return $this->position;
186
    }
187
188 1
    public function next()
189
    {
190 1
        ++$this->position;
191 1
    }
192
193 2
    public function valid()
194
    {
195 2
        return isset($this->addresses[$this->position]);
196
    }
197
198 1
    public function sort()
199
    {
200 1
        sort($this->addresses);
201 1
        return $this;
202
    }
203
204
    //Implement JsonSerializable
205 2
    public function jsonSerialize()
206
    {
207 2
        return $this->toArray();
208
    }
209
210
    //Implement Serializable
211 1
    public function serialize()
212
    {
213 1
        return serialize(array(
214 1
            $this->addresses,
215 1
            $this->addressInList
216 1
        ));
217
    }
218
219 1
    public function unserialize($data)
220
    {
221
        list(
222 1
            $this->addresses,
223 1
            $this->addressInList
224 1
        ) = unserialize($data);
225 1
    }
226
}
227