PageRenderTime 286ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 1ms

/WeBid/trunk/includes/useragent.inc.php

https://github.com/cipiceuca25/webid
PHP | 1221 lines | 712 code | 44 blank | 465 comment | 104 complexity | 2e0ab15e498b3d9944acdd1ab8bfa3cf MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. Script Name: Full Featured PHP Browser/OS detection
  4. Author: Harald Hope, Website: http://techpatterns.com/
  5. Script Source URI: http://techpatterns.com/downloads/php_browser_detection.php
  6. Version 5.3.16
  7. Copyright (C) May 2 2011
  8. Special thanks to alanjstr for cleaning up the code, especially on function get_item_version(),
  9. which he improved greatly. Also to Tapio Markula, for his initial inspiration of creating a
  10. useable php browser detector. Also to silver Harloe for his ideas about using associative arrays
  11. to both return and use as main return handler.
  12. This program is free software; you can redistribute it and/or modify it under
  13. the terms of the GNU General Public License as published by the Free Software
  14. Foundation; either version 3 of the License, or (at your option) any later version.
  15. This program is distributed in the hope that it will be useful, but WITHOUT
  16. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  17. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  18. Get the full text of the GPL here: http://www.gnu.org/licenses/gpl.txt
  19. Coding conventions:
  20. http://cvs.sourceforge.net/viewcvs.py/phpbb/phpBB2/docs/codingstandards.htm?rev=1.3
  21. ******************************************
  22. This is currently set to accept these primary parameters, although you can add as many as you want:
  23. Note: all string data is returned as LOWER CASE, so make sure to keep that in mind when testing.
  24. NOTE: as 5.3.0 some of these names have been changed to be more human readable. The old names will
  25. still work, and it is noted where this change has happened like this: [deprecated: moz_version].
  26. This change will will NOT break your existing programming or browser detection function calls.
  27. ******************************************
  28. 1. browser_math_number - [deprecated: math_number] returns basic version number, for math
  29. comparison, ie. 1.2rel2a becomes 1.2
  30. 2. browser_name - returns the full browser name string, if available, otherwise returns ''
  31. (information not available)
  32. 2. browser_number - [deprecated: number] returns the browser version number, if available,
  33. otherwise returns '' (information not available)
  34. 3. browser_working [deprecated: browser] - returns the working shorthand browser name:
  35. ie, op, moz, konq, saf, ns4, webkit, and some others. If not shorthand, it will probably just
  36. return the full browser name, like lynx
  37. 4. dom - returns true/false if it is a basic dom browser, ie >= 5, opera >= 5, all new mozillas,
  38. safaris, konquerors
  39. 5. ie_version - tests to see what general IE it is.
  40. Possible return values:
  41. ie9x - all new msie 9 or greater - note that if in compat mode, 7,8,9 all show as 7
  42. ie7x - all new msie 7 or greater
  43. ie5x - msie 5 and 6, not mac
  44. ieMac - msie 5.x mac release
  45. ie4 - msie 4
  46. old - pre msie 4
  47. 6. full - returns this array, listed by array index number:
  48. 0 - $browser_working
  49. 1 - $browser_number
  50. 2 - $ie_version
  51. 3 - $b_dom_browser
  52. 4 - $b_safe_browser
  53. 5 - $os_type
  54. 6 - $os_number
  55. 7 - $browser_name
  56. 8 - $ua_type
  57. 9 - $browser_math_number
  58. 10 - $a_moz_data
  59. 11 - $a_webkit_data
  60. 12 - $mobile_test (null or string value)
  61. 13 - $a_mobile_data (null or array of mobile data)
  62. 14 - $true_ie_number
  63. 15 - $run_time
  64. Note that moz/webkit_data are arrays which could contain null data, so always test first before
  65. assuming the moz/webkit arrays contain any data, ie, if moz or if webkit, then...
  66. 7. full_assoc - returns all relevant browser information in an associative array, same as above
  67. only with string indexes instead of numeric:
  68. 'browser_working' => $browser_working,
  69. 'browser_number' => $browser_number,
  70. 'ie_version' => $ie_version,
  71. 'dom' => $b_dom_browser,
  72. 'safe' => $b_safe_browser,
  73. 'os' => $os_type,
  74. 'os_number' => $os_number,
  75. 'browser_name_' => $browser_name,
  76. 'ua_type' => $ua_type,
  77. 'browser_math_number' => $browser_math_number,
  78. 'moz_data' => $a_moz_data,
  79. 'webkit_data' => $a_webkit_data,
  80. 'mobile_test' => $mobile_test,
  81. 'mobile_data' => $a_mobile_data,
  82. 'true_ie_number' => $true_ie_number
  83. 'run_time' => $run_time
  84. 8. mobile_test - returns a string of various mobile id methods, from device to os to browser.
  85. If string is not null, should be a mobile. Also see 15, 'type', which will be 'mobile'
  86. if handheld.
  87. 9. mobile_data - returns an array of data about mobiles. Note the browser/os number data is very
  88. unreliable so don't count on that. No blackberry version handling done explicitly.
  89. Make sure to test if this is an array because if it's not mobile it will be null, not an array
  90. listed by array index number:
  91. 0 - $mobile_device
  92. 1 - $mobile_browser
  93. 2 - $mobile_browser_number
  94. 3 - $mobile_os
  95. 4 - $mobile_os_number
  96. 5 - $mobile_server
  97. 6 - $mobile_server_number
  98. 7 - $mobile_device_number (this was added so has to be end of list to not break existing code)
  99. Note: $mobile_browser only returns if a specifically mobile browser is detected, like minimo.
  100. Same for mobile os, with the exception of linux. Otherwise the standard script os/browser data
  101. is used. $mobile_server is a handheld service like docomo, novarro-vision, etc. Sometimes the
  102. string will contain no other usable data than this to determine if it's handheld or not.
  103. 10. moz_data [deprecated: moz_version] - returns array of mozilla / gecko information
  104. Return Array listed by index number:
  105. 0 - $moz_type [moz version - the specific brand name that is, eg: firefox)
  106. 1 - $moz_number - the full version number of $moz_type (eg: for firefox: 3.6+2b)
  107. 2 - $moz_rv - the Mozilla rv version number, math comparison version. This tells you what
  108. gecko engine is running in the browser (eg rv: 1.8)
  109. 3 - $moz_rv_full - rv number (for full rv, including alpha and beta versions: 1.8.1-b3)
  110. 4 - $moz_release_date - release date of the browser
  111. 11. os - returns which os is being used - win, nt, mac, OR iphone, blackberry, palmos, palmsource,
  112. symbian, beos, os2, amiga, webtv, linux, unix.
  113. 12. os_number - returns windows versions, 95, 98, ce, me, nt: 4; 5 [windows 2000];
  114. 5.1 [windows xp]; 5.2 [Server 2003]; 6.0 [Windows Vista], 6.1 [Windows 7].
  115. Only win, nt, mac, iphone return os numbers (mac/iphone return 10 if OS X.)
  116. OR returns linux distro/unix release name, otherwise returns null
  117. 13. run_time - the time it takes this script to execute from start to point of returning value
  118. Requires PHP 5 or greater. Returns time in seconds to 8 decimal places: 0.00245687
  119. Run time does not count the time used by PHP to include/parse the file initially. That total
  120. time is about 5-10x longer. Because subsequent script run throughs go VERY fast, you will see
  121. the seconds go from something like 0.00115204 for first time, to something like 0.00004005
  122. for second and more runs.
  123. 14. safe - returns true/false, you can determine what makes the browser be safe lower down,
  124. currently it's set for ns4 and pre version 1 mozillas not being safe, plus all older browsers
  125. 15. true_ie_number - [deprecated: true_msie_version] returns the true version of msie running,
  126. ignoring the compat mode version.
  127. Note that php will turn 7.0 to 8 when adding 1, so keep that in mind in your tests. 7.1
  128. will become 8.1 as expected, however. This test currently only tests for 7.x -> 8.x
  129. FYI: in PHP, 7.0 == 7 is true but 7.0 === 7 is NOT true.
  130. If this is null but set, then it is NOT running in compatibility mode.
  131. 16. ua_type [deprecated: type] - returns one of the following:
  132. bot (web bot)
  133. bro (normal browser)
  134. bbro (simple browser)
  135. mobile (handheld)
  136. dow (downloading agent)
  137. lib (http library)
  138. 17. webkit_data - [deprecated: webkit_version] returns array of webkit data.
  139. Return Array listed by index number:
  140. 0 - $webkit_type [webkit version name (Eg. chrome)]
  141. 1 - $webkit_type_number [webkit version number (Eg. Chrome's: 1.2)]
  142. 2 - $browser_number [the actual webkit version number (Eg. Webkit's: 436)]
  143. ******************************************
  144. Optional second script parameter, to turn off features if not required. These would be the second
  145. argument used in the function call if used, like: browser_detection( 'full', '1' );
  146. Test Exclusions - switches to turn off various tests, useful if you want to optimize execution
  147. and don't need the test data type excluded.
  148. ******************************************
  149. 1 - turn off os tests
  150. 2 - turn off mobile tests
  151. 3 - turn off mobile and os tests
  152. ******************************************
  153. Optional third script parameter, pass the script externally derived UA strings, for testing/
  154. processing purposes. Idea from Rui Teixeira
  155. Note: include a blank second arg when you use the 3rd parameter if the second is not set:
  156. example: browser_detection( 'full', '', $test_string_data )
  157. Using third parameter sets $b_repeat to false in other words, if you use this parameter, the script
  158. will do the full processing on the UA string, then switch $b_repeat back to true at the end.
  159. However, be aware that all requests to the script after the last testing value is sent will
  160. use the previous testing value, NOT the actual UA string, so make sure to handle that in your
  161. programming if you require the true UA data to be processed after the final testing value is sent
  162. by resetting that data with the true UA value.
  163. *******************************************/
  164. // main script, uses two other functions, get_os_data() and get_item_version() as needed
  165. // Optional $test_excludes is either null or one of the above values
  166. function browser_detection( $which_test, $test_excludes='', $external_ua_string='' )
  167. {
  168. /*
  169. uncomment the global variable declaration if you want the variables to be available on
  170. a global level throughout your php page, make sure that php is configured to support
  171. the use of globals first!
  172. Use of globals should be avoided however, and they are not necessary with this script
  173. /*
  174. /*
  175. global $a_full_assoc_data, $a_mobile_data, $a_moz_data, $a_webkit_data, $b_dom_browser, $b_repeat, $b_safe_browser, $browser_name, $browser_number, $browser_math_number, $browser_user_agent, $browser_working, $ie_version, $mobile_test, $moz_number, $moz_rv, $moz_rv_full, $moz_release_date, $moz_type, $os_number, $os_type, $true_ie_number, $ua_type, $webkit_type, $webkit_type_number;
  176. */
  177. script_time(); // set script timer to start timing
  178. static $a_full_assoc_data, $a_mobile_data, $a_moz_data, $a_webkit_data, $b_dom_browser, $b_repeat, $b_safe_browser, $browser_name, $browser_number, $browser_math_number, $browser_user_agent, $browser_working, $ie_version, $mobile_test, $moz_number, $moz_rv, $moz_rv_full, $moz_release_date, $moz_type, $os_number, $os_type, $true_ie_number, $ua_type, $webkit_type, $webkit_type_number;
  179. // switch off the optimization for external ua string testing.
  180. if ( $external_ua_string )
  181. {
  182. $b_repeat = false;
  183. }
  184. /*
  185. this makes the test only run once no matter how many times you call it since
  186. all the variables are filled on the first run through, it's only a matter of
  187. returning the the right ones
  188. */
  189. if ( !$b_repeat )
  190. {
  191. //initialize all variables with default values to prevent error
  192. $a_browser_math_number = '';
  193. $a_full_assoc_data = '';
  194. $a_full_data = '';
  195. $a_mobile_data = '';
  196. $a_moz_data = '';
  197. $a_os_data = '';
  198. $a_unhandled_browser = '';
  199. $a_webkit_data = '';
  200. $b_dom_browser = false;
  201. $b_os_test = true;
  202. $b_mobile_test = true;
  203. $b_safe_browser = false;
  204. $b_success = false;// boolean for if browser found in main test
  205. $browser_math_number = '';
  206. $browser_temp = '';
  207. $browser_working = '';
  208. $browser_number = '';
  209. $ie_version = '';
  210. $mobile_test = '';
  211. $moz_release_date = '';
  212. $moz_rv = '';
  213. $moz_rv_full = '';
  214. $moz_type = '';
  215. $moz_number = '';
  216. $os_number = '';
  217. $os_type = '';
  218. $run_time = '';
  219. $true_ie_number = '';
  220. $ua_type = 'bot';// default to bot since you never know with bots
  221. $webkit_type = '';
  222. $webkit_type_number = '';
  223. // set the excludes if required
  224. if ( $test_excludes )
  225. {
  226. switch ( $test_excludes )
  227. {
  228. case '1':
  229. $b_os_test = false;
  230. break;
  231. case '2':
  232. $b_mobile_test = false;
  233. break;
  234. case '3':
  235. $b_os_test = false;
  236. $b_mobile_test = false;
  237. break;
  238. default:
  239. die( 'Error: bad $test_excludes parameter 2 used: ' . $test_excludes );
  240. break;
  241. }
  242. }
  243. /*
  244. make navigator user agent string lower case to make sure all versions get caught
  245. isset protects against blank user agent failure. tolower also lets the script use
  246. strstr instead of stristr, which drops overhead slightly.
  247. */
  248. if ( $external_ua_string )
  249. {
  250. $browser_user_agent = strtolower( $external_ua_string );
  251. }
  252. elseif ( isset( $_SERVER['HTTP_USER_AGENT'] ) )
  253. {
  254. $browser_user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  255. }
  256. else
  257. {
  258. $browser_user_agent = '';
  259. }
  260. /*
  261. pack the browser type array, in this order
  262. the order is important, because opera must be tested first, then omniweb [which has safari
  263. data in string], same for konqueror, then safari, then gecko, since safari navigator user
  264. agent id's with 'gecko' in string.
  265. Note that $b_dom_browser is set for all modern dom browsers, this gives you a default to use.
  266. array[0] = id string for useragent, array[1] is if dom capable, array[2] is working name
  267. for browser, array[3] identifies navigator useragent type
  268. Note: all browser strings are in lower case to match the strtolower output, this avoids
  269. possible detection errors
  270. Note: These are the navigator user agent types:
  271. bro - modern, css supporting browser.
  272. bbro - basic browser, text only, table only, defective css implementation
  273. bot - search type spider
  274. dow - known download agent
  275. lib - standard http libraries
  276. mobile - handheld or mobile browser, set using $mobile_test
  277. */
  278. // known browsers, list will be updated routinely, check back now and then
  279. $a_browser_types = array(
  280. array( 'opera', true, 'op', 'bro' ),
  281. array( 'msie', true, 'ie', 'bro' ),
  282. // webkit before gecko because some webkit ua strings say: like gecko
  283. array( 'webkit', true, 'webkit', 'bro' ),
  284. // konq will be using webkit soon
  285. array( 'konqueror', true, 'konq', 'bro' ),
  286. // covers Netscape 6-7, K-Meleon, Most linux versions, uses moz array below
  287. array( 'gecko', true, 'moz', 'bro' ),
  288. array( 'netpositive', false, 'netp', 'bbro' ),// beos browser
  289. array( 'lynx', false, 'lynx', 'bbro' ), // command line browser
  290. array( 'elinks ', false, 'elinks', 'bbro' ), // new version of links
  291. array( 'elinks', false, 'elinks', 'bbro' ), // alternate id for it
  292. array( 'links2', false, 'links2', 'bbro' ), // alternate links version
  293. array( 'links ', false, 'links', 'bbro' ), // old name for links
  294. array( 'links', false, 'links', 'bbro' ), // alternate id for it
  295. array( 'w3m', false, 'w3m', 'bbro' ), // open source browser, more features than lynx/links
  296. array( 'webtv', false, 'webtv', 'bbro' ),// junk ms webtv
  297. array( 'amaya', false, 'amaya', 'bbro' ),// w3c browser
  298. array( 'dillo', false, 'dillo', 'bbro' ),// linux browser, basic table support
  299. array( 'ibrowse', false, 'ibrowse', 'bbro' ),// amiga browser
  300. array( 'icab', false, 'icab', 'bro' ),// mac browser
  301. array( 'crazy browser', true, 'ie', 'bro' ),// uses ie rendering engine
  302. // search engine spider bots:
  303. array( 'bingbot', false, 'bing', 'bot' ),// bing
  304. array( 'exabot', false, 'exabot', 'bot' ),// exabot
  305. array( 'googlebot', false, 'google', 'bot' ),// google
  306. array( 'google web preview', false, 'googlewp', 'bot' ),// google preview
  307. array( 'mediapartners-google', false, 'adsense', 'bot' ),// google adsense
  308. array( 'yahoo-verticalcrawler', false, 'yahoo', 'bot' ),// old yahoo bot
  309. array( 'yahoo! slurp', false, 'yahoo', 'bot' ), // new yahoo bot
  310. array( 'yahoo-mm', false, 'yahoomm', 'bot' ), // gets Yahoo-MMCrawler and Yahoo-MMAudVid bots
  311. array( 'inktomi', false, 'inktomi', 'bot' ), // inktomi bot
  312. array( 'slurp', false, 'inktomi', 'bot' ), // inktomi bot
  313. array( 'fast-webcrawler', false, 'fast', 'bot' ),// Fast AllTheWeb
  314. array( 'msnbot', false, 'msn', 'bot' ),// msn search
  315. array( 'ask jeeves', false, 'ask', 'bot' ), //jeeves/teoma
  316. array( 'teoma', false, 'ask', 'bot' ),//jeeves teoma
  317. array( 'scooter', false, 'scooter', 'bot' ),// altavista
  318. array( 'openbot', false, 'openbot', 'bot' ),// openbot, from taiwan
  319. array( 'ia_archiver', false, 'ia_archiver', 'bot' ),// ia archiver
  320. array( 'zyborg', false, 'looksmart', 'bot' ),// looksmart
  321. array( 'almaden', false, 'ibm', 'bot' ),// ibm almaden web crawler
  322. array( 'baiduspider', false, 'baidu', 'bot' ),// Baiduspider asian search spider
  323. array( 'psbot', false, 'psbot', 'bot' ),// psbot image crawler
  324. array( 'gigabot', false, 'gigabot', 'bot' ),// gigabot crawler
  325. array( 'naverbot', false, 'naverbot', 'bot' ),// naverbot crawler, bad bot, block
  326. array( 'surveybot', false, 'surveybot', 'bot' ),//
  327. array( 'boitho.com-dc', false, 'boitho', 'bot' ),//norwegian search engine
  328. array( 'objectssearch', false, 'objectsearch', 'bot' ),// open source search engine
  329. array( 'answerbus', false, 'answerbus', 'bot' ),// http://www.answerbus.com/, web questions
  330. array( 'sohu-search', false, 'sohu', 'bot' ),// chinese media company, search component
  331. array( 'iltrovatore-setaccio', false, 'il-set', 'bot' ),
  332. // various http utility libaries
  333. array( 'w3c_validator', false, 'w3c', 'lib' ), // uses libperl, make first
  334. array( 'wdg_validator', false, 'wdg', 'lib' ), //
  335. array( 'libwww-perl', false, 'libwww-perl', 'lib' ),
  336. array( 'jakarta commons-httpclient', false, 'jakarta', 'lib' ),
  337. array( 'python-urllib', false, 'python-urllib', 'lib' ),
  338. // download apps
  339. array( 'getright', false, 'getright', 'dow' ),
  340. array( 'wget', false, 'wget', 'dow' ),// open source downloader, obeys robots.txt
  341. // netscape 4 and earlier tests, put last so spiders don't get caught
  342. array( 'mozilla/4.', false, 'ns', 'bbro' ),
  343. array( 'mozilla/3.', false, 'ns', 'bbro' ),
  344. array( 'mozilla/2.', false, 'ns', 'bbro' )
  345. );
  346. //array( '', false ); // browser array template
  347. /*
  348. moz types array
  349. note the order, netscape6 must come before netscape, which is how netscape 7 id's itself.
  350. rv comes last in case it is plain old mozilla. firefox/netscape/seamonkey need to be later
  351. Thanks to: http://www.zytrax.com/tech/web/firefox-history.html
  352. */
  353. $a_moz_types = array( 'bonecho', 'camino', 'epiphany', 'firebird', 'flock', 'galeon', 'iceape', 'icecat', 'k-meleon', 'minimo', 'multizilla', 'phoenix', 'songbird', 'swiftfox', 'seamonkey', 'shiretoko', 'iceweasel', 'firefox', 'minefield', 'netscape6', 'netscape', 'rv' );
  354. /*
  355. webkit types, this is going to expand over time as webkit browsers spread
  356. konqueror is probably going to move to webkit, so this is preparing for that
  357. It will now default to khtml. gtklauncher is the temp id for epiphany, might
  358. change. Defaults to applewebkit, and will all show the webkit number.
  359. */
  360. $a_webkit_types = array( 'arora', 'chrome', 'epiphany', 'gtklauncher', 'icab', 'konqueror', 'maxthon', 'midori', 'omniweb', 'rekonq', 'safari', 'shiira', 'uzbl', 'applewebkit', 'webkit' );
  361. /*
  362. run through the browser_types array, break if you hit a match, if no match, assume old browser
  363. or non dom browser, assigns false value to $b_success.
  364. */
  365. $i_count = count( $a_browser_types );
  366. for ( $i = 0; $i < $i_count; $i++ )
  367. {
  368. //unpacks browser array, assigns to variables, need to not assign til found in string
  369. $browser_temp = $a_browser_types[$i][0];// text string to id browser from array
  370. if ( strstr( $browser_user_agent, $browser_temp ) )
  371. {
  372. /*
  373. it defaults to true, will become false below if needed
  374. this keeps it easier to keep track of what is safe, only
  375. explicit false assignment will make it false.
  376. */
  377. $b_safe_browser = true;
  378. $browser_name = $browser_temp;// text string to id browser from array
  379. // assign values based on match of user agent string
  380. $b_dom_browser = $a_browser_types[$i][1];// hardcoded dom support from array
  381. $browser_working = $a_browser_types[$i][2];// working name for browser
  382. $ua_type = $a_browser_types[$i][3];// sets whether bot or browser
  383. switch ( $browser_working )
  384. {
  385. // this is modified quite a bit, now will return proper netscape version number
  386. // check your implementation to make sure it works
  387. case 'ns':
  388. $b_safe_browser = false;
  389. $browser_number = get_item_version( $browser_user_agent, 'mozilla' );
  390. break;
  391. case 'moz':
  392. /*
  393. note: The 'rv' test is not absolute since the rv number is very different on
  394. different versions, for example Galean doesn't use the same rv version as Mozilla,
  395. neither do later Netscapes, like 7.x. For more on this, read the full mozilla
  396. numbering conventions here: http://www.mozilla.org/releases/cvstags.html
  397. */
  398. // this will return alpha and beta version numbers, if present
  399. $moz_rv_full = get_item_version( $browser_user_agent, 'rv' );
  400. // this slices them back off for math comparisons
  401. $moz_rv = substr( $moz_rv_full, 0, 3 );
  402. // this is to pull out specific mozilla versions, firebird, netscape etc..
  403. $j_count = count( $a_moz_types );
  404. for ( $j = 0; $j < $j_count; $j++ )
  405. {
  406. if ( strstr( $browser_user_agent, $a_moz_types[$j] ) )
  407. {
  408. $moz_type = $a_moz_types[$j];
  409. $moz_number = get_item_version( $browser_user_agent, $moz_type );
  410. break;
  411. }
  412. }
  413. /*
  414. this is necesary to protect against false id'ed moz'es and new moz'es.
  415. this corrects for galeon, or any other moz browser without an rv number
  416. */
  417. if ( !$moz_rv )
  418. {
  419. // you can use this if you are running php >= 4.2
  420. if ( function_exists( 'floatval' ) )
  421. {
  422. $moz_rv = floatval( $moz_number );
  423. }
  424. else
  425. {
  426. $moz_rv = substr( $moz_number, 0, 3 );
  427. }
  428. $moz_rv_full = $moz_number;
  429. }
  430. // this corrects the version name in case it went to the default 'rv' for the test
  431. if ( $moz_type == 'rv' )
  432. {
  433. $moz_type = 'mozilla';
  434. }
  435. //the moz version will be taken from the rv number, see notes above for rv problems
  436. $browser_number = $moz_rv;
  437. // gets the actual release date, necessary if you need to do functionality tests
  438. get_set_count( 'set', 0 );
  439. $moz_release_date = get_item_version( $browser_user_agent, 'gecko/' );
  440. /*
  441. Test for mozilla 0.9.x / netscape 6.x
  442. test your javascript/CSS to see if it works in these mozilla releases, if it
  443. does, just default it to: $b_safe_browser = true;
  444. */
  445. if ( ( $moz_release_date < 20020400 ) || ( $moz_rv < 1 ) )
  446. {
  447. $b_safe_browser = false;
  448. }
  449. break;
  450. case 'ie':
  451. /*
  452. note we're adding in the trident/ search to return only first instance in case
  453. of msie 8, and we're triggering the break last condition in the test, as well
  454. as the test for a second search string, trident/
  455. Sample: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0)
  456. */
  457. $browser_number = get_item_version( $browser_user_agent, $browser_name, true, 'trident/' );
  458. // construct the proper real number if it's in compat mode and msie 10
  459. if ( strstr( $browser_number, '7.' ) )
  460. {
  461. if ( strstr( $browser_user_agent, 'trident/7' ) )
  462. {
  463. // note that 7.0 becomes 11 when adding 4, but if it's 7.1 it will be 11.1
  464. $true_ie_number = $browser_number + 4;
  465. }
  466. elseif ( strstr( $browser_user_agent, 'trident/6' ) )
  467. {
  468. // note that 7.0 becomes 10 when adding 3, but if it's 7.1 it will be 10.1
  469. $true_ie_number = $browser_number + 3;
  470. }
  471. // construct the proper real number if it's in compat mode and msie 8.0/9.0
  472. elseif ( strstr( $browser_user_agent, 'trident/5' ) )
  473. {
  474. // note that 7.0 becomes 9 when adding 2, but if it's 7.1 it will be 9.1
  475. $true_ie_number = $browser_number + 2;
  476. }
  477. elseif ( strstr( $browser_user_agent, 'trident/4' ) )
  478. {
  479. // note that 7.0 becomes 8 when adding 1, but if it's 7.1 it will be 8.1
  480. $true_ie_number = $browser_number + 1;
  481. }
  482. }
  483. // the 9 series is finally standards compatible, html 5 etc, so worth a new id
  484. if ( $browser_number >= 9 )
  485. {
  486. $ie_version = 'ie9x';
  487. }
  488. // 7/8 were not yet quite to standards levels but getting there
  489. elseif ( $browser_number >= 7 )
  490. {
  491. $ie_version = 'ie7x';
  492. }
  493. // then test for IE 5x mac, that's the most problematic IE out there
  494. elseif ( strstr( $browser_user_agent, 'mac') )
  495. {
  496. $ie_version = 'ieMac';
  497. }
  498. // ie 5/6 are both very weak in standards compliance
  499. elseif ( $browser_number >= 5 )
  500. {
  501. $ie_version = 'ie5x';
  502. }
  503. elseif ( ( $browser_number > 3 ) && ( $browser_number < 5 ) )
  504. {
  505. $b_dom_browser = false;
  506. $ie_version = 'ie4';
  507. // this depends on what you're using the script for, make sure this fits your needs
  508. $b_safe_browser = true;
  509. }
  510. else
  511. {
  512. $ie_version = 'old';
  513. $b_dom_browser = false;
  514. $b_safe_browser = false;
  515. }
  516. break;
  517. case 'op':
  518. $browser_number = get_item_version( $browser_user_agent, $browser_name );
  519. // opera is leaving version at 9.80 (or xx) for 10.x - see this for explanation
  520. // http://dev.opera.com/articles/view/opera-ua-string-changes/
  521. if ( strstr( $browser_number, '9.' ) && strstr( $browser_user_agent, 'version/' ) )
  522. {
  523. get_set_count( 'set', 0 );
  524. $browser_number = get_item_version( $browser_user_agent, 'version/' );
  525. }
  526. if ( $browser_number < 5 )// opera 4 wasn't very useable.
  527. {
  528. $b_safe_browser = false;
  529. }
  530. break;
  531. /*
  532. note: webkit returns always the webkit version number, not the specific user
  533. agent version, ie, webkit 583, not chrome 0.3
  534. */
  535. case 'webkit':
  536. // note that this is the Webkit version number
  537. $browser_number = get_item_version( $browser_user_agent, $browser_name );
  538. // this is to pull out specific webkit versions, safari, google-chrome etc..
  539. $j_count = count( $a_webkit_types );
  540. for ( $j = 0; $j < $j_count; $j++ )
  541. {
  542. if ( strstr( $browser_user_agent, $a_webkit_types[$j] ) )
  543. {
  544. $webkit_type = $a_webkit_types[$j];
  545. /*
  546. and this is the webkit type version number, like: chrome 1.2
  547. if omni web, we want the count 2, not default 1
  548. */
  549. if ( $webkit_type == 'omniweb' )
  550. {
  551. get_set_count( 'set', 2 );
  552. }
  553. $webkit_type_number = get_item_version( $browser_user_agent, $webkit_type );
  554. // epiphany hack
  555. if ( $a_webkit_types[$j] == 'gtklauncher' )
  556. {
  557. $browser_name = 'epiphany';
  558. }
  559. else
  560. {
  561. $browser_name = $a_webkit_types[$j];
  562. }
  563. break;
  564. }
  565. }
  566. break;
  567. default:
  568. $browser_number = get_item_version( $browser_user_agent, $browser_name );
  569. break;
  570. }
  571. // the browser was id'ed
  572. $b_success = true;
  573. break;
  574. }
  575. }
  576. //assigns defaults if the browser was not found in the loop test
  577. if ( !$b_success )
  578. {
  579. /*
  580. this will return the first part of the browser string if the above id's failed
  581. usually the first part of the browser string has the navigator useragent name/version in it.
  582. This will usually correctly id the browser and the browser number if it didn't get
  583. caught by the above routine.
  584. If you want a '' to do a if browser == '' type test, just comment out all lines below
  585. except for the last line, and uncomment the last line. If you want undefined values,
  586. the browser_name is '', you can always test for that
  587. */
  588. // delete this part if you want an unknown browser returned
  589. $browser_name = substr( $browser_user_agent, 0, strcspn( $browser_user_agent , '();') );
  590. // this extracts just the browser name from the string, if something usable was found
  591. if ( $browser_name && preg_match( '/[^0-9][a-z]*-*\ *[a-z]*\ *[a-z]*/', $browser_name, $a_unhandled_browser ) )
  592. {
  593. $browser_name = $a_unhandled_browser[0];
  594. if ( $browser_name == 'blackberry' )
  595. {
  596. get_set_count( 'set', 0 );
  597. }
  598. $browser_number = get_item_version( $browser_user_agent, $browser_name );
  599. }
  600. else
  601. {
  602. $browser_name = 'NA';
  603. $browser_number = 'NA';
  604. }
  605. // then uncomment this part
  606. //$browser_name = '';//deletes the last array item in case the browser was not a match
  607. }
  608. // get os data, mac os x test requires browser/version information, this is a change from older scripts
  609. if ( $b_os_test )
  610. {
  611. $a_os_data = get_os_data( $browser_user_agent, $browser_working, $browser_number );
  612. $os_type = $a_os_data[0];// os name, abbreviated
  613. $os_number = $a_os_data[1];// os number or version if available
  614. }
  615. /*
  616. this ends the run through once if clause, set the boolean
  617. to true so the function won't retest everything
  618. */
  619. $b_repeat = true;
  620. /*
  621. pulls out primary version number from more complex string, like 7.5a,
  622. use this for numeric version comparison
  623. */
  624. if ( $browser_number && preg_match( '/[0-9]*\.*[0-9]*/', $browser_number, $a_browser_math_number ) )
  625. {
  626. $browser_math_number = $a_browser_math_number[0];
  627. //print_r($a_browser_math_number);
  628. }
  629. if ( $b_mobile_test )
  630. {
  631. $mobile_test = check_is_mobile( $browser_user_agent );
  632. if ( $mobile_test )
  633. {
  634. $a_mobile_data = get_mobile_data( $browser_user_agent );
  635. $ua_type = 'mobile';
  636. }
  637. }
  638. }
  639. //$browser_number = $_SERVER["REMOTE_ADDR"];
  640. /*
  641. This is where you return values based on what parameter you used to call the function
  642. $which_test is the passed parameter in the initial browser_detection('os') for example returns
  643. the os version only.
  644. Update deprecated parameter names to new names
  645. */
  646. switch ( $which_test )
  647. {
  648. case 'math_number':
  649. $which_test = 'browser_math_number';
  650. break;
  651. case 'number':
  652. $which_test = 'browser_number';
  653. break;
  654. case 'browser':
  655. $which_test = 'browser_working';
  656. break;
  657. case 'moz_version':
  658. $which_test = 'moz_data';
  659. break;
  660. case 'true_msie_version':
  661. $which_test = 'true_ie_number';
  662. break;
  663. case 'type':
  664. $which_test = 'ua_type';
  665. break;
  666. case 'webkit_version':
  667. $which_test = 'webkit_data';
  668. break;
  669. }
  670. /*
  671. assemble these first so they can be included in full return data, using static variables
  672. Note that there's no need to keep repacking these every time the script is called
  673. */
  674. if ( !$a_moz_data )
  675. {
  676. $a_moz_data = array( $moz_type, $moz_number, $moz_rv, $moz_rv_full, $moz_release_date );
  677. }
  678. if ( !$a_webkit_data )
  679. {
  680. $a_webkit_data = array( $webkit_type, $webkit_type_number, $browser_number );
  681. }
  682. $run_time = script_time();
  683. // then pack the primary data array
  684. if ( !$a_full_assoc_data )
  685. {
  686. $a_full_assoc_data = array(
  687. 'browser_working' => $browser_working,
  688. 'browser_number' => $browser_number,
  689. 'ie_version' => $ie_version,
  690. 'dom' => $b_dom_browser,
  691. 'safe' => $b_safe_browser,
  692. 'os' => $os_type,
  693. 'os_number' => $os_number,
  694. 'browser_name' => $browser_name,
  695. 'ua_type' => $ua_type,
  696. 'browser_math_number' => $browser_math_number,
  697. 'moz_data' => $a_moz_data,
  698. 'webkit_data' => $a_webkit_data,
  699. 'mobile_test' => $mobile_test,
  700. 'mobile_data' => $a_mobile_data,
  701. 'true_ie_number' => $true_ie_number,
  702. 'run_time' => $run_time
  703. );
  704. }
  705. // return parameters, either full data arrays, or by associative array index key
  706. switch ( $which_test )
  707. {
  708. // returns all relevant browser information in an array with standard numberic indexes
  709. case 'full':
  710. $a_full_data = array(
  711. $browser_working,
  712. $browser_number,
  713. $ie_version,
  714. $b_dom_browser,
  715. $b_safe_browser,
  716. $os_type,
  717. $os_number,
  718. $browser_name,
  719. $ua_type,
  720. $browser_math_number,
  721. $a_moz_data,
  722. $a_webkit_data,
  723. $mobile_test,
  724. $a_mobile_data,
  725. $true_ie_number,
  726. $run_time
  727. );
  728. // print_r( $a_full_data );
  729. return $a_full_data;
  730. break;
  731. // returns all relevant browser information in an associative array
  732. case 'full_assoc':
  733. return $a_full_assoc_data;
  734. break;
  735. default:
  736. # check to see if the data is available, otherwise it's user typo of unsupported option
  737. if ( isset( $a_full_assoc_data[$which_test] ) )
  738. {
  739. return $a_full_assoc_data[$which_test];
  740. }
  741. else
  742. {
  743. die( "You passed the browser detector an unsupported option for parameter 1: " . $which_test );
  744. }
  745. break;
  746. }
  747. }
  748. // gets which os from the browser string
  749. function get_os_data ( $pv_browser_string, $pv_browser_name, $pv_version_number )
  750. {
  751. // initialize variables
  752. $os_working_type = '';
  753. $os_working_number = '';
  754. /*
  755. packs the os array. Use this order since some navigator user agents will put 'macintosh'
  756. in the navigator user agent string which would make the nt test register true
  757. */
  758. $a_mac = array( 'intel mac', 'ppc mac', 'mac68k' );// this is not used currently
  759. // same logic, check in order to catch the os's in order, last is always default item
  760. $a_unix_types = array( 'dragonfly', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'unixware', 'solaris', 'sunos', 'sun4', 'sun5', 'suni86', 'sun', 'irix5', 'irix6', 'irix', 'hpux9', 'hpux10', 'hpux11', 'hpux', 'hp-ux', 'aix1', 'aix2', 'aix3', 'aix4', 'aix5', 'aix', 'sco', 'unixware', 'mpras', 'reliant', 'dec', 'sinix', 'unix' );
  761. // only sometimes will you get a linux distro to id itself...
  762. $a_linux_distros = array( 'ubuntu', 'kubuntu', 'xubuntu', 'mepis', 'xandros', 'linspire', 'winspire', 'jolicloud', 'sidux', 'kanotix', 'debian', 'opensuse', 'suse', 'fedora', 'redhat', 'slackware', 'slax', 'mandrake', 'mandriva', 'gentoo', 'sabayon', 'linux' );
  763. $a_linux_process = array ( 'i386', 'i586', 'i686' );// not use currently
  764. // note, order of os very important in os array, you will get failed ids if changed
  765. $a_os_types = array( 'android', 'blackberry', 'iphone', 'palmos', 'palmsource', 'symbian', 'beos', 'os2', 'amiga', 'webtv', 'mac', 'nt', 'win', $a_unix_types, $a_linux_distros );
  766. //os tester
  767. $i_count = count( $a_os_types );
  768. for ( $i = 0; $i < $i_count; $i++ )
  769. {
  770. // unpacks os array, assigns to variable $a_os_working
  771. $os_working_data = $a_os_types[$i];
  772. /*
  773. assign os to global os variable, os flag true on success
  774. !strstr($pv_browser_string, "linux" ) corrects a linux detection bug
  775. */
  776. if ( !is_array( $os_working_data ) && strstr( $pv_browser_string, $os_working_data ) && !strstr( $pv_browser_string, "linux" ) )
  777. {
  778. $os_working_type = $os_working_data;
  779. switch ( $os_working_type )
  780. {
  781. // most windows now uses: NT X.Y syntax
  782. case 'nt':
  783. if ( strstr( $pv_browser_string, 'nt 6.1' ) )// windows 7
  784. {
  785. $os_working_number = 6.1;
  786. }
  787. elseif ( strstr( $pv_browser_string, 'nt 6.0' ) )// windows vista/server 2008
  788. {
  789. $os_working_number = 6.0;
  790. }
  791. elseif ( strstr( $pv_browser_string, 'nt 5.2' ) )// windows server 2003
  792. {
  793. $os_working_number = 5.2;
  794. }
  795. elseif ( strstr( $pv_browser_string, 'nt 5.1' ) || strstr( $pv_browser_string, 'xp' ) )// windows xp
  796. {
  797. $os_working_number = 5.1;//
  798. }
  799. elseif ( strstr( $pv_browser_string, 'nt 5' ) || strstr( $pv_browser_string, '2000' ) )// windows 2000
  800. {
  801. $os_working_number = 5.0;
  802. }
  803. elseif ( strstr( $pv_browser_string, 'nt 4' ) )// nt 4
  804. {
  805. $os_working_number = 4;
  806. }
  807. elseif ( strstr( $pv_browser_string, 'nt 3' ) )// nt 4
  808. {
  809. $os_working_number = 3;
  810. }
  811. break;
  812. case 'win':
  813. if ( strstr( $pv_browser_string, 'vista' ) )// windows vista, for opera ID
  814. {
  815. $os_working_number = 6.0;
  816. $os_working_type = 'nt';
  817. }
  818. elseif ( strstr( $pv_browser_string, 'xp' ) )// windows xp, for opera ID
  819. {
  820. $os_working_number = 5.1;
  821. $os_working_type = 'nt';
  822. }
  823. elseif ( strstr( $pv_browser_string, '2003' ) )// windows server 2003, for opera ID
  824. {
  825. $os_working_number = 5.2;
  826. $os_working_type = 'nt';
  827. }
  828. elseif ( strstr( $pv_browser_string, 'windows ce' ) )// windows CE
  829. {
  830. $os_working_number = 'ce';
  831. $os_working_type = 'nt';
  832. }
  833. elseif ( strstr( $pv_browser_string, '95' ) )
  834. {
  835. $os_working_number = '95';
  836. }
  837. elseif ( ( strstr( $pv_browser_string, '9x 4.9' ) ) || ( strstr( $pv_browser_string, ' me' ) ) )
  838. {
  839. $os_working_number = 'me';
  840. }
  841. elseif ( strstr( $pv_browser_string, '98' ) )
  842. {
  843. $os_working_number = '98';
  844. }
  845. elseif ( strstr( $pv_browser_string, '2000' ) )// windows 2000, for opera ID
  846. {
  847. $os_working_number = 5.0;
  848. $os_working_type = 'nt';
  849. }
  850. break;
  851. case 'mac':
  852. if ( strstr( $pv_browser_string, 'os x' ) )
  853. {
  854. // if it doesn't have a version number, it is os x;
  855. if ( strstr( $pv_browser_string, 'os x ' ) )
  856. {
  857. // numbers are like: 10_2.4, others 10.2.4
  858. $os_working_number = str_replace( '_', '.', get_item_version( $pv_browser_string, 'os x' ) );
  859. }
  860. else
  861. {
  862. $os_working_number = 10;
  863. }
  864. }
  865. /*
  866. this is a crude test for os x, since safari, camino, ie 5.2, & moz >= rv 1.3
  867. are only made for os x
  868. */
  869. elseif ( ( $pv_browser_name == 'saf' ) || ( $pv_browser_name == 'cam' ) ||
  870. ( ( $pv_browser_name == 'moz' ) && ( $pv_version_number >= 1.3 ) ) ||
  871. ( ( $pv_browser_name == 'ie' ) && ( $pv_version_number >= 5.2 ) ) )
  872. {
  873. $os_working_number = 10;
  874. }
  875. break;
  876. case 'iphone':
  877. $os_working_number = 10;
  878. break;
  879. default:
  880. break;
  881. }
  882. break;
  883. }
  884. /*
  885. check that it's an array, check it's the second to last item
  886. in the main os array, the unix one that is
  887. */
  888. elseif ( is_array( $os_working_data ) && ( $i == ( $i_count - 2 ) ) )
  889. {
  890. $j_count = count($os_working_data);
  891. for ($j = 0; $j < $j_count; $j++)
  892. {
  893. if ( strstr( $pv_browser_string, $os_working_data[$j] ) )
  894. {
  895. $os_working_type = 'unix'; //if the os is in the unix array, it's unix, obviously...
  896. $os_working_number = ( $os_working_data[$j] != 'unix' ) ? $os_working_data[$j] : '';// assign sub unix version from the unix array
  897. break;
  898. }
  899. }
  900. }
  901. /*
  902. check that it's an array, check it's the last item
  903. in the main os array, the linux one that is
  904. */
  905. elseif ( is_array( $os_working_data ) && ( $i == ( $i_count - 1 ) ) )
  906. {
  907. $j_count = count($os_working_data);
  908. for ($j = 0; $j < $j_count; $j++)
  909. {
  910. if ( strstr( $pv_browser_string, $os_working_data[$j] ) )
  911. {
  912. $os_working_type = 'lin';
  913. // assign linux distro from the linux array, there's a default
  914. //search for 'lin', if it's that, set version to ''
  915. $os_working_number = ( $os_working_data[$j] != 'linux' ) ? $os_working_data[$j] : '';
  916. break;
  917. }
  918. }
  919. }
  920. }
  921. // pack the os data array for return to main function
  922. $a_os_data = array( $os_working_type, $os_working_number );
  923. return $a_os_data;
  924. }
  925. /*
  926. Function Info:
  927. function returns browser number, gecko rv number, or gecko release date
  928. function get_item_version( $browser_user_agent, $search_string, $substring_length )
  929. $pv_extra_search='' allows us to set an additional search/exit loop parameter, but we
  930. only want this running when needed
  931. */
  932. function get_item_version( $pv_browser_user_agent, $pv_search_string, $pv_b_break_last='', $pv_extra_search='' )
  933. {
  934. // 12 is the longest that will be required, handles release dates: 20020323; 0.8.0+
  935. $substring_length = 15;
  936. $start_pos = 0; // set $start_pos to 0 for first iteration
  937. //initialize browser number, will return '' if not found
  938. $string_working_number = '';
  939. /*
  940. use the passed parameter for $pv_search_string
  941. start the substring slice right after these moz search strings
  942. there are some cases of double msie id's, first in string and then with then number
  943. $start_pos = 0;
  944. this test covers you for multiple occurrences of string, only with ie though
  945. with for example google bot you want the first occurance returned, since that's where the
  946. numbering happens
  947. */
  948. for ( $i = 0; $i < 4; $i++ )
  949. {
  950. //start the search after the first string occurrence
  951. if ( strpos( $pv_browser_user_agent, $pv_search_string, $start_pos ) !== false )
  952. {
  953. // update start position if position found
  954. $start_pos = strpos( $pv_browser_user_agent, $pv_search_string, $start_pos ) + strlen( $pv_search_string );
  955. /*
  956. msie (and maybe other userAgents requires special handling because some apps inject
  957. a second msie, usually at the beginning, custom modes allow breaking at first instance
  958. if $pv_b_break_last $pv_extra_search conditions exist. Since we only want this test
  959. to run if and only if we need it, it's triggered by caller passing these values.
  960. */
  961. if ( !$pv_b_break_last || ( $pv_extra_search && strstr( $pv_browser_user_agent, $pv_extra_search ) ) )
  962. {
  963. break;
  964. }
  965. }
  966. else
  967. {
  968. break;
  969. }
  970. }
  971. /*
  972. Handles things like extra omniweb/v456, gecko/, blackberry9700
  973. also corrects for the omniweb 'v'
  974. */
  975. $start_pos += get_set_count( 'get' );
  976. $string_working_number = substr( $pv_browser_user_agent, $start_pos, $substring_length );
  977. // Find the space, ;, or parentheses that ends the number
  978. $string_working_number = substr( $string_working_number, 0, strcspn($string_working_number, ' );/') );
  979. //make sure the returned value is actually the id number and not a string
  980. // otherwise return ''
  981. // strcspn( $string_working_number, '0123456789.') == strlen( $string_working_number)
  982. // if ( preg_match("/\\d/", $string_working_number) == 0 )
  983. if ( !is_numeric( substr( $string_working_number, 0, 1 ) ) )
  984. {
  985. $string_working_number = '';
  986. }
  987. //$string_working_number = strrpos( $pv_browser_user_agent, $pv_search_string );
  988. return $string_working_number;
  989. }
  990. function get_set_count( $pv_type, $pv_value='' )
  991. {
  992. static $slice_increment;
  993. $return_value = '';
  994. switch ( $pv_type )
  995. {
  996. case 'get':
  997. // set if unset, ie, first use. note that empty and isset are not good tests here
  998. if ( is_null( $slice_increment ) )
  999. {
  1000. $slice_increment = 1;
  1001. }
  1002. $return_value = $slice_increment;
  1003. $slice_increment = 1; // reset to default
  1004. return $return_value;
  1005. break;
  1006. case 'set':
  1007. $slice_increment = $pv_value;
  1008. break;
  1009. }
  1010. }
  1011. /*
  1012. Special ID notes:
  1013. Novarra-Vision is a Content Transformation Server (CTS)
  1014. */
  1015. function check_is_mobile( $pv_browser_user_agent )
  1016. {
  1017. $mobile_working_test = '';
  1018. /*
  1019. these will search for basic mobile hints, this should catch most of them, first check
  1020. known hand held device os, then check device names, then mobile browser names
  1021. This list is almost the same but not exactly as the 4 arrays in function below
  1022. */
  1023. $a_mobile_search = array(
  1024. /*
  1025. Make sure to use only data here that always will be a mobile, so this list is not
  1026. identical to the list of get_mobile_data
  1027. */
  1028. // os
  1029. 'android', 'epoc', 'linux armv', 'palmos', 'palmsource', 'windows ce', 'windows phone os', 'symbianos', 'symbian os', 'symbian', 'webos',
  1030. // devices - ipod before iphone or fails
  1031. 'benq', 'blackberry', 'danger hiptop', 'ddipocket', ' droid', 'ipad', 'ipod', 'iphone', 'kindle', 'lge-cx', 'lge-lx', 'lge-mx', 'lge vx', 'lge ', 'lge-', 'lg;lx', 'nintendo wii', 'nokia', 'palm', 'pdxgw', 'playstation', 'sagem', 'samsung', 'sec-sgh', 'sharp', 'sonyericsson', 'sprint', 'zune', 'j-phone', 'n410', 'mot 24', 'mot-', 'htc-', 'htc_', 'htc ', 'sec-', 'sie-m', 'sie-s', 'spv ', 'vodaphone', 'smartphone', 'armv', 'midp', 'mobilephone',
  1032. // browsers
  1033. 'avantgo', 'blazer', 'elaine', 'eudoraweb', 'iemobile', 'minimo', 'mobile safari', 'mobileexplorer', 'opera mobi', 'opera mini', 'netfront', 'opwv', 'polaris', 'semc-browser', 'up.browser', 'webpro', 'wms pie', 'xiino',
  1034. // services - astel out of business
  1035. 'astel', 'docomo', 'novarra-vision', 'portalmmm', 'reqwirelessweb', 'vodafone'
  1036. );
  1037. // then do basic mobile type search, this uses data from: get_mobile_data()
  1038. $j_count = count( $a_mobile_search );
  1039. for ($j = 0; $j < $j_count; $j++)
  1040. {
  1041. if ( strstr( $pv_browser_user_agent, $a_mobile_search[$j] ) )
  1042. {
  1043. $mobile_working_test = $a_mobile_search[$j];
  1044. break;
  1045. }
  1046. }
  1047. return $mobile_working_test;
  1048. }
  1049. /*
  1050. thanks to this page: http://www.zytrax.com/tech/web/mobile_ids.html
  1051. for data used here
  1052. */
  1053. function get_mobile_data( $pv_browser_user_agent )
  1054. {
  1055. $mobile_browser = '';
  1056. $mobile_browser_number = '';
  1057. $mobile_device = '';
  1058. $mobile_device_number = '';
  1059. $mobile_os = ''; // will usually be null, sorry
  1060. $mobile_os_number = '';
  1061. $mobile_server = '';
  1062. $mobile_server_number = '';
  1063. // browsers, show it as a handheld, but is not the os
  1064. $a_mobile_browser = array( 'avantgo', 'blazer', 'elaine', 'eudoraweb', 'iemobile', 'minimo', 'mobile safari', 'mobileexplorer', 'opera mobi', 'opera mini', 'netfront', 'opwv', 'polaris', 'semc-browser', 'up.browser', 'webpro', 'wms pie', 'xiino' );
  1065. /*
  1066. This goes from easiest to detect to hardest, so don't use this for output unless you
  1067. clean it up more is my advice.
  1068. Special Notes: do not include milestone in general mobile type test above, it's too generic
  1069. */
  1070. $a_mobile_device = array( 'benq', 'blackberry', 'danger hiptop', 'ddipocket', ' droid', 'htc_dream', 'htc espresso', 'htc hero', 'htc halo', 'htc huangshan', 'htc legend', 'htc liberty', 'htc paradise', 'htc supersonic', 'htc tattoo', 'ipad', 'ipod', 'iphone', 'kindle', 'lge-cx', 'lge-lx', 'lge-mx', 'lge vx', 'lg;lx', 'nintendo wii', 'nokia', 'palm', 'pdxgw', 'playstation', 'sagem', 'samsung', 'sec-sgh', 'sharp', 'sonyericsson', 'sprint', 'zunehd', 'zune', 'j-phone', 'milestone', 'n410', 'mot 24', 'mot-', 'htc-', 'htc_', 'htc ', 'lge ', 'lge-', 'sec-', 'sie-m', 'sie-s', 'spv ', 'smartphone', 'armv', 'midp', 'mobilephone' );
  1071. /*
  1072. note: linux alone can't be searched for, and almost all linux devices are armv types
  1073. ipad 'cpu os' is how the real os number is handled
  1074. */
  1075. $a_mobile_os = array( 'android', 'epoc', 'cpu os', 'iphone os', 'palmos', 'palmsource', 'windows phone os', 'windows ce', 'symbianos', 'symbian os', 'symbian', 'webos', 'linux armv' );
  1076. // sometimes there is just no other id for the unit that the CTS type service/server
  1077. $a_mobile_server = array( 'astel', 'docomo', 'novarra-vision', 'portalmmm', 'reqwirelessweb', 'vodafone' );
  1078. $k_count = count( $a_mobile_browser );
  1079. for ( $k = 0; $k < $k_count; $k++ )
  1080. {
  1081. if ( strstr( $pv_browser_user_agent, $a_mobile_browser[$k] ) )
  1082. {
  1083. $mobile_browser = $a_mobile_browser[$k];
  1084. // this may or may not work, highly unreliable because mobile ua strings are random
  1085. $mobile_browser_number = get_item_version( $pv_browser_user_agent, $mobile_browser );
  1086. break;
  1087. }
  1088. }
  1089. $k_count = count( $a_mobile_device );
  1090. for ( $k = 0; $k < $k_count; $k++ )
  1091. {
  1092. if ( strstr( $pv_browser_user_agent, $a_mobile_device[$k] ) )
  1093. {
  1094. $mobile_device = trim ( $a_mobile_device[$k], '-_' ); // but not space trims yet
  1095. if ( $mobile_device == 'blackberry' )
  1096. {
  1097. get_set_count( 'set', 0 );
  1098. }
  1099. $mobile_device_number = get_item_version( $pv_browser_user_agent, $mobile_device );
  1100. $mobile_device = trim( $mobile_device ); // some of the id search strings have white space
  1101. break;
  1102. }
  1103. }
  1104. $k_count = count( $a_mobile_os );
  1105. for ( $k = 0; $k < $k_count; $k++ )
  1106. {
  1107. if ( strstr( $pv_browser_user_agent, $a_mobile_os[$k] ) )
  1108. {
  1109. $mobile_os = $a_mobile_os[$k];
  1110. // this may or may not work, highly unreliable
  1111. $mobile_os_number = str_replace( '_', '.', get_item_version( $pv_browser_user_agent, $mobile_os ) );
  1112. break;
  1113. }
  1114. }
  1115. $k_count = count( $a_mobile_server );
  1116. for ( $k = 0; $k < $k_count; $k++ )
  1117. {
  1118. if ( strstr( $pv_browser_user_agent, $a_mobile_server[$k] ) )
  1119. {
  1120. $mobile_server = $a_mobile_server[$k];
  1121. // this may or may not work, highly unreliable
  1122. $mobile_server_number = get_item_version( $pv_browser_user_agent, $mobile_server );
  1123. break;
  1124. }
  1125. }
  1126. // just for cases where we know it's a mobile device already
  1127. if ( !$mobile_os && ( $mobile_browser || $mobile_device || $mobile_server ) && strstr( $pv_browser_user_agent, 'linux' ) )
  1128. {
  1129. $mobile_os = 'linux';
  1130. $mobile_os_number = get_item_version( $pv_browser_user_agent, 'linux' );
  1131. }
  1132. $a_mobile_data = array( $mobile_device, $mobile_browser, $mobile_browser_number, $mobile_os, $mobile_os_number, $mobile_server, $mobile_server_number, $mobile_device_number );
  1133. return $a_mobile_data;
  1134. }
  1135. // track total script execution time
  1136. function script_time()
  1137. {
  1138. static $script_time;
  1139. $elapsed_time = '';
  1140. /*
  1141. note that microtime(true) requires php 5 or greater for microtime(true)
  1142. */
  1143. if ( sprintf("%01.1f", phpversion() ) >= 5 ) {
  1144. if ( is_null( $script_time) ) {
  1145. $script_time = microtime(true);
  1146. }
  1147. else {
  1148. // note: (string)$var is same as strval($var)
  1149. // $elapsed_time = (string)( microtime(true) - $script_time );
  1150. $elapsed_time = ( microtime(true) - $script_time );
  1151. $elapsed_time = sprintf("%01.8f", $elapsed_time );
  1152. $script_time = NULL; // can't unset a static variable
  1153. return $elapsed_time;
  1154. }
  1155. }
  1156. }
  1157. /*
  1158. Here are some navigator.userAgent strings so you can see where the data comes from
  1159. UserAgent Data:
  1160. Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; User-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; http://bsalsa.com) ; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30618)
  1161. Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7 (.NET CLR 3.5.30729)
  1162. Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.5) Gecko/20031007 Firebird/0.7
  1163. Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.4) Gecko/20011128 Net…

Large files files are truncated, but you can click here to view the full file