Passed
Push — main ( d3029f...a35a1e )
by Will
14:00
created

platforms::get()   F

Complexity

Conditions 44
Paths 1

Size

Total Lines 374
Code Lines 296

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 349
CRAP Score 44

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 44
eloc 296
c 3
b 0
f 0
nc 1
nop 0
dl 0
loc 374
ccs 349
cts 350
cp 0.9971
crap 44
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 60
	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 47
				$mapping = [
35 47
					'5.0' => '2000',
36 47
					'5.1' => 'XP',
37 47
					'5.2' => 'XP',
38 47
					'6.0' => 'Vista',
39 47
					'6.1' => '7',
40 47
					'6.2' => '8',
41 47
					'6.3' => '8.1',
42 47
					'10.0' => '10'
43 47
				];
44 47
				$version = null;
45 47
				foreach (['Windows NT ', 'Windows '] AS $item) {
46 47
					if (($pos = \mb_stripos($value, $item)) !== false) {
47 47
						$version = \explode(' ', \mb_substr($value, $pos + \mb_strlen($item)))[0];
48 47
						break;
49
					}
50
				}
51 47
				return [
52 47
					'type' => 'human',
53 47
					'category' => 'desktop',
54 47
					'kernel' => 'Windows NT',
55 47
					'platform' => 'Windows',
56 47
					'platformversion' => $mapping[$version] ?? $version
57 47
				];
58 1
			},
59 1
			'android' => function (string $value, int $i, array $tokens) : array {
60 41
				$os = \explode(' ', $value, 3);
61
62
				// skip language
63 41
				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 41
				$device = empty($tokens[$i]) || \strlen($tokens[$i]) <= 2 || (\str_contains($tokens[$i], '/') && \mb_stripos($tokens[$i], 'Build/') === false) ? [] : devices::getDevice($tokens[$i]);
69 41
				return \array_merge($device, [
70 41
					'type' => 'human',
71 41
					'platform' => 'Android',
72 41
					'platformversion' => isset($os[1]) ? \explode('/', $os[1])[0] : null
73 41
				]);
74 1
			}
75 1
		];
76
77 48
		return [
78
79
			// platforms
80 48
			'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 48
			'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 48
			'Windows NT ' => new props('any', $fn['platformwindows']),
99 48
			'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 48
			}),
109 48
			'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 48
			}),
125 48
			'Win32' => new props('exact', [
126 48
				'type' => 'human',
127 48
				'category' => 'desktop',
128 48
				'architecture' => 'x86',
129 48
				'bits' => 32,
130 48
				'platform' => 'Windows'
131 48
			]),
132 48
			'Win64' => new props('exact', [
133 48
				'type' => 'human',
134 48
				'category' => 'desktop',
135 48
				'bits' => 64,
136 48
				'platform' => 'Windows'
137 48
			]),
138 48
			'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 48
			'Windows' => new props('any', function (string $value, int $i, array $tokens) use ($fn) : array {
148 48
				foreach ($tokens AS $item) {
149 48
					if (\str_starts_with($item, 'PalmSource')) {
150 2
						return [];
151
					}
152
				}
153 47
				return $fn['platformwindows']($value);
154 48
			}),
155 48
			'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 48
			'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 48
			}),
175 48
			'AppleTV' => new props('exact', [
176 48
				'type' => 'human',
177 48
				'category' => 'tv',
178 48
				'device' => 'AppleTV',
179 48
				'platform' => 'tvOS',
180 48
				'bits' => 64
181 48
			]),
182 48
			'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 48
			'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 48
			'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]
199 1
			]),
200 48
			'CrOS' => new props('start', function (string $value) : array {
201 4
				$parts = \explode(' ', $value);
202 4
				return [
203 4
					'type' => 'human',
204 4
					'category' => 'desktop',
205 4
					'platform' => 'Chrome OS',
206 4
					'platformversion' => $parts[2] ?? null
207 4
				];
208 48
			}),
209 48
			'Kindle/' => new props('start', fn (string $value) : array => [
210 2
				'type' => 'human',
211 2
				'category' => 'ebook',
212 2
				'platform' => 'Kindle',
213 2
				'platformversion' => \mb_substr($value, 7)
214 2
			]),
