PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/UserAgentParser/UserAgentParser.php

https://github.com/CodeYellowBV/piwik
PHP | 725 lines | 511 code | 87 blank | 127 comment | 55 complexity | 974d5ff712e0331175d543d797e821fd MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Copyright 2009, 2010 Matthieu Aubry & Piwik team
  4. * All rights reserved.
  5. *
  6. * @link https://github.com/piwik/piwik/tree/master/libs/UserAgentParser
  7. * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are
  11. * met:
  12. *
  13. * * Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * * Neither the name of Matthieu Aubry nor the names of its contributors
  21. * may be used to endorse or promote products derived from this
  22. * software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. */
  36. /**
  37. * Example usage
  38. *
  39. * Browser info:
  40. * var_dump(UserAgentParser::getBrowser($_SERVER['HTTP_USER_AGENT']));
  41. *
  42. * Outputs:
  43. * array
  44. * 'id' => 'FF'
  45. * 'name' => 'Firefox'
  46. * 'short_name' => 'Firefox'
  47. * 'version' => '3.0'
  48. * 'major_number' => '3'
  49. * 'minor_number' => '0'
  50. *
  51. * Operating System info:
  52. * var_dump(UserAgentParser::getOperatingSystem($_SERVER['HTTP_USER_AGENT']));
  53. *
  54. * Outputs:
  55. * array
  56. * 'id' => 'WXP'
  57. * 'name' => 'Windows XP'
  58. * 'short_name' => 'Win XP'
  59. *
  60. */
  61. class UserAgentParser
  62. {
  63. // browser regex => browser ID
  64. // if there are aliases, the common name should be last
  65. static protected $browsers = array(
  66. 'abrowse' => 'AB',
  67. 'amaya' => 'AM',
  68. 'amigavoyager' => 'AV',
  69. 'amiga-aweb' => 'AW',
  70. 'arora' => 'AR',
  71. 'beonex' => 'BE',
  72. // BlackBerry smartphones and tablets
  73. 'blackberry' => 'BB', // BlackBerry 6 and PlayBook adopted webkit
  74. 'bb10' => 'B2', // BlackBerry 10
  75. 'playbook' => 'BP',
  76. 'browsex' => 'BX',
  77. // Camino (and earlier incarnation)
  78. 'chimera' => 'CA',
  79. 'camino' => 'CA',
  80. 'cheshire' => 'CS',
  81. // Chrome, Chromium, and ChromePlus
  82. 'crmo' => 'CH',
  83. 'chrome' => 'CH',
  84. // Chrome Frame
  85. 'chromeframe' => 'CF',
  86. 'cometbird' => 'CO',
  87. 'dillo' => 'DI',
  88. 'elinks' => 'EL',
  89. 'epiphany' => 'EP',
  90. 'fennec' => 'FE',
  91. // Dolfin (or Dolphin)
  92. 'dolfin' => 'DF',
  93. // Firefox (in its many incarnations and rebranded versions)
  94. 'phoenix' => 'PX',
  95. 'mozilla firebird' => 'FB',
  96. 'firebird' => 'FB',
  97. 'bonecho' => 'FF',
  98. 'minefield' => 'FF',
  99. 'namoroka' => 'FF',
  100. 'shiretoko' => 'FF',
  101. 'granparadiso' => 'FF',
  102. 'iceweasel' => 'FF',
  103. 'icecat' => 'FF',
  104. 'firefox' => 'FF',
  105. 'thunderbird' => 'TB',
  106. 'flock' => 'FL',
  107. 'fluid' => 'FD',
  108. 'galeon' => 'GA',
  109. 'google earth' => 'GE',
  110. 'hana' => 'HA',
  111. 'hotjava' => 'HJ',
  112. 'ibrowse' => 'IB',
  113. 'icab' => 'IC',
  114. // IE (including shells: Acoo, AOL, Avant, Crazy Browser, Green Browser, KKMAN, Maxathon)
  115. 'msie' => 'IE',
  116. 'trident' => 'IE',
  117. 'microsoft internet explorer' => 'IE',
  118. 'internet explorer' => 'IE',
  119. 'iron' => 'IR',
  120. 'kapiko' => 'KP',
  121. 'kazehakase' => 'KZ',
  122. 'k-meleon' => 'KM',
  123. 'konqueror' => 'KO',
  124. 'links' => 'LI',
  125. 'lynx' => 'LX',
  126. 'midori' => 'MI',
  127. // SeaMonkey (formerly Mozilla Suite) (and rebranded versions)
  128. 'mozilla' => 'MO',
  129. 'gnuzilla' => 'SM',
  130. 'iceape' => 'SM',
  131. 'seamonkey' => 'SM',
  132. // NCSA Mosaic (and incarnations)
  133. 'mosaic' => 'MC',
  134. 'ncsa mosaic' => 'MC',
  135. // Netscape Navigator
  136. 'navigator' => 'NS',
  137. 'netscape6' => 'NS',
  138. 'netscape' => 'NS',
  139. 'nx' => 'NF',
  140. 'netfront' => 'NF',
  141. 'omniweb' => 'OW',
  142. // Opera
  143. 'nitro) opera' => 'OP',
  144. 'opera' => 'OP',
  145. 'rekonq' => 'RK',
  146. // Safari
  147. 'safari' => 'SF',
  148. 'applewebkit' => 'SF',
  149. 'titanium' => 'TI',
  150. 'webos' => 'WO',
  151. 'webpro' => 'WP',
  152. );
  153. // browser family (by layout engine)
  154. static protected $browserType = array(
  155. 'ie' => array('IE'),
  156. 'gecko' => array('NS', 'PX', 'FF', 'FB', 'CA', 'GA', 'KM', 'MO', 'SM', 'CO', 'FE', 'KP', 'KZ', 'TB'),
  157. 'khtml' => array('KO'),
  158. 'webkit' => array('SF', 'CH', 'OW', 'AR', 'EP', 'FL', 'WO', 'AB', 'IR', 'CS', 'FD', 'HA', 'MI', 'GE', 'DF', 'BB', 'BP', 'TI', 'CF', 'RK', 'B2', 'NF'),
  159. 'opera' => array('OP'),
  160. );
  161. // WebKit version numbers to Apple Safari version numbers (if Version/X.Y.Z not present)
  162. static protected $safariVersions = array(
  163. '536.25' => array('6', '0'),
  164. '534.48' => array('5', '1'),
  165. '533.16' => array('5', '0'),
  166. '533.4' => array('4', '1'),
  167. '526.11.2' => array('4', '0'),
  168. '525.26' => array('3', '2'),
  169. '525.13' => array('3', '1'),
  170. '522.11' => array('3', '0'),
  171. '412' => array('2', '0'),
  172. '312' => array('1', '3'),
  173. '125' => array('1', '2'),
  174. '100' => array('1', '1'),
  175. '85' => array('1', '0'),
  176. '73' => array('0', '9'),
  177. '48' => array('0', '8'),
  178. );
  179. // OmniWeb build numbers to OmniWeb version numbers (if Version/X.Y.Z not present)
  180. static protected $omniWebVersions = array(
  181. '622.15' => array('5', '11'),
  182. '622.10' => array('5', '10'),
  183. '622.8' => array('5', '9'),
  184. '622.3' => array('5', '8'),
  185. '621' => array('5', '7'),
  186. '613' => array('5', '6'),
  187. '607' => array('5', '5'),
  188. '563.34' => array('5', '1'),
  189. '558.36' => array('5', '0'),
  190. '496' => array('4', '5'),
  191. );
  192. // OS regex => OS ID
  193. static protected $operatingSystems = array(
  194. 'Android' => 'AND',
  195. 'Maemo' => 'MAE',
  196. 'CrOS ' => 'LIN',
  197. 'Linux' => 'LIN',
  198. 'Xbox' => 'XBX',
  199. // workaround for vendors who changed the WinPhone 7 user agent
  200. 'WP7' => 'WPH',
  201. 'CYGWIN_NT-6.2' => 'WI8',
  202. 'Windows NT 6.2' => 'WI8',
  203. 'Windows NT 6.3' => 'WI8',
  204. 'Windows 8' => 'WI8',
  205. 'CYGWIN_NT-6.1' => 'WI7',
  206. 'Windows NT 6.1' => 'WI7',
  207. 'Windows 7' => 'WI7',
  208. 'CYGWIN_NT-6.0' => 'WVI',
  209. 'Windows NT 6.0' => 'WVI',
  210. 'Windows Vista' => 'WVI',
  211. 'CYGWIN_NT-5.2' => 'WS3',
  212. 'Windows NT 5.2' => 'WS3',
  213. 'Windows Server 2003 / XP x64' => 'WS3',
  214. 'CYGWIN_NT-5.1' => 'WXP',
  215. 'Windows NT 5.1' => 'WXP',
  216. 'Windows XP' => 'WXP',
  217. 'CYGWIN_NT-5.0' => 'W2K',
  218. 'Windows NT 5.0' => 'W2K',
  219. 'Windows 2000' => 'W2K',
  220. 'CYGWIN_NT-4.0' => 'WNT',
  221. 'Windows NT 4.0' => 'WNT',
  222. 'WinNT' => 'WNT',
  223. 'Windows NT' => 'WNT',
  224. 'CYGWIN_ME-4.90' => 'WME',
  225. 'Win 9x 4.90' => 'WME',
  226. 'Windows ME' => 'WME',
  227. 'CYGWIN_98-4.10' => 'W98',
  228. 'Win98' => 'W98',
  229. 'Windows 98' => 'W98',
  230. 'CYGWIN_95-4.0' => 'W95',
  231. 'Win32' => 'W95',
  232. 'Win95' => 'W95',
  233. 'Windows 95' => 'W95',
  234. // Windows Phone OS 7 and above
  235. 'Windows Phone OS' => 'WPH',
  236. // Windows Mobile 6.x and some later versions of Windows Mobile 5
  237. 'IEMobile' => 'WMO', // fallback
  238. 'Windows Mobile' => 'WMO',
  239. // Windows CE, Pocket PC, and Windows Mobile 5 are indistinguishable without vendor/device specific detection
  240. 'Windows CE' => 'WCE',
  241. 'iPod' => 'IPD',
  242. 'iPad' => 'IPA',
  243. 'iPhone' => 'IPH',
  244. // 'iOS' => 'IOS',
  245. 'Darwin' => 'MAC',
  246. 'Macintosh' => 'MAC',
  247. 'Power Macintosh' => 'MAC',
  248. 'Mac_PowerPC' => 'MAC',
  249. 'Mac PPC' => 'MAC',
  250. 'PPC' => 'MAC',
  251. 'Mac PowerPC' => 'MAC',
  252. 'Mac OS' => 'MAC',
  253. 'webOS' => 'WOS',
  254. 'Palm webOS' => 'WOS',
  255. 'PalmOS' => 'POS',
  256. 'Palm OS' => 'POS',
  257. 'BB10' => 'BBX',
  258. 'BlackBerry' => 'BLB',
  259. 'RIM Tablet OS' => 'QNX',
  260. 'QNX' => 'QNX',
  261. 'SymbOS' => 'SYM',
  262. 'Symbian OS' => 'SYM',
  263. 'SymbianOS' => 'SYM',
  264. 'bada' => 'SBA',
  265. 'SunOS' => 'SOS',
  266. 'AIX' => 'AIX',
  267. 'HP-UX' => 'HPX',
  268. 'OpenVMS' => 'VMS',
  269. 'FreeBSD' => 'BSD',
  270. 'NetBSD' => 'NBS',
  271. 'OpenBSD' => 'OBS',
  272. 'DragonFly' => 'DFB',
  273. 'Syllable' => 'SYL',
  274. 'Nintendo WiiU' => 'WIU',
  275. 'Nintendo Wii' => 'WII',
  276. 'Nitro' => 'NDS',
  277. 'Nintendo DSi' => 'DSI',
  278. 'Nintendo DS' => 'NDS',
  279. 'Nintendo 3DS' => '3DS',
  280. 'PlayStation Vita' => 'PSV',
  281. 'PlayStation Portable' => 'PSP',
  282. 'PlayStation 3' => 'PS3',
  283. 'IRIX' => 'IRI',
  284. 'OSF1' => 'T64',
  285. 'OS/2' => 'OS2',
  286. 'BEOS' => 'BEO',
  287. 'Amiga' => 'AMI',
  288. 'AmigaOS' => 'AMI',
  289. );
  290. // os family
  291. // NOTE: The keys in this array are used by plugins/UserSettings/functions.php . Any changes
  292. // made here should also be made in that file.
  293. static protected $osType = array(
  294. 'Windows' => array('WI8', 'WI7', 'WVI', 'WS3', 'WXP', 'W2K', 'WNT', 'WME', 'W98', 'W95'),
  295. 'Linux' => array('LIN'),
  296. 'Mac' => array('MAC'),
  297. 'iOS' => array('IPD', 'IPA', 'IPH'),
  298. 'Android' => array('AND'),
  299. 'Windows Mobile' => array('WPH', 'WMO', 'WCE'),
  300. 'Gaming Console' => array('WII', 'WIU', 'PS3', 'XBX'),
  301. 'Mobile Gaming Console' => array('PSP', 'PSV', 'NDS', 'DSI', '3DS'),
  302. 'Unix' => array('SOS', 'AIX', 'HP-UX', 'BSD', 'NBS', 'OBS', 'DFB', 'SYL', 'IRI', 'T64'),
  303. 'Other Mobile' => array('MAE', 'WOS', 'POS', 'BLB', 'QNX', 'SYM', 'SBA'),
  304. 'Other' => array('VMS', 'OS2', 'BEOS', 'AMI')
  305. );
  306. static protected $browserIdToName;
  307. static protected $browserIdToShortName;
  308. static protected $operatingSystemsIdToName;
  309. static protected $operatingSystemsIdToShortName;
  310. static private $init = false;
  311. /**
  312. * Returns an array of the OS for the submitted user agent
  313. * 'id' => '',
  314. * 'name' => '',
  315. * 'short_name' => '',
  316. *
  317. * @param string $userAgent
  318. * @return string false if OS couldn't be identified, or 3 letters ID (eg. WXP)
  319. * @see UserAgentParser/OperatingSystems.php for the list of OS (also available in self::$operatingSystems)
  320. */
  321. static public function getOperatingSystem($userAgent)
  322. {
  323. $userAgent = self::cleanupUserAgent($userAgent);
  324. self::init();
  325. $info = array(
  326. 'id' => '',
  327. 'name' => '',
  328. 'short_name' => '',
  329. );
  330. foreach (self::$operatingSystems as $key => $value) {
  331. if (stristr($userAgent, $key) !== false) {
  332. $info['id'] = $value;
  333. break;
  334. }
  335. }
  336. if (empty($info['id'])) {
  337. return false;
  338. }
  339. $info['name'] = self::getOperatingSystemNameFromId($info['id']);
  340. $info['short_name'] = self::getOperatingSystemShortNameFromId($info['id']);
  341. return $info;
  342. }
  343. static protected function cleanupUserAgent($userAgent)
  344. {
  345. // in case value is URL encoded
  346. return urldecode($userAgent);
  347. }
  348. /**
  349. * Returns the browser information array, given a user agent string.
  350. *
  351. * @param string $userAgent
  352. * @return array false if the browser is "unknown", or
  353. * array( 'id' => '', // 2 letters ID, eg. FF
  354. * 'name' => '', // 2 letters ID, eg. FF
  355. * 'short_name' => '', // 2 letters ID, eg. FF
  356. * 'major_number' => '', // 2 in firefox 2.0.12
  357. * 'minor_number' => '', // 0 in firefox 2.0.12
  358. * 'version' => '', // major_number.minor_number
  359. * );
  360. * @see self::$browsers for the list of OS
  361. */
  362. static public function getBrowser($userAgent)
  363. {
  364. $userAgent = self::cleanupUserAgent($userAgent);
  365. self::init();
  366. $info = array(
  367. 'id' => '',
  368. 'name' => '',
  369. 'short_name' => '',
  370. 'major_number' => '',
  371. 'minor_number' => '',
  372. 'version' => '',
  373. );
  374. $browsers = self::$browsers;
  375. // derivative browsers often clone the base browser's useragent
  376. unset($browsers['firefox']);
  377. unset($browsers['mozilla']);
  378. unset($browsers['safari']);
  379. unset($browsers['applewebkit']);
  380. $browsersPattern = str_replace(')', '\)', implode('|', array_keys($browsers)));
  381. $results = array();
  382. // Misbehaving IE add-ons
  383. $userAgent = preg_replace('/[; ]Mozilla\/[0-9.]+ \([^)]+\)/', '', $userAgent);
  384. // Clean-up BlackBerry device UAs
  385. $userAgent = preg_replace('~^BlackBerry\d+/~', 'BlackBerry/', $userAgent);
  386. if (preg_match_all("/($browsersPattern)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)
  387. || (strpos($userAgent, 'Shiira') === false && preg_match_all("/(firefox|thunderbird|safari)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results))
  388. || preg_match_all("/(applewebkit)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)
  389. || preg_match_all("/^(mozilla)\/([0-9]+)([\.0-9a-z-]+)?(?: \[[a-z]{2}\])? (?:\([^)]*\))$/i", $userAgent, $results)
  390. || preg_match_all("/^(mozilla)\/[0-9]+(?:[\.0-9a-z-]+)?\s\(.* rv:([0-9]+)([.0-9a-z]+)\) gecko(\/[0-9]{8}|$)(?:.*)/i", $userAgent, $results)
  391. || (strpos($userAgent, 'Nintendo 3DS') !== false && preg_match_all("/^(mozilla).*version\/([0-9]+)([.0-9a-z]+)?/i", $userAgent, $results))
  392. ) {
  393. // browser code (usually the first match)
  394. $count = 0;
  395. $info['id'] = self::$browsers[strtolower($results[1][0])];
  396. // sometimes there's a better match at the end
  397. if (strpos($userAgent, 'chromeframe') !== false) {
  398. $count = count($results[0]) - 1;
  399. $info['id'] = 'CF';
  400. } elseif (($info['id'] == 'IE' || $info['id'] == 'LX') && (count($results[0]) > 1)) {
  401. $count = count($results[0]) - 1;
  402. $info['id'] = self::$browsers[strtolower($results[1][$count])];
  403. }
  404. // Netscape fix
  405. if ($info['id'] == 'MO' && $count == 0) {
  406. if (stripos($userAgent, 'PlayStation') !== false) {
  407. return false;
  408. }
  409. if (strpos($userAgent, 'Nintendo 3DS') !== false) {
  410. $info['id'] = 'NF';
  411. } elseif (count($results) == 4) {
  412. $info['id'] = 'NS';
  413. }
  414. } // BlackBerry devices
  415. elseif (strpos($userAgent, 'BlackBerry') !== false) {
  416. $info['id'] = 'BB';
  417. } elseif (strpos($userAgent, 'RIM Tablet OS') !== false) {
  418. $info['id'] = 'BP';
  419. } elseif (strpos($userAgent, 'BB10') !== false) {
  420. $info['id'] = 'B2';
  421. } elseif (strpos($userAgent, 'Playstation Vita') !== false) {
  422. $info['id'] = 'NF';
  423. if (preg_match_all("/(silk)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $newResults)) {
  424. $results = $newResults;
  425. $count = count($results[0]) - 1;
  426. }
  427. }
  428. // Version/X.Y.Z override
  429. if (preg_match_all("/(version)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $newResults)) {
  430. $results = $newResults;
  431. $count = count($results[0]) - 1;
  432. }
  433. // major version number (1 in mozilla 1.7)
  434. $info['major_number'] = $results[2][$count];
  435. // is an minor version number ? If not, 0
  436. $match = array();
  437. preg_match('/([.\0-9]+)?([\.a-z0-9]+)?/i', $results[3][$count], $match);
  438. if (isset($match[1])) {
  439. // find minor version number (7 in mozilla 1.7, 9 in firefox 0.9.3)
  440. $dot = strpos(substr($match[1], 1), '.');
  441. if ($dot !== false) {
  442. $info['minor_number'] = substr($match[1], 1, $dot);
  443. } else {
  444. $info['minor_number'] = substr($match[1], 1);
  445. }
  446. } else {
  447. $info['minor_number'] = '0';
  448. }
  449. $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
  450. // IE compatibility mode
  451. if ($info['id'] == 'IE'
  452. && (strncmp($userAgent, 'Mozilla/4.0', 11) == 0 || strncmp($userAgent, 'Mozilla/5.0', 11) == 0)
  453. && preg_match('~ Trident/([0-9]+)\.[0-9]+~', $userAgent, $tridentVersion)
  454. ) {
  455. $info['major_number'] = $tridentVersion[1] + 4;
  456. $info['minor_number'] = '0';
  457. $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
  458. }
  459. // Safari fix
  460. if ($info['id'] == 'SF') {
  461. foreach (self::$safariVersions as $buildVersion => $productVersion) {
  462. if (version_compare($info['version'], $buildVersion) >= 0) {
  463. $info['major_number'] = $productVersion[0];
  464. $info['minor_number'] = $productVersion[1];
  465. $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
  466. break;
  467. }
  468. }
  469. }
  470. // OmniWeb fix
  471. if ($info['id'] == 'OW') {
  472. foreach (self::$omniWebVersions as $buildVersion => $productVersion) {
  473. if (version_compare($info['version'], $buildVersion) >= 0) {
  474. $info['major_number'] = $productVersion[0];
  475. $info['minor_number'] = $productVersion[1];
  476. $info['version'] = $info['major_number'] . '.' . $info['minor_number'];
  477. break;
  478. }
  479. }
  480. }
  481. // SeaMonkey fix
  482. if ($info['id'] == 'MO' && $info['version'] == '1.9') {
  483. $info['id'] = 'SM';
  484. }
  485. $info['name'] = self::getBrowserNameFromId($info['id']);
  486. $info['short_name'] = self::getBrowserShortNameFromId($info['id']);
  487. return $info;
  488. }
  489. return false;
  490. }
  491. static protected function init()
  492. {
  493. if (self::$init) {
  494. return;
  495. }
  496. self::$init = true;
  497. // init browser names and short names
  498. self::$browserIdToName = array_map('ucwords', array_flip(self::$browsers));
  499. self::$browserIdToName['AB'] = 'ABrowse';
  500. self::$browserIdToName['AV'] = 'AmigaVoyager';
  501. self::$browserIdToName['AW'] = 'Amiga AWeb';
  502. self::$browserIdToName['BB'] = 'BlackBerry';
  503. self::$browserIdToName['BP'] = 'PlayBook';
  504. self::$browserIdToName['B2'] = 'BlackBerry';
  505. self::$browserIdToName['BX'] = 'BrowseX';
  506. self::$browserIdToName['CF'] = 'Chrome Frame';
  507. self::$browserIdToName['CO'] = 'CometBird';
  508. self::$browserIdToName['EL'] = 'ELinks';
  509. self::$browserIdToName['FF'] = 'Firefox';
  510. self::$browserIdToName['HJ'] = 'HotJava';
  511. self::$browserIdToName['IB'] = 'IBrowse';
  512. self::$browserIdToName['IC'] = 'iCab';
  513. self::$browserIdToName['KM'] = 'K-Meleon';
  514. self::$browserIdToName['MC'] = 'NCSA Mosaic';
  515. self::$browserIdToName['NF'] = 'NetFront';
  516. self::$browserIdToName['OW'] = 'OmniWeb';
  517. self::$browserIdToName['SF'] = 'Safari';
  518. self::$browserIdToName['SM'] = 'SeaMonkey';
  519. self::$browserIdToName['WO'] = 'Palm webOS';
  520. self::$browserIdToName['WP'] = 'WebPro';
  521. self::$browserIdToShortName = self::$browserIdToName;
  522. self::$browserIdToShortName['AW'] = 'AWeb';
  523. self::$browserIdToShortName['FB'] = 'Firebird';
  524. self::$browserIdToShortName['IE'] = 'IE';
  525. self::$browserIdToShortName['MC'] = 'Mosaic';
  526. self::$browserIdToShortName['BP'] = 'PlayBook';
  527. self::$browserIdToShortName['WO'] = 'webOS';
  528. // init OS names and short names
  529. $operatingSystemsIdToName = array(
  530. 'IPD' => 'iPod',
  531. 'IPA' => 'iPad',
  532. 'WME' => 'Windows Me',
  533. 'BEO' => 'BeOS',
  534. 'T64' => 'Tru64',
  535. 'NDS' => 'Nintendo DS',
  536. 'WIU' => 'Nintendo Wii U',
  537. '3DS' => 'Nintendo 3DS',
  538. // These are for BC purposes only
  539. 'W75' => 'WinPhone 7.5',
  540. 'WP7' => 'WinPhone 7',
  541. 'W65' => 'WinMo 6.5',
  542. 'W61' => 'WinMo 6.1',
  543. );
  544. self::$operatingSystemsIdToName = array_merge(array_flip(self::$operatingSystems), $operatingSystemsIdToName);
  545. $operatingSystemsIdToShortName = array(
  546. 'PS3' => 'PS3',
  547. 'PSP' => 'PSP',
  548. 'WII' => 'Wii',
  549. 'WIU' => 'Wii U',
  550. 'NDS' => 'DS',
  551. 'DSI' => 'DSi',
  552. '3DS' => '3DS',
  553. 'PSV' => 'PS Vita',
  554. 'WI8' => 'Win 8',
  555. 'WI7' => 'Win 7',
  556. 'WVI' => 'Win Vista',
  557. 'WS3' => 'Win S2003',
  558. 'WXP' => 'Win XP',
  559. 'W98' => 'Win 98',
  560. 'W2K' => 'Win 2000',
  561. 'WNT' => 'Win NT',
  562. 'WME' => 'Win Me',
  563. 'W95' => 'Win 95',
  564. 'WPH' => 'WinPhone',
  565. 'WMO' => 'WinMo',
  566. 'WCE' => 'Win CE',
  567. 'WOS' => 'webOS',
  568. 'UNK' => 'Unknown',
  569. );
  570. self::$operatingSystemsIdToShortName = array_merge(self::$operatingSystemsIdToName, $operatingSystemsIdToShortName);
  571. }
  572. static public function getBrowserNameFromId($browserId)
  573. {
  574. self::init();
  575. if (isset(self::$browserIdToName[$browserId])) {
  576. return self::$browserIdToName[$browserId];
  577. }
  578. if(class_exists('DeviceDetector')) {
  579. if( !empty(DeviceDetector::$browsers[$browserId])) {
  580. return DeviceDetector::$browsers[$browserId];
  581. }
  582. }
  583. return false;
  584. }
  585. static public function getBrowserShortNameFromId($browserId)
  586. {
  587. self::init();
  588. if (isset(self::$browserIdToShortName[$browserId])) {
  589. return self::$browserIdToShortName[$browserId];
  590. }
  591. return false;
  592. }
  593. static public function getBrowserFamilyFromId($browserId)
  594. {
  595. self::init();
  596. $familyNameToUse = 'unknown';
  597. foreach (self::$browserType as $familyName => $aBrowsers) {
  598. if (in_array($browserId, $aBrowsers)) {
  599. $familyNameToUse = $familyName;
  600. break;
  601. }
  602. }
  603. return $familyNameToUse;
  604. }
  605. static public function getOperatingSystemNameFromId($osId)
  606. {
  607. self::init();
  608. if (isset(self::$operatingSystemsIdToName[$osId])) {
  609. return self::$operatingSystemsIdToName[$osId];
  610. }
  611. if(class_exists('DeviceDetector')) {
  612. return DeviceDetector::getOsNameFromId($osId);
  613. }
  614. return false;
  615. }
  616. static public function getOperatingSystemShortNameFromId($osId)
  617. {
  618. self::init();
  619. if (isset(self::$operatingSystemsIdToShortName[$osId])) {
  620. return self::$operatingSystemsIdToShortName[$osId];
  621. }
  622. return false;
  623. }
  624. static public function getOperatingSystemIdFromName($osName)
  625. {
  626. return isset(self::$operatingSystems[$osName]) ? self::$operatingSystems[$osName] : false;
  627. }
  628. static public function getOperatingSystemFamilyFromId($osId)
  629. {
  630. self::init();
  631. foreach (self::$osType as $familyName => $aSystems) {
  632. if (in_array($osId, $aSystems)) {
  633. return $familyName;
  634. }
  635. }
  636. return 'unknown';
  637. }
  638. }