Passed
Push — main ( 55ce30...607587 )
by Will
12:52
created

platforms::get()   F

Complexity

Conditions 43
Paths 1

Size

Total Lines 355
Code Lines 280

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 330
CRAP Score 43

Importance

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