devices::get()   F
last analyzed

Complexity

Conditions 34
Paths 1

Size

Total Lines 401
Code Lines 326

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 388
CRAP Score 34

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 34
eloc 326
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 401
ccs 388
cts 389
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' => $tokens[++$i] ?? null,
227 2
				'vendor' => 'Roku',
228 2
				'device' => \mb_substr($value, 5)
229 2
			]),
230 34
			'AmigaOneX' => new props('start', fn (string $value) : array => [
231 2
				'type' => 'human',
232 2
				'category' => 'desktop',
233 2
				'vendor' => 'A-Eon Technology',
234 2
				'device' => 'AmigaOne',
235 2
				'model' => \mb_substr($value, 8)
236 2
			]),
237 34
			'googleweblight' => new props('exact', [
238 34
				'proxy' => 'googleweblight'
239 34
			]),
240 34
			'SAMSUNG-' => new props('start', function (string $value) : array {
241 2
				$parts = \explode('/', $value, 2);
242 2
				return [
243 2
					'type' => 'human',
244 2
					'category' => 'mobile',
245 2
					'vendor' => 'Samsung',
246 2
					'model' => \mb_substr($parts[0], 8),
247 2
					'build' => $parts[1] ?? null,
248 2
				];
249 34
			}),
250 12
			'Samsung' => new props('start', fn (string $value) : ?array => \str_starts_with($value, 'SamsungBrowser') ? null : [
251 12
				'vendor' => 'Samsung'
252 12
			]),
253 34
			'SM-' => new props('start', function (string $value) : array {
254 10
				$parts = \explode('.', \explode(' ', $value)[0]);
255 10
				return [
256 10
					'vendor' => 'Samsung',
257 10
					'model' => $parts[0],
258 10
					'build' => $parts[1] ?? null
259 10
				];
260 34
			}),
261 34
			'Acer' => new props('start', [
262 34
				'vendor' => 'Acer'
263 34
			]),
264 34
			'SonyEricsson' => new props('start', function (string $value) : array {
265 1
				$parts = \explode('/', $value, 2);
266 1
				return [
267 1
					'type' => 'human',
268 1
					'category' => 'mobile',
269 1
					'vendor' => 'Sony Ericsson',
270 1
					'model' => \mb_substr($parts[0], 12),
271 1
					'build' => $parts[1] ?? null
272 1
				];
273 34
			}),
274 34
			'LGE' => new props('exact', function (string $value, int $i, array $tokens) : array {
275 1
				$device = $tokens[++$i] ?? null;
276 1
				$platformversion = empty($tokens[++$i]) ? null : \mb_substr(\explode(' ', $tokens[$i])[0], 5);
277 1
				$build = $tokens[++$i] ?? null;
278 1
				return [
279 1
					'type' => 'human',
280 1
					'category' => 'tv',
281 1
					'model' => $device,
282 1
					'build' => $build,
283 1
					'platformversion' => $platformversion,
284 1
					'vendor' => 'LG'
285 1
				];
286 34
			}),
287 34
			'LG-' => new props('start', function (string $value) : array {
288 1
				$parts = \explode('/', \mb_substr($value, 3), 3);
289 1
				return [
290 1
					'type' => 'human',
291 1
					'category' => 'mobile',
292 1
					'vendor' => 'LG',
293 1
					'model' => \explode(' ', $parts[0])[0],
294 1
					'build' => $parts[1] ?? null
295 1
				];
296 34
			}),
297 34
			'NOKIA' => new props('start', fn (string $value) : array => \array_merge(devices::getDevice($value), [
298 34
				'type' => 'human',
299 34
				'category' => 'mobile',
300 34
				'vendor' => 'Nokia',
301 34
			])),
302 34
			'Lumia' => new props('start', fn (string $value) : array => \array_merge(devices::getDevice($value), [
303 34
				'type' => 'human',
304 34
				'category' => 'mobile',
305 34
				'vendor' => 'Nokia'
306 34
			])),
307 34
			'BRAVIA' => new props('start', [
308 34
				'type' => 'human',
309 34
				'category' => 'tv',
310 34
				'vendor' => 'Sony',
311 34
				'device' => 'Bravia'
312 34
			]),
313 34
			'TECNO' => new props('start', fn (string $value) : array => [
314 3
				'type' => 'human',
315 3
				'category' => 'mobile',
316 3
				'vendor' => 'Tecno',
317 3
				'model' => \explode(' ', \str_replace('-', ' ', $value), 2)[1] ?? null
318 3
			]),
319 34
			'Xiaomi' => new props('start', function (string $value, int $i, array $tokens) : array {
320 5
				return [
321 5
					'type' => 'human',
322 5
					'vendor' => 'Xiaomi',
323 5
					'device' => \mb_stripos($value, 'Poco') !== false ? 'Poco' : null,
324 5
					'model' => \mb_stripos($value, 'Xiaomi-Mi') !== 0 ? (\explode(' ', $value)[1] ?? null) : null,
325 5
					'platformversion' => \is_numeric($tokens[$i+1] ?? null) ? $tokens[$i+1] : null
326 5
				];
327 34
			}),