215 48
			'Tizen' => new props('start', function (string $value) : array {
216 1
				$parts = \explode(' ', $value, 2);
217 1
				return [
218 1
					'type' => 'human',
219 1
					'category' => 'desktop',
220 1
					'kernel' => 'Linux',
221 1
					'platform' => 'Tizen',
222 1
					'platformversion' => $parts[1] ?? null
223 1
				];
224 48
			}),
225 48
			'KAIOS/' => new props('start', function (string $value, int $i, array $tokens) : array {
226
227
				// find device
228 1
				foreach ($tokens AS $i => $item) {
229 1
					if ($item === 'Mobile' && !\str_starts_with($tokens[$i++] ?? 'rv:', 'rv:')) {
230 1
						if (\str_contains($tokens[$i], '/')) {
231 1
							$parts = \explode('/', $tokens[$i]);
232
						} else {
233 1
							$parts = \explode(' ', \str_replace('_', ' ', $tokens[$i]), 2);
234
						}
235 1
						break;
236
					}
237
				}
238 1
				return [
239 1
					'type' => 'human',
240 1
					'category' => 'mobile',
241 1
					'kernel' => 'Linux',
242 1
					'architecture' => 'Arm',
243 1
					'platform' => 'KaiOS',
244 1
					'platformversion' => \mb_substr($value, 6),
245 1
					'vendor' => !empty($parts[0]) ? devices::getVendor($parts[0]) : null,
246 1
					'device' => $parts[1] ?? null,
247 1
					'build' => $parts[2] ?? null
248 1
				];
249 48
	}		),
250 48
			'Ubuntu' => new props('start', $fn['platformlinux']),
251 48
			'Kubuntu' => new props('start', $fn['platformlinux']),
252 48
			'Mint' => new props('start', $fn['platformlinux']),
253 48
			'SUSE' => new props('start', $fn['platformlinux']),
254 48
			'Red Hat/' => new props('start', $fn['platformlinux']),
255 48
			'Debian' => new props('start', $fn['platformlinux']),
256 48
			'Darwin' => new props('start', $fn['platformlinux']),
257 48
			'Fedora' => new props('start', $fn['platformlinux']),
258 48
			'CentOS' => new props('start', $fn['platformlinux']),
259 48
			'Rocky' => new props('start', $fn['platformlinux']),
260 48
			'Alma' => new props('start', $fn['platformlinux']),
261 48
			'Gentoo' => new props('start', $fn['platformlinux']),
262 48
			'Slackware' => new props('start', $fn['platformlinux']),
263 48
			'OpenSUSE' => new props('start', $fn['platformlinux']),
264 48
			'FreeBSD' => new props('start', $fn['platformlinux']),
265 48
			'OpenBSD' => new props('start', $fn['platformlinux']),
266 48
			'ArchLinux' => new props('exact', fn () : array => [
267 1
				'type' => 'human',
268 1
				'category' => 'desktop',
269 1
				'kernel' => 'Linux',
270 1
				'platform' => 'Arch',
271 1
			]),
272 48
			'Arch' => new props('exact', fn () : array => [
273 1
				'type' => 'human',
274 1
				'category' => 'desktop',
275 1
				'kernel' => 'Linux',
276 1
				'platform' => 'Arch',
277 1
			]),
278 48
			'Web0S' => new props('exact', $fn['platformlinux']),
279 48
			'webOSTV' => new props('exact', [
280 48
				'type' => 'human',
281 48
				'category' => 'tv',
282 48
				'kernel' => 'Linux',
283 48
				'platform' => 'WebOS'
284 48
			]),
285 48
			'WEBOS' => new props('start', fn (string $value) : array => [
286 2
				'type' => 'human',
287 2
				'category' => 'tv',
288 2
				'kernel' => 'Linux',
289 2
				'platform' => 'WebOS',
290 2
				'platformversion' => \mb_substr($value, 5)
291 2
			]),
292 48
			'SunOS' => new props('start', [
293 48
				'type' => 'human',
294 48
				'category' => 'desktop',
295 48
				'kernel' => 'unix',
296 48
				'platform' => 'Solaris',
297 48
			]),
298 48
			'AmigaOS' => new props('any', function (string $value) : array {
299 3
				if (($pos = \mb_stripos($value, 'AmigaOS')) !== false) {
300 3
					$value = \mb_substr($value, $pos);
301
				}
302 3
				$parts = \explode(' ', $value, 2);
303 3
				return [
304 3
					'type' => 'human',
305 3
					'category' => 'desktop',
306 3
					'kernel' => 'Exec',
307 3
					'platform' => 'AmigaOS',
308 3
					'platformversion' => isset($parts[1]) && \strspn($parts[1], '0123456789.-_') === \strlen($parts[1]) ? $parts[1] : null
309 3
				];
310 48
			}),
