PluginProbe
Independent Analytics – WordPress Analytics Plugin / 2.10.1
Independent Analytics – WordPress Analytics Plugin v2.10.1
2.15.5 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 All 120 releases
independent-analytics / vendor / mlocati / ip-lib / src / Factory.php
Factory.php
281 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace IAWPSCOPED\IPLib;
4
5 use IAWPSCOPED\IPLib\Address\AddressInterface;
6 use IAWPSCOPED\IPLib\Range\Subnet;
7 use IAWPSCOPED\IPLib\Service\RangesFromBoundaryCalculator;
8 /**
9 * Factory methods to build class instances.
10 * @internal
11 */
12 class Factory
13 {
14 /**
15 * @deprecated since 1.17.0: use the parseAddressString() method instead.
16 * For upgrading:
17 * - if $mayIncludePort is true, use the ParseStringFlag::MAY_INCLUDE_PORT flag
18 * - if $mayIncludeZoneID is true, use the ParseStringFlag::MAY_INCLUDE_ZONEID flag
19 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
20 *
21 * @param string|mixed $address
22 * @param bool $mayIncludePort
23 * @param bool $mayIncludeZoneID
24 * @param bool $supportNonDecimalIPv4
25 *
26 * @return \IPLib\Address\AddressInterface|null
27 *
28 * @see \IPLib\Factory::parseAddressString()
29 * @since 1.1.0 added the $mayIncludePort argument
30 * @since 1.3.0 added the $mayIncludeZoneID argument
31 * @since 1.10.0 added the $supportNonDecimalIPv4 argument
32 */
33 public static function addressFromString($address, $mayIncludePort = \true, $mayIncludeZoneID = \true, $supportNonDecimalIPv4 = \false)
34 {
35 return static::parseAddressString($address, 0 + ($mayIncludePort ? ParseStringFlag::MAY_INCLUDE_PORT : 0) + ($mayIncludeZoneID ? ParseStringFlag::MAY_INCLUDE_ZONEID : 0) + ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
36 }
37 /**
38 * Parse an IP address string.
39 *
40 * @param string|mixed $address the address to parse
41 * @param int $flags A combination or zero or more flags
42 *
43 * @return \IPLib\Address\AddressInterface|null
44 *
45 * @see \IPLib\ParseStringFlag
46 * @since 1.17.0
47 */
48 public static function parseAddressString($address, $flags = 0)
49 {
50 $result = null;
51 if ($result === null) {
52 $result = Address\IPv4::parseString($address, $flags);
53 }
54 if ($result === null) {
55 $result = Address\IPv6::parseString($address, $flags);
56 }
57 return $result;
58 }
59 /**
60 * Convert a byte array to an address instance.
61 *
62 * @param int[]|array $bytes
63 *
64 * @return \IPLib\Address\AddressInterface|null
65 */
66 public static function addressFromBytes(array $bytes)
67 {
68 $result = null;
69 if ($result === null) {
70 $result = Address\IPv4::fromBytes($bytes);
71 }
72 if ($result === null) {
73 $result = Address\IPv6::fromBytes($bytes);
74 }
75 return $result;
76 }
77 /**
78 * @deprecated since 1.17.0: use the parseRangeString() method instead.
79 * For upgrading:
80 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
81 *
82 * @param string|mixed $range
83 * @param bool $supportNonDecimalIPv4
84 *
85 * @return \IPLib\Range\RangeInterface|null
86 *
87 * @see \IPLib\Factory::parseRangeString()
88 * @since 1.10.0 added the $supportNonDecimalIPv4 argument
89 */
90 public static function rangeFromString($range, $supportNonDecimalIPv4 = \false)
91 {
92 return static::parseRangeString($range, $supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0);
93 }
94 /**
95 * Parse an IP range string.
96 *
97 * @param string $range
98 * @param int $flags A combination or zero or more flags
99 *
100 * @return \IPLib\Range\RangeInterface|null
101 *
102 * @see \IPLib\ParseStringFlag
103 * @since 1.17.0
104 */
105 public static function parseRangeString($range, $flags = 0)
106 {
107 $result = null;
108 if ($result === null) {
109 $result = Range\Subnet::parseString($range, $flags);
110 }
111 if ($result === null) {
112 $result = Range\Pattern::parseString($range, $flags);
113 }
114 if ($result === null) {
115 $result = Range\Single::parseString($range, $flags);
116 }
117 return $result;
118 }
119 /**
120 * @deprecated since 1.17.0: use the getRangeFromBoundaries() method instead.
121 * For upgrading:
122 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
123 *
124 * @param string|\IPLib\Address\AddressInterface|mixed $from
125 * @param string|\IPLib\Address\AddressInterface|mixed $to
126 * @param bool $supportNonDecimalIPv4
127 *
128 * @return \IPLib\Address\AddressInterface|null
129 *
130 * @see \IPLib\Factory::getRangeFromBoundaries()
131 * @since 1.2.0
132 * @since 1.10.0 added the $supportNonDecimalIPv4 argument
133 */
134 public static function rangeFromBoundaries($from, $to, $supportNonDecimalIPv4 = \false)
135 {
136 return static::getRangeFromBoundaries($from, $to, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
137 }
138 /**
139 * Create the smallest address range that comprises two addresses.
140 *
141 * @param string|\IPLib\Address\AddressInterface|mixed $from
142 * @param string|\IPLib\Address\AddressInterface|mixed $to
143 * @param int $flags A combination or zero or more flags
144 *
145 * @return \IPLib\Range\RangeInterface|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types
146 *
147 * @see \IPLib\ParseStringFlag
148 * @since 1.17.0
149 */
150 public static function getRangeFromBoundaries($from, $to, $flags = 0)
151 {
152 list($from, $to) = self::parseBoundaries($from, $to, $flags);
153 return $from === \false || $to === \false ? null : static::rangeFromBoundaryAddresses($from, $to);
154 }
155 /**
156 * @deprecated since 1.17.0: use the getRangesFromBoundaries() method instead.
157 * For upgrading:
158 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
159 *
160 * @param string|\IPLib\Address\AddressInterface|mixed $from
161 * @param string|\IPLib\Address\AddressInterface|mixed $to
162 * @param bool $supportNonDecimalIPv4
163 *
164 * @return \IPLib\Range\Subnet[]|null
165 *
166 * @see \IPLib\Factory::getRangesFromBoundaries()
167 * @since 1.14.0
168 */
169 public static function rangesFromBoundaries($from, $to, $supportNonDecimalIPv4 = \false)
170 {
171 return static::getRangesFromBoundaries($from, $to, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
172 }
173 /**
174 * Create a list of Range instances that exactly describes all the addresses between the two provided addresses.
175 *
176 * @param string|\IPLib\Address\AddressInterface $from
177 * @param string|\IPLib\Address\AddressInterface $to
178 * @param int $flags A combination or zero or more flags
179 *
180 * @return \IPLib\Range\Subnet[]|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types
181 *
182 * @see \IPLib\ParseStringFlag
183 * @since 1.17.0
184 */
185 public static function getRangesFromBoundaries($from, $to, $flags = 0)
186 {
187 list($from, $to) = self::parseBoundaries($from, $to, $flags);
188 if ($from === \false || $to === \false || $from === null && $to === null) {
189 return null;
190 }
191 if ($from === null || $to === null) {
192 $address = $from ? $from : $to;
193 return array(new Subnet($address, $address, $address->getNumberOfBits()));
194 }
195 $numberOfBits = $from->getNumberOfBits();
196 if ($to->getNumberOfBits() !== $numberOfBits) {
197 return null;
198 }
199 $calculator = new RangesFromBoundaryCalculator($numberOfBits);
200 return $calculator->getRanges($from, $to);
201 }
202 /**
203 * @param \IPLib\Address\AddressInterface|null $from
204 * @param \IPLib\Address\AddressInterface|null $to
205 *
206 * @return \IPLib\Range\RangeInterface|null
207 *
208 * @since 1.2.0
209 */
210 protected static function rangeFromBoundaryAddresses($from = null, $to = null)
211 {
212 if (!$from instanceof AddressInterface && !$to instanceof AddressInterface) {
213 $result = null;
214 } elseif (!$to instanceof AddressInterface) {
215 $result = Range\Single::fromAddress($from);
216 } elseif (!$from instanceof AddressInterface) {
217 $result = Range\Single::fromAddress($to);
218 } else {
219 $result = null;
220 $addressType = $from->getAddressType();
221 if ($addressType === $to->getAddressType()) {
222 $cmp = \strcmp($from->getComparableString(), $to->getComparableString());
223 if ($cmp === 0) {
224 $result = Range\Single::fromAddress($from);
225 } else {
226 if ($cmp > 0) {
227 list($from, $to) = array($to, $from);
228 }
229 $fromBytes = $from->getBytes();
230 $toBytes = $to->getBytes();
231 $numBytes = \count($fromBytes);
232 $sameBits = 0;
233 for ($byteIndex = 0; $byteIndex < $numBytes; $byteIndex++) {
234 $fromByte = $fromBytes[$byteIndex];
235 $toByte = $toBytes[$byteIndex];
236 if ($fromByte === $toByte) {
237 $sameBits += 8;
238 } else {
239 $differentBitsInByte = \decbin($fromByte ^ $toByte);
240 $sameBits += 8 - \strlen($differentBitsInByte);
241 break;
242 }
243 }
244 $result = static::parseRangeString($from->toString() . '/' . (string) $sameBits);
245 }
246 }
247 }
248 return $result;
249 }
250 /**
251 * @param string|\IPLib\Address\AddressInterface $from
252 * @param string|\IPLib\Address\AddressInterface $to
253 * @param int $flags
254 *
255 * @return \IPLib\Address\AddressInterface[]|null[]|false[]
256 */
257 private static function parseBoundaries($from, $to, $flags = 0)
258 {
259 $result = array();
260 foreach (array('from', 'to') as $param) {
261 $value = ${$param};
262 if (!$value instanceof AddressInterface) {
263 $value = (string) $value;
264 if ($value === '') {
265 $value = null;
266 } else {
267 $value = static::parseAddressString($value, $flags);
268 if ($value === null) {
269 $value = \false;
270 }
271 }
272 }
273 $result[] = $value;
274 }
275 if ($result[0] && $result[1] && \strcmp($result[0]->getComparableString(), $result[1]->getComparableString()) > 0) {
276 $result = array($result[1], $result[0]);
277 }
278 return $result;
279 }
280 }
281