Passed
Push — main ( e55150...6ce6d7 )
by Will
02:49
created

platforms   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 313
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 33
eloc 242
c 3
b 0
f 0
dl 0
loc 313
ccs 290
cts 290
cp 1
rs 9.76

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getPlatform() 0 13 1
F get() 0 289 32
1
<?php
2
declare(strict_types = 1);
3
namespace hexydec\agentzero;
4
5
/**
6
 * @phpstan-import-type props from config
7
 */
8
class platforms {
9
10
	/**
11
	 * Generates a configuration array for matching platforms
12
	 * 
13
	 * @return props An array with keys representing the string to match, and a value of an array containing parsing and output settings
14
	 */
15 51
	public static function get() : array {
16 1
		$fn = [
17 1
			'platformlinux' => function (string $value) : array {
18 10
				if (!\str_starts_with($value, 'Red Hat/') && ($platform = \mb_strstr($value, ' ', true)) !== false) {
19 1
					$value = $platform;
20
				}
21 10
				$parts = \explode('/', $value, 2);
22 10
				if (!isset($parts[1])) {
23 8
					$parts = \explode('-', $value, 2);
24
				}
25 10
				if (!isset($parts[1])) {
26 6
					$parts = \explode(' ', $value, 2);
27
				}
28 10
				return [
29 10
					'type' => 'human',
30 10
					'category' => 'desktop',
31 10
					'kernel' => 'Linux',
32 10
					'platform' => self::getPlatform($parts[0]),
33 10
					'platformversion' => $parts[1] ?? null
34 10
				];
35 1
			},
36 1
			'platformwindows' => function (string $value) : array {
37 41
				$mapping = [
38 41
					'5.0' => '2000',
39 41
					'5.1' => 'XP',
40 41
					'5.2' => 'XP',
41 41
					'6.0' => 'Vista',
42 41
					'6.1' => '7',
43 41
					'6.2' => '8',
44 41
					'6.3' => '8.1',
45 41
					'10.0' => '10'
46 41
				];
47 41
				$version = null;
48 41
				foreach (['Windows NT ', 'Windows '] AS $item) {
49 41
					if (($pos = \mb_stripos($value, $item)) !== false) {
50 41
						$version = \explode(' ', \mb_substr($value, $pos + \mb_strlen($item)))[0];
51 41
						break;
52
					}
53
				}
54 41
				return [
55 41
					'type' => 'human',
56 41
					'category' => 'desktop',
57 41
					'kernel' => 'Windows NT',
58 41
					'platform' => 'Windows',
59 41
					'platformversion' => $mapping[$version] ?? $version
60 41
				];
61 1
			},
62 1
			'android' => function (string $value, int $i, array $tokens) : array {
63 31
				$os = \explode(' ', $value, 3);
64
65
				// skip language
66 31
				if (!empty($tokens[++$i]) && (\strlen($tokens[$i]) === 2 || (\strlen($tokens[$i]) === 5 && \mb_strpos($tokens[$i], '_') === 2))) {
67 2
					$i++;
68
				}
69
70
				// only where the token length is greater than 2, or it doesn't contain a /, or if it does it is Build/
71 31
				$device = empty($tokens[$i]) || \strlen($tokens[$i]) <= 2 || (\str_contains($tokens[$i], '/') && \mb_stripos($tokens[$i], 'Build/') === false) ? [] : devices::getDevice($tokens[$i]);
72 31
				return \array_merge($device, [
73 31
					'type' => 'human',
74 31
					'platform' => 'Android',
75 31
					'platformversion' => isset($os[1]) ? \explode('/', $os[1])[0] : null
76 31
				]);
77 1
			}
78 1
		];
79
80 1
		return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('Windows NT...on(...) { /* ... */ })) returns the type array<string,hexydec\agentzero\props> which is incompatible with the documented return type hexydec\agentzero\props.
Loading history...
81
82
			// platforms
83 1
			'Windows NT ' => new props('any', $fn['platformwindows']),
84 1
			'Windows Phone' => new props('start', function (string $value) : array {
85 3
				$version = \mb_substr($value, 14);
86 3
				return [
87 3
					'type' => 'human',
88 3
					'category' => 'mobile',
89 3
					'platform' => 'Windows Phone',
90 3
					'platformversion' => $version,
91 3
					'kernel' => \intval($version) >= 8 ? 'Windows NT' : 'Windows CE'
92 3
				];
93 1
			}),
94 1
			'Win98' => new props('start', [
95 1
				'type' => 'human',
96 1
				'category' => 'desktop',
97 1
				'architecture' => 'x86',
98 1
				'bits' => 32,
99 1
				'kernel' => 'MS-DOS',
100 1
				'platform' => 'Windows',
101 1
				'platformversion' => '98'
102 1
			]),
103 1
			'Win32' => new props('exact', [
104 1
				'type' => 'human',
105 1
				'category' => 'desktop',
106 1
				'architecture' => 'x86',
107 1
				'bits' => 32,
108 1
				'platform' => 'Windows'
109 1
			]),
110 1
			'Win64' => new props('exact', [
111 1
				'type' => 'human',
112 1
				'category' => 'desktop',
113 1
				'bits' => 64,
114 1
				'platform' => 'Windows'
115 1
			]),
116 1
			'WinNT' => new props('start', fn (string $value) : array => [
117 2
				'type' => 'human',
118 2
				'category' => 'desktop',
119 2
				'architecture' => 'x86',
120 2
				'bits' => 32,
121 2
				'kernel' => 'Windows NT',
122 2
				'platform' => 'Windows',
123 2
				'platformversion' => \mb_substr($value, 5)
124 2
			]),
125 1
			'Windows' => new props('any', $fn['platformwindows']),
126 1
			'Mac OS X' => new props('any', function (string $value) : array {
127 25
				$version = \str_replace('_', '.', \mb_substr($value, \mb_stripos($value, 'Mac OS X') + 9));
128 25
				$register = $version && \intval(\explode('.', $version)[1] ?? 0) >= 6 ? 64 : null;
129 25
				return [
130 25
					'type' => 'human',
131 25
					'category' => 'desktop',
132 25
					'kernel' => 'Linux',
133 25
					'platform' => 'Mac OS X',
134 25
					'platformversion' => $version === '' ? null : $version,
135 25
					'bits' => $register
136 25
				];
137 1
			}),
138 1
			'AppleTV' => new props('exact', [
139 1
				'type' => 'human',
140 1
				'category' => 'tv',
141 1
				'device' => 'AppleTV',
142 1
				'platform' => 'tvOS',
143 1
				'bits' => 64
144 1
			]),
145 1
			'iOS/' => new props('start', fn (string $value) : array => [
146 2
				'type' => 'human',
147 2
				'category' => 'mobile',
148 2
				'platform' => 'iOS',
149 2
				'platformversion' => \mb_substr($value, 4)
150 2
			]),
151 1
			'CrOS' => new props('start', function (string $value) : array {
152 4
				$parts = \explode(' ', $value);
153 4
				return [
154 4
					'type' => 'human',
155 4
					'category' => 'desktop',
156 4
					'platform' => 'Chrome OS',
157 4
					'platformversion' => $parts[2] ?? null
158 4
				];
159 1
			}),
160 1
			'Kindle/' => new props('start', fn (string $value) : array => [
161 2
				'type' => 'human',
162 2
				'category' => 'ebook',
163 2
				'platform' => 'Kindle',
164 2
				'platformversion' => \mb_substr($value, 7)
165 2
			]),
166 1
			'Tizen' => new props('start', function (string $value) : array {
167 1
				$parts = \explode(' ', $value, 2);
168 1
				return [
169 1
					'type' => 'human',
170 1
					'category' => 'desktop',
171 1
					'kernel' => 'Linux',
172 1
					'platform' => 'Tizen',
173 1
					'platformversion' => $parts[1] ?? null
174 1
				];
175 1
			}),
176 1
			'Ubuntu' => new props('start', $fn['platformlinux']),
177 1
			'Kubuntu' => new props('start', $fn['platformlinux']),
178 1
			'Mint' => new props('start', $fn['platformlinux']),
179 1
			'SUSE' => new props('start', $fn['platformlinux']),
180 1
			'Red Hat/' => new props('start', $fn['platformlinux']),
181 1
			'Debian' => new props('start', $fn['platformlinux']),
182 1
			'Darwin' => new props('start', $fn['platformlinux']),
183 1
			'Fedora' => new props('start', $fn['platformlinux']),
184 1
			'CentOS' => new props('start', $fn['platformlinux']),
185 1
			'Rocky' => new props('start', $fn['platformlinux']),
186 1
			'Alma' => new props('start', $fn['platformlinux']),
187 1
			'Gentoo' => new props('start', $fn['platformlinux']),
188 1
			'Slackware' => new props('start', $fn['platformlinux']),
189 1
			'ArchLinux' => new props('exact', fn () : array => [
190 1
				'type' => 'human',
191 1
				'category' => 'desktop',
192 1
				'kernel' => 'Linux',
193 1
				'platform' => 'Arch',
194 1
			]),
195 1
			'Arch' => new props('exact', fn (string $value) : array => [
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

195
			'Arch' => new props('exact', fn (/** @scrutinizer ignore-unused */ string $value) : array => [

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
196 1
				'type' => 'human',
197 1
				'category' => 'desktop',
198 1
				'kernel' => 'Linux',
199 1
				'platform' => 'Arch',
200 1
			]),
201 1
			'Web0S' => new props('exact', $fn['platformlinux']),
202 1
			'webOSTV' => new props('exact', [
203 1
				'type' => 'human',
204 1
				'category' => 'tv',
205 1
				'kernel' => 'Linux',
206 1
				'platform' => 'WebOS'
207 1
			]),
208 1
			'WEBOS' => new props('start', fn (string $value) : array => [
209 2
				'type' => 'human',
210 2
				'category' => 'tv',
211 2
				'kernel' => 'Linux',
212 2
				'platform' => 'WebOS',
213 2
				'platformversion' => \mb_substr($value, 5)
214 2
			]),
215 1
			'SunOS' => new props('start', [
216 1
				'type' => 'human',
217 1
				'category' => 'desktop',
218 1
				'kernel' => 'unix',
219 1
				'platform' => 'Solaris',
220 1
			]),
221 1
			'AmigaOS' => new props('any', function (string $value) : array {
222 3
				if (($pos = \mb_stripos($value, 'AmigaOS')) !== false) {
223 3
					$value = \mb_substr($value, $pos);
224
				}
225 3
				$parts = \explode(' ', $value, 2);
226 3
				return [
227 3
					'type' => 'human',
228 3
					'category' => 'desktop',
229 3
					'kernel' => 'Exec',
230 3
					'platform' => 'AmigaOS',
231 3
					'platformversion' => isset($parts[1]) && \strspn($parts[1], '0123456789.-_') === \strlen($parts[1]) ? $parts[1] : null
232 3
				];
233 1
			}),
234 1
			'Fuchsia' => new props('exact', function (string $value, int $i, array $tokens) : array {
235 1
				$os = \explode(' ', $tokens[++$i], 2);
236 1
				return [
237 1
					'type' => 'human',
238 1
					'category' => 'mobile',
239 1
					'kernel' => 'Zircon',
240 1
					'platform' => 'Fuchsia',
241 1
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
242 1
				];
243 1
			}),
244 1
			'Maemo' => new props('exact', function (string $value, int $i, array $tokens) : array {
245 1
				$os = \explode(' ', $tokens[++$i], 2);
246 1
				return [
247 1
					'type' => 'human',
248 1
					'category' => 'mobile',
249 1
					'kernel' => 'Linux',
250 1
					'platform' => 'Maemo',
251 1
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
252 1
				];
253 1
			}),
254 1
			'J2ME/MIDP' => new props('exact', fn (string $value) : array => [
255 3
				'type' => 'human',
256 3
				'category' => 'mobile',
257 3
				'kernel' => 'Java VM',
258 3
				'platform' => $value
259 3
			]),
260 1
			'Haiku' => new props('any', function (string $value) : array {
261 3
				$parts = \explode('/', $value, 2);
262 3
				return [
263 3
					'type' => 'human',
264 3
					'category' => 'desktop',
265 3
					'kernel' => 'Haiku',
266 3
					'platform' => 'Haiku',
267 3
					'platformversion' => $parts[1] ?? null
268 3
				];
269 1
			}),
270 1
			'BeOS' => new props('start', function (string $value) : array {
271 1
				$parts = \explode('/', $value, 2);
272 1
				return [
273 1
					'type' => 'human',
274 1
					'category' => 'desktop',
275 1
					'kernel' => 'BeOS',
276 1
					'platform' => 'BeOS',
277 1
					'platformversion' => $parts[1] ?? null
278 1
				];
279 1
			}),
280 1
			'Android' => new props('exact', $fn['android']),
281 1
			'Android ' => new props('start', $fn['android']),
282 1
			'Linux' => new props('any', function (string $value, int $i, array $tokens) : array {
283 51
				return [
284 51
					'kernel' => 'Linux',
285 51
					'platform' => 'Linux',
286 51
					'platformversion' => \str_contains($tokens[$i + 1] ?? '', '.') && \strspn($tokens[$i + 1], '0123456789.') >= 3 ? \explode(' ', $tokens[$i + 1])[0] : null
287 51
				];
288 1
			}),
289 1
			'X11' => new props('exact', function (string $value, int $i, array $tokens) : array {
290 28
				$os = \explode(' ', $tokens[++$i] ?? '', 2);
291 28
				return [
292 28
					'category' => 'desktop',
293 28
					'kernel' => 'Linux',
294 28
					'platform' => $os[0] ?: 'X11',
295 28
					'platformversion' => isset($os[1]) && \strspn($os[1], '0123456789.-_', \strlen($os[0])) === \strlen($os[1]) ? $os[1] : null
296 28
				];
297 1
			}),
298 1
			'OS/2' => new props('exact', [
299 1
				'category' => 'desktop',
300 1
				'platform' => 'OS/2'
301 1
			]),
302 1
			'Version/' => new props('start', fn (string $value) : array => [
303 37
				'platformversion' => \mb_substr($value, 8)
304 37
			])
305 1
		];
306
	}
307
308 15
	public static function getPlatform(string $value) : string {
309 15
		$map = [
310 15
			'webos' => 'WebOS',
311 15
			'web0s' => 'WebOS',
312 15
			'j2me/midp' => 'J2ME/MIDP',
313 15
			'centos' => 'CentOS',
314 15
			'suse' => 'SUSE',
315 15
			'freebsd' => 'FreeBSD',
316 15
			'openbsd' => 'OpenBSD',
317 15
			'netbsd' => 'NetBSD'
318 15
		];
319 15
		$value = \mb_strtolower($value);
320 15
		return $map[$value] ?? \mb_convert_case($value, MB_CASE_TITLE);
321
	}
322
}