311 48
			'Fuchsia' => new props('exact', function (string $value, int $i, array $tokens) : array {
312 1
				$os = \explode(' ', $tokens[++$i], 2);
313 1
				return [
314 1
					'type' => 'human',
315 1
					'category' => 'mobile',
316 1
					'kernel' => 'Zircon',
317 1
					'platform' => 'Fuchsia',
318 1
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
319 1
				];
320 48
			}),
321 48
			'Maemo' => new props('exact', function (string $value, int $i, array $tokens) : array {
322 1
				$os = \explode(' ', $tokens[++$i], 2);
323 1
				return [
324 1
					'type' => 'human',
325 1
					'category' => 'mobile',
326 1
					'kernel' => 'Linux',
327 1
					'platform' => 'Maemo',
328 1
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
329 1
				];
330 48
			}),
331 48
			'J2ME/MIDP' => new props('exact', fn (string $value) : array => [
332 3
				'type' => 'human',
333 3
				'category' => 'mobile',
334 3
				'kernel' => 'Java VM',
335 3
				'platform' => $value
336 3
			]),
337 48
			'Haiku' => new props('any', function (string $value) : array {
338 3
				$parts = \explode('/', $value, 2);
339 3
				return [
340 3
					'type' => 'human',
341 3
					'category' => 'desktop',
342 3
					'kernel' => 'Haiku',
343 3
					'platform' => 'Haiku',
344 3
					'platformversion' => $parts[1] ?? null
345 3
				];
346 48
			}),
347 48
			'BeOS' => new props('start', function (string $value) : array {
348 1
				$parts = \explode('/', $value, 2);
349 1
				return [
350 1
					'type' => 'human',
351 1
					'category' => 'desktop',
352 1
					'kernel' => 'BeOS',
353 1
					'platform' => 'BeOS',
354 1
					'platformversion' => $parts[1] ?? null
355 1
				];
356 48
			}),
357 48
			'Android' => new props('exact', $fn['android']),
358 48
			'Android/' => new props('start', fn (string $value) : array => [
359 1
				'type' => 'human',
360 1
				'platform' => 'Android',
361 1
				'platformversion' => \explode('/', $value, 3)[1] ?: null
362 1
			]),
363 48
			'Android ' => new props('start', $fn['android']),
364 48
			'Linux' => new props('any', function (string $value, int $i, array $tokens) : array {
365 60
				return [
366 60
					'kernel' => 'Linux',
367 60
					'platform' => 'Linux',
368 60
					'platformversion' => \str_contains($tokens[$i + 1] ?? '', '.') && \strspn($tokens[$i + 1], '0123456789.') >= 3 ? \explode(' ', $tokens[$i + 1])[0] : null
369 60
				];
370 48
			}),
371 48
			'X11' => new props('exact', function (string $value, int $i, array $tokens) : array {
372 32
				$os = \explode(' ', $tokens[++$i] ?? '', 2);
373 32
				return [
374 32
					'category' => 'desktop',
375 32
					'kernel' => 'Linux',
376 32
					'platform' => $os[0] ?: 'X11',
377 32
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
378 32
				];
379 48
			}),
380 48
			'OS/2' => new props('exact', [
381 48
				'category' => 'desktop',
382 48
				'platform' => 'OS/2'
383 48
			]),
384 48
			'Version/' => new props('start', fn (string $value) : array => [
385 45
				'platformversion' => \mb_substr($value, 8)
386 45
			])
387 48
		];
388
	}
389
390 23
	public static function getPlatform(string $value) : string {
391 23
		$map = [
392 23
			'webos' => 'WebOS',
393 23
			'web0s' => 'WebOS',
394 23
			'j2me/midp' => 'J2ME/MIDP',
395 23
			'centos' => 'CentOS',
396 23
			'suse' => 'SUSE',
397 23
			'freebsd' => 'FreeBSD',
398 23
			'openbsd' => 'OpenBSD',
399 23
			'netbsd' => 'NetBSD',
400 23
			'opensuse' => 'OpenSUSE'
401 23
		];
402 23
		$value = \mb_strtolower($value);
403 23
		return $map[$value] ?? \mb_convert_case($value, MB_CASE_TITLE);
404
	}
405
}