PluginProbe
Depicter — Popup & Slider Builder / trunk
Depicter — Popup & Slider Builder vtrunk
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / foroco / php-browser-detection / src / BrowserDetection.php

BrowserDetection.php in Depicter — Popup & Slider Builder trunk, at vendor/foroco/php-browser-detection/src/BrowserDetection.php

1,687 lines 72.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 *
5 * PHP Browser Detection Class
6 *
7 * The MIT License (MIT)
8 *
9 * Copyright (c) 2020-2024 Artem Murugov <murugov@gmail.com>
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy of
12 * this software and associated documentation files (the "Software"), to deal in
13 * the Software without restriction, including without limitation the rights to
14 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 * the Software, and to permit persons to whom the Software is furnished to do so,
16 * subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in all
19 * copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 * @version 2.8
29 * @last-modified September 3, 2024
30 * @link https://github.com/foroco/php-browser-detection
31 */
32
33 namespace foroco;
34
35 class BrowserDetection
36 {
37 public $useragent;
38 private $get_mode;
39 private $touch_support_mode;
40 private $real_os_name;
41 private $macos_version_minor;
42 private $result_ios;
43 private $result_mobile;
44 private $result_os_type;
45 private $result_os_family;
46 private $result_os_name ;
47 private $result_os_version;
48 private $result_os_title;
49 private $result_device_type;
50 private $result_browser_name;
51 private $result_browser_version;
52 private $result_browser_title;
53 private $result_browser_chromium_version;
54 private $result_browser_gecko_version;
55 private $result_browser_webkit_version;
56 private $result_browser_chrome_original;
57 private $result_browser_firefox_original;
58 private $result_browser_safari_original;
59 private $result_browser_android_webview;
60 private $result_browser_ios_webview;
61 private $result_browser_desktop_mode;
62 private $result_64bits_mode;
63
64 /**
65 * Reset all common defined properties method
66 *
67 * @return null
68 */
69
70 private function resetProperties()
71 {
72 $this->real_os_name = '';
73 $this->result_ios = FALSE;
74 $this->result_mobile = 0;
75 $this->macos_version_minor = 0;
76 $this->result_os_type = 'unknown';
77 $this->result_os_family = 'unknown';
78 $this->result_os_name = 'unknown';
79 $this->result_os_version = 0;
80 $this->result_os_title = 'unknown';
81 $this->result_device_type = 'unknown';
82 $this->result_browser_name = 'unknown';
83 $this->result_browser_version = 0;
84 $this->result_browser_title = 'unknown';
85 $this->result_browser_chromium_version = 0;
86 $this->result_browser_gecko_version = 0;
87 $this->result_browser_webkit_version = 0;
88 $this->result_browser_chrome_original = 0;
89 $this->result_browser_firefox_original = 0;
90 $this->result_browser_safari_original = 0;
91 $this->result_browser_android_webview = 0;
92 $this->result_browser_ios_webview = 0;
93 $this->result_browser_desktop_mode = 0;
94 $this->result_64bits_mode = 0;
95 return NULL;
96 }
97
98 /**
99 * Common User-Agent matching
100 *
101 * @param string $data The string to data search for
102 * @param boolean $case_s Determines if we do a case-sensitive search (false) or a case insensitive (true)
103 * @return boolean Returns true if $data found in $useragent property, false otherwise.
104 */
105
106 private function match_ua($data, $case_s = FALSE)
107 {
108 if (empty($data)) return FALSE;
109
110 if (substr($data, 0, 1)==='/' && substr($data, -1)==='/')
111 {
112 if ($case_s == TRUE) $data = $data.'i';
113 if (preg_match($data, $this->useragent, $matches))
114 {
115 if (!isset($matches[0])) $matches[0] = 0;
116 if (!isset($matches[1])) $matches[1] = 0;
117 if (!isset($matches[2])) $matches[2] = 0;
118 return $matches;
119 }
120 else
121 {
122 return FALSE;
123 }
124 }
125 else
126 {
127 $data_a = explode('|', $data);
128 foreach ($data_a as $v)
129 {
130 if ($case_s == FALSE)
131 {
132 if (strpos($this->useragent, $v) !== FALSE) return TRUE;
133 }
134 else
135 {
136 if (stripos($this->useragent, $v) !== FALSE) return TRUE;
137 }
138 }
139 }
140
141 return FALSE;
142 }
143
144 /**
145 * Method to call User-Agent matching method if matching data is case insensitive
146 *
147 * @param string $data The string to data search for
148 * @return boolean Returns true if case insensitive $data found in $useragent property, false otherwise.
149 */
150
151 private function matchi_ua($data)
152 {
153 return $this->match_ua($data, TRUE);
154 }
155
156 /**
157 * Detect iOS
158 * The method will try to recognize iOS signs from $useragent property and will placed true in result_ios property if iOS found, false otherwise. Also returns true if iOS found, false otherwise
159 *
160 * @return bool
161 */
162
163 private function match_ios()
164 {
165 if ($this->match_ua('iPhone|iphone|iPad;|iPod') && !$this->match_ua('x86_64|i386'))
166 {
167 $this->result_ios = TRUE;
168 return TRUE;
169 }
170 return FALSE;
171 }
172
173 /**
174 * Detect mobile OS
175 * The method will try to recognize mobile OS signs from $useragent property and will placed true in result_mobile property if mobile OS found, false otherwise.
176 *
177 * @return null
178 */
179
180 private function match_mobile()
181 {
182 // Match 64 bits Windows Desktop OS
183
184 if ($this->match_ua('WOW64|Win64'))
185 {
186 $this->result_64bits_mode = 1;
187 return NULL;
188 }
189
190 // Match Windows Desktop OS
191
192 if ($this->match_ua('Windows NT')) return NULL;
193
194 // Match Qt embedded system
195
196 if ($this->match_ua('QtEmbedded;')) return NULL;
197
198 // Match Android OS
199
200 if ($this->match_ua('Android'))
201 {
202 $this->result_mobile = 1;
203 return NULL;
204 }
205
206 // Match iOS
207
208 if ($this->match_ios())
209 {
210 $this->result_mobile = 1;
211 return NULL;
212 }
213
214 // Match iOS browsers in Desktop Mode
215
216 if ($this->match_ua('Mac OS X'))
217 {
218 if ($this->match_ua('/Mac\sOS\sX.*iOS/')) $this->result_mobile = 1;
219 return NULL;
220 }
221
222 // Match Android browsers in Desktop Mode
223
224 if ($this->match_ua('/X11\;(?:[U\;\s]+)?\sLinux/') && $this->match_ua('Version/4.0 Chrome/|SamsungBrowser|Miui|XiaoMi|EdgA|Puffin|UCBrowser|JioPages|Ecosia android'))
225 {
226 $this->result_mobile = 1;
227 return NULL;
228 }
229
230 // Match other mobile signs
231
232 if ($this->matchi_ua('mobile|tablet') || $this->match_ua('BlackBerry|BB10;|MIDP|PlayBook|Windows Phone|Windows Mobile|Windows CE|IEMobile|Opera Mini|OPiOS|Opera Mobi|CrKey armv|Kindle|Silk/|Bada|Tizen|Lumia|Symbian|SymbOS|(Series|PalmOS|PalmSource|Dolfin|Crosswalk|Obigo|MQQBrowser|CriOS|WhatsApp/') || $this->matchi_ua('nokia|playstation|watch')) $this->result_mobile = 1;
233 return NULL;
234 }
235
236 /**
237 * Convert MacOS numeric version to MacOS codename
238 *
239 * @param int $version The given MacOS version
240 * @return string Returns MacOS codename string
241 */
242
243 private function macos_codename($version)
244 {
245 switch($version)
246 {
247 case 0: $result_codename = 'Cheetah'; break;
248 case 1: $result_codename = 'Puma'; break;
249 case 2: $result_codename = 'Jaguar'; break;
250 case 3: $result_codename = 'Panther'; break;
251 case 4: $result_codename = 'Tiger'; break;
252 case 5: $result_codename = 'Leopard'; break;
253 case 6: $result_codename = 'Snow Leopard'; break;
254 case 7: $result_codename = 'Lion'; break;
255 case 8: $result_codename = 'Mountain Lion'; break;
256 case 9: $result_codename = 'Mavericks'; break;
257 case 10: $result_codename = 'Yosemite'; break;
258 case 11: $result_codename = 'El Capitan'; break;
259 case 12: $result_codename = 'Sierra'; break;
260 case 13: $result_codename = 'High Sierra'; break;
261 case 14: $result_codename = 'Mojave'; break;
262 case 15: $result_codename = 'Catalina'; break;
263 case 16: $result_codename = 'Big Sur'; break;
264 case 17: $result_codename = 'Monterey'; break;
265 case 18: $result_codename = 'Ventura'; break;
266 default: $result_codename = 'New'; break;
267 }
268 return $result_codename;
269 }
270
271 /**
272 * Common User-Agent parsing
273 * The method will try to recognize environment data from $useragent property and will placed it in defined properties.
274 *
275 * @return null
276 */
277
278 private function getResult()
279 {
280 // Detect mobile device
281
282 $this->match_mobile();
283
284 // Detect mobile browser Desktop Mode
285
286 if ($this->touch_support_mode == TRUE)
287 {
288 // Android Desktop Mode
289
290 if ($this->match_ua('X11; Linux x86_64|X11; Linux aarch64|X11; U; U; Linux x86_64|X11; Linux; U;|X11; Linux zbov') && !$this->match_ua('kded/|kioclient|queror|Goanna|Epiphany|Brick|Iceweasel|SeaMonkey|Thunderbird|Qt|Arora|Ubuntu|Debian|Fedora|Linux Mint|elementary|Raspbian|Slackware|ArchLinux|Gentoo'))
291 {
292 $this->real_os_name = 'Android';
293 $this->result_mobile = 1;
294 $this->result_browser_desktop_mode = 1;
295 }
296
297 // iOS Desktop Mode
298
299 if ($this->match_ua('Intel Mac OS X'))
300 {
301 $this->real_os_name = 'iOS';
302 $this->result_mobile = 1;
303 $this->result_browser_desktop_mode = 1;
304 }
305 }
306
307 // Windows Phone Desktop Mode
308
309 if ($this->match_ua('WPDesktop;'))
310 {
311 $this->real_os_name = 'Windows Phone';
312 $this->result_mobile = 1;
313 $this->result_browser_desktop_mode = 1;
314 }
315
316 // Android Desktop Mode without touch support check
317
318 if ($this->result_mobile == 1 && $this->result_os_type === 'unknown')
319 {
320 if ($this->match_ua('/X11\;(?:[U\;\s]+)?\sLinux/') && $this->match_ua('Version/4.0 Chrome/|SamsungBrowser|Miui|XiaoMi|EdgA|Puffin|UCBrowser|JioPages|Ecosia android'))
321 {
322 $this->real_os_name = 'Android';
323 $this->result_browser_desktop_mode = 1;
324 }
325 }
326
327 // iOS Desktop Mode without touch support check
328
329 if ($this->result_mobile == 1 && $this->result_ios == FALSE && $this->result_os_type === 'unknown')
330 {
331 if ($this->match_ua('/Mac\sOS\sX.*iOS/'))
332 {
333 $this->real_os_name = 'iOS';
334 $this->result_browser_desktop_mode = 1;
335 }
336 }
337
338 /*
339 --------------
340 OS DETECTION
341 --------------
342
343 --------------
344 Mixed OS(es)
345 --------------
346 */
347
348 $os_need_continue = TRUE;
349
350 // Windows OS
351
352 if ($this->get_mode !== 'browser' && $this->match_ua('Windows|Win32') && !$this->match_ua('Windows Phone|Windows Mobile|Windows CE|WPDesktop'))
353 {
354 $this->result_os_name = 'Windows';
355 $matches = $this->match_ua('/Windows ([ .a-zA-Z0-9]+)[;\\)]/');
356 $version = is_array($matches) ? $matches[1] : 0;
357 if ($version === 'NT 11.0') $this->result_os_version = '11';
358 if ($version === 'NT 10.1') $this->result_os_version = '11';
359 if ($version === 'NT 10.0') $this->result_os_version = '10';
360 if ($version === 'NT 6.4') $this->result_os_version = '10';
361 if ($version === 'NT 6.3') $this->result_os_version = '8.1';
362 if ($version === 'NT 6.2') $this->result_os_version = '8';
363 if ($version === 'NT 6.1') $this->result_os_version = '7';
364 if ($version === 'NT 6.0') $this->result_os_version = 'Vista';
365 if ($version === 'NT 6') $this->result_os_version = 'NT';
366 if ($version === 'NT 5.2') $this->result_os_version = 'XP';
367 if ($version === 'NT 5.1') $this->result_os_version = 'XP';
368 if ($version === 'NT 5.01') $this->result_os_version = '2000';
369 if ($version === 'NT 5.0') $this->result_os_version = '2000';
370 if ($version === 'NT 5') $this->result_os_version = '2000';
371 if ($version === 'NT 4.0') $this->result_os_version = 'NT 4.0';
372 if ($version === 'NT4.0') $this->result_os_version = 'NT 4.0';
373 if ($version === 'NT') $this->result_os_version = 'NT';
374 if ($version === '98') $this->result_os_version = '98';
375 if ($version === '95') $this->result_os_version = '95';
376 if ($version === 'ME') $this->result_os_version = 'ME';
377 if (empty($this->result_os_version))
378 {
379 if ($this->match_ua('/Win16/')) $this->result_os_version = '3.1';
380 if ($this->match_ua('/(Windows\s95|Win95|Windows_95)/')) $this->result_os_version = '95';
381 if ($this->match_ua('/(Windows\s98|Win98)/')) $this->result_os_version = '98';
382 if ($this->match_ua('/Windows\s2000/')) $this->result_os_version = '2000';
383 if ($this->match_ua('/Win\sNT\s5\.0/')) $this->result_os_version = '2000';
384 if ($this->match_ua('/Windows\sXP/')) $this->result_os_version = 'XP';
385 if ($this->match_ua('/WinNT4\.0/')) $this->result_os_version = 'NT 4.0';
386 if ($this->match_ua('/Windows\sVista/')) $this->result_os_version = 'Vista';
387 if ($this->match_ua('/Windows\s7/')) $this->result_os_version = '7';
388 if ($this->match_ua('/Windows\s8/')) $this->result_os_version = '8';
389 if ($this->match_ua('/Windows\s8.1/')) $this->result_os_version = '8.1';
390 if ($this->match_ua('/Windows\s10/')) $this->result_os_version = '10';
391 if ($this->match_ua('/Windows\s11/')) $this->result_os_version = '11';
392 }
393 if (!empty($this->result_os_version)) $this->result_os_title = 'Windows '.$this->result_os_version;
394 else $this->result_os_title = 'Windows (unknown version)';
395 if (intval($this->result_os_version)<7 || intval($this->result_os_version)>10) $this->result_os_type = 'desktop';
396 else $this->result_os_type = 'mixed';
397 $this->result_os_family = 'windows';
398 $os_need_continue = FALSE;
399 }
400
401 /*
402 -------------
403 Desktop OS
404 -------------
405 */
406
407 if ($this->get_mode !== 'browser' && $this->result_mobile == 0)
408 {
409 $this->result_os_type = 'desktop';
410
411 // Mac OS (X) / macOS
412
413 if ($os_need_continue && $this->match_ua('Mac OS X|Mac_PowerPC|Macintosh|Mac_68K') && !$this->match_ua('AmigaOS'))
414 {
415 $this->result_os_version = 0;
416 $this->result_os_name = 'MacOS';
417 if ($this->match_ua('Mac OS X'))
418 {
419 $matches = $this->match_ua('/Mac OS X (\d+)[_.](\d+)(?:[_.](\d+)|)/');
420
421 $version = isset($matches[1]) ? $matches[1] : 0;
422 $version_minor = isset($matches[2]) ? $matches[2] : 0;
423 $version_revision = isset($matches[3]) ? $matches[3] : -1;
424
425 // macOS version to minor version conversion (needs since Big Sur)
426 if ($version == 10 && $version_minor == 0) $version_minor = 16;
427 if ($version == 11) $version_minor = 16;
428 if ($version == 12) $version_minor = 17;
429
430 // macOS with a particular major/minor/revision version structure (needs since Big Sur)
431 if ($version == 10 && $version_minor == 15 && $version_revision == 7) $version_minor = 16;
432 if ($version == 10 && $version_minor == 16 && $version_revision == 0) $version_minor = 17;
433
434 if (!empty($version_minor))
435 {
436 if ($version >= 10) $this->result_os_version = $this->macos_codename($version_minor);
437 $this->macos_version_minor = $version_minor;
438 }
439
440 if (!empty($this->result_os_version)) $this->result_os_title = 'MacOS '.$this->result_os_version;
441 else $this->result_os_title = 'MacOS (unknown version)';
442 }
443 else
444 {
445 $this->result_os_title = 'MacOS';
446 }
447 $this->result_os_family = 'macintosh';
448 $os_need_continue = FALSE;
449 }
450
451 // Linux family OS(es)
452
453 if ($os_need_continue)
454 {
455 $os_list[] = array('Ubuntu'=>'/Ubuntu(?: )?(?:\/)?([0-9]+\.[0-9]+)/');
456 $os_list[] = array('Kubuntu'=>'/Kubuntu(?: )?(?:\/)?([0-9]+\.[0-9]+)/');
457 $os_list[] = array('Linux Mint'=>'/Linux Mint\/([.0-9]+)/');
458 $os_list[] = array('CentOS'=>'/CentOS\/([0-9]+\.[0-9]+)/');
459 $os_list[] = array('OpenSUSE'=>'/SUSE\/([0-9]+\.[0-9]+)/');
460 $os_list[] = array('Red Hat'=>'/Red\sHat\/([0-9]+\.[0-9]+)/');
461
462 foreach($os_list as $os_list_va)
463 {
464 $k = key($os_list_va);
465 $v = $os_list_va[$k];
466
467 $matches = $this->match_ua($v);
468 if ($matches)
469 {
470 $this->result_os_family = 'linux';
471 $this->result_os_name = $k;
472 $this->result_os_version = is_array($matches) ? (float)$matches[1] : 0;
473 $os_need_continue = FALSE;
474 break;
475 }
476 }
477 $os_list = NULL;
478 }
479
480 // Other Desktop OS(es)
481
482 if ($os_need_continue)
483 {
484 $other_os = array();
485
486 $other_os[] = array('Chrome OS'=>'CrOS');
487 $other_os[] = array('Chrome OS'=>'Chromium OS');
488 $other_os[] = array('Linux Mint'=>'Linux Mint');
489 $other_os[] = array('Kubuntu'=>'Kubuntu');
490 $other_os[] = array('Ubuntu'=>'Ubuntu');
491 $other_os[] = array('Ubuntu'=>'ubuntu');
492 $other_os[] = array('Debian'=>'Debian');
493 $other_os[] = array('CentOS'=>'CentOS');
494 $other_os[] = array('Fedora'=>'Fedora');
495 $other_os[] = array('Arch Linux'=>'ArchLinux');
496 $other_os[] = array('OpenSUSE'=>'SUSE');
497 $other_os[] = array('Red Hat'=>'Red Hat');
498 $other_os[] = array('Elementary'=>' elementary');
499 $other_os[] = array('OpenBSD'=>'OpenBSD');
500 $other_os[] = array('NetBSD'=>'NetBSD');
501 $other_os[] = array('FreeBSD'=>'FreeBSD');
502 $other_os[] = array('SunOS'=>'SunOS');
503 $other_os[] = array('RISC OS'=>'RISC OS');
504 $other_os[] = array('Linux'=>'Linux');
505 $other_os[] = array('Linux'=>'X11;');
506 $other_os[] = array('Linux'=>'Mozilla/5.0 (x86_64)');
507 $other_os[] = array('Linux'=>'Mozilla/5.0 (i686)');
508 $other_os[] = array('Linux'=>'U; NETFLIX');
509 $other_os[] = array('Linux'=>'GNU; ');
510 $other_os[] = array('Linux'=>'QtEmbedded; U; Linux;');
511 $other_os[] = array('AmigaOS'=>'AmigaOS');
512 $other_os[] = array('Haiku'=>'Haiku');
513 $other_os[] = array('Roku OS'=>'Roku/');
514 $other_os[] = array('BeOS'=>'BeOS');
515
516 foreach ($other_os as $other_os_va)
517 {
518 $k = key($other_os_va);
519 $v = $other_os_va[$k];
520
521 if ($this->match_ua($v))
522 {
523 $this->result_os_family = 'linux';
524 if ($k === 'AmigaOS') $this->result_os_family = 'amiga';
525 if ($k === 'Haiku' || $k === 'BeOS') $this->result_os_family = 'beos';
526 if ($k === 'OpenBSD' || $k === 'NetBSD' || $k === 'FreeBSD' || $k === 'SunOS' || $k === 'RISC OS') $this->result_os_family = 'unix';
527 $this->result_os_version = 0;
528 $this->result_os_name = $k;
529 $this->result_os_title = $k;
530 $os_need_continue = FALSE;
531 break;
532 }
533 }
534 $other_os = NULL;
535 }
536
537 // End of desktop OS detection
538 }
539
540 /*
541 -------------
542 Mobile OS
543 -------------
544 */
545
546 if ($this->result_mobile == 1)
547 {
548 if ($this->result_os_type==='unknown') $this->result_os_type = 'mobile';
549
550 // Desktop Mode on generic mobile OS
551
552 // Android Desktop Mode
553
554 if ($os_need_continue && $this->result_browser_desktop_mode == 1 && $this->real_os_name === 'Android')
555 {
556 $this->result_os_version = 0;
557 $this->result_os_name = 'Android';
558 $this->result_os_family = 'android';
559 $os_need_continue = FALSE;
560 }
561
562 // iOS Desktop Mode
563
564 if ($os_need_continue && $this->result_browser_desktop_mode == 1 && $this->real_os_name === 'iOS')
565 {
566 $this->result_os_version = 0;
567 $this->result_os_name = 'iOS';
568 $this->result_os_family = 'macintosh';
569 $os_need_continue = FALSE;
570 }
571
572 // WP Desktop Mode
573
574 if ($os_need_continue && $this->result_browser_desktop_mode == 1 && $this->real_os_name === 'Windows Phone')
575 {
576 $this->result_os_version = 0;
577 $this->result_os_name = 'Windows Phone';
578 $this->result_os_family = 'windows';
579 $os_need_continue = FALSE;
580 }
581
582 // Android OS
583
584 if ($os_need_continue && $this->match_ua('Android') && !$this->match_ua('Windows Phone|Windows Mobile|Tizen'))
585 {
586 $this->result_os_version = 0;
587 $this->result_os_name = 'Android';
588 $matches = $this->match_ua('/Android(?: |\-)([0-9]+\.[0-9]+)/');
589 $this->result_os_version = is_array($matches) ? (float)$matches[1] : 0;
590 if (empty($this->result_os_version))
591 {
592 $matches = $this->match_ua('/Android(?: |\-)(\d+)/');
593 $this->result_os_version = is_array($matches) ? (float)$matches[1] : 0;
594 }
595 $this->result_os_family = 'android';
596 $os_need_continue = FALSE;
597 }
598
599 // iOS OS
600
601 if ($os_need_continue && $this->result_ios!=FALSE && !$this->match_ua('Windows Phone|Windows Mobile'))
602 {
603 $this->result_os_version = 0;
604 $this->result_os_name = 'iOS';
605 $matches = $this->match_ua('/\sOS\s(\d+)[_.](\d+)/');
606 $version = is_array($matches) ? $matches[1] : 0;
607 $version_minor = is_array($matches) ? $matches[2] : 0;
608 if (!empty($version)) $this->result_os_version = floatval($version.'.'.$version_minor);
609 $this->result_os_family = 'macintosh';
610 $os_need_continue = FALSE;
611 }
612
613 // WhatsApp Android / iOS
614
615 if ($os_need_continue && $this->match_ua('WhatsApp/'))
616 {
617 $matches = $this->match_ua('/WhatsApp\/([.0-9]+)\s(A|i)$/');
618 $os_match = is_array($matches) ? $matches[2] : 0;
619
620 if ($os_match === 'A')
621 {
622 $this->result_os_name = 'Android';
623 $this->result_os_family = 'android';
624 }
625
626 if ($os_match === 'i')
627 {
628 $this->result_os_name = 'iOS';
629 $this->result_os_family = 'macintosh';
630 }
631 }
632
633 // Windows Phone OS, Tizen OS, Bada OS, Kindle OS, FIre OS, Java Platform
634
635 if ($os_need_continue)
636 {
637 $os_list[] = array('Windows Phone'=>'/Phone(?: OS)? ([.0-9]+)/');
638 $os_list[] = array('Windows Mobile'=>'/Windows Mobile ([.0-9]+)/');
639 $os_list[] = array('Windows Mobile'=>'Windows Mobile');
640 $os_list[] = array('Windows CE'=>'Windows CE');
641 $os_list[] = array('Firefox OS'=>'/Mozilla\/5\.0\s\((?:Mobile|Tablet);(?:.*;)?\srv:[.0-9]+\)\sGecko\/[.0-9]+\sFirefox\/[.0-9]+$/');
642 $os_list[] = array('Tizen'=>'/Tizen[\/\s]([.0-9]+)/');
643 $os_list[] = array('Bada'=>'/Bada[;\/]([.0-9]+)/');
644 $os_list[] = array('Kindle'=>'/Kindle\/([0-9]+\.[0-9]+)/');
645 $os_list[] = array('Fire OS'=>'KFJW|Silk/');
646 $os_list[] = array('Java Platform'=>'/MIDP\-([0-9]+\.[0-9]+)/');
647 $os_list[] = array('Java Platform'=>'/MIDP/');
648 $os_list[] = array('MAUI Platform'=>'/MAUI\s|\sMAUI/');
649
650 foreach($os_list as $os_list_va)
651 {
652 $k = key($os_list_va);
653 $v = $os_list_va[$k];
654
655 $matches = $this->match_ua($v);
656 if ($matches)
657 {
658 $this->result_os_family = 'linux';
659 if (strpos($k, 'Windows') !== FALSE) $this->result_os_family = 'windows';
660 $this->result_os_name = $k;
661 $this->result_os_version = is_array($matches) ? (float)$matches[1] : 0;
662 $os_need_continue = FALSE;
663
664 // J2ME/MIDP or MAUI
665
666 if (strpos($k, 'Java Platform') !== FALSE || strpos($k, 'MAUI Platform') !== FALSE)
667 {
668 $this->result_os_family = 'unknown';
669 $os_need_continue = TRUE;
670 }
671 break;
672 }
673 }
674 $os_list = NULL;
675 }
676
677 // Other Mobile OS(es)
678
679 if ($os_need_continue)
680 {
681 $other_os = array();
682
683 $other_os[] = array('Android'=>'CrKey armv');
684 $other_os[] = array('Android'=>'SpreadTrum;');
685 $other_os[] = array('BlackBerry'=>'BlackBerry');
686 $other_os[] = array('BlackBerry'=>'BB10;');
687 $other_os[] = array('BlackBerry'=>'RIM Tablet');
688 $other_os[] = array('Symbian'=>'Symbian');
689 $other_os[] = array('Symbian'=>'(Series');
690 $other_os[] = array('Symbian'=>'SymbOS');
691 $other_os[] = array('WatchOS'=>'Watch');
692 $other_os[] = array('KaiOS'=>'KAIOS');
693 $other_os[] = array('RemixOS'=>'Remix Mini');
694 $other_os[] = array('RemixOS'=>'RemixOS');
695 $other_os[] = array('Sailfish OS'=>'Sailfish');
696 $other_os[] = array('LiveArea'=>'PlayStation Vita');
697 $other_os[] = array('PalmOS'=>'PalmOS');
698 $other_os[] = array('PalmOS'=>'PalmSource');
699 $other_os[] = array('Maemo'=>'Maemo');
700 $other_os[] = array('PlayStation Platform'=>'PlayStation');
701 $other_os[] = array('PlayStation Platform'=>'PLAYSTATION');
702
703 foreach ($other_os as $other_os_va)
704 {
705 $k = key($other_os_va);
706 $v = $other_os_va[$k];
707
708 if ($this->match_ua($v))
709 {
710 if ($k === 'Android') $this->result_os_family = 'android';
711 if ($k === 'BlackBerry') $this->result_os_family = 'blackberry';
712 if ($k === 'Symbian') $this->result_os_family = 'symbian';
713 if ($k === 'WatchOS') $this->result_os_family = 'macintosh';
714 if ($k === 'Sailfish OS' || $k === 'KaiOS' || $k === 'Maemo') $this->result_os_family = 'linux';
715 if ($k === 'RemixOS') $this->result_os_family = 'android';
716 if ($k === 'LiveArea') $this->result_os_family = 'livearea';
717 if ($k === 'PalmOS') $this->result_os_family = 'palm';
718 if ($k === 'PlayStation Platform') $this->result_os_family = 'unix';
719 $this->result_os_version = 0;
720 $this->result_os_name = $k;
721 $this->result_os_title = $k;
722 $os_need_continue = FALSE;
723 break;
724 }
725 }
726
727 $other_os = NULL;
728 }
729
730 // End of mobile OS detection
731 }
732
733 // Other mixed-type linux-family OS(es)
734
735 if ($this->get_mode !== 'browser' && ($this->result_os_family === 'linux' || $this->result_os_family === 'unknown'))
736 {
737 $other_os = array();
738
739 $other_os[] = array('WebOS'=>'hpwOS');
740 $other_os[] = array('WebOS'=>'Web0S');
741 $other_os[] = array('WebOS'=>'WebOS');
742 $other_os[] = array('WebOS'=>'webOS');
743
744 foreach ($other_os as $other_os_va)
745 {
746 $k = key($other_os_va);
747 $v = $other_os_va[$k];
748
749 if ($this->match_ua($v))
750 {
751 $this->result_os_family = 'linux';
752 $this->result_os_type = 'mixed';
753 $this->result_os_version = 0;
754 $this->result_os_name = $k;
755 $this->result_os_title = $k;
756 break;
757 }
758 }
759 $other_os = NULL;
760 }
761
762 // Darwin (MacOS and iOS)
763
764 if ($os_need_continue && $this->match_ua(' Darwin') && !$this->match_ua('X11;'))
765 {
766 $this->result_os_family = 'macintosh';
767
768 if ($this->match_ua('x86_64|i386|Mac'))
769 {
770 $this->result_os_type = 'desktop';
771 $this->result_os_name = 'MacOS';
772 }
773 else
774 {
775 $this->result_os_type = 'mobile';
776 $this->result_mobile = 1;
777 $this->result_os_name = 'iOS';
778 $this->result_ios = TRUE;
779 }
780
781 $this->result_os_version = 0;
782 $darwin_os_version = 0;
783
784 $matches = $this->match_ua('/\sDarwin(\s|\/)([0-9]+\.[0-9]+)/');
785 if (!empty($matches[2])) $darwin_os_version = (float)$matches[2];
786
787 $darwin_macos_map = array('1.3'=>'0', '1.4'=>'1', '5.1'=>'1', '5.5'=>'1', '6.0'=>'2', '6.8'=>'2', '7.0'=>'3', '7.9'=>'3', '8.0'=>'4', '8.1'=>'4', '9.0'=>'5', '9.8'=>'5', '10.0'=>'6', '10.8'=>'6', '11.0'=>'7', '11.4'=>'7', '12.0'=>'8', '12.6'=>'8', '13.0'=>'9', '13.4'=>'9', '14.0'=>'10', '14.5'=>'10', '15.0'=>'11', '15.6'=>'11', '16.0'=>'12', '16.6'=>'12', '17.0'=>'13', '17.7'=>'13', '18.0'=>'14', '18.2'=>'14', '19.0'=>'15', '19.6'=>'15', '20.0'=>'16', '20.6'=>'16', '21.0'=>'17', '21.6'=>'17', '22.0'=>'18', '22.3'=>'18');
788 $darwin_ios_map = array('9.0'=>'1', '9.8'=>'1', '10.0'=>'4', '10.8'=>'4', '11.0'=>'5', '11.4'=>'5', '12.0'=>'6', '13.0'=>'7', '14.0'=>'8', '15.0'=>'9', '15.6'=>'9', '16.0'=>'10', '16.6'=>'10', '17.0'=>'11', '17.7'=>'11', '18.0'=>'12', '18.2'=>'12', '19.0'=>'13', '19.6'=>'13', '20.0'=>'14', '20.6'=>'14', '21.0'=>'15', '21.6'=>'15', '22.0'=>'16', '22.3'=>'16');
789
790 if ($this->result_os_name === 'MacOS') $darwin_map = $darwin_macos_map;
791 else $darwin_map = $darwin_ios_map;
792
793 foreach ($darwin_map as $k=>$v)
794 {
795 $darwin_map_min[$k] = abs($k-$darwin_os_version);
796 }
797
798 asort($darwin_map_min);
799 $darwin_map_key = key($darwin_map_min);
800 $this->result_os_version = $darwin_map[$darwin_map_key];
801
802 if ($this->result_os_name === 'MacOS')
803 {
804 $this->result_os_version = $this->macos_codename($darwin_map[$darwin_map_key]);
805 if (!empty($this->result_os_version)) $this->result_os_title = 'MacOS '.$this->result_os_version;
806 else $this->result_os_title = 'MacOS';
807 }
808
809 $darwin_map = NULL;
810 $darwin_map_min = NULL;
811 $darwin_macos_map = NULL;
812 $darwin_ios_map = NULL;
813 $os_need_continue = FALSE;
814 }
815
816 // Set OS title and type
817
818 if ($this->get_mode !== 'browser' && $this->result_os_name !== 'MacOS')
819 {
820 if (!empty($this->result_os_version)) $this->result_os_title = $this->result_os_name.' '.$this->result_os_version;
821 else
822 {
823 if ($this->result_os_name !== 'Windows') $this->result_os_title = $this->result_os_name;
824 else $this->result_os_title = $this->result_os_name.' (unknown version)';
825 }
826 if (strpos($this->result_os_name, 'unknown') !== false) $this->result_os_type = 'unknown';
827 if ($this->result_os_version == NULL) $this->result_os_version = 0;
828 }
829
830 /*
831 ---------------------
832 Detect 64bits mode
833 ---------------------
834 */
835
836 if ($this->result_os_name === 'iOS' && $this->result_os_version >= 11) $this->result_64bits_mode = 1;
837 if ($this->result_os_name === 'MacOS' && $this->macos_version_minor >= 8) $this->result_64bits_mode = 1;
838
839 if ($this->result_64bits_mode == 0)
840 {
841 if ($this->match_ua('64') && $this->match_ua('x64;|x86_64|x86-64|arm64|arm_64|aarch64|Linux x64|mips64|amd64|AMD64|ia64|IRIX64|ppc64|sparc64|x64_64'))
842 {
843 $this->result_64bits_mode = 1;
844 }
845 }
846
847 if ($this->result_os_name === 'Android' && $this->result_browser_desktop_mode == 1) $this->result_64bits_mode = 0;
848 if ($this->result_64bits_mode == 1 && $this->match_ua('86') && $this->match_ua('i386|i686')) $this->result_64bits_mode = 0;
849
850 // If mode 'os' only
851
852 if ($this->get_mode === 'os') return NULL;
853
854 /*
855 -------------------
856 BROWSER DETECTION
857 -------------------
858
859 ---------------------
860 Mixed-type Browsers
861 ---------------------
862 */
863
864 $browser_need_continue = TRUE;
865 if ($this->get_mode === 'device') $browser_need_continue = FALSE;
866
867 // Chrome / Chromium
868
869 if ($browser_need_continue && $this->match_ua('Chrome/|Chromium/|CriOS/|CrMo/'))
870 {
871 $this->result_browser_version = 0;
872 $matches = $this->match_ua('/(Chrome|Chromium|CriOS|CrMo)\/([0-9]+)\.?/');
873 $this->result_browser_name = 'Chrome';
874 if (!empty($matches[1]) && $matches[1]==='Chromium') $this->result_browser_name = 'Chromium';
875 if (!empty($matches[2])) $this->result_browser_version = (int)$matches[2];
876 $this->result_browser_chromium_version = $this->result_browser_version;
877 if ($this->match_ua('CriOS/')) $this->result_browser_chromium_version = 0;
878 if ($this->match_ua('/Gecko\)\s(Chrome|CrMo)\/(\d+\.\d+\.\d+\.\d+)\s(?:Mobile)?(?:\/[.0-9A-Za-z]+\s|\s)?Safari\/[.0-9]+$/') && !$this->match_ua('SalamWeb| Valve | GOST')) $this->result_browser_chrome_original = 1;
879 }
880
881 // Firefox
882
883 if ($browser_need_continue && $this->result_browser_chromium_version == 0 && $this->match_ua('Firefox/') && !$this->match_ua('Focus/|FxiOS|Waterfox|Ghostery:'))
884 {
885 $this->result_browser_version = 0;
886 $matches = $this->match_ua('/Firefox\/([0-9]+)\./');
887 $this->result_browser_name = 'Firefox';
888 if (!empty($matches[1])) $this->result_browser_version = (int)$matches[1];
889 if($this->match_ua('/\)\sGecko\/[.0-9]+\sFirefox\/[.0-9]+$/')) $this->result_browser_firefox_original = 1;
890 }
891
892 // Cross-device browsers (Yandex, Edge, Firefox, Opera, Puffin, Vivaldi, QQ Browser, Whale, Brave etc)
893
894 if ($browser_need_continue && $this->result_browser_chrome_original == 0 && $this->result_browser_firefox_original == 0)
895 {
896 $browser_list[] = array('Yandex Browser', 'YaBrowser', '/YaBrowser\/([0-9]+\.[0-9]+)/', '1', 'YaApp_');
897 $browser_list[] = array('Edge', 'Edg', '/Edg(|e|A|iOS)\/([0-9]+)\./', '2', '');
898 $browser_list[] = array('Opera', ' OPR/', '/OPR\/(\d+)/', '1', 'Opera Mini|OPiOS|OPT/|OPRGX/|AlohaBrowser');
899 $browser_list[] = array('Opera', 'Opera', '/Opera.*Version\/([0-9]+\.[0-9]+)/', '1', 'Opera Mini|OPiOS|OPT/|InettvBrowser/');
900 $browser_list[] = array('Opera', 'Opera', '/Opera(\s|\/)([0-9]+\.[0-9]+)/', '2', 'Opera Mini|OPiOS|OPT/|InettvBrowser/');
901 $browser_list[] = array('UC Browser', 'UBrowser|UCBrowser|UCMini', '/(UBrowser|UCBrowser|UCMini)\/([0-9]+\.[0-9]+)/', '2', 'UCTurbo|AliApp');
902 $browser_list[] = array('UC Browser Turbo', 'UCTurbo/', '/UCTurbo\/([0-9]+\.[0-9]+)/', '1', '');
903 $browser_list[] = array('Puffin', 'Puffin/', '/Puffin\/([0-9]+\.[0-9]+)/', '1', '');
904 $browser_list[] = array('Vivaldi', 'Vivaldi/', '/Vivaldi\/([0-9]+\.[0-9]+)/', '1', '');
905 $browser_list[] = array('QQ Browser', 'QQBrowser/', '/QQBrowser\/([0-9]+\.[0-9]+)/', '1', '');
906 $browser_list[] = array('Coc Coc', 'coc_coc_browser', '/coc_coc_browser\/([0-9]+)/', '1', '');
907 $browser_list[] = array('Whale', 'Whale/', '/Whale\/([0-9]+\.[0-9]+)/', '1', 'NAVER(inapp;');
908 $browser_list[] = array('Brave', 'Brave', '/Brave(?: Chrome)?\/([0-9]+)/', '1', '');
909 $browser_list[] = array('Maxthon', 'Maxthon/', '/Maxthon\/([0-9]+\.[0-9]+)/', '1', '');
910 $browser_list[] = array('Maxthon', 'MxBrowser/', '/MxBrowser\/([0-9]+\.[0-9]+)/', '1', '');
911 $browser_list[] = array('2345 Explorer', '2345Explorer|2345Browser', '/(2345Explorer|2345Browser)(?: |\/)?([0-9]+\.[0-9]+)/', '2', '');
912 $browser_list[] = array('IceCat', 'IceCat/', '/IceCat\/([0-9]+)/', '1', '');
913 $browser_list[] = array('Lunascape', 'Lunascape', '/Lunascape(?: |\/)?([0-9]+\.[0-9]+)/', '1', '');
914 $browser_list[] = array('Seznam Browser', 'Seznam.cz/|SznProhlizec/', '/(Seznam\.cz|SznProhlizec)\/([0-9]+\.[0-9]+)/', '2', '');
915 $browser_list[] = array('Sleipnir', 'Sleipnir/', '/Sleipnir\/([0-9]+\.[0-9]+)/', '1', '');
916 $browser_list[] = array('Sputnik', 'SputnikBrowser/', '/SputnikBrowser\/([0-9]+\.[0-9]+)/', '1', '');
917 $browser_list[] = array('Oculus Browser', 'OculusBrowser/', '/OculusBrowser\/([0-9]+\.[0-9]+)/', '1', '');
918 $browser_list[] = array('PaleMoon', 'PaleMoon', '/PaleMoon\/([0-9]+\.[0-9]+)/', '1', '');
919 $browser_list[] = array('SalamWeb', 'SalamWeb|Salam Browser', '/SalamWeb\/([0-9]+\.[0-9]+)/', '1', '');
920 $browser_list[] = array('Swing', 'Swing/|Swing(And)/', '/Swing(?:\(And\))?\/([0-9]+\.[0-9]+)/', '1', '');
921 $browser_list[] = array('Safe Exam Browser', 'SEB/', '/SEB\/([0-9]+\.[0-9]+)/', '1', '');
922 $browser_list[] = array('Colibri', 'Colibri/', '/Colibri\/([0-9]+\.[0-9]+)/', '1', '');
923 $browser_list[] = array('Opera GX', 'OPRGX', '/OPRGX\/([0-9]+)/', '1', '');
924 $browser_list[] = array('Opera GX', 'OPX/', '/OPX\/([0-9]+\.[0-9]+)/', '1', '');
925 $browser_list[] = array('Xvast', 'Xvast/', '/Xvast\/([0-9]+\.[0-9]+)/', '1', '');
926 $browser_list[] = array('Atom', 'Atom/', '/Atom\/([0-9]+\.[0-9]+)/', '1', '');
927 $browser_list[] = array('NetCast', 'SmartTV/', '/SmartTV\/([0-9]+)/', '1', '');
928 $browser_list[] = array('LG Browser', ' LG Browser/', '/\sLG\sBrowser\/([0-9]+)/', '1', '');
929 $browser_list[] = array('Ghostery Browser', 'Ghostery:', '/Ghostery\:([0-9]+\.[0-9]+)/', '1', '');
930 $browser_list[] = array('Aloha Browser', 'AlohaBrowser/', '/AlohaBrowser\/([0-9]+\.[0-9]+)/', '1', '');
931 $browser_list[] = array('Lenovo Browser', 'SLBrowser/', '/SLBrowser\/([0-9]+\.[0-9]+)/', '1', '');
932 $browser_list[] = array('Samsung Browser TV', '/SamsungBrowser\/[.0-9]+\sTV\s/', '/SamsungBrowser\/([0-9]+\.[0-9]+)/', '1', '');
933 $browser_list[] = array('WeChat App', 'MicroMessenger/', '/MicroMessenger\/([0-9]+\.[0-9]+)/', '1', '');
934 $browser_list[] = array('WKWebView', '/Intel\sMac\sOS\sX\s\d+.*\)\sAppleWebKit\/[.0-9]+.*Gecko\)$/', 'AppleWebKit', '1', '');
935 $browser_list[] = array('Sber Browser', 'SberBrowser/', '/SberBrowser\/([0-9]+\.[0-9]+)/', '1', '');
936
937 foreach($browser_list as $browser_list_va)
938 {
939 $match = $browser_list_va[1];
940 $match_exclude = $browser_list_va[4];
941
942 if ($this->match_ua($match) && !$this->match_ua($match_exclude))
943 {
944 $this->result_browser_version = 0;
945 $this->result_browser_name = $browser_list_va[0];
946 $matches = $this->match_ua($browser_list_va[2]);
947 $matches_n = intval($browser_list_va[3]);
948 $this->result_browser_version = is_array($matches) ? (float)$matches[$matches_n] : 0;
949 if (!empty($this->result_browser_version))
950 {
951 $browser_need_continue = FALSE;
952 break;
953 }
954 }
955 }
956
957 $browser_list = NULL;
958 }
959
960 // Gecko engine detection
961
962 if ($this->get_mode !== 'device' && $this->result_browser_chromium_version == 0 && $this->match_ua('Gecko/|ArtisBrowser/') && ($this->match_ua('/\srv:[.0-9a-z]+(?:\;\s.*|)\)\sGecko\/[.0-9]+\s/') || $this->match_ua('QwantMobile/|ArtisBrowser/')))
963 {
964 $this->result_browser_gecko_version = 0;
965 $match = $this->match_ua('/\srv:([0-9]+\.[0-9]+)(?:[.0-9a-z]+)?(?:\;\s.*|)\)\sGecko\/[.0-9]+\s/');
966
967 if (is_array($match))
968 {
969 if ($match[1]>=5) $match[1] = intval($match[1]);
970 else $match[1] = (float)$match[1];
971 }
972
973 if (!empty($match[1])) $this->result_browser_gecko_version = $match[1];
974 else
975 {
976 $match = $this->match_ua('/\sGecko\/([.0-9]+)\s.*QwantMobile\/[.0-9]+$/');
977 if (!empty($match[1])) $this->result_browser_gecko_version = intval($match[1]);
978 else
979 {
980 $match = $this->match_ua('/\srv:([0-9]+\.[0-9]+)\)\s.*ArtisBrowser\/[.0-9]+$/');
981 if (!empty($match[1])) $this->result_browser_gecko_version = intval($match[1]);
982 }
983 }
984
985 // Gecko >= 109 issue
986
987 if ($this->result_browser_gecko_version >= 109 && $this->result_browser_gecko_version < 120)
988 {
989 $match = $this->match_ua('/\srv:[.0-9a-z]+(?:\;\s.*|)\)\sGecko\/[.0-9]+\s.*(?:Firefox|MaxBrowser)\/([0-9]+)\./');
990 if (!empty($match[1])) $this->result_browser_gecko_version = intval($match[1]);
991 }
992 }
993
994 // WebKit engine detection
995
996 if ($this->get_mode !== 'device' && $this->result_browser_chromium_version == 0 && $this->result_browser_gecko_version == 0 && $this->matchi_ua('AppleWebKit/'))
997 {
998 $this->result_browser_webkit_version = 0;
999 $match = $this->matchi_ua('/AppleWebKit\/([0-9]+\.[0-9]+)/');
1000 if (!empty($match[1])) $this->result_browser_webkit_version = (float)$match[1];
1001 }
1002
1003 /*
1004 ------------------
1005 Desktop Browsers
1006 ------------------
1007 */
1008
1009 if ($browser_need_continue && $this->result_browser_chrome_original==0 && $this->result_browser_firefox_original==0 && $this->result_mobile == 0)
1010 {
1011 // Safari
1012
1013 $browser_list[] = array('Safari', '/AppleWebKit\/[.0-9]+.*Gecko\)\sSafari\/[.0-9A-Za-z]+$/', '/Safari\/(\d+)/', '1', 'Version/');
1014 $browser_list[] = array('Safari', '/Version\/([0-9]+\.[0-9]+).*Safari/', '/Version\/([0-9]+\.[0-9]+).*Safari/', '1', 'Epiphany|Arora/|Midori|midori|SlimBoat|Roccat');
1015
1016 // IE
1017
1018 $browser_list[] = array('Internet Explorer', 'MSIE', '/MSIE(?:\s|)([0-9]+)/', '1', 'Opera|IEMobile|Trident/');
1019 $browser_list[] = array('Internet Explorer', 'Trident/', '/Trident\/([0-9]+)/', '1', 'Opera|IEMobile');
1020
1021 // Chromium based browsers
1022
1023 $browser_list[] = array('Avast Browser', 'Avast/', '/Avast\/([0-9]+)/', '1', '');
1024 $browser_list[] = array('AVG Browser', 'AVG/', '/AVG\/([0-9]+)/', '1', '');
1025 $browser_list[] = array('CCleaner Browser', 'CCleaner/', '/CCleaner\/([0-9]+)/', '1', '');
1026 $browser_list[] = array('Comodo Dragon', 'Dragon/', '/Dragon\/([0-9]+)/', '1', 'IceDragon');
1027 $browser_list[] = array('Iridium', 'Iridium/', '/Iridium\/.*Safari.*Chrome\/([0-9]+)/', '1', '');
1028 $browser_list[] = array('Maxthon Nitro', 'MxNitro|mxnitro', '/(MxNitro|mxnitro)\/([0-9]+\.[0-9]+)/', '2', '');
1029 $browser_list[] = array('Iron', ' Iron ', '/Chrome\/([0-9]+)/', '1', '');
1030 $browser_list[] = array('Iron', 'Iron/', '/Iron\/([0-9]+)/', '1', '');
1031 $browser_list[] = array('Hola Browser', 'Hola/', '/Hola\/([0-9]+\.[0-9]+)/', '1', '');
1032 $browser_list[] = array('Sogou Explorer', '/Chrome.*Safari.*SE\s.*MetaSr/', '/Chrome\/([0-9]+)/', '1', '');
1033 $browser_list[] = array('360 browser', 'QIHU 360', '/Chrome\/([0-9]+)/', '1', '');
1034 $browser_list[] = array('Slimjet', 'Slimjet/', '/Slimjet\/([0-9]+)/', '1', '');
1035 $browser_list[] = array('FreeU', 'FreeU|Freeu', '/(FreeU|Freeu)\/([0-9]+)/', '2', '');
1036 $browser_list[] = array('Kinza', 'Kinza/', '/Kinza\/([0-9]+\.[0-9]+)/', '1', '');
1037 $browser_list[] = array('Station', 'Station/', '/Station\/([0-9]+\.[0-9]+)/', '1', '');
1038 $browser_list[] = array('Superbird', 'Superbird|SuperBird', '/(Superbird|SuperBird)\/([0-9]+)/', '2', '');
1039 $browser_list[] = array('Polypane', 'Polypane/', '/Polypane\/([0-9]+\.[0-9]+)/', '1', '');
1040 $browser_list[] = array('OhHai Browser', 'OhHaiBrowser/', '/OhHaiBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1041 $browser_list[] = array('Sizzy', 'Sizzy', '/Sizzy\/([0-9]+\.[0-9]+)/', '1', '');
1042 $browser_list[] = array('AOL Desktop', 'ADG/', '/ADG\/([0-9]+\.[0-9]+)/', '1', '');
1043 $browser_list[] = array('Elements Browser', 'Elements Browser', '/Elements\sBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1044 $browser_list[] = array('115 Browser', '115Browser', '/115Browser\/([0-9]+\.[0-9]+)/', '1', '');
1045 $browser_list[] = array('Falkon', 'Falkon/', '/Falkon\/([0-9]+\.[0-9]+)/', '1', '');
1046 $browser_list[] = array('AOL Shield Pro', 'AOLShield', '/AOLShield\/([0-9]+)/', '1', '');
1047 $browser_list[] = array('Google Earth', 'Google Earth', '/Google Earth(?:|\sPro)\/([0-9]+\.[0-9]+)/', '1', '');
1048 $browser_list[] = array('Chedot', 'Chedot/', '/Chedot\/([0-9]+\.[0-9]+)/', '1', '');
1049 $browser_list[] = array('SlimBoat', 'SlimBoat/', '/SlimBoat\/([0-9]+\.[0-9]+)/', '1', '');
1050 $browser_list[] = array('Rambler Browser', 'Nichrome/', '/Chrome\/([0-9]+)/', '1', '');
1051 $browser_list[] = array('Beaker Browser', 'BeakerBrowser/', '/BeakerBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1052 $browser_list[] = array('Amigo', 'Amigo/', '/Amigo\/([0-9]+\.[0-9]+)/', '1', '');
1053 $browser_list[] = array('Opera Neon', ' MMS/', '/\sMMS\/([0-9]+\.[0-9]+)/', '1', '');
1054 $browser_list[] = array('SmartTV Browser', 'Thano/', '/Thano\/([0-9]+\.[0-9]+)/', '1', '');
1055 $browser_list[] = array('Biscuit', 'Biscuit/', '/Biscuit\/([0-9]+\.[0-9]+)/', '1', '');
1056 $browser_list[] = array('Chromium GOST', 'Chromium GOST', '/Chrome\/([0-9]+\.[0-9]+)/', '1', '');
1057 $browser_list[] = array('Dashob', 'Dashob/', '/Dashob\/([0-9]+\.[0-9]+)/', '1', '');
1058 $browser_list[] = array('Dezor', 'Dezor/', '/Dezor\/([0-9]+\.[0-9]+)/', '1', '');
1059 $browser_list[] = array('Duoyu Browser', 'duoyu_business/', '/duoyu_business\/([0-9]+\.[0-9]+)/', '1', '');
1060 $browser_list[] = array('iTop Browser', ' iTop', '/Chrome\/([0-9]+\.[0-9]+)*.+\siTop$/', '1', '');
1061 $browser_list[] = array('Polarity', 'Polarity/', '/Polarity\/([0-9]+\.[0-9]+)/', '1', '');
1062 $browser_list[] = array('Sielo', 'Sielo/', '/Sielo\/([0-9]+\.[0-9]+)/', '1', '');
1063 $browser_list[] = array('Norton Browser', 'Norton/', '/Norton\/([0-9]+)/', '1', '');
1064 $browser_list[] = array('Avira Browser', 'Avira/', '/Avira\/([0-9]+)/', '1', '');
1065
1066 // Webkit, Gecko and other engine based browsers
1067
1068 $browser_list[] = array('Cyberfox', 'Cyberfox/', '/Cyberfox\/([0-9]+)/', '1', '');
1069 $browser_list[] = array('SeaMonkey', 'SeaMonkey/', '/SeaMonkey\/([0-9]+\.[0-9]+)/', '1', '');
1070 $browser_list[] = array('K-Meleon', 'K-Meleon', '/K\-Meleon\/([0-9]+\.[0-9]+)/', '1', '');
1071 $browser_list[] = array('Iceweasel', '/[iI]ce[wW]easel/', '/[iI]ce[wW]easel/', '1', '');
1072 $browser_list[] = array('IceApe', 'Iceape/', '/Iceape\/([0-9]+\.[0-9]+)/', '1', '');
1073 $browser_list[] = array('Comodo Ice Dragon', 'IceDragon/', '/IceDragon\/([0-9]+\.[0-9]+)/', '1', '');
1074 $browser_list[] = array('QtWeb', 'QtWeb Internet Browser/', '/QtWeb\sInternet\sBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1075 $browser_list[] = array('QtWebEngine', 'QtWebEngine', '/QtWebEngine\/([0-9]+\.[0-9]+)/', '1', 'Konqueror');
1076 $browser_list[] = array('Qt', 'Qt/', '/Qt\/([0-9]+\.[0-9]+)/', '1', '');
1077 $browser_list[] = array('WebKitGTK', 'WebKitGTK+/', '/WebKitGTK\+\/([0-9]+\.[0-9]+)/', '1', '');
1078 $browser_list[] = array('Konqueror', 'Konqueror', '/Konqueror\/([0-9]+\.[0-9]+)/', '1', 'QtWebEngine');
1079 $browser_list[] = array('Konqueror', 'konqueror', '/konqueror\/([0-9]+\.[0-9]+)/', '1', 'QtWebEngine');
1080 $browser_list[] = array('Konqueror', 'Konqueror', '/\sQtWebEngine\/([0-9]+\.[0-9]+)(|[.0-9]+)\sChrome\/[.0-9]+.*\sSafari\/[.0-9]+.*Konqueror\s/', '1', '');
1081 $browser_list[] = array('Epiphany', 'Epiphany', '/Epiphany\/([0-9]+\.[0-9]+)/', '1', '');
1082 $browser_list[] = array('OmniWeb', 'OmniWeb/', '/OmniWeb\//', '1', '');
1083 $browser_list[] = array('iCab', 'iCab', '/iCab(\s|\/)([0-9]+\.[0-9]+)/', '2', '');
1084 $browser_list[] = array('Camino', 'Camino/', '/Camino\/([0-9]+\.[0-9]+)/', '1', '');
1085 $browser_list[] = array('Midori', 'Midori|midori', '/Midori\/([.0-9]+)/', '1', '');
1086 $browser_list[] = array('Otter', 'Otter/', '/Otter\/([0-9]+\.[0-9]+)/', '1', '');
1087 $browser_list[] = array('Kazehakase', 'Kazehakase/', '/Kazehakase\/([0-9]+\.[0-9]+)/', '1', '');
1088 $browser_list[] = array('QupZilla', 'QupZilla/', '/QupZilla\/([0-9]+\.[0-9]+)/', '1', '');
1089 $browser_list[] = array('Waterfox', 'Waterfox/', '/Waterfox\/([0-9]+)/', '1', '');
1090 $browser_list[] = array('Waterfox', 'Waterfox', '/Firefox\/([0-9]+)/', '1', '');
1091 $browser_list[] = array('Basilisk', 'Basilisk/', '/\srv:([0-9]+\.[0-9]+)/', '1', '');
1092 $browser_list[] = array('Dooble', 'Dooble/', '/Dooble\/([0-9]+\.[0-9]+)/', '1', '');
1093 $browser_list[] = array('Fluid', 'Fluid/', '/Fluid\/([0-9]+\.[0-9]+)/', '1', '');
1094 $browser_list[] = array('Arora', 'Arora/', '/Arora\/([0-9]+\.[0-9]+)/', '1', '');
1095 $browser_list[] = array('Artis Browser', 'ArtisBrowser/', '/ArtisBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1096 $browser_list[] = array('Steam Client', ' Valve ', '/Valve\s(|Steam\s)Client/', '1', 'Tenfoot');
1097 $browser_list[] = array('Steam Overlay', ' Valve ', '/Valve\sSteam\sGameOverlay/', '1', 'Tenfoot|Client/');
1098 $browser_list[] = array('Rekonq', ' rekonq', '/rekonq\/([0-9]+\.[0-9]+)/', '1', '');
1099 $browser_list[] = array('Odyssey Web Browser', 'Odyssey Web Browser', '/OWB\/([0-9]+\.[0-9]+)/', '1', '');
1100 $browser_list[] = array('Safari SDK', '/^Safari\/[.0-9]+\sCFNetwork\/[.0-9]+\sDarwin\/[.0-9]+/', '/Safari\//', '1', '');
1101 $browser_list[] = array('Internet TV Browser', 'InettvBrowser/', '/InettvBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1102 $browser_list[] = array('Firefox', 'BonEcho/', '/BonEcho\/([0-9]+)/', '1', '');
1103 $browser_list[] = array('Firefox', 'GranParadiso/', '/GranParadiso\/([0-9]+)/', '1', '');
1104 $browser_list[] = array('Firefox', 'Shiretoko/', '/Shiretoko\/([0-9]+)/', '1', '');
1105 $browser_list[] = array('Firefox', 'Namoroka/', '/Namoroka\/([0-9]+)/', '1', '');
1106 $browser_list[] = array('iTunes App', 'iTunes/', '/iTunes\/([0-9]+\.[0-9]+)/', '1', '');
1107 $browser_list[] = array('Mypal Browser', 'Mypal/', '/Mypal\/([0-9]+\.[0-9]+)/', '1', '');
1108 $browser_list[] = array('Mercury', 'Mercury/', '/Firefox\/([0-9]+\.[0-9]+)/', '1', '');
1109 $browser_list[] = array('Arctic Fox', 'ArcticFox/', '/ArcticFox\/([0-9]+\.[0-9]+)/', '1', '');
1110 $browser_list[] = array('Roccat', ' Roccat/', '/Roccat\/([0-9]+\.[0-9]+)/', '1', '');
1111 $browser_list[] = array('Lunascape', ' lswebkit ', ' lswebkit ', '1', '');
1112
1113 foreach($browser_list as $browser_list_va)
1114 {
1115 $match = $browser_list_va[1];
1116 $match_exclude = $browser_list_va[4];
1117
1118 if ($this->match_ua($match) && !$this->match_ua($match_exclude))
1119 {
1120 $this->result_browser_version = 0;
1121 $this->result_browser_name = $browser_list_va[0];
1122 $matches = $this->match_ua($browser_list_va[2]);
1123 $matches_n = intval($browser_list_va[3]);
1124 $this->result_browser_version = is_array($matches) ? (float)$matches[$matches_n] : 0;
1125
1126 // Gnome Web browser detection on Linux/Unix OS
1127
1128 if ($this->result_browser_name === 'Safari' && ($this->result_os_family === 'linux' || $this->result_os_family === 'unix'))
1129 {
1130 $this->result_browser_name = 'Gnome Web';
1131 }
1132
1133 // Safari old version conversion
1134
1135 if ($match === '/AppleWebKit\/[.0-9]+.*Gecko\)\sSafari\/[.0-9A-Za-z]+$/')
1136 {
1137 $ev = intval($this->result_browser_version);
1138 if (!empty($ev)) $this->result_browser_version = 1;
1139 if ($ev>400) $this->result_browser_version = 2;
1140 if ($ev>500) $this->result_browser_version = 3;
1141 if ($ev>527) $this->result_browser_version = 4;
1142 if ($ev>532) $this->result_browser_version = 5;
1143 if ($ev>535) $this->result_browser_version = 6;
1144 $this->result_browser_safari_original = 1;
1145 }
1146
1147 // IE Trident engine version conversion
1148
1149 if ($match === 'Trident/')
1150 {
1151 if ($this->result_browser_version==4) $this->result_browser_version = 8;
1152 if ($this->result_browser_version==5) $this->result_browser_version = 9;
1153 if ($this->result_browser_version==6) $this->result_browser_version = 10;
1154 if ($this->result_browser_version==7) $this->result_browser_version = 11;
1155 }
1156
1157 if (!empty($this->result_browser_version))
1158 {
1159 $browser_need_continue = FALSE;
1160 break;
1161 }
1162 }
1163 }
1164
1165 $browser_list = NULL;
1166
1167 // End of desktop browsers detection
1168 }
1169
1170 /*
1171 -----------------
1172 Mobile Browsers
1173 -----------------
1174 */
1175
1176 if ($browser_need_continue && $this->result_browser_chrome_original==0 && $this->result_browser_firefox_original==0 && $this->result_mobile == 1)
1177 {
1178 // Mobile browsers with detectable versions
1179
1180 $browser_list[] = array('Safari Mobile', '/(iPhone|iphone|iPad;|iPod).*AppleWebKit\/[.0-9]+\s\(KHTML,\slike\sGecko\)\s.*Version\/[.,0-9]+\sMobile\//', '/Version\/([0-9]+\.[0-9]+)(|\.[0-9]+|\,[0-9]+)\sMobile\//', '1', 'RDDocuments|AlohaBrowser|DuckDuckGo|MiuiBrowser|Snapchat|NAVER(inapp;|1Password|OPT/|Ddg/');
1181 $browser_list[] = array('Safari Mobile', '/(Intel\sMac\sOS\sX).*AppleWebKit\/.*Version\/[.,0-9]+\s(?:|Mobile\/\w+\s)Safari\/[.0-9A-Za-z]+(|\/[0-9]+|\s\(.*\))+$/', '/Version\/([0-9]+\.[0-9]+)(|\.[0-9]+|\,[0-9]+)/', '1', 'CriOS|RDDocuments|AlohaBrowser|DuckDuckGo|MiuiBrowser|Snapchat|NAVER(inapp;|1Password|OPT/|Ddg/');
1182 $browser_list[] = array('Android Browser', '/Android.*Version\/[.0-9]+\s(?:Mobile\s)?Safari\/[.0-9]+(|\-[0-9]+)$/', '/Android.*Version\/([0-9]+\.[0-9]+)/', '1', 'Chrome/');
1183 $browser_list[] = array('Android Browser', 'Dalvik/', '/Dalvik\/([.0-9]+)\s\(Linux;\sU;\sAndroid\s/', '2', 'Chrome/');
1184 $browser_list[] = array('Samsung Browser', 'SamsungBrowser', '/SamsungBrowser\/([0-9]+\.[0-9]+)/', '1', 'CrossApp');
1185 $browser_list[] = array('Firefox Focus', 'Focus/', '/Focus\/([0-9]+\.[0-9]+)/', '1', '');
1186 $browser_list[] = array('Firefox iOS', 'FxiOS', '/FxiOS\/([0-9]*[.]?[0-9]+)/', '1', '');
1187 $browser_list[] = array('Opera Mini', 'Opera Mini|OPiOS', '/(Opera Mini|OPiOS)\/([0-9]+\.[0-9]+)/', '2', '');
1188 $browser_list[] = array('Opera Touch', 'OPT/', '/OPT\/([0-9]+\.[0-9]+)/', '1', '');
1189 $browser_list[] = array('Huawei Browser', 'HuaweiBrowser/', '/HuaweiBrowser\/([0-9]+)/', '1', '');
1190 $browser_list[] = array('DuckDuckGo', 'DuckDuckGo/', '/DuckDuckGo\/([0-9]+)/', '1', '');
1191 $browser_list[] = array('DuckDuckGo', 'Ddg/', '/Ddg\/([0-9]+\.[0-9]+)/', '1', '');
1192 $browser_list[] = array('Mi Browser', 'MiuiBrowser/', '/MiuiBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1193 $browser_list[] = array('Mint Browser', 'Mint Browser/', '/Mint\sBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1194 $browser_list[] = array('Avast Browser', 'AvastSecureBrowser/', '/AvastSecureBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1195 $browser_list[] = array('Google App', '/(iPhone|iphone|iPad;|iPod).*\)\sGSA\/([0-9]+)/', '/(iPhone|iphone|iPad;|iPod).*\)\sGSA\/([0-9]+)/', '2', '');
1196 $browser_list[] = array('Google App', '/\sGSA\//', '/\sGSA\/([0-9]+)/', '1', '');
1197 $browser_list[] = array('Facebook App', 'FBAV/|FBSV/', '/(FBAV|FBSV)\/([0-9]+)\./', '2', 'FBAN/Messenger|FB_IAB/MESSENGER');
1198 $browser_list[] = array('Instagram App', 'Instagram', '/Instagram\s([0-9]+)\./', '1', '');
1199 $browser_list[] = array('Facebook Messenger', 'FBAN/Messenger|FB_IAB/MESSENGER', '/(FBAV|FBSV)\/([0-9]+)\./', '2', '');
1200 $browser_list[] = array('Snapchat', 'Snapchat', '/\sSnapchat\/([0-9]+\.[0-9]+)/', '1', '');
1201 $browser_list[] = array('WhatsApp', 'WhatsApp', '/WhatsApp\/([0-9]+\.[0-9]+)/', '1', '');
1202 $browser_list[] = array('Viber', 'Viber/', '/Viber\/([0-9]+\.[0-9]+)/', '1', '');
1203 $browser_list[] = array('Yandex App', 'YaApp_', '/YaApp_(Android|iOS)\/([0-9]+\.[0-9]+)/', '2', '');
1204 $browser_list[] = array('Yandex App', 'YandexSearch/', '/YandexSearch\/([0-9]+\.[0-9]+)/', '1', '');
1205 $browser_list[] = array('Yandex App', 'YaSearchBrowser/', '/YaSearchBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1206 $browser_list[] = array('Dolfin', 'Dolfin/', '/Dolfin\/([0-9]+\.[0-9]+)/', '1', '');
1207 $browser_list[] = array('Flipboard App', 'Flipboard/', '/Flipboard\/([0-9]+\.[0-9]+)/', '1', '');
1208 $browser_list[] = array('FreeU', 'FreeU|Freeu', '/(FreeU|Freeu)\/([0-9]+\.[0-9]+)/', '2', '');
1209 $browser_list[] = array('Iron', 'Iron Safari|MobileIron', '/Chrome\/([0-9]+)/', '1', '');
1210 $browser_list[] = array('Sogou Mobile Browser', 'SogouMobileBrowser/', '/SogouMobileBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1211 $browser_list[] = array('Meizu Browser', 'MZBrowser/', '/MZBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1212 $browser_list[] = array('360 Mobile Browser', '360 Aphone', '/360\sAphone\sBrowser\s\(([0-9]+\.[0-9]+)/', '1', '');
1213 $browser_list[] = array('Adblock Browser', 'ABB/', '/ABB\/([0-9]+\.[0-9]+)/', '1', '');
1214 $browser_list[] = array('Ecosia Browser', 'Ecosia', '/Chrome\/([0-9]+)/', '1', '');
1215 $browser_list[] = array('HeyTap Browser', 'HeyTapBrowser/', '/HeyTapBrowser\/([0-9]+)/', '1', '');
1216 $browser_list[] = array('Oppo Browser', 'OppoBrowser/', '/OppoBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1217 $browser_list[] = array('Silk', 'Silk/', '/Silk\/([0-9]+\.[0-9]+)/', '1', '');
1218 $browser_list[] = array('Surf Browser', 'SurfBrowser/', '/SurfBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1219 $browser_list[] = array('Phoenix Browser', 'PHX/', '/PHX\/([0-9]+\.[0-9]+)/', '1', '');
1220 $browser_list[] = array('CM Mobile', 'ACHEETAHI', '/Chrome\/([0-9]+)/', '1', '');
1221 $browser_list[] = array('Bing App', ' BingWeb', '/BingWeb\/([0-9]+\.[0-9]+)/', '1', '');
1222 $browser_list[] = array('Firefox Klar', 'Klar/', '/Klar\/([0-9]+\.[0-9]+)/', '1', '');
1223 $browser_list[] = array('Super Fast Browser', 'SFBrowser|tssomas', '/(SFBrowser|tssomas)\/([0-9]+\.[0-9]+)/', '2', '');
1224 $browser_list[] = array('Tenta Browser', 'Tenta/', '/Tenta\/([0-9]+\.[0-9]+)/', '1', '');
1225 $browser_list[] = array('Kiwi Browser', 'Kiwi Chrome/', '/Kiwi\sChrome\/([0-9]+)/', '1', '');
1226 $browser_list[] = array('JioPages', 'JioBrowser/', '/JioBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1227 $browser_list[] = array('JioPages', 'JioPages/', '/JioPages\/([0-9]+\.[0-9]+)/', '1', '');
1228 $browser_list[] = array('Qwant Mobile', 'QwantBrowser', '/QwantBrowser\/([0-9]+)/', '1', '');
1229 $browser_list[] = array('Qwant Mobile', 'QwantMobile', '/QwantMobile\/([0-9]+\.[0-9]+)/', '1', '');
1230 $browser_list[] = array('Cake Browser', '; Cake) ', '/\;\sCake\).*AppleWebKit.*Version\/([0-9]+\.[0-9]+)/', '1', '');
1231 $browser_list[] = array('DU Browser', 'bdbrowser', '/bdbrowser(|_i18n)\/([0-9]+\.[0-9]+)/', '2', '');
1232 $browser_list[] = array('DU Browser', 'baidubrowser', '/baidubrowser\/([0-9]+\.[0-9]+)/', '1', '');
1233 $browser_list[] = array('Baidu Search App', 'baiduboxapp/', '/baiduboxapp\/([0-9]+\.[0-9]+)/', '1', '');
1234 $browser_list[] = array('DU Browser HD', 'BaiduHD/', '/BaiduHD\/([0-9]+\.[0-9]+)/', '1', '');
1235 $browser_list[] = array('Hi Browser', 'HiBrowser/', '/HiBrowser\/?(?:v)?([0-9]+\.[0-9]+)/', '1', '');
1236 $browser_list[] = array('VmWare Browser', 'AirWatch Browser', '/AirWatch\sBrowser\sv([0-9]+\.[0-9]+)/', '1', '');
1237 $browser_list[] = array('Iron Mobile', 'MobileIron/', '/MobileIron\/([0-9]+\.[0-9]+)/', '1', '');
1238 $browser_list[] = array('NineSky', 'Ninesky-android-mobile/', '/Ninesky\-android\-mobile\/([0-9]+\.[0-9]+)/', '1', '');
1239 $browser_list[] = array('Realme Browser', 'RealmeBrowser/', '/RealmeBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1240 $browser_list[] = array('Vivo Browser', 'VivoBrowser/', '/VivoBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1241 $browser_list[] = array('Web Explorer', 'Web Explorer/', '/Web\sExplorer\/([0-9]+\.[0-9]+)/', '1', '');
1242 $browser_list[] = array('NTENT Browser', 'NTENTBrowser/', '/NTENTBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1243 $browser_list[] = array('Nox Browser', 'NoxBrowser/', '/NoxBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1244 $browser_list[] = array('Quark Browser', 'Quark/', '/Quark\/([0-9]+\.[0-9]+)/', '1', '');
1245 $browser_list[] = array('Yaani Browser', 'YaaniBrowser', '/YaaniBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1246 $browser_list[] = array('Tizen Browser', '/Tizen(?: )?(?:\/)?[.0-9]+.*AppleWebKit\/.*(Version|SLP Browser|Tizen Browser|TizenBrowser)\/([0-9]+\.[0-9]+)/', '/Tizen(?: )?(?:\/)?[.0-9]+.*AppleWebKit\/.*(Version|SLP Browser|Tizen Browser|TizenBrowser)\/([0-9]+\.[0-9]+)/', '2', '');
1247 $browser_list[] = array('Internet Explorer Mobile', 'IEMobile', '/IEMobile(?: )?(?:\/)?([0-9]+)/', '1', '');
1248 $browser_list[] = array('Internet Explorer Mobile', 'Trident/', '/Trident\/[.0-9].*Touch;*.rv\:([0-9]+)/', '1', '');
1249 $browser_list[] = array('ZetaKey', 'Zetakey/', '/Zetakey\/([0-9]+\.[0-9]+)/', '1', '');
1250 $browser_list[] = array('Nokia Browser', 'NokiaBrowser/', '/NokiaBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1251 $browser_list[] = array('NetFront', 'NetFront/', '/NetFront\/([0-9]+\.[0-9]+)/', '1', '');
1252 $browser_list[] = array('BlackBerry Browser', '/(BB10;|BlackBerry|PlayBook).*AppleWebKit.*Version\/([0-9]+\.[0-9]+)/', '/(BB10;|BlackBerry|PlayBook).*AppleWebKit.*Version\/([0-9]+\.[0-9]+)/', '2', '');
1253 $browser_list[] = array('ONE Browser', 'OneBrowser/', '/OneBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1254 $browser_list[] = array('Web Explorer', 'webexplorer/', '/webexplorer\/([0-9]+)/', '1', '');
1255 $browser_list[] = array('Start Internet Browser', 'Start/', '/Start\/([0-9]+)/', '1', '');
1256 $browser_list[] = array('EUI Browser', 'EUI Browser', '/EUI\sBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1257 $browser_list[] = array('iCab Mobile', 'iCabMobile', '/iCabMobile(\s|\/)([0-9]+\.[0-9]+)/', '2', '');
1258 $browser_list[] = array('Mercury', 'Mercury/', '/Mercury\/([0-9]+\.[0-9]+)/', '1', '');
1259 $browser_list[] = array('Samsung Browser', '; SAMSUNG S|; SAMSUNG G', '/\;\sSAMSUNG\s(S|G)+.*\sBuild\/.*\)\sAppleWebKit\/.*Version\/([0-9]+\.[0-9]+)\sChrome\/[.0-9]+.*\sSafari\/[.0-9]+$/', '2', 'SamsungBrowser');
1260 $browser_list[] = array('Documents App', 'RDDocuments/', '/RDDocuments\/([0-9]+\.[0-9]+)/', '1', '');
1261 $browser_list[] = array('Opera Coast', 'Coast/', '/Coast\/([0-9]+)/', '1', '');
1262 $browser_list[] = array('Android Browser', '/Android.*Version\/[.0-9]+\s(?:Mobile\s)?Safari(|\/[.0-9]+\sCyanogenMod.*)+$/', '/Android.*Version\/([0-9]+\.[0-9]+)/', '1', 'Chrome/');
1263 $browser_list[] = array('Playstation Browser', '/(PlayStation\s|PLAYSTATION\s)/', '/(PlayStation\s|PLAYSTATION\s)/', '1', '');
1264 $browser_list[] = array('Naver App', 'NAVER(inapp;', '/NAVER\(inapp;\ssearch;\s\d+;\s([0-9]+\.[0-9]+)/', '1', '');
1265 $browser_list[] = array('Line App', ' Line/', '/\sLine\/([0-9]+\.[0-9]+)/', '1', '');
1266 $browser_list[] = array('QQ App', ' QQ/', '/\sQQ\/([0-9]+\.[0-9]+)/', '1', '');
1267 $browser_list[] = array('GNews App', ' GNews ', '/\sGNews\s.*\/([0-9]+\.[0-9]+)/', '1', '');
1268 $browser_list[] = array('1Password App', '1Password', '/\s1Password\/([0-9]+\.[0-9]+)/', '1', '');
1269 $browser_list[] = array('Pinterest App', 'Pinterest', '/Pinterest/', '1', '');
1270 $browser_list[] = array('Twitter App', ' Twitter', '/Twitter/', '1', '');
1271 $browser_list[] = array('Ali App', ' AliApp', '/\sAliApp/', '1', '');
1272 $browser_list[] = array('Alipay', 'AlipayClient', '/AlipayClient\/([0-9]+\.[0-9]+)/', '1', '');
1273 $browser_list[] = array('Samsung CrossApp', 'CrossApp/', '/CrossApp\/([0-9]+\.[0-9]+)/', '1', '');
1274 $browser_list[] = array('Diigo', 'DiigoBrowser', '/DiigoBrowser/', '1', '');
1275 $browser_list[] = array('Stargon', 'Stargon/', '/Stargon\/([0-9]+\.[0-9]+)/', '1', '');
1276 $browser_list[] = array('You Browser', 'YouBrowser/', '/YouBrowser\/([0-9]+\.[0-9]+)/', '1', '');
1277 $browser_list[] = array('Max Browser', 'MaxBrowser/', '/MaxBrowser\/([0-9]+)/', '1', '');
1278 $browser_list[] = array('Soul Browser', 'Soul/', '/Soul\/([0-9]+)/', '1', '');
1279
1280 foreach($browser_list as $browser_list_va)
1281 {
1282 $match = $browser_list_va[1];
1283 $match_exclude = $browser_list_va[4];
1284
1285 // Some OS specified browsers matching optimization
1286
1287 $current_browser_continue = TRUE;
1288 if ($this->get_mode !== 'browser')
1289 {
1290 $current_browser = $browser_list_va[0];
1291
1292 // Some iOS specified browsers matching optimization
1293
1294 if ($current_browser === 'Safari Mobile' || $current_browser === 'Firefox iOS')
1295 {
1296 if ($this->result_os_name !== 'iOS') $current_browser_continue = FALSE;
1297 }
1298
1299 // Some Android specified browsers matching optimization
1300
1301 if ($current_browser === 'Android Browser' || $current_browser === 'Samsung Browser' || $current_browser === 'Huawei Browser')
1302 {
1303 if ($this->result_os_name !== 'Android') $current_browser_continue = FALSE;
1304 }
1305
1306 // WP specified browser matching optimization
1307
1308 if ($current_browser === 'Internet Explorer Mobile' && $this->result_os_name !== 'Windows Phone' && $this->result_os_name !== 'Windows Mobile') $current_browser_continue = FALSE;
1309
1310 // Tizen specified browser matching optimization
1311
1312 if ($current_browser === 'Tizen Browser' && $this->result_os_name !== 'Tizen') $current_browser_continue = FALSE;
1313
1314 // BlackBerry specified browser matching optimization
1315
1316 if ($current_browser === 'BlackBerry Browser' && $this->result_os_name !== 'BlackBerry') $current_browser_continue = FALSE;
1317
1318 // Google App matching optimization
1319
1320 if ($current_browser === 'Google App' && !$this->match_ua(' GSA/')) $current_browser_continue = FALSE;
1321 }
1322
1323 if ($current_browser_continue == TRUE && $this->match_ua($match) && !$this->match_ua($match_exclude))
1324 {
1325 $this->result_browser_version = 0;
1326 $this->result_browser_name = $browser_list_va[0];
1327 $matches = $this->match_ua($browser_list_va[2]);
1328 $matches_n = intval($browser_list_va[3]);
1329
1330 if (is_array($matches))
1331 {
1332 if ($this->result_browser_name === 'Safari Mobile' && strpos($matches[$matches_n], '_') !== FALSE) $matches[$matches_n] = str_replace('_', '.', $matches[$matches_n]);
1333 $this->result_browser_version = (float)$matches[$matches_n];
1334 }
1335 else
1336 {
1337 $this->result_browser_version = 0;
1338 }
1339
1340 if (!empty($this->result_browser_version))
1341 {
1342 $browser_need_continue = FALSE;
1343 break;
1344 }
1345 }
1346 }
1347
1348 $browser_list = NULL;
1349
1350 // End of mobile browsers detection
1351 }
1352
1353 // Other browsers without version specified
1354
1355 if ($browser_need_continue)
1356 {
1357 $other_bsr = array();
1358
1359 $other_bsr[] = array('Maple'=>'Maple');
1360 $other_bsr[] = array('Espial'=>'Espial');
1361
1362 foreach ($other_bsr as $other_bsr_va)
1363 {
1364 $k = key($other_bsr_va);
1365 $v = $other_bsr_va[$k];
1366
1367 if ($this->match_ua($v))
1368 {
1369 $this->result_browser_version = 0;
1370 $this->result_browser_name = $k;
1371 $this->result_browser_title = $k;
1372 break;
1373 }
1374 }
1375 $other_bsr = NULL;
1376 }
1377
1378 // MacOS and iOS Apps
1379
1380 if ($this->result_browser_name === 'unknown' && $this->match_ua('CFNetwork/') && $this->match_ua('Darwin/') && !$this->match_ua('Safari/'))
1381 {
1382 $matches = $this->match_ua('/^(.*)(\/[.0-9]+|\s\(unknown\sversion\))(.*)\sCFNetwork\/[.0-9]+\sDarwin\/[.0-9]+/');
1383 if (!empty($matches[1]))
1384 {
1385 $matches[1] = str_replace('%20', ' ', $matches[1]);
1386 $matches[1] = str_replace('com.apple.Safari.', '', $matches[1]);
1387 $matches[1] = str_replace('com.apple.WebKit.', '', $matches[1]);
1388 $matches[1] = str_replace('com.apple.Notes.', '', $matches[1]);
1389 $matches[1] = str_replace('com.apple.mobilenotes.', '', $matches[1]);
1390 $this->result_browser_name = $matches[1].' App';
1391 if ($this->result_browser_name === 'Browser App') $this->result_browser_name = 'Darwin Browser';
1392 $darwin_app = TRUE;
1393 }
1394 }
1395
1396 /*
1397 -------------------
1398 WebView detection
1399 -------------------
1400 */
1401
1402 if ($this->result_mobile == 1)
1403 {
1404 // Android WebView
1405
1406 if ($this->result_os_name === 'Android')
1407 {
1408 if ($this->match_ua('; wv|;FB|FB_IAB|OKApp|DuckDuckGo')) $this->result_browser_android_webview = 1;
1409 if ($this->result_browser_chrome_original == 0 && $this->result_browser_chromium_version != 0 && $this->match_ua('/like\sGecko\)\sVersion\/[.0-9]+\sChrome\/[.0-9]+\s/')) $this->result_browser_android_webview = 1;
1410 }
1411
1412 // WKWebView
1413
1414 if ($this->result_ios)
1415 {
1416 $webkit_webview = FALSE;
1417
1418 if ($this->match_ua('/\s\((iPhone|iphone|iPad|iPod);.*\)\sAppleWebKit\/[.0-9]+\s\(KHTML\,\slike Gecko\)\s(?!CriOS|FxiOS|OPiOS|EdgiOS)(?!Version).*Mobile\/([0-9A-Z]+)/')) $webkit_webview = TRUE;
1419 if ($this->result_browser_name === 'unknown' && $this->match_ua('MobileSafari/') && $this->match_ua('CFNetwork/')) $webkit_webview = TRUE;
1420
1421 if ($webkit_webview)
1422 {
1423 $this->result_browser_ios_webview = 1;
1424
1425 if ($this->result_browser_name === 'unknown')
1426 {
1427 $this->result_browser_name = 'WKWebView';
1428 $this->result_browser_version = 0;
1429 }
1430 }
1431 }
1432 }
1433
1434 /*
1435 -------------------------
1436 Detect Safari original
1437 -------------------------
1438 */
1439
1440 if ($this->result_browser_name === 'Safari' || $this->result_browser_name === 'Safari Mobile')
1441 {
1442 if ($this->match_ua('/AppleWebKit\/[.0-9]+.*Gecko\)\sVersion\/[.0-9].*Safari\/[.0-9A-Za-z]+$/')) $this->result_browser_safari_original = 1;
1443 }
1444
1445 // Check and correct browser version anomaly
1446
1447 if (intval($this->result_browser_version)>200 && !$this->match_ua('FBAV/|FBSV/|GSA/|Instagram')) $this->result_browser_version = 0;
1448
1449 // Set Browser title
1450
1451 if (!empty($this->result_browser_version)) $this->result_browser_title = $this->result_browser_name.' '.$this->result_browser_version;
1452 else
1453 {
1454 $this->result_browser_title = $this->result_browser_name.' (unknown version)';
1455
1456 $browsers_without_versions = array();
1457 $browsers_without_versions[] = 'Android Browser';
1458 $browsers_without_versions[] = 'WKWebView';
1459 $browsers_without_versions[] = 'Safari SDK';
1460 $browsers_without_versions[] = 'Playstation Browser';
1461 $browsers_without_versions[] = 'OmniWeb';
1462 $browsers_without_versions[] = 'Steam Client';
1463 $browsers_without_versions[] = 'Steam Overlay';
1464 $browsers_without_versions[] = 'Maple';
1465 $browsers_without_versions[] = 'Espial';
1466 $browsers_without_versions[] = 'Diigo Browser';
1467 $browsers_without_versions[] = 'IceWeasel';
1468 $browsers_without_versions[] = 'Iceweasel';
1469 $browsers_without_versions[] = 'Facebook App';
1470 $browsers_without_versions[] = 'Twitter App';
1471 $browsers_without_versions[] = 'Bing App';
1472 $browsers_without_versions[] = 'Pinterest App';
1473 $browsers_without_versions[] = 'Ali App';
1474 $browsers_without_versions[] = 'Alipay App';
1475 $browsers_without_versions[] = 'Lunascape';
1476
1477 if (in_array($this->result_browser_name, $browsers_without_versions) || isset($darwin_app))
1478 {
1479 $this->result_browser_title = $this->result_browser_name;
1480 }
1481
1482 $browsers_without_versions = NULL;
1483 }
1484
1485 if (strpos($this->result_browser_name, 'unknown') !== FALSE) $this->result_browser_title = 'unknown';
1486 if ($this->result_browser_version == NULL) $this->result_browser_version = 0;
1487
1488 // EdgeHTML browser should not be detected as a Chromium engine
1489 if ($this->result_browser_name === 'Edge' && $this->result_browser_version >= 12 && $this->result_browser_version <= 18) $this->result_browser_chromium_version = 0;
1490
1491 if ($this->get_mode === 'browser') return NULL;
1492
1493 /*
1494 ---------------------
1495 Detect device types
1496 ---------------------
1497 */
1498
1499 // Desktop
1500
1501 if ($this->result_os_family !== 'unknown' && $this->result_os_type !== 'mixed') $this->result_device_type = 'desktop';
1502
1503 // Mobile
1504
1505 if ($this->result_mobile == 1) $this->result_device_type = 'mobile';
1506
1507 // TV
1508
1509 if ($this->match_ua('TV|HDMI|CrKey| Escape |Kylo/|SmartLabs|SC/IHD|Viera|BRAVIA|NetCast|Roku/DVP| Roku |Maple|DuneHD|CE-HTML|EIS iPanel|Sunniwell; Resolution|Freebox|Netbox|Netgem|AFTT|AFTM|AFTB|DLNADOC| iconBIT |olleh tv|stbapp |; MIBOX|ABOX-I|; H96 |; X96|HX S905|; M8S |MINIM8S|MXIII-|; NEO-X|; NEO-U| Nexus Player |TPM171E|; V88 |MXQPRO|NEXBOX-|; Leelbox|ZIDOO|; A95X| Beelink |; T95Z|; TX3 ') && !$this->match_ua('BTV-')) $this->result_device_type = 'tv';
1510
1511 // Console
1512
1513 if ($this->matchi_ua('playstation') || $this->match_ua('Xbox|GAMEPAD|Nintendo|OUYA|; SHIELD Build')) $this->result_device_type = 'console';
1514
1515 // MediaPlayer
1516
1517 if ($this->match_ua('iPod|AlexaMediaPlayer|AppleCoreMedia')) $this->result_device_type = 'mediaplayer';
1518
1519 // Car
1520
1521 if ($this->match_ua('CarBrowser|Tesla/')) $this->result_device_type = 'car';
1522
1523 // Watch
1524
1525 if ($this->matchi_ua('watch') && !$this->match_ua('AirWatch')) $this->result_device_type = 'watch';
1526
1527 if ($this->get_mode === 'device') return NULL;
1528
1529 /*
1530 ---------------------------------------------
1531 Detect 64bits mode (browser + OS specified)
1532 ---------------------------------------------
1533 */
1534
1535 if ($this->result_os_name === 'MacOS' && $this->macos_version_minor >= 6)
1536 {
1537 if ($this->result_browser_name === 'Safari' || $this->result_browser_name === 'Safari SDK') $this->result_64bits_mode = 1;
1538 }
1539
1540 /*
1541 ---------------------------------------------------------
1542 MacOS Big Sur + Firefox version > 86 detection feature
1543 ---------------------------------------------------------
1544 */
1545
1546 if ($this->result_os_name === 'MacOS' && $this->macos_version_minor == 15 && $this->result_browser_name === 'Firefox' && $this->result_browser_version > 86)
1547 {
1548 $this->result_os_version = 'Big Sur';
1549 $this->result_os_title = 'MacOS '.$this->result_os_version;
1550 }
1551
1552 return NULL;
1553 }
1554
1555 /**
1556 * The method returns all possible environment data from User-Agent
1557 *
1558 * @param string $ua The User-Agent string
1559 * @param string $result_format If specified, method returns result as JSON
1560 * @return mixed Returns User-Agent parsing result as array or JSON string (optional)
1561 */
1562
1563 public function getAll($ua, $result_format = '')
1564 {
1565 $this->useragent = trim($ua);
1566 $this->get_mode = 'all';
1567 $this->resetProperties();
1568 $this->getResult();
1569 $result = array('os_type'=>$this->result_os_type,
1570 'os_family'=>$this->result_os_family,
1571 'os_name'=>$this->result_os_name,
1572 'os_version'=>$this->result_os_version,
1573 'os_title'=>$this->result_os_title,
1574 'device_type'=>$this->result_device_type,
1575 'browser_name'=>$this->result_browser_name,
1576 'browser_version'=>$this->result_browser_version,
1577 'browser_title'=>$this->result_browser_title,
1578 'browser_chrome_original'=>$this->result_browser_chrome_original,
1579 'browser_firefox_original'=>$this->result_browser_firefox_original,
1580 'browser_safari_original'=>$this->result_browser_safari_original,
1581 'browser_chromium_version'=>$this->result_browser_chromium_version,
1582 'browser_gecko_version'=>$this->result_browser_gecko_version,
1583 'browser_webkit_version'=>$this->result_browser_webkit_version,
1584 'browser_android_webview'=>$this->result_browser_android_webview,
1585 'browser_ios_webview'=>$this->result_browser_ios_webview,
1586 'browser_desktop_mode'=>$this->result_browser_desktop_mode,
1587 '64bits_mode'=>$this->result_64bits_mode);
1588
1589 if (strtolower($result_format) === 'json') $result = json_encode($result);
1590 $this->touch_support_mode = FALSE;
1591 return $result;
1592 }
1593
1594 /**
1595 * The method returns OS data from User-Agent
1596 *
1597 * @param string $ua The User-Agent string
1598 * @param string $result_format If specified, method returns result as JSON
1599 * @return mixed Returns User-Agent parsing result as array or JSON string (optional)
1600 */
1601
1602 public function getOS($ua, $result_format = '')
1603 {
1604 $this->useragent = trim($ua);
1605 $this->get_mode = 'os';
1606 $this->resetProperties();
1607 $this->getResult();
1608 $result = array('os_type'=>$this->result_os_type,
1609 'os_family'=>$this->result_os_family,
1610 'os_name'=>$this->result_os_name,
1611 'os_version'=>$this->result_os_version,
1612 'os_title'=>$this->result_os_title,
1613 '64bits_mode'=>$this->result_64bits_mode);
1614
1615 if (strtolower($result_format) === 'json') $result = json_encode($result);
1616 $this->touch_support_mode = FALSE;
1617 return $result;
1618 }
1619
1620 /**
1621 * The method returns Browser data from User-Agent
1622 *
1623 * @param string $ua The User-Agent string
1624 * @param string $result_format If specified, method returns result as JSON
1625 * @return mixed Returns User-Agent parsing result as array or JSON string (optional)
1626 */
1627
1628 public function getBrowser($ua, $result_format = '')
1629 {
1630 $this->useragent = trim($ua);
1631 $this->get_mode = 'browser';
1632 $this->resetProperties();
1633 $this->getResult();
1634 $result = array('browser_name'=>$this->result_browser_name,
1635 'browser_version'=>$this->result_browser_version,
1636 'browser_title'=>$this->result_browser_title,
1637 'browser_chrome_original'=>$this->result_browser_chrome_original,
1638 'browser_firefox_original'=>$this->result_browser_firefox_original,
1639 'browser_safari_original'=>$this->result_browser_safari_original,
1640 'browser_chromium_version'=>$this->result_browser_chromium_version,
1641 'browser_gecko_version'=>$this->result_browser_gecko_version,
1642 'browser_webkit_version'=>$this->result_browser_webkit_version,
1643 'browser_android_webview'=>$this->result_browser_android_webview,
1644 'browser_ios_webview'=>$this->result_browser_ios_webview,
1645 'browser_desktop_mode'=>$this->result_browser_desktop_mode);
1646
1647 if (strtolower($result_format) === 'json') $result = json_encode($result);
1648 $this->touch_support_mode = FALSE;
1649 return $result;
1650 }
1651
1652 /**
1653 * The method returns Device Type data from User-Agent
1654 *
1655 * @param string $ua The User-Agent string
1656 * @param string $result_format If specified, method returns result as JSON
1657 * @return mixed Returns User-Agent parsing result as array or JSON string (optional)
1658 */
1659
1660 public function getDevice($ua, $result_format = '')
1661 {
1662 $this->useragent = trim($ua);
1663 $this->get_mode = 'device';
1664 $this->resetProperties();
1665 $this->getResult();
1666 $result = array('device_type'=>$this->result_device_type);
1667
1668 if (strtolower($result_format) === 'json') $result = json_encode($result);
1669 $this->touch_support_mode = FALSE;
1670 return $result;
1671 }
1672
1673 /**
1674 * This method is needed to detect mobile browsers in Desktop Mode (Android and iOS)
1675 * The method should call if browser supports Touch events (client-side JS detection is necessary)
1676 *
1677 * @return null
1678 */
1679
1680 public function setTouchSupport()
1681 {
1682 $this->touch_support_mode = TRUE;
1683 return NULL;
1684 }
1685 }
1686
1687 ?>