Passed
Push — main ( b74a3d...1ce707 )
by Will
12:35
created

browsers::getBrowser()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 51
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 46
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 43
c 0
b 0
f 0
nc 6
nop 5
dl 0
loc 51
ccs 46
cts 46
cp 1
crap 6
rs 8.6097

How to fix   Long Method   

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 browsers {
6
7 86
	protected static function getBrowser(string $value, int $i, array $tokens, string $key, array $config = []) : array {
8 86
		if (!\str_contains($value, 'Opera Mini') && ($browser = \mb_strrchr($value, ' ')) !== false) {
9 1
			$value = \ltrim($browser);
10
		}
11 86
		$parts = \explode('/', $value); // split more incase there are more slashes
12 86
		$map = [
13 86
			'opr' => 'Opera',
14 86
			'crios' => 'Chrome',
15 86
			'edg' => 'Edge',
16 86
			'edgios' => 'Edge',
17 86
			'edga' => 'Edge',
18 86
			'webpositive' => 'WebPositive',
19 86
			'nintendobrowser' => 'NintendoBrowser',
20 86
			'up.browser' => 'UP.Browser',
21 86
			'ucbrowser' => 'UCBrowser',
22 86
			'netfront' => 'NetFront',
23 86
			'seamonkey' => 'SeaMonkey',
24 86
			'icecat' => 'IceCat',
25 86
			'iceape' => 'IceApe',
26 86
			'iceweasel' => 'IceWeasel',
27 86
			'bonecho' => 'BonEcho',
28 86
			'palemoon' => 'PaleMoon',
29 86
			'k-meleon' => 'K-Meleon',
30 86
			'samsungbrowser' => 'Samsung Internet',
31 86
			'huaweibrowser' => 'Huawei Browser',
32 86
			'qqbrowser' => 'QQ Browser',
33 86
			'miuibrowser' => 'MIUI Browser'
34 86
		];
35 86
		$data = ['type' => 'human'];
36 86
		$browser = \mb_strtolower(\array_shift($parts));
37 86
		$data['browser'] = $map[$browser] ?? \mb_convert_case($browser, MB_CASE_TITLE);
38
39
		// get browser version
40 86
		foreach ($parts AS $item) {
41 86
			if (\strpbrk($item, '1234567890') !== false) {
42 86
				$data['browserversion'] = $item;
43 86
				break;
44
			}
45
		}
46 86
		$map = [
47 86
			'Samsung Internet' => 'samsung',
48 86
			'Huawei Browser' => 'huawei',
49 86
			'K-Meleon' => 'kmeleon',
50 86
			'Fennec' => 'firefox',
51 86
			'Native Opera Mini' => 'opera',
52 86
			'Cronet' => 'chrome'
53 86
		];
54 86
		$key = $map[$data['browser']] ?? \mb_strtolower($data['browser']);
55 86
		return \array_merge(
56 86
			$data,
57 86
			isset($data['browserversion']) ? versions::get($key, $data['browserversion'], $config['versions']) : []
58 86
		);
59
	}
60
	/**
61
	 * Generates a configuration array for matching browsers
62
	 * 
63
	 * @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
64
	 */
65 62
	public static function get() : array {
66 48
		$fn = [
67 48
			'browserslash' => fn (string $value, int $i, array $tokens, string $key, array $config = []) : array => self::getBrowser($value, $i, $tokens, $key, $config),
68 48
			'gecko' => function (string $value, int $i, array $tokens, string $key, array $config = []) : array {
69 27
				$parts = \explode('/', $value, 2);
70 27
				return \array_replace(self::getBrowser($value, $i, $tokens, $key, $config), [
71 27
					'engine' => 'Gecko',
72 27
					'engineversion' => $parts[1] ?? null,
73 27
				]);
74 48
			},
75 48
			'presto' => function (string $value, int $i, array $tokens, string $key, array $config = []) : array {
76 5
				$parts = \explode('/', $value, 2);
77 5
				return \array_replace(self::getBrowser($value, $i, $tokens, $key, $config), [
78 5
					'engine' => 'Presto',
79 5
					'engineversion' => $parts[1] ?? null,
80 5
				]);
81 48
			},
82 48
			'chromium' => function (string $value, int $i, array $tokens, string $key, array $config = []) : array {
83 62
				$parts = \explode('/', $value, 3);
84 62
				$engineversion = isset($parts[1]) && \strspn($parts[1], '1234567890.') === \strlen($parts[1]) ? $parts[1] : null;
85 62
				return \array_replace(self::getBrowser($value, $i, $tokens, $key, $config), [
86 62
					'engine' => \intval($engineversion ?? 28) < 28 ? 'WebKit' : 'Blink',
87 62
					'engineversion' => $engineversion
88 62
				]);
89 48
			},
90 48
			'safari' => function (string $value, int $i, array $tokens, string $key, array $config = []) : array {
91 35
				$parts = \explode('/', $value, 2);
92 35
				$version = $parts[1] ?? null;
93 35
				foreach ($tokens AS $item) {
94 35
					if (\mb_stripos($item, 'Version/') === 0) {
95 23
						$version = \mb_substr($item, 8);
96
					}
97
				}
98 35
				return \array_replace([
99 35
					'type' => 'human',
100 35
					'browser' => 'Safari',
101 35
					'browserversion' => $version ?? null,
102 35
					'engine' => 'WebKit',
103 35
					'engineversion' => $parts[1] ?? null
104 35
				], $version !== null ? versions::get('safari', $version, $config['versions']) : []);
105 48
			},
106 48
		];
107 17
		return [
108 17
			'Opera Mini/' => new props('start', $fn['presto']),
109 17
			'Native Opera Mini/' => new props('start', $fn['presto']),
110 17
			'Opera/' => new props('start', $fn['presto']),
111 17
			'OPR/' => new props('start', $fn['browserslash']),
112 17
			'CriOS/' => new props('start', $fn['browserslash']),
113 17
			'Brave/' => new props('start', $fn['browserslash']),
114 17
			'Vivaldi/' => new props('start', $fn['browserslash']),
115 17
			'Maxthon/' => new props('start', $fn['browserslash']),
116 17
			'Maxthon ' => new props('start', fn (string $value, int $i, array $tokens, string $key, array $config = []) : array => \array_merge([
117 17
				'browser' => 'Maxthon',
118 17
				'browserversion' => \mb_substr($value, 8)
119 17
			], versions::get('maxathon', \mb_substr($value, 8), $config['versions']))),
120 17
			'Konqueror/' => new props('start', $fn['browserslash']),
121 17
			'K-Meleon/' => new props('start', $fn['browserslash']),
122 17
			'UCBrowser/' => new props('start', $fn['browserslash']),
123 17
			'Waterfox/' => new props('start', $fn['browserslash']),
124 17
			'PaleMoon/' => new props('start', $fn['browserslash']),
125 17
			'IceWeasel/' => new props('start', $fn['browserslash']),
126 17
			'IceCat/' => new props('start', $fn['browserslash']),
127 17
			'IceApe/' => new props('start', $fn['browserslash']),
128 17
			'Basilisk/' => new props('start', $fn['browserslash']),
129 17
			'SeaMonkey/' => new props('start', $fn['browserslash']),
130 17
			'UP.Browser/' => new props('start', $fn['browserslash']),
131 17
			'Netscape/' => new props('start', $fn['browserslash']),
132 17
			'Thunderbird/' => new props('start', $fn['browserslash']),
133 17
			'Galeon/' => new props('start', $fn['browserslash']),
134 17
			'WebPositive/' => new props('start', $fn['browserslash']),
135 17
			'K-Ninja/' => new props('start', $fn['browserslash']),
136 17
			'SamsungBrowser/' => new props('start', $fn['browserslash']),
137 17
			'HuaweiBrowser/' => new props('start', $fn['browserslash']),
138 17
			'NintendoBrowser/' => new props('start', $fn['browserslash']),
139 17
			'Epiphany/' => new props('start', $fn['browserslash']),
140 17
			'Silk/' => new props('start', $fn['browserslash']),
141 17
			'NetFront/' => new props('start', $fn['browserslash']),
142 17
			'Dooble/' => new props('start', $fn['browserslash']),
143 17
			'Falkon/' => new props('start', $fn['browserslash']),
144 17
			'Namoroka/' => new props('start', $fn['browserslash']),
145 17
			'CocCoc/' => new props('start', $fn['browserslash']),
146 17
			'Obigo/' => new props('start', $fn['browserslash']),
147 17
			'QQBrowser/' => new props('any', function (string $value, int $i, array $tokens, string $key, array $config = []) use ($fn) : array {
148 2
				return $fn['browserslash'](\mb_substr($value, \mb_stripos($value, 'QQBrowser/') ?: 0), $i, $tokens, $key, $config); // sometimes missing a space from previous declaration, and MQQBrowser for mobile.
149 17
			}),
150 17
			'MiuiBrowser/' => new props('any', function (string $value, int $i, array $tokens, string $key, array $config = []) use ($fn) : array {
151 2
				return $fn['browserslash'](\mb_substr($value, \mb_stripos($value, 'MiuiBrowser/') ?: 0), $i, $tokens, $key, $config);
152 17
			}),
153 17
			'Lynx/' => new props('start', fn (string $value) : array => [
154 2
				'browser' => 'Lynx',
155 2
				'browserversion' => \explode('/', $value, 2)[1] ?? null,
156 2
				'engine' => 'Libwww',
157 2
				'type' => 'human',
158 2
				'category' => 'desktop'
159 2
			]),
160 17
			'Midori' => new props('start', function (string $value, int $i, array $tokens, string $key, array $config = []) : array {
161 1
				$parts = \explode('/', $value, 2);
162 1
				$version = $parts[1] ?? \explode(' ', $value, 2)[1] ?? null;
163 1
				$major = $version !== null ? \intval($version) : null;
164 1
				return \array_merge([
165 1
					'type' => 'human',
166 1
					'browser' => 'Midori',
167 1
					'engine' => $major >= 11 ? 'Gecko' : ($major < 9 ? 'WebKit' : 'Blink'),
168 1
					'browserversion' => $version
169 1
				], $version !== null ? versions::get('midori', $version, $config['versions']) : []);
170 17
			}),
171 17
			'PrivacyBrowser/' => new props('start', $fn['browserslash']),
172 17
			'Fennec/' => new props('start', $fn['gecko']),
173 17
			'Firefox/' => new props('start', $fn['gecko']),
174 17
			' Firefox/' => new props('any', $fn['gecko']),
175 17
			'Firefox' => new props('exact', [
176 17
				'type' => 'human',
177 17
				'engine' => 'Gecko',
178 17
				'browser' => 'Firefox'
179 17
			]),
180 17
			'Minimo/' => new props('start', function (string $value, int $i, array $tokens, string $key, array $config = []) use ($fn) : array {
181 1
				$data = $fn['browserslash']($value, $i, $tokens, $key, $config);
182 1
				return \array_merge($data, [
183 1
					'engine' => 'Gecko'
184 1
				]);
185 17
			}),
186 17
			'BonEcho/' => new props('start', function (string $value, int $i, array $tokens, string $key, array $config = []) use ($fn) : array {
187 1
				$data = $fn['browserslash']($value, $i, $tokens, $key, $config);
188 1
				return \array_merge($data, [
189 1
					'engine' => 'Gecko'
190 1
				]);
191 17
			}),
192 17
			'Links/' => new props('start', $fn['browserslash']),
193 17
			'Links' => new props('exact', fn (string $value, int $i, array $tokens, string $key, array $config = []) => [
194 2
				'type' => 'human',
195 2
				'browser' => $value,
196 2
				'browserversion' => $tokens[$i + 1]
197 2
			]),
198 17
			'Elinks/' => new props('start', $fn['browserslash']),
199 17
			'ELinks' => new props('exact', fn (string $value, int $i, array $tokens, string $key, array $config = []) => [
200 2
				'type' => 'human',
201 2
				'browser' => $value,
202 2
				'browserversion' => $tokens[$i + 1]
203 2
			]),
204 17
			'Blazer' => new props('start', fn (string $value, int $i, array $tokens, string $key, array $config = []) : array => [
205 3
				'type' => 'human',
206 3
				'browser' => 'Blazer',
207 3
				'browserversion' => \mb_substr($value, 7),
208 3
				'engine' => 'Proprietary'
209 3
			]),
210 17
			'Edg/' => new props('start', $fn['browserslash']),
211 17
			'EdgA/' => new props('start', $fn['browserslash']),
212 17
			'Edge/' => new props('start', $fn['browserslash']),
213 17
			'EdgiOS/' => new props('start', $fn['browserslash']),
214 17
			'MSIE ' => new props('start', fn (string $value, int $i, array $tokens, string $key, array $config = []) : array => \array_merge([
215 17
				'type' => 'human',
216 17
				'browser' => 'Internet Explorer',
217 17
				'browserversion' => \mb_substr($value, 5),
218 17
				'engine' => 'Trident'
219 17
			], versions::get('ie', \mb_substr($value, 5), $config['versions']))),
220 17
			'BOIE9' => new props('start', fn (string $value, int $i, array $tokens, string $key, array $config = []) => \array_merge([
221 17
				'type' => 'human',
222 17
				'browser' => 'Internet Explorer',
223 17
				'browserversion' => '9.0',
224 17
				'engine' => 'Trident'
225 17
			], versions::get('ie', '9.0', $config['versions']))),
226 17
			'IEMobile/' => new props('start', fn (string $value, int $i, array $tokens, string $key, array $config = []) : array => \array_merge([
227 17
				'type' => 'human',
228 17
				'browser' => 'Internet Explorer',
229 17
				'browserversion' => \mb_substr($value, 9),
230 17
				'engine' => 'Trident'
231 17
			], versions::get('ie', \mb_substr($value, 9), $config['versions']))),
232 17
			'Trident' => new props('start', [ // infill for missing browser name
233 17
				'browser' => 'Internet Explorer'
234 17
			]),
235 17
			'Cronet/' => new props('start', $fn['chromium']),
236 17
			'Chromium/' => new props('start', $fn['chromium']),
237 17
			'Chrome/' => new props('start', $fn['chromium']),
238 17
			'Safari/' => new props('start', $fn['safari']),
239 17
			'Mozilla/' => new props('start', $fn['browserslash']),
240 17
			'rv:' => new props('start', fn (string $value) : array => [
241 38
				'browserversion' => \mb_substr($value, 3)
242 38
			])
243 17
		];
244
	}
245
}