platforms::get()   F
last analyzed

Complexity

Conditions 46
Paths 1

Size

Total Lines 402
Code Lines 318

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 377
CRAP Score 46

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 46
eloc 318
c 3
b 0
f 0
nc 1
nop 0
dl 0
loc 402
ccs 377
cts 378
cp 0.9974
crap 46
rs 3.3333

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types = 1);
3
namespace hexydec\agentzero;
4
5
class platforms {
6
7
	/**
8
	 * Generates a configuration array for matching platforms
9
	 * 
10
	 * @return array<string,props> An array with keys representing the string to match, and values a props object defining how to generate the match and which properties to set
11
	 */
12 61
	public static function get() : array {
13 1
		$fn = [
14 1
			'platformlinux' => function (string $value) : array {
15 16
				if (!\str_starts_with($value, 'Red Hat/') && ($platform = \mb_strstr($value, ' ', true)) !== false) {
16 5
					$value = $platform;
17
				}
18 16
				$parts = \explode('/', $value, 2);
19 16
				if (!isset($parts[1])) {
20 14
					$parts = \explode('-', $value, 2);
21
				}
22 16
				if (!isset($parts[1])) {
23 12
					$parts = \explode(' ', $value, 2);
24
				}
25 16
				return [
26 16
					'type' => 'human',
27 16
					'category' => 'desktop',
28 16
					'kernel' => 'Linux',
29 16
					'platform' => self::getPlatform($parts[0]),
30 16
					'platformversion' => $parts[1] ?? null
31 16
				];
32 1
			},
33 1
			'platformwindows' => function (string $value) : array {
34 48
				$mapping = [
35 48
					'5.0' => '2000',
36 48
					'5.1' => 'XP',
37 48
					'5.2' => 'XP',
38 48
					'6.0' => 'Vista',
39 48
					'6.1' => '7',
40 48
					'6.2' => '8',
41 48
					'6.3' => '8.1',
42 48
					'10.0' => '10'
43 48
				];
44 48
				$version = null;
45 48
				foreach (['Windows NT ', 'Windows '] AS $item) {
46 48
					if (($pos = \mb_stripos($value, $item)) !== false) {
47 48
						$version = \explode(' ', \mb_substr($value, $pos + \mb_strlen($item)))[0];
48 48
						break;
49
					}
50
				}
51 48
				return [
52 48
					'type' => 'human',
53 48
					'category' => 'desktop',
54 48
					'kernel' => 'Windows NT',
55 48
					'platform' => 'Windows',
56 48
					'platformversion' => $mapping[$version] ?? $version
57 48
				];
58 1
			},
59 1
			'android' => function (string $value, int $i, array $tokens) : array {
60 42
				$os = \explode(' ', $value, 3);
61
62
				// skip language
63 42
				if (!empty($tokens[++$i]) && (\strlen($tokens[$i]) === 2 || (\strlen($tokens[$i]) === 5 && \mb_strpos($tokens[$i], '_') === 2))) {
64 2
					$i++;
65
				}
66
67
				// only where the token length is greater than 2, or it doesn't contain a /, or if it does it is Build/
68 42
				$device = empty($tokens[$i]) || \strlen($tokens[$i]) <= 2 || (\str_contains($tokens[$i], '/') && \mb_stripos($tokens[$i], 'Build/') === false) ? [] : devices::getDevice($tokens[$i]);
69 42
				return \array_merge($device, [
70 42
					'type' => 'human',
71 42
					'platform' => 'Android',
72 42
					'platformversion' => isset($os[1]) ? \explode('/', $os[1])[0] : null
73 42
				]);
74 1
			}
75 1
		];
76
77 49
		return [
78
79
			// platforms
80 49
			'PalmSource' => new props('start', fn (string $value) : array => [
81 3
				'type' => 'human',
82 3
				'category' => 'mobile',
83 3
				'platform' => 'PalmOS',
84 3
				'platformversion' => \mb_substr($value, 11) ?: null,
85 3
				'kernel' => 'AMX 68000',
86 3
				'architecture' => 'Arm',
87 3
				'bits' => 32,
88 3
			]),
89 49
			'PalmOS' => new props('start', fn (string $value) : array => [
90 2
				'type' => 'human',
91 2
				'category' => 'mobile',
92 2
				'platform' => 'PalmOS',
93 2
				'platformversion' => \mb_substr($value, 7) ?: null,
94 2
				'kernel' => 'AMX 68000',
95 2
				'architecture' => 'Arm',
96 2
				'bits' => 32,
97 2
			]),
98 49
			'Windows NT ' => new props('any', $fn['platformwindows']),
99 49
			'Windows Phone' => new props('start', function (string $value) : array {
100 3
				$version = \mb_substr($value, 14);
101 3
				return [
102 3
					'type' => 'human',
103 3
					'category' => 'mobile',
104 3
					'platform' => 'Windows Phone',
105 3
					'platformversion' => $version,
106 3
					'kernel' => \intval($version) >= 8 ? 'Windows NT' : 'Windows CE'
107 3
				];
108 49
			}),
109 49
			'Win98' => new props('start', function (string $value, int $i, array $tokens) : array {
110 2
				foreach ($tokens AS $item) {
111 2
					if (\str_starts_with($item, 'PalmSource')) {
112
						return [];
113
					}
114
				}
115 2
				return [
116 2
					'type' => 'human',
117 2
					'category' => 'desktop',
118 2
					'architecture' => 'x86',
119 2
					'bits' => 32,
120 2
					'kernel' => 'MS-DOS',
121 2
					'platform' => 'Windows',
122 2
					'platformversion' => '98'
123 2
				];
124 49
			}),
125 49
			'Win32' => new props('exact', [
126 49
				'type' => 'human',
127 49
				'category' => 'desktop',
128 49
				'architecture' => 'x86',
129 49
				'bits' => 32,
130 49
				'platform' => 'Windows'
131 49
			]),
132 49
			'Win64' => new props('exact', [
133 49
				'type' => 'human',
134 49
				'category' => 'desktop',
135 49
				'bits' => 64,
136 49
				'platform' => 'Windows'
137 49
			]),
138 49
			'WinNT' => new props('start', fn (string $value) : array => [
139 2
				'type' => 'human',
140 2
				'category' => 'desktop',
141 2
				'architecture' => 'x86',
142 2
				'bits' => 32,
143 2
				'kernel' => 'Windows NT',
144 2
				'platform' => 'Windows',
145 2
				'platformversion' => \mb_substr($value, 5)
146 2
			]),
147 49
			'Windows' => new props('any', function (string $value, int $i, array $tokens) use ($fn) : array {
148 49
				foreach ($tokens AS $item) {
149 49
					if (\str_starts_with($item, 'PalmSource')) {
150 2
						return [];
151
					}
152
				}
153 48
				return $fn['platformwindows']($value);
154 49
			}),
155 49
			'MacOS/' => new props('start', fn (string $value) : array => [
156 2
				'type' => 'human',
157 2
				'category' => 'desktop',
158 2
				'vendor' => 'Apple',
159 2
				'platform' => 'MacOS',
160 2
				'platformversion' => \mb_substr($value, 6),
161 2
				'bits' => 64
162 2
			]),
163 49
			'Mac OS X' => new props('any', function (string $value) : array {
164 31
				$version = \str_replace('_', '.', \mb_substr($value, \mb_stripos($value, 'Mac OS X') + 9));
165 31
				$register = $version && \intval(\explode('.', $version)[1] ?? 0) >= 6 ? 64 : null;
166 31
				return [
167 31
					'type' => 'human',
168 31
					'category' => 'desktop',
169 31
					'kernel' => 'Linux',
170 31
					'platform' => 'Mac OS X',
171 31
					'platformversion' => $version === '' ? null : $version,
172 31
					'bits' => $register
173 31
				];
174 49
			}),
175 49
			'AppleTV' => new props('exact', [
176 49
				'type' => 'human',
177 49
				'category' => 'tv',
178 49
				'device' => 'AppleTV',
179 49
				'platform' => 'tvOS',
180 49
				'bits' => 64
181 49
			]),
182 49
			'iOS/' => new props('start', fn (string $value) : array => [
183 2
				'type' => 'human',
184 2
				'category' => 'mobile',
185 2
				'platform' => 'iOS',
186 2
				'platformversion' => \mb_substr($value, 4)
187 2
			]),
188 49
			'iOS ' => new props('start', fn (string $value) : array => [
189 3
				'type' => 'human',
190 3
				'category' => 'mobile',
191 3
				'platform' => 'iOS',
192 3
				'platformversion' => \str_replace('_', '.', \mb_substr($value, 4))
193 3
			]),
194 49
			'iOS' => new props('exact', fn (string $value, int $i, array $tokens) : array => [
195 1
				'type' => 'human',
196 1
				'category' => 'mobile',
197 1
				'platform' => 'iOS',
198 1
				'platformversion' => $tokens[$i+1] ?? null
199 1
			]),
200 49
			'iPadOS' => new props('exact', fn (string $value, int $i, array $tokens) : array => [
201 1
				'type' => 'human',
202 1
				'category' => 'tablet',
203 1
				'vendor' => 'Apple',
204 1
				'device' => 'iPad',
205 1
				'platform' => 'iOS',
206 1
				'platformversion' => $tokens[$i+1] ?? null
207 1
			]),
208 49
			'CrOS' => new props('start', function (string $value) : array {
209 4
				$parts = \explode(' ', $value);
210 4
				return [
211 4
					'type' => 'human',
212 4
					'category' => 'desktop',
213 4
					'platform' => 'Chrome OS',
214 4
					'platformversion' => $parts[2] ?? null
215 4
				];
216 49
			}),
217 49
			'Kindle/' => new props('start', fn (string $value) : array => [
218 2
				'type' => 'human',
219 2
				'category' => 'ebook',
220 2
				'platform' => 'Kindle',
221 2
				'platformversion' => \mb_substr($value, 7)
222 2
			]),
223 49
			'Tizen' => new props('start', function (string $value) : array {
224 1
				$parts = \explode(' ', $value, 2);
225 1
				return [
226 1
					'type' => 'human',
227 1
					'category' => 'desktop',
228 1
					'kernel' => 'Linux',
229 1
					'platform' => 'Tizen',
230 1
					'platformversion' => $parts[1] ?? null
231 1
				];
232 49
			}),
233 49
			'KAIOS/' => new props('start', function (string $value, int $i, array $tokens) : array {
234
235
				// find device
236 1
				foreach ($tokens AS $i => $item) {
237 1
					if ($item === 'Mobile' && !\str_starts_with($tokens[$i++] ?? 'rv:', 'rv:')) {
238 1
						if (\str_contains($tokens[$i], '/')) {
239 1
							$parts = \explode('/', $tokens[$i]);
240
						} else {
241 1
							$parts = \explode(' ', \str_replace('_', ' ', $tokens[$i]), 2);
242
						}
243 1
						break;
244
					}
245
				}
246 1
				return [
247 1
					'type' => 'human',
248 1
					'category' => 'mobile',
249 1
					'kernel' => 'Linux',
250 1
					'architecture' => 'Arm',
251 1
					'platform' => 'KaiOS',
252 1
					'platformversion' => \mb_substr($value, 6),
253 1
					'vendor' => !empty($parts[0]) ? devices::getVendor($parts[0]) : null,
254 1
					'device' => $parts[1] ?? null,
255 1
					'build' => $parts[2] ?? null
256 1
				];
257 49
	}		),
258 49
			'Ubuntu' => new props('start', $fn['platformlinux']),
259 49
			'Kubuntu' => new props('start', $fn['platformlinux']),
260 49
			'Mint' => new props('start', $fn['platformlinux']),
261 49
			'SUSE' => new props('start', $fn['platformlinux']),
262 49
			'Red Hat/' => new props('start', $fn['platformlinux']),
263 49
			'Debian' => new props('start', $fn['platformlinux']),
264 49
			'Darwin' => new props('start', $fn['platformlinux']),
265 49
			'Fedora' => new props('start', $fn['platformlinux']),
266 49
			'CentOS' => new props('start', $fn['platformlinux']),
267 49
			'Rocky' => new props('start', $fn['platformlinux']),
268 49
			'Alma' => new props('start', $fn['platformlinux']),
269 49
			'Gentoo' => new props('start', $fn['platformlinux']),
270 49
			'Slackware' => new props('start', $fn['platformlinux']),
271 49
			'OpenSUSE' => new props('start', $fn['platformlinux']),
272 49
			'FreeBSD' => new props('start', $fn['platformlinux']),
273 49
			'OpenBSD' => new props('start', $fn['platformlinux']),
274 49
			'ArchLinux' => new props('exact', fn () : array => [
275 1
				'type' => 'human',
276 1
				'category' => 'desktop',
277 1
				'kernel' => 'Linux',
278 1
				'platform' => 'Arch',
279 1
			]),
280 49
			'Arch' => new props('exact', fn () : array => [
281 1
				'type' => 'human',
282 1
				'category' => 'desktop',
283 1
				'kernel' => 'Linux',
284 1
				'platform' => 'Arch',
285 1
			]),
286 49
			'Web0S' => new props('exact', $fn['platformlinux']),
287 49
			'webOSTV' => new props('exact', [
288 49
				'type' => 'human',
289 49
				'category' => 'tv',
290 49
				'kernel' => 'Linux',
291 49
				'platform' => 'WebOS'
292 49
			]),
293 49
			'WEBOS' => new props('start', fn (string $value) : array => [
294 2
				'type' => 'human',
295 2
				'category' => 'tv',
296 2
				'kernel' => 'Linux',
297 2
				'platform' => 'WebOS',
298 2
				'platformversion' => \mb_substr($value, 5)
299 2
			]),
300 49
			'Roku ' => new props('start', function (string $value, int $i, array $tokens) : array {
301 1
				$app = \str_contains($tokens[$i - 1] ?? '', '/') ? \explode('/', $tokens[$i - 1], 2) : null;
302 1
				return \array_merge(
303 1
					[
304 1
						'type' => 'human',
305 1
						'category' => 'tv',
306 1
						'kernel' => 'Linux',
307 1
						'platform' => 'Roku OS',
308 1
						'platformversion' => \mb_substr($value, 5),
309 1
						'app' => $app[0] ?? null,
310 1
						'appname' => $app[0] ?? null,
311 1
						'appversion' => $app[1] ?? null,
312 1
					],
313 1
					isset($tokens[$i + 2]) ? devices::getDevice($tokens[$i + 2]) : []
314 1
				);
315 49
			}),
316 49
			'SunOS' => new props('start', [
317 49
				'type' => 'human',
318 49
				'category' => 'desktop',
319 49
				'kernel' => 'unix',
320 49
				'platform' => 'Solaris',
321 49
			]),
322 49
			'AmigaOS' => new props('any', function (string $value) : array {
323 3
				if (($pos = \mb_stripos($value, 'AmigaOS')) !== false) {
324 3
					$value = \mb_substr($value, $pos);
325
				}
326 3
				$parts = \explode(' ', $value, 2);
327 3
				return [
328 3
					'type' => 'human',
329 3
					'category' => 'desktop',
330 3
					'kernel' => 'Exec',
331 3
					'platform' => 'AmigaOS',
332 3
					'platformversion' => isset($parts[1]) && \strspn($parts[1], '0123456789.-_') === \strlen($parts[1]) ? $parts[1] : null
333 3
				];
334 49
			}),
335 49
			'Fuchsia' => new props('exact', function (string $value, int $i, array $tokens) : array {
336 1
				$os = \explode(' ', $tokens[++$i], 2);
337 1
				return [
338 1
					'type' => 'human',
339 1
					'category' => 'mobile',
340 1
					'kernel' => 'Zircon',
341 1
					'platform' => 'Fuchsia',
342 1
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
343 1
				];
344 49
			}),
345 49
			'Maemo' => new props('exact', function (string $value, int $i, array $tokens) : array {
346 1
				$os = \explode(' ', $tokens[++$i], 2);
347 1
				return [
348 1
					'type' => 'human',
349 1
					'category' => 'mobile',
350 1
					'kernel' => 'Linux',
351 1
					'platform' => 'Maemo',
352 1
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
353 1
				];
354 49
			}),
355 49
			'J2ME/MIDP' => new props('exact', fn (string $value) : array => [
356 3
				'type' => 'human',
357 3
				'category' => 'mobile',
358 3
				'kernel' => 'Java VM',
359 3
				'platform' => $value
360 3
			]),
361 49
			'Haiku' => new props('any', function (string $value) : array {
362 3
				$parts = \explode('/', $value, 2);
363 3
				return [
364 3
					'type' => 'human',
365 3
					'category' => 'desktop',
366 3
					'kernel' => 'Haiku',
367 3
					'platform' => 'Haiku',
368 3
					'platformversion' => $parts[1] ?? null
369 3
				];
370 49
			}),
371 49
			'BeOS' => new props('start', function (string $value) : array {
372 1
				$parts = \explode('/', $value, 2);
373 1
				return [
374 1
					'type' => 'human',
375 1
					'category' => 'desktop',
376 1
					'kernel' => 'BeOS',
377 1
					'platform' => 'BeOS',
378 1
					'platformversion' => $parts[1] ?? null
379 1
				];
380 49
			}),
381 49
			'Android' => new props('exact', $fn['android']),
382 49
			'Android/' => new props('start', fn (string $value) : array => [
383 2
				'type' => 'human',
384 2
				'platform' => 'Android',
385 2
				'platformversion' => \explode('/', $value, 3)[1] ?: null
386 2
			]),
387 49
			'Android ' => new props('start', $fn['android']),
388 49
			'Android-' => new props('start', $fn['android']),
389 49
			'Linux' => new props('any', function (string $value, int $i, array $tokens) : array {
390 61
				return [
391 61
					'kernel' => 'Linux',
392 61
					'platform' => 'Linux',
393 61
					'platformversion' => \str_contains($tokens[$i + 1] ?? '', '.') && \strspn($tokens[$i + 1], '0123456789.') >= 3 ? \explode(' ', $tokens[$i + 1])[0] : null
394 61
				];
395 49
			}),
396 49
			'X11' => new props('exact', function (string $value, int $i, array $tokens) : array {
397 32
				$os = \explode(' ', $tokens[++$i] ?? '', 2);
398 32
				return [
399 32
					'category' => 'desktop',
400 32
					'kernel' => 'Linux',
401 32
					'platform' => $os[0] ?: 'X11',
402 32
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
403 32
				];
404 49
			}),
405 49
			'OS/2' => new props('exact', [
406 49
				'category' => 'desktop',
407 49
				'platform' => 'OS/2'
408 49
			]),
409 49
			'Version/' => new props('start', fn (string $value) : array => [
410 46
				'platformversion' => \mb_substr($value, 8)
411 46
			]),
412 49
			'platformVersion/' => new props('start', fn (string $value) : array => [
413 2
				'platformversion' => \mb_substr($value, 16)
414 2
			]),
415 49
		];
416
	}
417
418 24
	public static function getPlatform(string $value) : string {
419 24
		$map = [
420 24
			'webos' => 'WebOS',
421 24
			'web0s' => 'WebOS',
422 24
			'j2me/midp' => 'J2ME/MIDP',
423 24
			'centos' => 'CentOS',
424 24
			'suse' => 'SUSE',
425 24
			'freebsd' => 'FreeBSD',
426 24
			'openbsd' => 'OpenBSD',
427 24
			'netbsd' => 'NetBSD',
428 24
			'opensuse' => 'OpenSUSE',
429 24
			'iphone' => 'iOS'
430 24
		];
431 24
		$value = \mb_strtolower($value);
432 24
		return $map[$value] ?? \mb_convert_case($value, MB_CASE_TITLE);
433
	}
434
}