PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.2
Independent Analytics – WordPress Analytics Plugin v2.15.2
2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / mlocati / ip-lib / src / Range / Pattern.php
independent-analytics / vendor / mlocati / ip-lib / src / Range Last commit date
AbstractRange.php 2 weeks ago Pattern.php 2 weeks ago RangeInterface.php 2 weeks ago Single.php 2 weeks ago Subnet.php 2 weeks ago Type.php 2 weeks ago
Pattern.php
326 lines
1 <?php
2
3 namespace IAWPSCOPED\IPLib\Range;
4
5 use IAWPSCOPED\IPLib\Address\AddressInterface;
6 use IAWPSCOPED\IPLib\Address\IPv4;
7 use IAWPSCOPED\IPLib\Address\IPv6;
8 use IAWPSCOPED\IPLib\Address\Type as AddressType;
9 use IAWPSCOPED\IPLib\ParseStringFlag;
10 use IAWPSCOPED\IPLib\Service\BinaryMath;
11 /**
12 * Represents an address range in pattern format (only ending asterisks are supported).
13 *
14 * @example 127.0.*.*
15 * @example ::/8
16 *
17 * @phpstan-consistent-constructor
18 * @internal
19 */
20 class Pattern extends AbstractRange
21 {
22 /**
23 * Starting address of the range.
24 *
25 * @var \IPLib\Address\AddressInterface
26 */
27 protected $fromAddress;
28 /**
29 * Final address of the range.
30 *
31 * @var \IPLib\Address\AddressInterface
32 */
33 protected $toAddress;
34 /**
35 * Number of ending asterisks.
36 *
37 * @var int
38 */
39 protected $asterisksCount;
40 /**
41 * The type of the range of this IP range.
42 *
43 * @var int|false|null false if this range crosses multiple range types, null if yet to be determined
44 *
45 * @since 1.5.0
46 */
47 protected $rangeType;
48 /**
49 * Initializes the instance.
50 *
51 * @param \IPLib\Address\AddressInterface $fromAddress
52 * @param \IPLib\Address\AddressInterface $toAddress
53 * @param int $asterisksCount
54 */
55 public function __construct(AddressInterface $fromAddress, AddressInterface $toAddress, $asterisksCount)
56 {
57 $this->fromAddress = $fromAddress;
58 $this->toAddress = $toAddress;
59 $this->asterisksCount = $asterisksCount;
60 }
61 /**
62 * {@inheritdoc}
63 *
64 * @see \IPLib\Range\RangeInterface::__toString()
65 */
66 public function __toString()
67 {
68 return $this->toString();
69 }
70 /**
71 * @deprecated since 1.17.0: use the parseString() method instead.
72 * For upgrading:
73 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
74 *
75 * @param string|mixed $range
76 * @param bool $supportNonDecimalIPv4
77 *
78 * @return static|null
79 *
80 * @see \IPLib\Range\Pattern::parseString()
81 * @since 1.10.0 added the $supportNonDecimalIPv4 argument
82 */
83 public static function fromString($range, $supportNonDecimalIPv4 = \false)
84 {
85 return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
86 }
87 /**
88 * Try get the range instance starting from its string representation.
89 *
90 * @param string|mixed $range
91 * @param int $flags A combination or zero or more flags
92 *
93 * @return static|null
94 *
95 * @since 1.17.0
96 * @see \IPLib\ParseStringFlag
97 */
98 public static function parseString($range, $flags = 0)
99 {
100 if (!\is_string($range) || \strpos($range, '*') === \false) {
101 return null;
102 }
103 if ($range === '*.*.*.*') {
104 $fromAddress = IPv4::parseString('0.0.0.0');
105 /** @var \IPLib\Address\IPv4 $fromAddress */
106 $toAddress = IPv4::parseString('255.255.255.255');
107 /** @var \IPLib\Address\IPv4 $toAddress */
108 return new static($fromAddress, $toAddress, 4);
109 }
110 if ($range === '*:*:*:*:*:*:*:*') {
111 $fromAddress = IPv6::parseString('::');
112 /** @var \IPLib\Address\IPv6 $fromAddress */
113 $toAddress = IPv6::parseString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff');
114 /** @var \IPLib\Address\IPv6 $toAddress */
115 return new static($fromAddress, $toAddress, 8);
116 }
117 $matches = null;
118 if (\strpos($range, '.') !== \false && \preg_match('/^[^*]+((?:\\.\\*)+)$/', $range, $matches)) {
119 $asterisksCount = \strlen($matches[1]) >> 1;
120 if ($asterisksCount > 0) {
121 $missingDots = 3 - \substr_count($range, '.');
122 if ($missingDots > 0) {
123 $range .= \str_repeat('.*', $missingDots);
124 $asterisksCount += $missingDots;
125 }
126 }
127 $fromAddress = IPv4::parseString(\str_replace('*', '0', $range), $flags);
128 if ($fromAddress === null) {
129 return null;
130 }
131 $fixedBytes = \array_slice($fromAddress->getBytes(), 0, -$asterisksCount);
132 $otherBytes = \array_fill(0, $asterisksCount, 255);
133 $toAddress = IPv4::fromBytes(\array_merge($fixedBytes, $otherBytes));
134 /** @var \IPLib\Address\IPv4 $toAddress */
135 return new static($fromAddress, $toAddress, $asterisksCount);
136 }
137 if (\strpos($range, ':') !== \false && \preg_match('/^[^*]+((?::\\*)+)$/', $range, $matches)) {
138 $asterisksCount = \strlen($matches[1]) >> 1;
139 $fromAddress = IPv6::parseString(\str_replace('*', '0', $range));
140 if ($fromAddress === null) {
141 return null;
142 }
143 $fixedWords = \array_slice($fromAddress->getWords(), 0, -$asterisksCount);
144 $otherWords = \array_fill(0, $asterisksCount, 0xffff);
145 $toAddress = IPv6::fromWords(\array_merge($fixedWords, $otherWords));
146 /** @var \IPLib\Address\IPv6 $toAddress */
147 return new static($fromAddress, $toAddress, $asterisksCount);
148 }
149 return null;
150 }
151 /**
152 * {@inheritdoc}
153 *
154 * @see \IPLib\Range\RangeInterface::toString()
155 */
156 public function toString($long = \false)
157 {
158 if ($this->asterisksCount === 0) {
159 return $this->fromAddress->toString($long);
160 }
161 switch (\true) {
162 case $this->fromAddress instanceof \IAWPSCOPED\IPLib\Address\IPv4:
163 $chunks = \explode('.', $this->fromAddress->toString());
164 $chunks = \array_slice($chunks, 0, -$this->asterisksCount);
165 $chunks = \array_pad($chunks, 4, '*');
166 $result = \implode('.', $chunks);
167 break;
168 case $this->fromAddress instanceof \IAWPSCOPED\IPLib\Address\IPv6:
169 if ($long) {
170 $chunks = \explode(':', $this->fromAddress->toString(\true));
171 $chunks = \array_slice($chunks, 0, -$this->asterisksCount);
172 $chunks = \array_pad($chunks, 8, '*');
173 $result = \implode(':', $chunks);
174 } elseif ($this->asterisksCount === 8) {
175 $result = '*:*:*:*:*:*:*:*';
176 } else {
177 $bytes = $this->toAddress->getBytes();
178 $bytes = \array_slice($bytes, 0, -$this->asterisksCount * 2);
179 $bytes = \array_pad($bytes, 16, 1);
180 $address = IPv6::fromBytes($bytes);
181 /** @var IPv6 $address */
182 $before = \substr($address->toString(\false), 0, -\strlen(':101') * $this->asterisksCount);
183 $result = $before . \str_repeat(':*', $this->asterisksCount);
184 }
185 break;
186 default:
187 throw new \Exception('@todo');
188 }
189 return $result;
190 }
191 /**
192 * {@inheritdoc}
193 *
194 * @see \IPLib\Range\RangeInterface::getAddressType()
195 */
196 public function getAddressType()
197 {
198 return $this->fromAddress->getAddressType();
199 }
200 /**
201 * {@inheritdoc}
202 *
203 * @see \IPLib\Range\RangeInterface::getStartAddress()
204 */
205 public function getStartAddress()
206 {
207 return $this->fromAddress;
208 }
209 /**
210 * {@inheritdoc}
211 *
212 * @see \IPLib\Range\RangeInterface::getEndAddress()
213 */
214 public function getEndAddress()
215 {
216 return $this->toAddress;
217 }
218 /**
219 * {@inheritdoc}
220 *
221 * @see \IPLib\Range\RangeInterface::getComparableStartString()
222 */
223 public function getComparableStartString()
224 {
225 return $this->fromAddress->getComparableString();
226 }
227 /**
228 * {@inheritdoc}
229 *
230 * @see \IPLib\Range\RangeInterface::getComparableEndString()
231 */
232 public function getComparableEndString()
233 {
234 return $this->toAddress->getComparableString();
235 }
236 /**
237 * {@inheritdoc}
238 *
239 * @see \IPLib\Range\RangeInterface::asSubnet()
240 * @since 1.8.0
241 */
242 public function asSubnet()
243 {
244 return new Subnet($this->getStartAddress(), $this->getEndAddress(), $this->getNetworkPrefix());
245 }
246 /**
247 * {@inheritdoc}
248 *
249 * @see \IPLib\Range\RangeInterface::asPattern()
250 */
251 public function asPattern()
252 {
253 return $this;
254 }
255 /**
256 * {@inheritdoc}
257 *
258 * @see \IPLib\Range\RangeInterface::getSubnetMask()
259 */
260 public function getSubnetMask()
261 {
262 if ($this->getAddressType() !== AddressType::T_IPv4) {
263 return null;
264 }
265 switch ($this->asterisksCount) {
266 case 0:
267 $bytes = array(255, 255, 255, 255);
268 break;
269 case 4:
270 $bytes = array(0, 0, 0, 0);
271 break;
272 default:
273 $bytes = \array_pad(\array_fill(0, 4 - $this->asterisksCount, 255), 4, 0);
274 break;
275 }
276 return IPv4::fromBytes($bytes);
277 }
278 /**
279 * {@inheritdoc}
280 *
281 * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName()
282 */
283 public function getReverseDNSLookupName()
284 {
285 return $this->asterisksCount === 0 ? array($this->getStartAddress()->getReverseDNSLookupName()) : $this->asSubnet()->getReverseDNSLookupName();
286 }
287 /**
288 * {@inheritdoc}
289 *
290 * @see \IPLib\Range\RangeInterface::getSize()
291 */
292 public function getSize()
293 {
294 $fromAddress = $this->fromAddress;
295 $maxPrefix = $fromAddress::getNumberOfBits();
296 $prefix = $this->getNetworkPrefix();
297 return \pow(2, $maxPrefix - $prefix);
298 }
299 /**
300 * {@inheritdoc}
301 *
302 * @see \IPLib\Range\RangeInterface::getExactSize()
303 */
304 public function getExactSize()
305 {
306 $fromAddress = $this->fromAddress;
307 $maxPrefix = $fromAddress::getNumberOfBits();
308 $prefix = $this->getNetworkPrefix();
309 return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix);
310 }
311 /**
312 * {@inheritdoc}
313 *
314 * @see \IPLib\Range\RangeInterface::getNetworkPrefix()
315 */
316 public function getNetworkPrefix()
317 {
318 switch ($this->getAddressType()) {
319 case AddressType::T_IPv4:
320 return 8 * (4 - $this->asterisksCount);
321 case AddressType::T_IPv6:
322 return 16 * (8 - $this->asterisksCount);
323 }
324 }
325 }
326