328 34
			'ThinkPad' => new props('start', function (string $value, int $i, array $tokens) : array {
329 1
				if (\mb_strpos($tokens[++$i] ?? '', 'Build/') === 0) {
330 1
					$device = \explode('_', \mb_substr($tokens[$i], 6));
331
				}
332 1
				return [
333 1
					'type' => 'human',
334 1
					'vendor' => 'Lenovo',
335 1
					'device' => $device[0] ?? null,
336 1
					'model' => $device[1] ?? null,
337 1
					'build' => $device[2] ?? null
338 1
				];
339 34
			}),
340 34
			'BlackBerry' => new props('start', function (string $value) : array {
341 1
				$parts = \explode('/', $value);
342 1
				return [
343 1
					'type' => 'human',
344 1
					'category' => 'mobile',
345 1
					'vendor' => 'Blackberry',
346 1
					'device' => \mb_substr($parts[0], 10) ?: null,
347 1
					'platform' => 'Blackberry OS',
348 1
					'platformversion' => $parts[1] ?? null
349 1
				];
350 34
			}),
351 34
			'CUBOT' => new props('exact', fn () : array => [
352 2
				'type' => 'human',
353 2
				'vendor' => 'Cubot'
354 2
			]),
355 34
			'TCL ' => new props('start', fn (string $value) : array => [
356 2
				'type' => 'human',
357 2
				'category' => 'tv',
358 2
				'vendor' => 'TCL',
359 2
				'model' => \mb_substr($value, 4)
360 2
			]),
361 34
			'deviceName/' => new props('start', fn (string $value) : array => self::getDevice(\mb_substr($value, 11))),
362 34
			'deviceModel/' => new props('start', fn (string $value) : array => [
363 2
				'model' => \mb_substr($value, 12)
364 2
			]),
365 34
			'Model/' => new props('start', fn (string $value) : array => [
366 1
				'model' => \mb_substr($value, 6)
367 1
			]),
368 34
			'Build/' => new props('any', fn (string $value) : array => self::getDevice($value)),
369 34
			'width=' => new props('start', fn (string $value) : array => [
370 2
				'width' => \intval(\mb_substr($value, 6))
371 2
			]),
372 34
			'height=' => new props('start', fn (string $value) : array => [
373 2
				'height' => \intval(\mb_substr($value, 7))
374 2
			]),
375 34
			'dpi=' => new props('start', fn (string $value) : array => [
376 1
				'dpi' => \mb_substr($value, 4)
377 1
			]),
378 34
			'NetType/' => new props('start', function (string $value) : array {
379 4
				$type = \mb_convert_case(\mb_substr($value, 8), MB_CASE_UPPER);
380 4
				return [
381 4
					'nettype' => \in_array($type, ['WF', 'WIFI'], true) ? 'WiFi' : $type
382 4
				];
383 34
			}),
384 34
			'netWorkType/' => new props('start', function (string $value) : array {
385 1
				$type = \mb_convert_case(\mb_substr($value, 12), MB_CASE_UPPER);
386 1
				return [
387 1
					'nettype' => \in_array($type, ['WF', 'WIFI'], true) ? 'WiFi' : $type
388 1
				];
389 34
			}),
390 34
			'2G' => new props('exact', ['nettype' => '2g']),
391 34
			'3G' => new props('exact', ['nettype' => '3g']),
392 34
			'4G' => new props('exact', ['nettype' => '4g']),
393 34
			'4.5G' => new props('exact', ['nettype' => '4g']),
394 34
			'4.5G+' => new props('exact', ['nettype' => '4g']),
395 34
			'5G' => new props('exact', ['nettype' => '5g']),
396 34
			'x' => new props('any', function (string $value) : ?array {
397 91
				if (\str_contains($value, '@')) {
398 2
					$dpi = \explode('@', $value);
399 2
					$value = $dpi[0];
400
				}
401 91
				$parts = \explode('x', $value);
402 91
				if (!isset($parts[2]) && \is_numeric($parts[0]) && \is_numeric($parts[1]) && !empty($parts[0]) && !empty($parts[1])) {
403 11
					return [
404 11
						'width' => \intval($parts[0]),
405 11
						'height' => \intval($parts[1]),
406 11
						'density' => isset($dpi[1]) ? \floatval(\rtrim($dpi[1], 'x')) : null
407 11
					];
408
				}
409 91
				return null;
410 34
			}),
411 34
			'MB' => new props('end', fn (string $value) : array => [
412 2
				'ram' => \intval(\mb_substr($value, 0, -2))
413 2
			])
414 34
		];
415
	}
416
417
	/**
418
	 * Extracts device information from a token
419
	 * 
420
	 * @param string $value A token expected to contain device information
421
	 * @return array<string,string|null> An array containing the extracted devices information
422
	 */
423 43
	public static function getDevice(string $value) : array {
424 43
		foreach (['Mobile', 'Tablet', 'Safari', 'AppleWebKit', 'Linux', 'rv:'] AS $item) {
425 43
			if (\mb_stripos($value, $item) === 0) {
426 8
				return [];
427
			}
428
		}
429 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

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

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