PageRenderTime 58ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/jetpack/class.jetpack-user-agent.php

https://github.com/arimado/smh-wp-2
PHP | 1376 lines | 885 code | 201 blank | 290 comment | 265 complexity | b0e01888f3147516b004ce8f3b57538f MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0
  1. <?php
  2. function jetpack_is_mobile( $kind = 'any', $return_matched_agent = false ) {
  3. static $kinds = array( 'smart' => false, 'dumb' => false, 'any' => false );
  4. static $first_run = true;
  5. static $matched_agent = '';
  6. $ua_info = new Jetpack_User_Agent_Info();
  7. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) || strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'ipad' ) )
  8. return false;
  9. if( $ua_info->is_android_tablet() && $ua_info->is_kindle_touch() === false )
  10. return false;
  11. if( $ua_info->is_blackberry_tablet() )
  12. return false;
  13. if ( $first_run ) {
  14. $first_run = false;
  15. //checks for iPhoneTier devices & RichCSS devices
  16. if ( $ua_info->isTierIphone() || $ua_info->isTierRichCSS() ) {
  17. $kinds['smart'] = true;
  18. $matched_agent = $ua_info->matched_agent;
  19. }
  20. if ( !$kinds['smart'] ) {
  21. // if smart, we are not dumb so no need to check
  22. $dumb_agents = $ua_info->dumb_agents;
  23. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  24. foreach ( $dumb_agents as $dumb_agent ) {
  25. if ( false !== strpos( $agent, $dumb_agent ) ) {
  26. $kinds['dumb'] = true;
  27. $matched_agent = $dumb_agent;
  28. break;
  29. }
  30. }
  31. if ( !$kinds['dumb'] ) {
  32. if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
  33. $kinds['dumb'] = true;
  34. $matched_agent = 'http_x_wap_profile';
  35. } elseif ( isset( $_SERVER['HTTP_ACCEPT']) && ( preg_match( '/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'] ) || false !== strpos( strtolower( $_SERVER['HTTP_ACCEPT'] ), 'application/vnd.wap.xhtml+xml' ) ) ) {
  36. $kinds['dumb'] = true;
  37. $matched_agent = 'vnd.wap.xhtml+xml';
  38. }
  39. }
  40. }
  41. if ( $kinds['dumb'] || $kinds['smart'] )
  42. $kinds['any'] = true;
  43. }
  44. if ( $return_matched_agent )
  45. return $matched_agent;
  46. return $kinds[$kind];
  47. }
  48. class Jetpack_User_Agent_Info {
  49. var $useragent;
  50. var $matched_agent;
  51. var $isTierIphone; //Stores whether is the iPhone tier of devices.
  52. var $isTierRichCss; //Stores whether the device can probably support Rich CSS, but JavaScript (jQuery) support is not assumed.
  53. var $isTierGenericMobile; //Stores whether it is another mobile device, which cannot be assumed to support CSS or JS (eg, older BlackBerry, RAZR)
  54. private $_platform = null; //Stores the device platform name
  55. const PLATFORM_WINDOWS = 'windows';
  56. const PLATFORM_IPHONE = 'iphone';
  57. const PLATFORM_IPOD = 'ipod';
  58. const PLATFORM_IPAD = 'ipad';
  59. const PLATFORM_BLACKBERRY = 'blackberry';
  60. const PLATFORM_BLACKBERRY_10 = 'blackberry_10';
  61. const PLATFORM_SYMBIAN = 'symbian_series60';
  62. const PLATFORM_SYMBIAN_S40 = 'symbian_series40';
  63. const PLATFORM_J2ME_MIDP = 'j2me_midp';
  64. const PLATFORM_ANDROID = 'android';
  65. const PLATFORM_ANDROID_TABLET = 'android_tablet';
  66. const PLATFORM_FIREFOX_OS = 'firefoxOS';
  67. var $dumb_agents = array(
  68. 'nokia', 'blackberry', 'philips', 'samsung', 'sanyo', 'sony', 'panasonic', 'webos',
  69. 'ericsson', 'alcatel', 'palm',
  70. 'windows ce', 'opera mini', 'series60', 'series40',
  71. 'au-mic,', 'audiovox', 'avantgo', 'blazer',
  72. 'danger', 'docomo', 'epoc',
  73. 'ericy', 'i-mode', 'ipaq', 'midp-',
  74. 'mot-', 'netfront', 'nitro',
  75. 'palmsource', 'pocketpc', 'portalmmm',
  76. 'rover', 'sie-',
  77. 'symbian', 'cldc-', 'j2me',
  78. 'smartphone', 'up.browser', 'up.link',
  79. 'up.link', 'vodafone/', 'wap1.', 'wap2.', 'mobile', 'googlebot-mobile',
  80. );
  81. //The constructor. Initializes default variables.
  82. function Jetpack_User_Agent_Info()
  83. {
  84. if ( !empty( $_SERVER['HTTP_USER_AGENT'] ) )
  85. $this->useragent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  86. }
  87. /**
  88. * This method detects the mobile User Agent name.
  89. *
  90. * @return string The matched User Agent name, false otherwise.
  91. */
  92. function get_mobile_user_agent_name() {
  93. if( $this->is_chrome_for_iOS( ) ) //keep this check before the safari rule
  94. return 'chrome-for-ios';
  95. elseif ( $this->is_iphone_or_ipod( 'iphone-safari' ) )
  96. return 'iphone';
  97. elseif ( $this->is_ipad( 'ipad-safari' ) )
  98. return 'ipad';
  99. elseif ( $this->is_android_tablet() ) //keep this check before the android rule
  100. return 'android_tablet';
  101. elseif ( $this->is_android() )
  102. return 'android';
  103. elseif ( $this->is_blackberry_10() )
  104. return 'blackberry_10';
  105. elseif ( $this->is_blackbeberry() )
  106. return 'blackberry';
  107. elseif ( $this->is_WindowsPhone7() )
  108. return 'win7';
  109. elseif ( $this->is_windows_phone_8() )
  110. return 'winphone8';
  111. elseif ( $this->is_opera_mini() )
  112. return 'opera-mini';
  113. elseif ( $this->is_opera_mini_dumb() )
  114. return 'opera-mini-dumb';
  115. elseif ( $this->is_opera_mobile() )
  116. return 'opera-mobi';
  117. elseif ( $this->is_blackberry_tablet() )
  118. return 'blackberry_tablet';
  119. elseif ( $this->is_kindle_fire() )
  120. return 'kindle-fire';
  121. elseif ( $this->is_PalmWebOS() )
  122. return 'webos';
  123. elseif ( $this->is_S60_OSSBrowser() )
  124. return 'series60';
  125. elseif ( $this->is_firefox_os() )
  126. return 'firefoxOS';
  127. elseif ( $this->is_firefox_mobile() )
  128. return 'firefox_mobile';
  129. elseif ( $this->is_MaemoTablet() )
  130. return 'maemo';
  131. elseif ( $this->is_MeeGo() )
  132. return 'meego';
  133. elseif( $this->is_TouchPad() )
  134. return 'hp_tablet';
  135. elseif ( $this->is_facebook_for_iphone() )
  136. return 'facebook-for-iphone';
  137. elseif ( $this->is_facebook_for_ipad() )
  138. return 'facebook-for-ipad';
  139. elseif ( $this->is_twitter_for_iphone() )
  140. return 'twitter-for-iphone';
  141. elseif ( $this->is_twitter_for_ipad() )
  142. return 'twitter-for-ipad';
  143. elseif ( $this->is_wordpress_for_ios() )
  144. return 'ios-app';
  145. elseif ( $this->is_iphone_or_ipod( 'iphone-not-safari' ) )
  146. return 'iphone-unknown';
  147. elseif ( $this->is_ipad( 'ipad-not-safari' ) )
  148. return 'ipad-unknown';
  149. else {
  150. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  151. $dumb_agents = $this->dumb_agents;
  152. foreach ( $dumb_agents as $dumb_agent ) {
  153. if ( false !== strpos( $agent, $dumb_agent ) ) {
  154. return $dumb_agent;
  155. }
  156. }
  157. }
  158. return false;
  159. }
  160. /**
  161. * This method detects the mobile device's platform. All return strings are from the class constants.
  162. * Note that this function returns the platform name, not the UA name/type. You should use a different function
  163. * if you need to test the UA capabilites.
  164. *
  165. * @return string Name of the platform, false otherwise.
  166. */
  167. public function get_platform() {
  168. if ( isset( $this->_platform ) ) {
  169. return $this->_platform;
  170. }
  171. if ( strpos( $this->useragent, 'windows phone' ) !== false ) {
  172. $this->_platform = self::PLATFORM_WINDOWS;
  173. }
  174. elseif ( strpos( $this->useragent, 'windows ce' ) !== false ) {
  175. $this->_platform = self::PLATFORM_WINDOWS;
  176. }
  177. elseif ( strpos( $this->useragent, 'ipad' ) !== false ) {
  178. $this->_platform = self::PLATFORM_IPAD;
  179. }
  180. else if ( strpos( $this->useragent, 'ipod' ) !== false ) {
  181. $this->_platform = self::PLATFORM_IPOD;
  182. }
  183. else if ( strpos( $this->useragent, 'iphone' ) !== false ) {
  184. $this->_platform = self::PLATFORM_IPHONE;
  185. }
  186. elseif ( strpos( $this->useragent, 'android' ) !== false ) {
  187. if ( $this->is_android_tablet() )
  188. $this->_platform = self::PLATFORM_ANDROID_TABLET;
  189. else
  190. $this->_platform = self::PLATFORM_ANDROID;
  191. }
  192. elseif ( $this->is_kindle_fire() ) {
  193. $this->_platform = self::PLATFORM_ANDROID_TABLET;
  194. }
  195. elseif ( $this->is_blackberry_10() ) {
  196. $this->_platform = self::PLATFORM_BLACKBERRY_10;
  197. }
  198. elseif ( strpos( $this->useragent, 'blackberry' ) !== false ) {
  199. $this->_platform = self::PLATFORM_BLACKBERRY;
  200. }
  201. elseif ( $this->is_blackberry_tablet() ) {
  202. $this->_platform = self::PLATFORM_BLACKBERRY;
  203. }
  204. elseif ( $this->is_symbian_platform() ) {
  205. $this->_platform = self::PLATFORM_SYMBIAN;
  206. }
  207. elseif ( $this->is_symbian_s40_platform() ) {
  208. $this->_platform = self::PLATFORM_SYMBIAN_S40;
  209. }
  210. elseif ( $this->is_J2ME_platform() ) {
  211. $this->_platform = self::PLATFORM_J2ME_MIDP;
  212. }
  213. elseif ( $this->is_firefox_os() ) {
  214. $this->_platform = self::PLATFORM_FIREFOX_OS;
  215. }
  216. else
  217. $this->_platform = false;
  218. return $this->_platform;
  219. }
  220. /*
  221. * This method detects for UA which can display iPhone-optimized web content.
  222. * Includes iPhone, iPod Touch, Android, WebOS, Fennec (Firefox mobile), etc.
  223. *
  224. */
  225. function isTierIphone() {
  226. if ( isset( $this->isTierIphone ) ) {
  227. return $this->isTierIphone;
  228. }
  229. if ( $this->is_iphoneOrIpod() ) {
  230. $this->matched_agent = 'iphone';
  231. $this->isTierIphone = true;
  232. $this->isTierRichCss = false;
  233. $this->isTierGenericMobile = false;
  234. }
  235. elseif ( $this->is_android() ) {
  236. $this->matched_agent = 'android';
  237. $this->isTierIphone = true;
  238. $this->isTierRichCss = false;
  239. $this->isTierGenericMobile = false;
  240. }
  241. elseif ( $this->is_windows_phone_8() ) {
  242. $this->matched_agent = 'winphone8';
  243. $this->isTierIphone = true;
  244. $this->isTierRichCss = false;
  245. $this->isTierGenericMobile = false;
  246. }
  247. elseif ( $this->is_WindowsPhone7() ) {
  248. $this->matched_agent = 'win7';
  249. $this->isTierIphone = true;
  250. $this->isTierRichCss = false;
  251. $this->isTierGenericMobile = false;
  252. }
  253. elseif ( $this->is_blackberry_10() ) {
  254. $this->matched_agent = 'blackberry-10';
  255. $this->isTierIphone = true;
  256. $this->isTierRichCss = false;
  257. $this->isTierGenericMobile = false;
  258. }
  259. elseif ( $this->is_blackbeberry() && $this->detect_blackberry_browser_version() == 'blackberry-webkit' ) {
  260. $this->matched_agent = 'blackberry-webkit';
  261. $this->isTierIphone = true;
  262. $this->isTierRichCss = false;
  263. $this->isTierGenericMobile = false;
  264. }
  265. elseif ( $this->is_blackberry_tablet() ) {
  266. $this->matched_agent = 'blackberry_tablet';
  267. $this->isTierIphone = true;
  268. $this->isTierRichCss = false;
  269. $this->isTierGenericMobile = false;
  270. }
  271. elseif ( $this->is_PalmWebOS() ) {
  272. $this->matched_agent = 'webos';
  273. $this->isTierIphone = true;
  274. $this->isTierRichCss = false;
  275. $this->isTierGenericMobile = false;
  276. }
  277. elseif ( $this->is_TouchPad() ) {
  278. $this->matched_agent = 'hp_tablet';
  279. $this->isTierIphone = true;
  280. $this->isTierRichCss = false;
  281. $this->isTierGenericMobile = false;
  282. }
  283. elseif ( $this->is_firefox_os() ) {
  284. $this->matched_agent = 'firefoxOS';
  285. $this->isTierIphone = true;
  286. $this->isTierRichCss = false;
  287. $this->isTierGenericMobile = false;
  288. }
  289. elseif ( $this->is_firefox_mobile() ) {
  290. $this->matched_agent = 'fennec';
  291. $this->isTierIphone = true;
  292. $this->isTierRichCss = false;
  293. $this->isTierGenericMobile = false;
  294. }
  295. elseif ( $this->is_opera_mobile() ) {
  296. $this->matched_agent = 'opera-mobi';
  297. $this->isTierIphone = true;
  298. $this->isTierRichCss = false;
  299. $this->isTierGenericMobile = false;
  300. }
  301. elseif ( $this->is_MaemoTablet() ) {
  302. $this->matched_agent = 'maemo';
  303. $this->isTierIphone = true;
  304. $this->isTierRichCss = false;
  305. $this->isTierGenericMobile = false;
  306. }
  307. elseif ( $this->is_MeeGo() ) {
  308. $this->matched_agent = 'meego';
  309. $this->isTierIphone = true;
  310. $this->isTierRichCss = false;
  311. $this->isTierGenericMobile = false;
  312. }
  313. elseif ( $this->is_kindle_touch() ) {
  314. $this->matched_agent = 'kindle-touch';
  315. $this->isTierIphone = true;
  316. $this->isTierRichCss = false;
  317. $this->isTierGenericMobile = false;
  318. }
  319. else {
  320. $this->isTierIphone = false;
  321. }
  322. return $this->isTierIphone;
  323. }
  324. /*
  325. * This method detects for UA which are likely to be capable
  326. * but may not necessarily support JavaScript.
  327. * Excludes all iPhone Tier UA.
  328. *
  329. */
  330. function isTierRichCss(){
  331. if ( isset( $this->isTierRichCss ) ) {
  332. return $this->isTierRichCss;
  333. }
  334. if ($this->isTierIphone())
  335. return false;
  336. //The following devices are explicitly ok.
  337. if ( $this->is_S60_OSSBrowser() ) {
  338. $this->matched_agent = 'series60';
  339. $this->isTierIphone = false;
  340. $this->isTierRichCss = true;
  341. $this->isTierGenericMobile = false;
  342. }
  343. elseif ( $this->is_opera_mini() ) {
  344. $this->matched_agent = 'opera-mini';
  345. $this->isTierIphone = false;
  346. $this->isTierRichCss = true;
  347. $this->isTierGenericMobile = false;
  348. }
  349. elseif ( $this->is_blackbeberry() ) {
  350. $detectedDevice = $this->detect_blackberry_browser_version();
  351. if ( $detectedDevice === 'blackberry-5' || $detectedDevice == 'blackberry-4.7' || $detectedDevice === 'blackberry-4.6' ) {
  352. $this->matched_agent = $detectedDevice;
  353. $this->isTierIphone = false;
  354. $this->isTierRichCss = true;
  355. $this->isTierGenericMobile = false;
  356. }
  357. }
  358. else {
  359. $this->isTierRichCss = false;
  360. }
  361. return $this->isTierRichCss;
  362. }
  363. // Detects if the user is using a tablet.
  364. // props Corey Gilmore, BGR.com
  365. static function is_tablet() {
  366. return ( 0 // never true, but makes it easier to manage our list of tablet conditions
  367. || self::is_ipad()
  368. || self::is_android_tablet()
  369. || self::is_blackberry_tablet()
  370. || self::is_kindle_fire()
  371. || self::is_MaemoTablet()
  372. || self::is_TouchPad()
  373. );
  374. }
  375. /*
  376. * Detects if the current UA is the default iPhone or iPod Touch Browser.
  377. *
  378. * DEPRECATED: use is_iphone_or_ipod
  379. *
  380. */
  381. static function is_iphoneOrIpod(){
  382. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  383. return false;
  384. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  385. if ( ( strpos( $ua, 'iphone' ) !== false ) || ( strpos( $ua,'ipod' ) !== false ) ) {
  386. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  387. return false;
  388. else
  389. return true;
  390. }
  391. else
  392. return false;
  393. }
  394. /*
  395. * Detects if the current UA is iPhone Mobile Safari or another iPhone or iPod Touch Browser.
  396. *
  397. * They type can check for any iPhone, an iPhone using Safari, or an iPhone using something other than Safari.
  398. *
  399. * Note: If you want to check for Opera mini, Opera mobile or Firefox mobile (or any 3rd party iPhone browser),
  400. * you should put the check condition before the check for 'iphone-any' or 'iphone-not-safari'.
  401. * Otherwise those browsers will be 'catched' by the iphone string.
  402. *
  403. */
  404. static function is_iphone_or_ipod( $type = 'iphone-any' ) {
  405. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  406. return false;
  407. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  408. $is_iphone = ( strpos( $ua, 'iphone' ) !== false ) || ( strpos( $ua,'ipod' ) !== false );
  409. $is_safari = ( false !== strpos( $ua, 'safari' ) );
  410. if ( 'iphone-safari' == $type )
  411. return $is_iphone && $is_safari;
  412. elseif ( 'iphone-not-safari' == $type )
  413. return $is_iphone && !$is_safari;
  414. else
  415. return $is_iphone;
  416. }
  417. /*
  418. * Detects if the current UA is Chrome for iOS
  419. *
  420. * The User-Agent string in Chrome for iOS is the same as the Mobile Safari User-Agent, with CriOS/<ChromeRevision> instead of Version/<VersionNum>.
  421. * - Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3
  422. */
  423. static function is_chrome_for_iOS( ) {
  424. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  425. return false;
  426. if ( self::is_iphone_or_ipod( 'iphone-safari' ) === false ) return false;
  427. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  428. if ( strpos( $ua, 'crios/' ) !== false )
  429. return true;
  430. else
  431. return false;
  432. }
  433. /*
  434. * Detects if the current UA is Twitter for iPhone
  435. *
  436. * Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_5 like Mac OS X; nb-no) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8L1 Twitter for iPhone
  437. * Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Twitter for iPhone
  438. *
  439. */
  440. static function is_twitter_for_iphone( ) {
  441. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  442. return false;
  443. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  444. if ( strpos( $ua, 'ipad' ) !== false )
  445. return false;
  446. if ( strpos( $ua, 'twitter for iphone' ) !== false )
  447. return true;
  448. else
  449. return false;
  450. }
  451. /*
  452. * Detects if the current UA is Twitter for iPad
  453. *
  454. * Old version 4.X - Mozilla/5.0 (iPad; U; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8L1 Twitter for iPad
  455. * Ver 5.0 or Higher - Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 Twitter for iPhone
  456. *
  457. */
  458. static function is_twitter_for_ipad( ) {
  459. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  460. return false;
  461. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  462. if ( strpos( $ua, 'twitter for ipad' ) !== false )
  463. return true;
  464. elseif( strpos( $ua, 'ipad' ) !== false && strpos( $ua, 'twitter for iphone' ) !== false )
  465. return true;
  466. else
  467. return false;
  468. }
  469. /*
  470. * Detects if the current UA is Facebook for iPhone
  471. * - Facebook 4020.0 (iPhone; iPhone OS 5.0.1; fr_FR)
  472. * - Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_0 like Mac OS X; en_US) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.0;FBSS/2; FBCR/O2;FBID/phone;FBLC/en_US;FBSF/2.0]
  473. * - Mozilla/5.0 (iPhone; CPU iPhone OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9B206 [FBAN/FBIOS;FBAV/5.0;FBBV/47423;FBDV/iPhone3,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/5.1.1;FBSS/2; FBCR/3ITA;FBID/phone;FBLC/en_US]
  474. */
  475. static function is_facebook_for_iphone( ) {
  476. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  477. return false;
  478. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  479. if( strpos( $ua, 'iphone' ) === false )
  480. return false;
  481. if ( strpos( $ua, 'facebook' ) !== false && strpos( $ua, 'ipad' ) === false )
  482. return true;
  483. else if ( strpos( $ua, 'fbforiphone' ) !== false && strpos( $ua, 'tablet' ) === false )
  484. return true;
  485. else if ( strpos( $ua, 'fban/fbios;' ) !== false && strpos( $ua, 'tablet' ) === false ) //FB app v5.0 or higher
  486. return true;
  487. else
  488. return false;
  489. }
  490. /*
  491. * Detects if the current UA is Facebook for iPad
  492. * - Facebook 4020.0 (iPad; iPhone OS 5.0.1; en_US)
  493. * - Mozilla/5.0 (iPad; U; CPU iPhone OS 5_0 like Mac OS X; en_US) AppleWebKit (KHTML, like Gecko) Mobile [FBAN/FBForIPhone;FBAV/4.0.2;FBBV/4020.0;FBDV/iPad2,1;FBMD/iPad;FBSN/iPhone OS;FBSV/5.0;FBSS/1; FBCR/;FBID/tablet;FBLC/en_US;FBSF/1.0]
  494. * - Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10A403 [FBAN/FBIOS;FBAV/5.0;FBBV/47423;FBDV/iPad2,1;FBMD/iPad;FBSN/iPhone OS;FBSV/6.0;FBSS/1; FBCR/;FBID/tablet;FBLC/en_US]
  495. */
  496. static function is_facebook_for_ipad( ) {
  497. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  498. return false;
  499. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  500. if ( strpos( $ua, 'ipad' ) === false )
  501. return false;
  502. if ( strpos( $ua, 'facebook' ) !== false || strpos( $ua, 'fbforiphone' ) !== false || strpos( $ua, 'fban/fbios;' ) !== false )
  503. return true;
  504. else
  505. return false;
  506. }
  507. /*
  508. * Detects if the current UA is WordPress for iOS
  509. */
  510. static function is_wordpress_for_ios( ) {
  511. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  512. return false;
  513. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  514. if ( strpos( $ua, 'wp-iphone' ) !== false )
  515. return true;
  516. else
  517. return false;
  518. }
  519. /*
  520. * Detects if the current device is an iPad.
  521. * They type can check for any iPad, an iPad using Safari, or an iPad using something other than Safari.
  522. *
  523. * Note: If you want to check for Opera mini, Opera mobile or Firefox mobile (or any 3rd party iPad browser),
  524. * you should put the check condition before the check for 'iphone-any' or 'iphone-not-safari'.
  525. * Otherwise those browsers will be 'catched' by the ipad string.
  526. *
  527. */
  528. static function is_ipad( $type = 'ipad-any' ) {
  529. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  530. return false;
  531. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  532. $is_ipad = ( false !== strpos( $ua, 'ipad' ) );
  533. $is_safari = ( false !== strpos( $ua, 'safari' ) );
  534. if ( 'ipad-safari' == $type )
  535. return $is_ipad && $is_safari;
  536. elseif ( 'ipad-not-safari' == $type )
  537. return $is_ipad && !$is_safari;
  538. else
  539. return $is_ipad;
  540. }
  541. /*
  542. * Detects if the current browser is Firefox Mobile (Fennec)
  543. *
  544. * http://www.useragentstring.com/pages/Fennec/
  545. * Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.1.1) Gecko/20110415 Firefox/4.0.2pre Fennec/4.0.1
  546. * Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1
  547. */
  548. static function is_firefox_mobile( ) {
  549. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  550. return false;
  551. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  552. if ( strpos( $ua, 'fennec' ) !== false )
  553. return true;
  554. else
  555. return false;
  556. }
  557. /*
  558. * Detects if the current browser is FirefoxOS Native browser
  559. *
  560. * Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
  561. *
  562. */
  563. static function is_firefox_os( ) {
  564. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  565. return false;
  566. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  567. if ( strpos( $ua, 'mozilla' ) !== false && strpos( $ua, 'mobile' ) !== false && strpos( $ua, 'gecko' ) !== false && strpos( $ua, 'firefox' ) !== false)
  568. return true;
  569. else
  570. return false;
  571. }
  572. /*
  573. * Detects if the current browser is Opera Mobile
  574. *
  575. * What is the difference between Opera Mobile and Opera Mini?
  576. * - Opera Mobile is a full Internet browser for mobile devices.
  577. * - Opera Mini always uses a transcoder to convert the page for a small display.
  578. * (it uses Opera advanced server compression technology to compress web content before it gets to a device.
  579. * The rendering engine is on Opera's server.)
  580. *
  581. * Opera/9.80 (Windows NT 6.1; Opera Mobi/14316; U; en) Presto/2.7.81 Version/11.00"
  582. */
  583. static function is_opera_mobile( ) {
  584. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  585. return false;
  586. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  587. if ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'mobi' ) !== false )
  588. return true;
  589. else
  590. return false;
  591. }
  592. /*
  593. * Detects if the current browser is Opera Mini
  594. *
  595. * Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
  596. * Opera/9.80 (Android;Opera Mini/6.0.24212/24.746 U;en) Presto/2.5.25 Version/10.5454
  597. * Opera/9.80 (iPhone; Opera Mini/5.0.019802/18.738; U; en) Presto/2.4.15
  598. * Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja) Presto/2.4.15
  599. * Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja) Presto/2.4.15
  600. * Opera/9.80 (Series 60; Opera Mini/5.1.22783/23.334; U; en) Presto/2.5.25 Version/10.54
  601. * Opera/9.80 (BlackBerry; Opera Mini/5.1.22303/22.387; U; en) Presto/2.5.25 Version/10.54
  602. *
  603. */
  604. static function is_opera_mini( ) {
  605. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  606. return false;
  607. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  608. if ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'mini' ) !== false )
  609. return true;
  610. else
  611. return false;
  612. }
  613. /*
  614. * Detects if the current browser is Opera Mini, but not on a smart device OS(Android, iOS, etc)
  615. * Used to send users on dumb devices to m.wor
  616. */
  617. static function is_opera_mini_dumb( ) {
  618. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  619. return false;
  620. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  621. if ( self::is_opera_mini() ) {
  622. if ( strpos( $ua, 'android' ) !== false || strpos( $ua, 'iphone' ) !== false || strpos( $ua, 'ipod' ) !== false
  623. || strpos( $ua, 'ipad' ) !== false || strpos( $ua, 'blackberry' ) !== false)
  624. return false;
  625. else
  626. return true;
  627. } else {
  628. return false;
  629. }
  630. }
  631. /*
  632. * Detects if the current browser is Opera Mobile or Mini.
  633. * DEPRECATED: use is_opera_mobile or is_opera_mini
  634. *
  635. * Opera Mini 5 Beta: Opera/9.80 (J2ME/MIDP; Opera Mini/5.0.15650/756; U; en) Presto/2.2.0
  636. * Opera Mini 8: Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
  637. */
  638. static function is_OperaMobile() {
  639. _deprecated_function( __FUNCTION__, 'always', 'is_opera_mini() or is_opera_mobile()' );
  640. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  641. return false;
  642. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  643. if ( strpos( $ua, 'opera' ) !== false ) {
  644. if ( ( strpos( $ua, 'mini' ) !== false ) || ( strpos( $ua,'mobi' ) !== false ) )
  645. return true;
  646. else
  647. return false;
  648. } else {
  649. return false;
  650. }
  651. }
  652. /*
  653. * Detects if the current browser is a Windows Phone 7 device.
  654. * ex: Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; LG; GW910)
  655. */
  656. static function is_WindowsPhone7() {
  657. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  658. return false;
  659. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  660. if ( strpos( $ua, 'windows phone os 7' ) === false ) {
  661. return false;
  662. } else {
  663. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  664. return false;
  665. else
  666. return true;
  667. }
  668. }
  669. /*
  670. * Detects if the current browser is a Windows Phone 8 device.
  671. * ex: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; Touch; IEMobile/10.0; <Manufacturer>; <Device> [;<Operator>])
  672. */
  673. static function is_windows_phone_8() {
  674. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  675. return false;
  676. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  677. if ( strpos( $ua, 'windows phone 8' ) === false ) {
  678. return false;
  679. } else {
  680. return true;
  681. }
  682. }
  683. /*
  684. * Detects if the current browser is on a Palm device running the new WebOS. This EXCLUDES TouchPad.
  685. *
  686. * ex1: Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pre/1.1
  687. * ex2: Mozilla/5.0 (webOS/1.4.0; U; en-US) AppleWebKit/532.2 (KHTML, like Gecko) Version/1.0 Safari/532.2 Pixi/1.1
  688. *
  689. */
  690. static function is_PalmWebOS() {
  691. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  692. return false;
  693. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  694. if ( strpos( $ua, 'webos' ) === false ) {
  695. return false;
  696. } else {
  697. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  698. return false;
  699. else
  700. return true;
  701. }
  702. }
  703. /*
  704. * Detects if the current browser is the HP TouchPad default browser. This excludes phones wt WebOS.
  705. *
  706. * TouchPad Emulator: Mozilla/5.0 (hp-desktop; Linux; hpwOS/2.0; U; it-IT) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 Desktop/1.0
  707. * TouchPad: Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0
  708. *
  709. */
  710. static function is_TouchPad() {
  711. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  712. return false;
  713. $http_user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  714. if ( false !== strpos( $http_user_agent, 'hp-tablet' ) || false !== strpos( $http_user_agent, 'hpwos' ) || false !== strpos( $http_user_agent, 'touchpad' ) ) {
  715. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  716. return false;
  717. else
  718. return true;
  719. }
  720. else
  721. return false;
  722. }
  723. /*
  724. * Detects if the current browser is the Series 60 Open Source Browser.
  725. *
  726. * OSS Browser 3.2 on E75: Mozilla/5.0 (SymbianOS/9.3; U; Series60/3.2 NokiaE75-1/110.48.125 Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
  727. *
  728. * 7.0 Browser (Nokia 5800 XpressMusic (v21.0.025)) : Mozilla/5.0 (SymbianOS/9.4; U; Series60/5.0 Nokia5800d-1/21.0.025; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
  729. *
  730. * Browser 7.1 (Nokia N97 (v12.0.024)) : Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/12.0.024; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.12344
  731. *
  732. */
  733. static function is_S60_OSSBrowser() {
  734. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  735. return false;
  736. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  737. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  738. return false;
  739. $pos_webkit = strpos( $agent, 'webkit' );
  740. if ( $pos_webkit !== false ) {
  741. //First, test for WebKit, then make sure it's either Symbian or S60.
  742. if ( strpos( $agent, 'symbian' ) !== false || strpos( $agent, 'series60' ) !== false ) {
  743. return true;
  744. } else
  745. return false;
  746. } elseif ( strpos( $agent, 'symbianos' ) !== false && strpos( $agent,'series60' ) !== false ) {
  747. return true;
  748. } elseif ( strpos( $agent, 'nokia' ) !== false && strpos( $agent,'series60' ) !== false ) {
  749. return true;
  750. }
  751. return false;
  752. }
  753. /*
  754. *
  755. * Detects if the device platform is the Symbian Series 60.
  756. *
  757. */
  758. static function is_symbian_platform() {
  759. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  760. return false;
  761. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  762. $pos_webkit = strpos( $agent, 'webkit' );
  763. if ( $pos_webkit !== false ) {
  764. //First, test for WebKit, then make sure it's either Symbian or S60.
  765. if ( strpos( $agent, 'symbian' ) !== false || strpos( $agent, 'series60' ) !== false ) {
  766. return true;
  767. } else
  768. return false;
  769. } elseif ( strpos( $agent, 'symbianos' ) !== false && strpos( $agent,'series60' ) !== false ) {
  770. return true;
  771. } elseif ( strpos( $agent, 'nokia' ) !== false && strpos( $agent,'series60' ) !== false ) {
  772. return true;
  773. } elseif ( strpos( $agent, 'opera mini' ) !== false ) {
  774. if( strpos( $agent,'symbianos' ) !== false || strpos( $agent,'symbos' ) !== false || strpos( $agent,'series 60' ) !== false )
  775. return true;
  776. }
  777. return false;
  778. }
  779. /*
  780. *
  781. * Detects if the device platform is the Symbian Series 40.
  782. * Nokia Browser for Series 40 is a proxy based browser, previously known as Ovi Browser.
  783. * This browser will report 'NokiaBrowser' in the header, however some older version will also report 'OviBrowser'.
  784. *
  785. */
  786. static function is_symbian_s40_platform() {
  787. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  788. return false;
  789. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  790. if ( strpos( $agent, 'series40' ) !== false ) {
  791. if( strpos( $agent,'nokia' ) !== false || strpos( $agent,'ovibrowser' ) !== false || strpos( $agent,'nokiabrowser' ) !== false )
  792. return true;
  793. }
  794. return false;
  795. }
  796. static function is_J2ME_platform() {
  797. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  798. return false;
  799. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  800. if ( strpos( $agent, 'j2me/midp' ) !== false ) {
  801. return true;
  802. } elseif ( strpos( $agent, 'midp' ) !== false && strpos( $agent, 'cldc' ) ) {
  803. return true;
  804. }
  805. return false;
  806. }
  807. /*
  808. * Detects if the current UA is on one of the Maemo-based Nokia Internet Tablets.
  809. */
  810. static function is_MaemoTablet() {
  811. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  812. return false;
  813. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  814. $pos_maemo = strpos( $agent, 'maemo' );
  815. if ( $pos_maemo === false ) return false;
  816. //Must be Linux + Tablet, or else it could be something else.
  817. if ( strpos( $agent, 'tablet' ) !== false && strpos( $agent, 'linux' ) !== false ) {
  818. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  819. return false;
  820. else
  821. return true;
  822. } else
  823. return false;
  824. }
  825. /*
  826. * Detects if the current UA is a MeeGo device (Nokia Smartphone).
  827. */
  828. static function is_MeeGo() {
  829. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  830. return false;
  831. $ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  832. if ( strpos( $ua, 'meego' ) === false ) {
  833. return false;
  834. } else {
  835. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  836. return false;
  837. else
  838. return true;
  839. }
  840. }
  841. /*
  842. is_webkit() can be used to check the User Agent for an webkit generic browser
  843. */
  844. static function is_webkit() {
  845. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  846. return false;
  847. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  848. $pos_webkit = strpos( $agent, 'webkit' );
  849. if ( $pos_webkit !== false )
  850. return true;
  851. else
  852. return false;
  853. }
  854. /**
  855. * Detects if the current browser is the Native Android browser.
  856. * @return boolean true if the browser is Android otherwise false
  857. */
  858. static function is_android() {
  859. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  860. return false;
  861. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  862. $pos_android = strpos( $agent, 'android' );
  863. if ( $pos_android !== false ) {
  864. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  865. return false;
  866. else
  867. return true;
  868. }
  869. else
  870. return false;
  871. }
  872. /**
  873. * Detects if the current browser is the Native Android Tablet browser.
  874. * Assumes 'Android' should be in the user agent, but not 'mobile'
  875. *
  876. * @return boolean true if the browser is Android and not 'mobile' otherwise false
  877. */
  878. static function is_android_tablet( ) {
  879. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  880. return false;
  881. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  882. $pos_android = strpos( $agent, 'android' );
  883. $pos_mobile = strpos( $agent, 'mobile' );
  884. $post_android_app = strpos( $agent, 'wp-android' );
  885. if ( $pos_android !== false && $pos_mobile === false && $post_android_app === false ) {
  886. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  887. return false;
  888. else
  889. return true;
  890. } else
  891. return false;
  892. }
  893. /**
  894. * Detects if the current browser is the Kindle Fire Native browser.
  895. *
  896. * Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-84) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true
  897. * Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.1.0-84) AppleWebKit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=false
  898. *
  899. * @return boolean true if the browser is Kindle Fire Native browser otherwise false
  900. */
  901. static function is_kindle_fire( ) {
  902. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  903. return false;
  904. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  905. $pos_silk = strpos( $agent, 'silk/' );
  906. $pos_silk_acc = strpos( $agent, 'silk-accelerated=' );
  907. if ( $pos_silk !== false && $pos_silk_acc !== false )
  908. return true;
  909. else
  910. return false;
  911. }
  912. /**
  913. * Detects if the current browser is the Kindle Touch Native browser
  914. *
  915. * Mozilla/5.0 (X11; U; Linux armv7l like Android; en-us) AppleWebKit/531.2+ (KHTML, like Gecko) Version/5.0 Safari/533.2+ Kindle/3.0+
  916. *
  917. * @return boolean true if the browser is Kindle monochrome Native browser otherwise false
  918. */
  919. static function is_kindle_touch( ) {
  920. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  921. return false;
  922. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  923. $pos_kindle_touch = strpos( $agent, 'kindle/3.0+' );
  924. if ( $pos_kindle_touch !== false && self::is_kindle_fire() === false )
  925. return true;
  926. else
  927. return false;
  928. }
  929. // Detect if user agent is the WordPress.com Windows 8 app (used ONLY on the custom oauth stylesheet)
  930. static function is_windows8_auth( ) {
  931. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  932. return false;
  933. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  934. $pos = strpos( $agent, 'msauthhost' );
  935. if ( $pos !== false )
  936. return true;
  937. else
  938. return false;
  939. }
  940. // Detect if user agent is the WordPress.com Windows 8 app.
  941. static function is_wordpress_for_win8( ) {
  942. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  943. return false;
  944. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  945. $pos = strpos( $agent, 'wp-windows8' );
  946. if ( $pos !== false )
  947. return true;
  948. else
  949. return false;
  950. }
  951. /*
  952. * is_blackberry_tablet() can be used to check the User Agent for a RIM blackberry tablet
  953. * The user agent of the BlackBerry® Tablet OS follows a format similar to the following:
  954. * Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.8+ (KHTML, like Gecko) Version/0.0.1 Safari/534.8+
  955. *
  956. */
  957. static function is_blackberry_tablet() {
  958. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  959. return false;
  960. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  961. $pos_playbook = stripos( $agent, 'PlayBook' );
  962. $pos_rim_tablet = stripos( $agent, 'RIM Tablet' );
  963. if ( ($pos_playbook === false) || ($pos_rim_tablet === false) )
  964. {
  965. return false;
  966. } else {
  967. return true;
  968. }
  969. }
  970. /*
  971. is_blackbeberry() can be used to check the User Agent for a blackberry device
  972. Note that opera mini on BB matches this rule.
  973. */
  974. static function is_blackbeberry() {
  975. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  976. return false;
  977. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  978. $pos_blackberry = strpos( $agent, 'blackberry' );
  979. if ( $pos_blackberry !== false ) {
  980. if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
  981. return false;
  982. else
  983. return true;
  984. } else {
  985. return false;
  986. }
  987. }
  988. /*
  989. is_blackberry_10() can be used to check the User Agent for a BlackBerry 10 device.
  990. */
  991. static function is_blackberry_10() {
  992. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  993. return ( strpos( $agent, 'bb10' ) !== false ) && ( strpos( $agent, 'mobile' ) !== false );
  994. }
  995. /**
  996. * Retrieve the blackberry OS version.
  997. *
  998. * Return strings are from the following list:
  999. * - blackberry-10
  1000. * - blackberry-7
  1001. * - blackberry-6
  1002. * - blackberry-torch //only the first edition. The 2nd edition has the OS7 onboard and doesn't need any special rule.
  1003. * - blackberry-5
  1004. * - blackberry-4.7
  1005. * - blackberry-4.6
  1006. * - blackberry-4.5
  1007. *
  1008. * @return string Version of the BB OS.
  1009. * If version is not found, get_blackbeberry_OS_version will return boolean false.
  1010. */
  1011. static function get_blackbeberry_OS_version() {
  1012. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  1013. return false;
  1014. if ( self::is_blackberry_10() )
  1015. return 'blackberry-10';
  1016. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  1017. $pos_blackberry = stripos( $agent, 'blackberry' );
  1018. if ( $pos_blackberry === false ) {
  1019. //not a blackberry device
  1020. return false;
  1021. }
  1022. //blackberry devices OS 6.0 or higher
  1023. //Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+
  1024. //Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1+
  1025. //Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0 Mobile Safari/534.11+
  1026. $pos_webkit = stripos( $agent, 'webkit' );
  1027. if ( $pos_webkit !== false ) {
  1028. //detected blackberry webkit browser
  1029. $pos_torch = stripos( $agent, 'BlackBerry 9800' );
  1030. if ( $pos_torch !== false ) {
  1031. return 'blackberry-torch'; //match the torch first edition. the 2nd edition should use the OS7 and doesn't need any special rule
  1032. } else {
  1033. //detecting the BB OS version for devices running OS 6.0 or higher
  1034. if ( preg_match( '#Version\/([\d\.]+)#i', $agent, $matches ) ) {
  1035. $version = $matches[1];
  1036. $version_num = explode( '.', $version );
  1037. if( is_array( $version_num ) === false || count( $version_num ) <= 1 )
  1038. return 'blackberry-6'; //not a BB device that match our rule.
  1039. else
  1040. return 'blackberry-'.$version_num[0];
  1041. } else {
  1042. //if doesn't match returns the minimun version with a webkit browser. we should never fall here.
  1043. return 'blackberry-6'; //not a BB device that match our rule.
  1044. }
  1045. }
  1046. }
  1047. //blackberry devices <= 5.XX
  1048. //BlackBerry9000/5.0.0.93 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/179
  1049. if ( preg_match( '#BlackBerry\w+\/([\d\.]+)#i', $agent, $matches ) ) {
  1050. $version = $matches[1];
  1051. } else {
  1052. return false; //not a BB device that match our rule.
  1053. }
  1054. $version_num = explode( '.', $version );
  1055. if( is_array( $version_num ) === false || count( $version_num ) <= 1 )
  1056. return false;
  1057. if ( $version_num[0] == 5 ) {
  1058. return 'blackberry-5';
  1059. } elseif ( $version_num[0] == 4 && $version_num[1] == 7 ) {
  1060. return 'blackberry-4.7';
  1061. } elseif ( $version_num[0] == 4 && $version_num[1] == 6 ) {
  1062. return 'blackberry-4.6';
  1063. } elseif ( $version_num[0] == 4 && $version_num[1] == 5 ) {
  1064. return 'blackberry-4.5';
  1065. } else {
  1066. return false;
  1067. }
  1068. return false;
  1069. }
  1070. /**
  1071. * Retrieve the blackberry browser version.
  1072. *
  1073. * Return string are from the following list:
  1074. * - blackberry-10
  1075. * - blackberry-webkit
  1076. * - blackberry-5
  1077. * - blackberry-4.7
  1078. * - blackberry-4.6
  1079. *
  1080. * @return string Type of the BB browser.
  1081. * If browser's version is not found, detect_blackbeberry_browser_version will return boolean false.
  1082. */
  1083. static function detect_blackberry_browser_version() {
  1084. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  1085. return false;
  1086. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  1087. if ( self::is_blackberry_10() )
  1088. return 'blackberry-10';
  1089. $pos_blackberry = strpos( $agent, 'blackberry' );
  1090. if ( $pos_blackberry === false ) {
  1091. //not a blackberry device
  1092. return false;
  1093. }
  1094. $pos_webkit = strpos( $agent, 'webkit' );
  1095. if ( ! ( $pos_webkit === false ) ) {
  1096. return 'blackberry-webkit';
  1097. } else {
  1098. if ( preg_match( '#BlackBerry\w+\/([\d\.]+)#i', $agent, $matches ) ) {
  1099. $version = $matches[1];
  1100. } else {
  1101. return false; //not a BB device that match our rule.
  1102. }
  1103. $version_num = explode( '.', $version );
  1104. if( is_array( $version_num ) === false || count( $version_num ) <= 1 )
  1105. return false;
  1106. if ( $version_num[0] == 5 ) {
  1107. return 'blackberry-5';
  1108. } elseif ( $version_num[0] == 4 && $version_num[1] == 7 ) {
  1109. return 'blackberry-4.7';
  1110. } elseif ( $version_num[0] == 4 && $version_num[1] == 6 ) {
  1111. return 'blackberry-4.6';
  1112. } else {
  1113. //A very old BB device is found or this is a BB device that doesn't match our rules.
  1114. return false;
  1115. }
  1116. }
  1117. return false;
  1118. }
  1119. //Checks if a visitor is coming from one of the WordPress mobile apps
  1120. static function is_mobile_app() {
  1121. if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
  1122. return false;
  1123. $agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
  1124. if ( isset( $_SERVER['X_USER_AGENT'] ) && preg_match( '|wp-webos|', $_SERVER['X_USER_AGENT'] ) )
  1125. return true; //wp4webos 1.1 or higher
  1126. $app_agents = array( 'wp-android', 'wp-blackberry', 'wp-iphone', 'wp-nokia', 'wp-webos', 'wp-windowsphone' );
  1127. // the mobile reader on iOS has an incorrect UA when loading the reader
  1128. // currently it is the default one provided by the iOS framework which
  1129. // causes problems with 2-step-auth
  1130. // User-Agent WordPress/3.1.4 CFNetwork/609 Darwin/13.0.0
  1131. $app_agents[] = 'wordpress/3.1';
  1132. foreach ( $app_agents as $app_agent ) {
  1133. if ( false !== strpos( $agent, $app_agent ) )
  1134. return true;
  1135. }
  1136. return false;
  1137. }
  1138. /**
  1139. * Was the current request made by a known bot?
  1140. *
  1141. * @return boolean
  1142. */
  1143. static function is_bot() {
  1144. static $is_bot = null;
  1145. if ( is_null( $is_bot ) ) {
  1146. $is_bot = Jetpack_User_Agent_Info::is_bot_user_agent( $_SERVER['HTTP_USER_AGENT'] );
  1147. }
  1148. return $is_bot;
  1149. }
  1150. /**
  1151. * Is the given user-agent a known bot?
  1152. * If you want an is_bot check for the current request's UA, use is_bot() instead of passing a user-agent to this method.
  1153. *
  1154. * @param $ua (string) A user-agent string
  1155. * @return boolean
  1156. */
  1157. static function is_bot_user_agent( $ua = null ) {
  1158. if ( empty( $ua ) )
  1159. return false;
  1160. $bot_agents = array(
  1161. 'alexa', 'altavista', 'ask jeeves', 'attentio', 'baiduspider', 'bingbot', 'chtml generic', 'crawler', 'fastmobilecrawl',
  1162. 'feedfetcher-google', 'firefly', 'froogle', 'gigabot', 'googlebot', 'googlebot-mobile', 'heritrix', 'ia_archiver', 'irlbot',
  1163. 'infoseek', 'jumpbot', 'lycos', 'mediapartners', 'mediobot', 'motionbot', 'msnbot', 'mshots', 'openbot',
  1164. 'pss-webkit-request',
  1165. 'pythumbnail', 'scooter', 'slurp', 'snapbot', 'spider', 'taptubot', 'technoratisnoop',
  1166. 'teoma', 'twiceler', 'yahooseeker', 'yahooysmcm', 'yammybot',
  1167. );
  1168. foreach ( $bot_agents as $bot_agent ) {
  1169. if ( false !== stripos( $ua, $bot_agent ) ) {
  1170. return true;
  1171. }
  1172. }
  1173. return false;
  1174. }
  1175. }