Passed
Push — main ( 4dd032...ebaf8d )
by Will
03:20
created

devices::get()   F

Complexity

Conditions 34
Paths 1

Size

Total Lines 402
Code Lines 327

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 389
CRAP Score 34

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 34
eloc 327
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 402
ccs 389
cts 390
cp 0.9974
crap 34
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 devices {
6
7
	/**
8
	 * Generates a configuration array for matching devices
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 91
	public static function get() : array {
13 3
		$fn = [
14 3
			'ios' => function (string $value, int $i, array $tokens) : array {
15 19
				$version = null;
16 19
				$model = null;
17
18
				// device name with slash like iPhone/16.5
19 19
				$parts = \explode('/', $value, 3);
20 19
				if (isset($parts[1])) {
21 1
					$value = $parts[0];
22 1
					$version = $parts[1];
23
				}
24
25
				// look at other tokens to gather info
26 19
				foreach ($tokens AS $item) {
27 19
					if (\str_starts_with($item, 'Mobile/')) {
28 19
						$model = \mb_substr($item, 7);
29 19
					} elseif (\str_starts_with($item, 'CPU iPhone OS ')) {
30 18
						$version = \str_replace('_', '.', \mb_substr($item, 14, \mb_strpos($item, ' ', 14) - 14));
31 19
					} elseif (\str_starts_with($item, 'CPU OS ')) {
32 2
						$version = \str_replace('_', '.', \mb_substr($item, 7, \mb_strpos($item, ' ', 7) - 7));
33
					}
34
				}
35 19
				return [
36 19
					'type' => 'human',
37 19
					'category' => $value === 'iPad' ? 'tablet' : 'mobile',
38 19
					'architecture' => 'Arm',
39 19
					'bits' => $value === 'iPod' ? 32 : 64,
40 19
					'kernel' => 'Linux',
41 19
					'platform' => 'iOS',
42 19
					'platformversion' => $version,
43 19
					'vendor' => 'Apple',
44 19
					'device' => \mb_stripos($value, 'iPhone') === 0 ? 'iPhone' : $value,
45 19
					'model' => $model
46 19
				];
47 3
			},
48 3
			'xbox' => fn (string $value) : array => [
49 3
				'type' => 'human',
50 3
				'category' => 'console',
51 3
				'vendor' => 'Microsoft',
52 3
				'device' => 'Xbox',
53 3
				'model' => ($model = \mb_substr($value, 5)) === '' ? null : $model
54 3
			],
55 3
			'playstation' => function (string $value) : array {
56 1
				$parts = \explode(' ', $value);
57 1
				if (\str_contains($parts[1], '/')) {
58 1
					list($parts[1], $parts[2]) = \explode('/', $parts[1]);
59
				}
60 1
				$platform = [
61 1
					'4' => 'Orbis OS',
62 1
					'5' => 'FreeBSD'
63 1
				];
64 1
				return [
65 1
					'device' => 'PlayStation',
66 1
					'model' => $parts[1] ?? null,
67 1
					'kernel' => 'Linux',
68 1
					'platform' => $platform[$parts[1]] ?? null,
69 1
					'platformversion' => $parts[2] ?? null,
70 1
					'type' => 'human',
71 1
					'category' => 'console',
72 1
					'vendor' => 'Sony',
73 1
					'processor' => 'AMD',
74 1
					'architecture' => 'x86',
75 1
					'bits' => 64
76 1
				];
77 3
			},
78 3
			'firetablet' => function (string $value) : ?array {
79 3
				$model = \explode(' ', $value)[0];
80 3
				if (\ctype_alpha($model) && \mb_strlen($model) <= 7) {
81 3
					return [
82 3
						'type' => 'human',
83 3
						'category' => 'tablet',
84 3
						'vendor' => 'Amazon',
85 3
						'device' => 'Fire Tablet',
86 3
						'model' => $model
87 3
					];
88
				}
89
				return null;
90 3
			}
91 3
		];
92 34
		return [
93 34
			'iPhone' => new props('start', $fn['ios']),
94 34
			'iPad' => new props('exact', $fn['ios']),
95 34
			'iPod' => new props('exact', $fn['ios']),
96 34
			'iPod touch' => new props('exact', $fn['ios']),
97 34
			'Macintosh' => new props('exact', [
98 34
				'vendor' => 'Apple',
99 34
				'device' => 'Macintosh'
100 34
			]),
101 34
			'Quest' => new props('start', fn (string $value) : array => [
102 4
				'vendor' => 'Oculus',
103 4
				'device' => 'Quest',
104 4
				'model' => ($model = \mb_substr($value, 6)) === '' ? null : $model,
105 4
				'type' => 'human',
106 4
				'category' => 'vr'
107 4
			]),
108 34
			'Pacific' => new props('start', [
109 34
				'vendor' => 'Oculus',
110 34
				'device' => 'Go',
111 34
				'type' => 'human',
112 34
				'category' => 'vr'
113 34
			]),
114 34
			'Nintendo' => new props('start', fn (string $value) : array => [
115 4
				'type' => 'human',
116 4
				'category' => 'console',
117 4
				'vendor' => 'Nintendo',
118 4
				'device' => $value === 'Nintendo WiiU' ? 'Wii U' : \mb_substr($value, 9),
119 4
				'architecture' => \str_ends_with($value, 'U') ? 'PowerPC' : null
120 4
			]),
121 34
			'Xbox Series S' => new props('exact', $fn['xbox']),
122 34
			'Xbox Series X' => new props('exact', $fn['xbox']),
123 34
			'Xbox One' => new props('exact', $fn['xbox']),
124 34
			'Xbox 360' => new props('exact', $fn['xbox']),
125 34
			'Xbox' => new props('exact', $fn['xbox']),
126 34
			'Playstation 3' => new props('start', $fn['playstation']),
127 34
			'Playstation 4' => new props('start', $fn['playstation']),
128 34
			'Playstation 5' => new props('start', $fn['playstation']),
129 34
			'Playstation Vita' => new props('start', fn (string $value) : array => [
130 2
				'type' => 'human',
131 2
				'category' => 'console',
132 2
				'vendor' => 'Sony',
133 2
				'device' => 'PlayStation',
134 2
				'model' => 'Vita',
135 2
				'architecture' => 'Arm',
136 2
				'processor' => 'MediaTek',
137 2
				'cpu' => 'Cortex-A9 MPCore',
138 2
				'bits' => 32,
139 2
				'width' => 960,
140 2
				'height' => 544,
141 2
				'dpi' => 220,
142 2
				'ram' => 512,
143 2
				'kernel' => 'Linux',
144 2
				'platform' => 'PlayStation Vita System Software',
145 2
				'platformversion' => \mb_substr($value, 17)
146 2
			]),
147 34
			'Playstation Portable' => new props('start', fn (string $value, int $i, array $tokens) : array => [
148 2
				'type' => 'human',
149 2
				'category' => 'console',
150 2
				'vendor' => 'Sony',
151 2
				'device' => 'PlayStation',
152 2
				'model' => 'PSP',
153 2
				'architecture' => 'Arm',
154 2
				'cpu' => 'MIPS R4000',
155 2
				'cpuclock' => 333,
156 2
				'bits' => 64,
157 2
				'width' => 480,
158 2
				'height' => 272,
159 2
				'ram' => 64,
160 2
				'kernel' => 'Linux',
161 2
				'platform' => 'PlayStation Portable System Software',
162 2
				'platformversion' => $tokens[++$i],
163 2
				'browser' => 'NetFront',
164 2
				'engine' => 'WebKit'
165 2
			]),
166 34
			'SHIELD Android TV' => new props('start', [
167 34
				'type' => 'human',
168 34
				'category' => 'console',
169 34
				'vendor' => 'NVIDIA',
170 34
				'device' => 'Shield'
171 34
			]),
172 34
			'CrKey/' => new props('start', fn (string $value) : array => [
173 3
				'type' => 'human',
174 3
				'category' => 'tv',
175 3
				'app' => 'Chromecast',
176 3
				'appname' => 'CrKey',
177 3
				'appversion' => \explode(',', \mb_substr($value, 6), 2)[0]
178 3
			]),
179 34
			'ChromeBook' => new props('any', [
180 34
				'type' => 'human',
181 34
				'category' => 'desktop'
182 34
			]),
183 34
			'GoogleTV' => new props('exact', [
184 34
				'type' => 'human',
185 34
				'category' => 'tv',
186 34
				'device' => 'GoogleTV'
187 34
			]),
188 34
			'CriKey/' => new props('start', fn (string $value) : array => [
189 1
				'type' => 'human',
190 1
				'category' => 'tv',
191 1
				'device' => 'Chromecast',
192 1
				'vendor' => 'Google',
193 1
				'platformversion' => \mb_substr($value, 7)
194 1
			]),
195 34
			'Apple/' => new props('start', function (string $value) : array {
196 1
				$value = \mb_substr($value, 6);
197 1
				$split = \strcspn($value, '0123456789');
198 1
				$device = \mb_substr($value, 0, $split);
199 1
				return [
200 1
					'type' => 'human',
201 1
					'category' => $device === 'iPad' ? 'tablet' : 'mobile',
202 1
					'vendor' => 'Apple',
203 1
					'device' => $device,
204 1
					'model' => \mb_substr($value, $split) ?: null
205 1
				];
206 34
			}),
207 34
			'hw/iPhone' => new props('start', fn (string $value) : array => [
208 1
				'platform' => 'iOS',
209 1
				'vendor' => 'Apple',
210 1
				'device' => 'iPhone',
211 1
				'model' => \str_replace('_', '.', \mb_substr($value, 9))
212 1
			]),
213 34
			'KF' => new props('start', $fn['firetablet']),
214 34
			'AFT' => new props('start', fn (string $value) : array => [
215 2
				'type' => 'human',
216 2
				'category' => 'tv',
217 2
				'vendor' => 'Amazon',
218 2
				'device' => 'Fire TV',
219 2
				'model' => $value
220 2
			]),
221 34
			'Roku/' => new props('start', fn (string $value, int $i, array $tokens) : array => [
222 2
				'type' => 'human',
223 2
				'category' => 'tv',
224 2
				'kernel' => 'Linux',
225 2
				'platform' => 'Roku OS',
226 2
				'platformversion' => \mb_substr($value, 5),
227 2
				'vendor' => 'Roku',
228 2
				'device' => 'Roku',
229 2
				'build' => $tokens[++$i] ?? null
230 2
			]),
231 34
			'AmigaOneX' => new props('start', fn (string $value) : array => [
232 2
				'type' => 'human',
233 2
				'category' => 'desktop',
234 2
				'vendor' => 'A-Eon Technology',
235 2
				'device' => 'AmigaOne',
236 2
				'model' => \mb_substr($value, 8)
237 2
			]),
238 34
			'googleweblight' => new props('exact', [
239 34
				'proxy' => 'googleweblight'
240 34
			]),
241 34
			'SAMSUNG-' => new props('start', function (string $value) : array {
242 2
				$parts = \explode('/', $value, 2);
243 2
				return [
244 2
					'type' => 'human',
245 2
					'category' => 'mobile',
246 2
					'vendor' => 'Samsung',
247 2
					'model' => \mb_substr($parts[0], 8),
248 2
					'build' => $parts[1] ?? null,
249 2
				];
250 34
			}),
251 12
			'Samsung' => new props('start', fn (string $value) : ?array => \str_starts_with($value, 'SamsungBrowser') ? null : [
252 12
				'vendor' => 'Samsung'
253 12
			]),
254 34
			'SM-' => new props('start', function (string $value) : array {
255 10
				$parts = \explode('.', \explode(' ', $value)[0]);
256 10
				return [
257 10
					'vendor' => 'Samsung',
258 10
					'model' => $parts[0],
259 10
					'build' => $parts[1] ?? null
260 10
				];
261 34
			}),
262 34
			'Acer' => new props('start', [
263 34
				'vendor' => 'Acer'
264 34
			]),
265 34
			'SonyEricsson' => new props('start', function (string $value) : array {
266 1
				$parts = \explode('/', $value, 2);
267 1
				return [
268 1
					'type' => 'human',
269 1
					'category' => 'mobile',
270 1
					'vendor' => 'Sony Ericsson',
271 1
					'model' => \mb_substr($parts[0], 12),
272 1
					'build' => $parts[1] ?? null
273 1
				];
274 34
			}),
275 34
			'LGE' => new props('exact', function (string $value, int $i, array $tokens) : array {
276 1
				$device = $tokens[++$i] ?? null;
277 1
				$platformversion = empty($tokens[++$i]) ? null : \mb_substr(\explode(' ', $tokens[$i])[0], 5);
278 1
				$build = $tokens[++$i] ?? null;
279 1
				return [
280 1
					'type' => 'human',
281 1
					'category' => 'tv',
282 1
					'model' => $device,
283 1
					'build' => $build,
284 1
					'platformversion' => $platformversion,
285 1
					'vendor' => 'LG'
286 1
				];
287 34
			}),
288 34
			'LG-' => new props('start', function (string $value) : array {
289 1
				$parts = \explode('/', \mb_substr($value, 3), 3);
290 1
				return [
291 1
					'type' => 'human',
292 1
					'category' => 'mobile',
293 1
					'vendor' => 'LG',
294 1
					'model' => \explode(' ', $parts[0])[0],
295 1
					'build' => $parts[1] ?? null
296 1
				];
297 34
			}),
298 34
			'NOKIA' => new props('start', fn (string $value) : array => \array_merge(devices::getDevice($value), [
299 34
				'type' => 'human',
300 34
				'category' => 'mobile',
301 34
				'vendor' => 'Nokia',
302 34
			])),
303 34
			'Lumia' => new props('start', fn (string $value) : array => \array_merge(devices::getDevice($value), [
304 34
				'type' => 'human',
305 34
				'category' => 'mobile',
306 34
				'vendor' => 'Nokia'
307 34
			])),
308 34
			'BRAVIA' => new props('start', [
309 34
				'type' => 'human',
310 34
				'category' => 'tv',
311 34
				'vendor' => 'Sony',
312 34
				'device' => 'Bravia'
313 34
			]),
314 34
			'TECNO' => new props('start', fn (string $value) : array => [
315 3
				'type' => 'human',
316 3
				'category' => 'mobile',
317 3
				'vendor' => 'Tecno',
318 3
				'model' => \explode(' ', \str_replace('-', ' ', $value), 2)[1] ?? null
319 3
			]),
320 34
			'Xiaomi' => new props('start', function (string $value, int $i, array $tokens) : array {
321 5
				return [
322 5
					'type' => 'human',
323 5
					'vendor' => 'Xiaomi',
324 5
					'device' => \mb_stripos($value, 'Poco') !== false ? 'Poco' : null,
325 5
					'model' => \mb_stripos($value, 'Xiaomi-Mi') !== 0 ? (\explode(' ', $value)[1] ?? null) : null,
326 5
					'platformversion' => \is_numeric($tokens[$i+1] ?? null) ? $tokens[$i+1] : null
327 5
				];
328 34
			}),
329 34
			'ThinkPad' => new props('start', function (string $value, int $i, array $tokens) : array {
330 1
				if (\mb_strpos($tokens[++$i] ?? '', 'Build/') === 0) {
331 1
					$device = \explode('_', \mb_substr($tokens[$i], 6));
332
				}
333 1
				return [
334 1
					'type' => 'human',
335 1
					'vendor' => 'Lenovo',
336 1
					'device' => $device[0] ?? null,
337 1
					'model' => $device[1] ?? null,
338 1
					'build' => $device[2] ?? null
339 1
				];
340 34
			}),
341 34
			'BlackBerry' => new props('start', function (string $value) : array {
342 1
				$parts = \explode('/', $value);
343 1
				return [
344 1
					'type' => 'human',
345 1
					'category' => 'mobile',
346 1
					'vendor' => 'Blackberry',
347 1
					'device' => \mb_substr($parts[0], 10) ?: null,
348 1
					'platform' => 'Blackberry OS',
349 1
					'platformversion' => $parts[1] ?? null
350 1
				];
351 34
			}),
352 34
			'CUBOT' => new props('exact', fn () : array => [
353 2
				'type' => 'human',
354 2
				'vendor' => 'Cubot'
355 2
			]),
356 34
			'TCL ' => new props('start', fn (string $value) : array => [
357 2
				'type' => 'human',
358 2
				'category' => 'tv',
359 2
				'vendor' => 'TCL',
360 2
				'model' => \mb_substr($value, 4)
361 2
			]),
362 34
			'deviceName/' => new props('start', fn (string $value) : array => self::getDevice(\mb_substr($value, 11))),
363 34
			'deviceModel/' => new props('start', fn (string $value) : array => [
364 2
				'model' => \mb_substr($value, 12)
365 2
			]),
366 34
			'Model/' => new props('start', fn (string $value) : array => [
367 1
				'model' => \mb_substr($value, 6)
368 1
			]),
369 34
			'Build/' => new props('any', fn (string $value) : array => self::getDevice($value)),
370 34
			'width=' => new props('start', fn (string $value) : array => [
371 2
				'width' => \intval(\mb_substr($value, 6))
372 2
			]),
373 34
			'height=' => new props('start', fn (string $value) : array => [
374 2
				'height' => \intval(\mb_substr($value, 7))
375 2
			]),
376 34
			'dpi=' => new props('start', fn (string $value) : array => [
377 1
				'dpi' => \mb_substr($value, 4)
378 1
			]),
379 34
			'NetType/' => new props('start', function (string $value) : array {
380 4
				$type = \mb_convert_case(\mb_substr($value, 8), MB_CASE_UPPER);
381 4
				return [
382 4
					'nettype' => \in_array($type, ['WF', 'WIFI'], true) ? 'WiFi' : $type
383 4
				];
384 34
			}),
385 34
			'netWorkType/' => new props('start', function (string $value) : array {
386 1
				$type = \mb_convert_case(\mb_substr($value, 12), MB_CASE_UPPER);
387 1
				return [
388 1
					'nettype' => \in_array($type, ['WF', 'WIFI'], true) ? 'WiFi' : $type
389 1
				];
390 34
			}),
391 34
			'2G' => new props('exact', ['nettype' => '2g']),
392 34
			'3G' => new props('exact', ['nettype' => '3g']),
393 34
			'4G' => new props('exact', ['nettype' => '4g']),
394 34
			'4.5G' => new props('exact', ['nettype' => '4g']),
395 34
			'4.5G+' => new props('exact', ['nettype' => '4g']),
396 34
			'5G' => new props('exact', ['nettype' => '5g']),
397 34
			'x' => new props('any', function (string $value) : ?array {
398 91
				if (\str_contains($value, '@')) {
399 2
					$dpi = \explode('@', $value);
400 2
					$value = $dpi[0];
401
				}
402 91
				$parts = \explode('x', $value);
403 91
				if (!isset($parts[2]) && \is_numeric($parts[0]) && \is_numeric($parts[1]) && !empty($parts[0]) && !empty($parts[1])) {
404 11
					return [
405 11
						'width' => \intval($parts[0]),
406 11
						'height' => \intval($parts[1]),
407 11
						'density' => isset($dpi[1]) ? \floatval(\rtrim($dpi[1], 'x')) : null
408 11
					];
409
				}
410 91
				return null;
411 34
			}),
412 34
			'MB' => new props('end', fn (string $value) : array => [
413 2
				'ram' => \intval(\mb_substr($value, 0, -2))
414 2
			])
415 34
		];
416
	}
417
418
	/**
419
	 * Extracts device information from a token
420
	 * 
421
	 * @param string $value A token expected to contain device information
422
	 * @return array<string,string|null> An array containing the extracted devices information
423
	 */
424 43
	public static function getDevice(string $value) : array {
425 43
		foreach (['Mobile', 'Tablet', 'Safari', 'AppleWebKit', 'Linux', 'rv:'] AS $item) {
426 43
			if (\mb_stripos($value, $item) === 0) {
427 8
				return [];
428
			}
429
		}
430 38
		$parts = \explode('Build/', \str_ireplace('build/', 'Build/', $value), 2);
0 ignored issues
show
Bug introduced by
It seems like str_ireplace('build/', 'Build/', $value) can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

430
		$parts = \explode('Build/', /** @scrutinizer ignore-type */ \str_ireplace('build/', 'Build/', $value), 2);
Loading history...
431 38
		$parts[0] = \trim($parts[0]);
432 38
		$build = $parts[1] ?? null;
433 38
		$vendors = [
434 38
			'Samsung' => 'Samsung',
435 38
			'OnePlus' => 'OnePlus',
436 38
			'CPH' =>'OnePlus',
437 38
			'KB' => 'OnePlus',
438 38
			'Pixel' => 'Google',
439 38
			'SM-' => 'Samsung',
440 38
			'LM-' => 'LG',
441 38
			'LG' => 'LG',
442 38
			'LG-' => 'LG',
443 38
			'RealMe' => 'RealMe',
444 38
			'RMX' => 'RealMe',
445 38
			'HTC' => 'HTC',
446 38
			'Nexus' => 'Google',
447 38
			'Redmi' => 'Redmi', // must be above 'MI '
448 38
			'MI ' => 'Xiaomi',
449 38
			'HM ' => 'Xiaomi',
450 38
			'Xiaomi' => 'Xiaomi',
451 38
			'Huawei' => 'Huawei',
452 38
			'Honor' => 'Honor',
453 38
			'Motorola' => 'Motorola',
454 38
			'moto' => 'Motorola',
455 38
			'Intel' => 'Intel',
456 38
			'SonyEricsson' => 'Sony Ericsson',
457 38
			'Tecno' => 'Tecno',
458 38
			'Vivo' => 'Vivo',
459 38
			'Oppo' => 'Oppo',
460 38
			'Asus' => 'Asus',
461 38
			'Acer' => 'Acer',
462 38
			'Alcatel' => 'Alcatel',
463 38
			'Infinix' => 'Infinix',
464 38
			'Poco' => 'Poco',
465 38
			'Cubot' => 'Cubot',
466 38
			'Kingkong' => 'Cubot',
467 38
			'Nokia' => 'Nokia',
468 38
			'WR' => 'Westinghouse',
469 38
			'HKP' => 'HKPro',
470 38
			'Roku' => 'Roku',
471 38
			'TCL' => 'TCL'
472 38
		];
473
474
		// find vendor
475 38
		$vendor = null;
476 38
		foreach ($vendors AS $key => $item) {
477 38
			if (($pos = \mb_stripos($value, $key)) !== false) {
478 29
				$vendor = self::getVendor($item);
479
480
				// remove vendor name
481 29
				if ($pos === 0 && ($key === $item || $key === 'SonyEricsson')) {
482 17
					$parts[0] = \trim(\mb_substr($parts[0], \mb_strlen($key)), ' -_/');
483
				}
484 29
				break;
485
			}
486
		}
487 38
		$model = \explode(' ', \str_replace('_', ' ', $parts[0]), 2);
488 38
		$device = $model[0] !== '' && \ctype_alpha($model[0]) ? \ucfirst($model[0]) : null; // device name if only letters
489 38
		$model = $device === null ? \implode(' ', $model) : ($model[1] ?? null); // reconstruct remainder of device name
490
491
		// remove everything after a slash
492 38
		if ($build === null && \str_contains($model ?? '', '/')) {
493 1
			$model = \mb_strstr($model, '/', true);
0 ignored issues
show
Bug introduced by
It seems like $model can also be of type null; however, parameter $haystack of mb_strstr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

493
			$model = \mb_strstr(/** @scrutinizer ignore-type */ $model, '/', true);
Loading history...
494
		}
495
496
		// special case for SMART TV
497 38
		if (\strcasecmp($device.$model, 'smarttv') === 0) {
498 1
			$device = 'Smart TV';
499 1
			$model = null;
500
		}
501
		// var_dump($value, $parts, $device, $model);
502 38
		return [
503 38
			'vendor' => $vendor,
504 38
			'device' => $device,
505 38
			'model' => $model ? \ucwords($model) : null,
506 38
			'build' => $build
507 38
		];
508
	}
509
510 30
	public static function getVendor(string $value) : string {
511 30
		$map = [
512 30
			'oneplus' => 'OnePlus',
513 30
			'lg' => 'LG',
514 30
			'lge' => 'LG',
515 30
			'realme' => 'RealMe',
516 30
			'htc' => 'HTC',
517 30
			'sonyericsson' => 'Sony Ericsson',
518 30
			'tcl' => 'TCL',
519 30
			'zte' => 'ZTE',
520 30
			'hmd' => 'HMD',
521 30
			'lt' => 'LT'
522 30
		];
523 30
		$value = \mb_strtolower($value);
524 30
		return $map[$value] ?? \mb_convert_case($value, MB_CASE_TITLE);
525
	}
526
}