Completed
Push — fix/reduce-db-queries ( 61f6a8...ad3872 )
by
unknown
21:01 queued 11:50
created

class.jetpack-user-agent.php ➔ jetpack_is_mobile()   D

Complexity

Conditions 22
Paths 111

Size

Total Lines 102
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
cc 22
eloc 43
c 2
b 0
f 2
nc 111
nop 2
dl 0
loc 102
rs 4.5094

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Determine if the current User Agent matches the passed $kind
5
 *
6
 * @param string $kind Category of mobile device to check for.
7
 *                         Either: any, dumb, smart.
8
 * @param bool   $return_matched_agent Boolean indicating if the UA should be returned
9
 *
10
 * @return bool|string Boolean indicating if current UA matches $kind. If
11
 *                              $return_matched_agent is true, returns the UA string
12
 */
13
function jetpack_is_mobile( $kind = 'any', $return_matched_agent = false ) {
14
	static $kinds         = array( 'smart' => false, 'dumb' => false, 'any' => false );
15
	static $first_run     = true;
16
	static $matched_agent = '';
17
18
	/**
19
	 * Filter the value of jetpack_is_mobile before it is calculated.
20
	 *
21
	 * Passing a truthy value to the filter will short-circuit determining the
22
	 * mobile type, returning the passed value instead.
23
	 *
24
	 * @since  4.2.0
25
	 *
26
	 * @param bool|string $matches Boolean if current UA matches $kind or not. If
27
	 *                             $return_matched_agent is true, should return the UA string
28
	 * @param string      $kind Category of mobile device being checked
29
	 * @param bool        $return_matched_agent Boolean indicating if the UA should be returned
30
	 */
31
	$pre = apply_filters( 'pre_jetpack_is_mobile', null, $kind, $return_matched_agent );
32
33
	if ( null !== $pre ) {
34
		return $pre;
35
	}
36
37
	$ua_info = new Jetpack_User_Agent_Info();
38
39
	if ( empty( $_SERVER['HTTP_USER_AGENT'] ) || strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'ipad' ) ) {
40
		return false;
41
	}
42
43
	// Remove Samsung Galaxy tablets (SCH-I800) from being mobile devices
44
	if ( strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ) , 'sch-i800') ) {
45
		return false;
46
	}
47
48
	if( $ua_info->is_android_tablet() &&  $ua_info->is_kindle_touch() === false ) {
49
		return false;
50
	}
51
52
	if( $ua_info->is_blackberry_tablet() ) {
53
		return false;
54
	}
55
56
	if ( $first_run ) {
57
		$first_run = false;
58
59
		//checks for iPhoneTier devices & RichCSS devices
60
		if ( $ua_info->isTierIphone() || $ua_info->isTierRichCSS() ) {
61
			$kinds['smart'] = true;
62
			$matched_agent  = $ua_info->matched_agent;
63
		}
64
65
		if ( ! $kinds['smart'] ) {
66
			// if smart, we are not dumb so no need to check
67
			$dumb_agents = $ua_info->dumb_agents;
68
			$agent       = strtolower( $_SERVER['HTTP_USER_AGENT'] );
69
70
			foreach ( $dumb_agents as $dumb_agent ) {
71
				if ( false !== strpos( $agent, $dumb_agent ) ) {
72
					$kinds['dumb'] = true;
73
					$matched_agent = $dumb_agent;
74
75
					break;
76
				}
77
			}
78
79
			if ( ! $kinds['dumb'] ) {
80
				if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
81
					$kinds['dumb'] = true;
82
					$matched_agent = 'http_x_wap_profile';
83
				} elseif ( isset( $_SERVER['HTTP_ACCEPT']) && ( preg_match( '/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'] ) || false !== strpos( strtolower( $_SERVER['HTTP_ACCEPT'] ), 'application/vnd.wap.xhtml+xml' ) ) ) {
84
					$kinds['dumb'] = true;
85
					$matched_agent = 'vnd.wap.xhtml+xml';
86
				}
87
			}
88
		}
89
90
		if ( $kinds['dumb'] || $kinds['smart'] ) {
91
			$kinds['any'] = true;
92
		}
93
	}
94
95
	$value = $kinds[ $kind ];
96
97
	if ( $return_matched_agent ) {
98
		$value = $matched_agent;
99
	}
100
101
	/**
102
	 * Filter the value of jetpack_is_mobile
103
	 *
104
	 * @since  4.2.0
105
	 *
106
	 * @param bool|string $matches Boolean if current UA matches $kind or not. If
107
	 *                             $return_matched_agent is true, should return the UA string
108
	 * @param string      $kind Category of mobile device being checked
109
	 * @param bool        $return_matched_agent Boolean indicating if the UA should be returned
110
	 */
111
	$value = apply_filters( 'jetpack_is_mobile', $value, $kind, $return_matched_agent );
112
113
	return $value;
114
}
115
116
class Jetpack_User_Agent_Info {
117
118
	public $useragent;
119
	public $matched_agent;
120
	public $isTierIphone; //Stores whether is the iPhone tier of devices.
121
	public $isTierRichCss; //Stores whether the device can probably support Rich CSS, but JavaScript (jQuery) support is not assumed.
122
	public $isTierGenericMobile; //Stores whether it is another mobile device, which cannot be assumed to support CSS or JS (eg, older BlackBerry, RAZR)
123
124
    private $_platform = null; //Stores the device platform name
125
	const PLATFORM_WINDOWS 			= 'windows';
126
	const PLATFORM_IPHONE 			= 'iphone';
127
	const PLATFORM_IPOD 			= 'ipod';
128
	const PLATFORM_IPAD 			= 'ipad';
129
	const PLATFORM_BLACKBERRY 		= 'blackberry';
130
	const PLATFORM_BLACKBERRY_10 	= 'blackberry_10';
131
	const PLATFORM_SYMBIAN			= 'symbian_series60';
132
	const PLATFORM_SYMBIAN_S40		= 'symbian_series40';
133
	const PLATFORM_J2ME_MIDP		= 'j2me_midp';
134
	const PLATFORM_ANDROID 			= 'android';
135
	const PLATFORM_ANDROID_TABLET	= 'android_tablet';
136
	const PLATFORM_FIREFOX_OS		= 'firefoxOS';
137
138
	public $dumb_agents = array(
139
		'nokia', 'blackberry', 'philips', 'samsung', 'sanyo', 'sony', 'panasonic', 'webos',
140
		'ericsson', 'alcatel', 'palm',
141
		'windows ce', 'opera mini', 'series60', 'series40',
142
		'au-mic,', 'audiovox', 'avantgo', 'blazer',
143
		'danger', 'docomo', 'epoc',
144
		'ericy', 'i-mode', 'ipaq',  'midp-',
145
		'mot-', 'netfront', 'nitro',
146
		'palmsource',  'pocketpc', 'portalmmm',
147
		'rover', 'sie-',
148
		'symbian', 'cldc-', 'j2me',
149
		'smartphone', 'up.browser', 'up.link',
150
		'up.link', 'vodafone/', 'wap1.', 'wap2.', 'mobile', 'googlebot-mobile',
151
	);
152
153
   //The constructor. Initializes default variables.
154
   function __construct()
155
   {
156
   		if ( !empty( $_SERVER['HTTP_USER_AGENT'] ) )
157
       		$this->useragent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
158
   }
159
160
   /**
161
    * This method detects the mobile User Agent name.
162
    *
163
    * @return string The matched User Agent name, false otherwise.
164
    */
165
   function get_mobile_user_agent_name() {
166
   		if( $this->is_chrome_for_iOS( ) ) //keep this check before the safari rule
167
   			return 'chrome-for-ios';
168
	   	elseif ( $this->is_iphone_or_ipod( 'iphone-safari' ) )
169
	 	  	return  'iphone';
170
	   	elseif ( $this->is_ipad( 'ipad-safari' ) )
171
	   		return 'ipad';
172
	   	elseif ( $this->is_android_tablet() ) //keep this check before the android rule
173
	   		return 'android_tablet';
174
	   	elseif ( $this->is_android() )
175
	   		return 'android';
176
	   	elseif ( $this->is_blackberry_10() )
177
	   		return 'blackberry_10';
178
	   	elseif ( $this->is_blackbeberry() )
179
	   		return 'blackberry';
180
	   	elseif ( $this->is_WindowsPhone7() )
181
	   		return 'win7';
182
	   	elseif ( $this->is_windows_phone_8() )
183
	   		return 'winphone8';
184
	   	elseif ( $this->is_opera_mini() )
185
	   		return 'opera-mini';
186
		elseif ( $this->is_opera_mini_dumb() )
187
	   		return 'opera-mini-dumb';
188
	   	elseif ( $this->is_opera_mobile() )
189
	   		return 'opera-mobi';
190
	   	elseif ( $this->is_blackberry_tablet() )
191
	   		return 'blackberry_tablet';
192
	   	elseif ( $this->is_kindle_fire() )
193
	   		return 'kindle-fire';
194
	   	elseif ( $this->is_PalmWebOS() )
195
	   		return 'webos';
196
	   	elseif ( $this->is_S60_OSSBrowser() )
197
	   		return 'series60';
198
	   	elseif ( $this->is_firefox_os() )
199
	   	   	return 'firefoxOS';
200
	   	elseif ( $this->is_firefox_mobile() )
201
	   		return 'firefox_mobile';
202
	   	elseif ( $this->is_MaemoTablet() )
203
	   		return 'maemo';
204
		elseif ( $this->is_MeeGo() )
205
	   		return 'meego';
206
	   	elseif( $this->is_TouchPad() )
207
	   		return 'hp_tablet';
208
	    elseif ( $this->is_facebook_for_iphone() )
209
 	  		return  'facebook-for-iphone';
210
 	  	elseif ( $this->is_facebook_for_ipad() )
211
 	  		return  'facebook-for-ipad';
212
   		elseif ( $this->is_twitter_for_iphone() )
213
 	  		return  'twitter-for-iphone';
214
 	  	elseif ( $this->is_twitter_for_ipad() )
215
 	  		return  'twitter-for-ipad';
216
 	  	elseif ( $this->is_wordpress_for_ios() )
217
 	  		return  'ios-app';
218
	   	elseif ( $this->is_iphone_or_ipod( 'iphone-not-safari' ) )
219
	 	  	return  'iphone-unknown';
220
	   	elseif ( $this->is_ipad( 'ipad-not-safari' ) )
221
	   		return 'ipad-unknown';
222
	   	elseif ( $this->is_Nintendo_3DS() )
223
	   		return 'nintendo-3ds';
224
	   	else {
225
	   		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
226
	   		$dumb_agents = $this->dumb_agents;
227
	   		foreach ( $dumb_agents as $dumb_agent ) {
228
	   			if ( false !== strpos( $agent, $dumb_agent ) ) {
229
	   				return $dumb_agent;
230
	   			}
231
	   		}
232
	   	}
233
234
	   	return false;
235
   }
236
237
   /**
238
    * This method detects the mobile device's platform. All return strings are from the class constants.
239
    * Note that this function returns the platform name, not the UA name/type. You should use a different function
240
    * if you need to test the UA capabilites.
241
    *
242
    * @return string Name of the platform, false otherwise.
243
    */
244
   public function get_platform() {
245
   	if ( isset( $this->_platform ) ) {
246
   		return $this->_platform;
247
   	}
248
249
    if ( strpos( $this->useragent, 'windows phone' ) !== false ) {
250
   		$this->_platform = self::PLATFORM_WINDOWS;
251
   	}
252
   	elseif ( strpos( $this->useragent, 'windows ce' ) !== false ) {
253
   		$this->_platform = self::PLATFORM_WINDOWS;
254
   	}
255
   	elseif ( strpos( $this->useragent, 'ipad' ) !== false ) {
256
   		$this->_platform = self::PLATFORM_IPAD;
257
   	}
258
   	else if ( strpos( $this->useragent, 'ipod' ) !== false ) {
259
   		$this->_platform = self::PLATFORM_IPOD;
260
   	}
261
   	else if ( strpos( $this->useragent, 'iphone' ) !== false ) {
262
   		$this->_platform = self::PLATFORM_IPHONE;
263
   	}
264
   	elseif ( strpos( $this->useragent, 'android' ) !== false ) {
265
   	 if ( $this->is_android_tablet() )
266
   		 $this->_platform = self::PLATFORM_ANDROID_TABLET;
267
   	 else
268
   		$this->_platform = self::PLATFORM_ANDROID;
269
   	}
270
    elseif ( $this->is_kindle_fire() ) {
271
   		$this->_platform = self::PLATFORM_ANDROID_TABLET;
272
   	}
273
   	elseif ( $this->is_blackberry_10() ) {
274
   		$this->_platform = self::PLATFORM_BLACKBERRY_10;
275
   	}
276
   	elseif ( strpos( $this->useragent, 'blackberry' ) !== false ) {
277
   		$this->_platform = self::PLATFORM_BLACKBERRY;
278
   	}
279
   	elseif ( $this->is_blackberry_tablet() ) {
280
   		$this->_platform = self::PLATFORM_BLACKBERRY;
281
   	}
282
    elseif ( $this->is_symbian_platform() ) {
283
   		$this->_platform = self::PLATFORM_SYMBIAN;
284
   	}
285
    elseif ( $this->is_symbian_s40_platform() ) {
286
   		$this->_platform = self::PLATFORM_SYMBIAN_S40;
287
   	}
288
    elseif ( $this->is_J2ME_platform() ) {
289
   		$this->_platform = self::PLATFORM_J2ME_MIDP;
290
   	}
291
   	elseif ( $this->is_firefox_os() ) {
292
   		$this->_platform = self::PLATFORM_FIREFOX_OS;
293
   	}
294
   	else
295
   		$this->_platform = false;
296
297
   		return $this->_platform;
298
   }
299
300
	/*
301
	 * This method detects for UA which can display iPhone-optimized web content.
302
	 * Includes iPhone, iPod Touch, Android, WebOS, Fennec (Firefox mobile), etc.
303
	 *
304
	 */
305
	function isTierIphone() {
306
		if ( isset( $this->isTierIphone ) ) {
307
			return $this->isTierIphone;
308
		}
309
		if ( $this->is_iphoneOrIpod() ) {
310
			$this->matched_agent = 'iphone';
311
			$this->isTierIphone = true;
312
			$this->isTierRichCss = false;
313
			$this->isTierGenericMobile = false;
314
		}
315 View Code Duplication
		elseif ( $this->is_android() ) {
316
			$this->matched_agent = 'android';
317
			$this->isTierIphone = true;
318
			$this->isTierRichCss = false;
319
			$this->isTierGenericMobile = false;
320
		}
321 View Code Duplication
		elseif ( $this->is_windows_phone_8() ) {
322
			$this->matched_agent = 'winphone8';
323
			$this->isTierIphone = true;
324
			$this->isTierRichCss = false;
325
			$this->isTierGenericMobile = false;
326
		}
327 View Code Duplication
		elseif ( $this->is_WindowsPhone7() ) {
328
			$this->matched_agent = 'win7';
329
			$this->isTierIphone = true;
330
			$this->isTierRichCss = false;
331
			$this->isTierGenericMobile = false;
332
		}
333 View Code Duplication
		elseif ( $this->is_blackberry_10() ) {
334
			$this->matched_agent = 'blackberry-10';
335
			$this->isTierIphone = true;
336
			$this->isTierRichCss = false;
337
			$this->isTierGenericMobile = false;
338
		}
339 View Code Duplication
		elseif ( $this->is_blackbeberry() && $this->detect_blackberry_browser_version() == 'blackberry-webkit' ) {
340
			$this->matched_agent = 'blackberry-webkit';
341
			$this->isTierIphone = true;
342
			$this->isTierRichCss = false;
343
			$this->isTierGenericMobile = false;
344
		}
345 View Code Duplication
		elseif ( $this->is_blackberry_tablet() ) {
346
			$this->matched_agent = 'blackberry_tablet';
347
			$this->isTierIphone = true;
348
			$this->isTierRichCss = false;
349
			$this->isTierGenericMobile = false;
350
		}
351 View Code Duplication
		elseif ( $this->is_PalmWebOS() ) {
352
			$this->matched_agent = 'webos';
353
			$this->isTierIphone = true;
354
			$this->isTierRichCss = false;
355
			$this->isTierGenericMobile = false;
356
		}
357 View Code Duplication
		elseif ( $this->is_TouchPad() ) {
358
			$this->matched_agent = 'hp_tablet';
359
			$this->isTierIphone = true;
360
			$this->isTierRichCss = false;
361
			$this->isTierGenericMobile = false;
362
		}
363 View Code Duplication
		elseif ( $this->is_firefox_os() ) {
364
			$this->matched_agent = 'firefoxOS';
365
			$this->isTierIphone = true;
366
			$this->isTierRichCss = false;
367
			$this->isTierGenericMobile = false;
368
		}
369 View Code Duplication
		elseif ( $this->is_firefox_mobile() ) {
370
			$this->matched_agent = 'fennec';
371
			$this->isTierIphone = true;
372
			$this->isTierRichCss = false;
373
			$this->isTierGenericMobile = false;
374
		}
375 View Code Duplication
		elseif ( $this->is_opera_mobile() ) {
376
			$this->matched_agent = 'opera-mobi';
377
			$this->isTierIphone = true;
378
			$this->isTierRichCss = false;
379
			$this->isTierGenericMobile = false;
380
		}
381 View Code Duplication
		elseif ( $this->is_MaemoTablet() ) {
382
			$this->matched_agent = 'maemo';
383
			$this->isTierIphone = true;
384
			$this->isTierRichCss = false;
385
			$this->isTierGenericMobile = false;
386
		}
387 View Code Duplication
		elseif ( $this->is_MeeGo() ) {
388
			$this->matched_agent = 'meego';
389
			$this->isTierIphone = true;
390
			$this->isTierRichCss = false;
391
			$this->isTierGenericMobile = false;
392
		}
393 View Code Duplication
		elseif ( $this->is_kindle_touch() ) {
394
			$this->matched_agent = 'kindle-touch';
395
			$this->isTierIphone = true;
396
			$this->isTierRichCss = false;
397
			$this->isTierGenericMobile = false;
398
		}
399 View Code Duplication
		elseif ( $this->is_Nintendo_3DS() ) {
400
			$this->matched_agent = 'nintendo-3ds';
401
			$this->isTierIphone = true;
402
			$this->isTierRichCss = false;
403
			$this->isTierGenericMobile = false;
404
		}
405
		else {
406
			$this->isTierIphone = false;
407
		}
408
		return $this->isTierIphone;
409
	}
410
411
	/*
412
	 * This method detects for UA which are likely to be capable
413
	 * but may not necessarily support JavaScript.
414
	 * Excludes all iPhone Tier UA.
415
	 *
416
	 */
417
	function isTierRichCss(){
418
		if ( isset( $this->isTierRichCss ) ) {
419
			return $this->isTierRichCss;
420
		}
421
		if ($this->isTierIphone())
422
		return false;
423
424
		//The following devices are explicitly ok.
425
		if ( $this->is_S60_OSSBrowser() ) {
426
			$this->matched_agent = 'series60';
427
			$this->isTierIphone = false;
428
			$this->isTierRichCss = true;
429
			$this->isTierGenericMobile = false;
430
		}
431 View Code Duplication
		elseif ( $this->is_opera_mini() ) {
432
			$this->matched_agent = 'opera-mini';
433
			$this->isTierIphone = false;
434
			$this->isTierRichCss = true;
435
			$this->isTierGenericMobile = false;
436
		}
437
		elseif ( $this->is_blackbeberry() ) {
438
			$detectedDevice = $this->detect_blackberry_browser_version();
439
			if ( $detectedDevice === 'blackberry-5' || $detectedDevice == 'blackberry-4.7' || $detectedDevice === 'blackberry-4.6' ) {
440
				$this->matched_agent = $detectedDevice;
441
				$this->isTierIphone = false;
442
				$this->isTierRichCss = true;
443
				$this->isTierGenericMobile = false;
444
			}
445
		}
446
		else {
447
			$this->isTierRichCss = false;
448
		}
449
450
		return $this->isTierRichCss;
451
	}
452
453
	// Detects if the user is using a tablet.
454
	// props Corey Gilmore, BGR.com
455
	static function is_tablet() {
456
		return ( 0 // never true, but makes it easier to manage our list of tablet conditions
457
				||  self::is_ipad()
458
				||  self::is_android_tablet()
459
				||  self::is_blackberry_tablet()
460
				||  self::is_kindle_fire()
461
				||  self::is_MaemoTablet()
462
				||  self::is_TouchPad()
463
		);
464
	}
465
466
	/*
467
	 *  Detects if the current UA is the default iPhone or iPod Touch Browser.
468
	 *
469
	 *  DEPRECATED: use is_iphone_or_ipod
470
	 *
471
	 */
472
	static function is_iphoneOrIpod(){
473
474
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
475
			return false;
476
477
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
478 View Code Duplication
		if ( ( strpos( $ua, 'iphone' ) !== false ) || ( strpos( $ua,'ipod' ) !== false ) ) {
479
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
480
	   			return false;
481
	   		else
482
	   			return true;
483
		}
484
		else
485
			return false;
486
	}
487
488
489
	/*
490
	 *  Detects if the current UA is iPhone Mobile Safari or another iPhone or iPod Touch Browser.
491
	 *
492
	 *  They type can check for any iPhone, an iPhone using Safari, or an iPhone using something other than Safari.
493
	 *
494
	 *  Note: If you want to check for Opera mini, Opera mobile or Firefox mobile (or any 3rd party iPhone browser),
495
	 *  you should put the check condition before the check for 'iphone-any' or 'iphone-not-safari'.
496
	 *  Otherwise those browsers will be 'catched' by the iphone string.
497
	 *
498
	 */
499
	static function is_iphone_or_ipod( $type = 'iphone-any' ) {
500
501
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
502
			return false;
503
504
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
505
		$is_iphone = ( strpos( $ua, 'iphone' ) !== false ) || ( strpos( $ua,'ipod' ) !== false );
506
		$is_safari = ( false !== strpos( $ua, 'safari' ) );
507
508
		if ( 'iphone-safari' == $type )
509
			return $is_iphone && $is_safari;
510
		elseif ( 'iphone-not-safari' == $type )
511
			return $is_iphone && !$is_safari;
512
		else
513
			return $is_iphone;
514
	}
515
516
517
	/*
518
	*  Detects if the current UA is Chrome for iOS
519
	*
520
	*  The User-Agent string in Chrome for iOS is the same as the Mobile Safari User-Agent, with CriOS/<ChromeRevision> instead of Version/<VersionNum>.
521
	*  - 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
522
	*/
523
	static function is_chrome_for_iOS( ) {
524
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
525
			return false;
526
527
		if ( self::is_iphone_or_ipod( 'iphone-safari' ) === false ) return false;
528
529
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
530
531
		if ( strpos( $ua, 'crios/' ) !== false )
532
			return true;
533
		else
534
			return false;
535
	}
536
537
538
	/*
539
	 *  Detects if the current UA is Twitter for iPhone
540
	 *
541
	 * 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
542
	 * 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
543
	 *
544
	 */
545
	static function is_twitter_for_iphone( ) {
546
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
547
			return false;
548
549
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
550
551
		if ( strpos( $ua, 'ipad' ) !== false )
552
			return false;
553
554
		if ( strpos( $ua, 'twitter for iphone' ) !== false )
555
			return true;
556
		else
557
			return false;
558
	}
559
560
	/*
561
	 * Detects if the current UA is Twitter for iPad
562
	 *
563
	 * 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
564
	 * 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
565
	 *
566
	 */
567 View Code Duplication
	static function is_twitter_for_ipad( ) {
568
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
569
			return false;
570
571
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
572
573
		if ( strpos( $ua, 'twitter for ipad' ) !== false )
574
			return true;
575
		elseif( strpos( $ua, 'ipad' ) !== false && strpos( $ua, 'twitter for iphone' ) !== false )
576
			return true;
577
		else
578
			return false;
579
	}
580
581
582
	/*
583
	 * Detects if the current UA is Facebook for iPhone
584
	 * - Facebook 4020.0 (iPhone; iPhone OS 5.0.1; fr_FR)
585
	 * - 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]
586
	 * - 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]
587
	 */
588
	static function is_facebook_for_iphone( ) {
589
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
590
			return false;
591
592
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
593
594
		if( strpos( $ua, 'iphone' ) === false )
595
			return false;
596
597
		if ( strpos( $ua, 'facebook' ) !== false  && strpos( $ua, 'ipad' ) === false )
598
			return true;
599
		else if ( strpos( $ua, 'fbforiphone' ) !== false && strpos( $ua, 'tablet' ) === false )
600
			return true;
601
		else if ( strpos( $ua, 'fban/fbios;' ) !== false && strpos( $ua, 'tablet' ) === false ) //FB app v5.0 or higher
602
			return true;
603
		else
604
			return false;
605
	}
606
607
	/*
608
	 * Detects if the current UA is Facebook for iPad
609
	 * - Facebook 4020.0 (iPad; iPhone OS 5.0.1; en_US)
610
	 * - 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]
611
	 * - 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]
612
	 */
613 View Code Duplication
	static function is_facebook_for_ipad( ) {
614
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
615
			return false;
616
617
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
618
619
		if ( strpos( $ua, 'ipad' ) === false )
620
			return false;
621
622
		if ( strpos( $ua, 'facebook' ) !== false || strpos( $ua, 'fbforiphone' ) !== false  || strpos( $ua, 'fban/fbios;' ) !== false )
623
			return true;
624
		else
625
			return false;
626
	}
627
628
	/*
629
	 *  Detects if the current UA is WordPress for iOS
630
	 */
631
	static function is_wordpress_for_ios( ) {
632
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
633
			return false;
634
635
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
636
		if ( strpos( $ua, 'wp-iphone' ) !== false )
637
			return true;
638
		else
639
			return false;
640
	}
641
642
	/*
643
	 * Detects if the current device is an iPad.
644
	 * They type can check for any iPad, an iPad using Safari, or an iPad using something other than Safari.
645
	 *
646
	 * Note: If you want to check for Opera mini, Opera mobile or Firefox mobile (or any 3rd party iPad browser),
647
	 * you should put the check condition before the check for 'iphone-any' or 'iphone-not-safari'.
648
	 * Otherwise those browsers will be 'catched' by the ipad string.
649
	 *
650
	*/
651
	static function is_ipad( $type = 'ipad-any' ) {
652
653
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
654
			return false;
655
656
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
657
658
		$is_ipad = ( false !== strpos( $ua, 'ipad' ) );
659
		$is_safari = ( false !== strpos( $ua, 'safari' ) );
660
661
		if ( 'ipad-safari' == $type )
662
			return $is_ipad && $is_safari;
663
		elseif ( 'ipad-not-safari' == $type )
664
			return $is_ipad && !$is_safari;
665
		else
666
			return $is_ipad;
667
	}
668
669
	/*
670
	 * Detects if the current browser is Firefox Mobile (Fennec)
671
	 *
672
	 * http://www.useragentstring.com/pages/Fennec/
673
	 * Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.1.1) Gecko/20110415 Firefox/4.0.2pre Fennec/4.0.1
674
	 * Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b2pre) Gecko/20081015 Fennec/1.0a1
675
	 */
676
	static function is_firefox_mobile( ) {
677
678
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
679
			return false;
680
681
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
682
683
		if ( strpos( $ua, 'fennec' ) !== false )
684
			return true;
685
		else
686
			return false;
687
	}
688
689
690
	/*
691
	 * Detects if the current browser is FirefoxOS Native browser
692
	*
693
	* Mozilla/5.0 (Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
694
	*
695
	*/
696 View Code Duplication
	static function is_firefox_os( ) {
697
698
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
699
			return false;
700
701
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
702
703
		if ( strpos( $ua, 'mozilla' ) !== false && strpos( $ua, 'mobile' ) !== false && strpos( $ua, 'gecko' ) !== false && strpos( $ua, 'firefox' ) !== false)
704
			return true;
705
		else
706
			return false;
707
	}
708
709
710
	/*
711
	 * Detects if the current browser is Opera Mobile
712
	 *
713
	 * What is the difference between Opera Mobile and Opera Mini?
714
	 * - Opera Mobile is a full Internet browser for mobile devices.
715
	 * - Opera Mini always uses a transcoder to convert the page for a small display.
716
	 * (it uses Opera advanced server compression technology to compress web content before it gets to a device.
717
	 *  The rendering engine is on Opera's server.)
718
	 *
719
	 * Opera/9.80 (Windows NT 6.1; Opera Mobi/14316; U; en) Presto/2.7.81 Version/11.00"
720
	 * Opera/9.50 (Nintendo DSi; Opera/507; U; en-US)
721
	 */
722 View Code Duplication
	static function is_opera_mobile( ) {
723
724
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
725
			return false;
726
727
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
728
729
		if ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'mobi' ) !== false )
730
			return true;
731
		elseif ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'nintendo dsi' ) !== false )
732
			return true;
733
		else
734
			return false;
735
	}
736
737
738
	/*
739
	 * Detects if the current browser is Opera Mini
740
	 *
741
	 * Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
742
	 * Opera/9.80 (Android;Opera Mini/6.0.24212/24.746 U;en) Presto/2.5.25 Version/10.5454
743
	 * Opera/9.80 (iPhone; Opera Mini/5.0.019802/18.738; U; en) Presto/2.4.15
744
	 * Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja) Presto/2.4.15
745
	 * Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja) Presto/2.4.15
746
	 * Opera/9.80 (Series 60; Opera Mini/5.1.22783/23.334; U; en) Presto/2.5.25 Version/10.54
747
	 * Opera/9.80 (BlackBerry; Opera Mini/5.1.22303/22.387; U; en) Presto/2.5.25 Version/10.54
748
	 *
749
	 */
750
	static function is_opera_mini( ) {
751
752
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
753
			return false;
754
755
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
756
757
		if ( strpos( $ua, 'opera' ) !== false && strpos( $ua, 'mini' ) !== false )
758
			return true;
759
		else
760
			return false;
761
	}
762
763
	/*
764
	 * Detects if the current browser is Opera Mini, but not on a smart device OS(Android, iOS, etc)
765
	 * Used to send users on dumb devices to m.wor
766
	 */
767
	static function is_opera_mini_dumb( ) {
768
769
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
770
			return false;
771
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
772
773
		if ( self::is_opera_mini() ) {
774
			if ( strpos( $ua, 'android' ) !== false  || strpos( $ua, 'iphone' ) !== false || strpos( $ua, 'ipod' ) !== false
775
		 	|| strpos( $ua, 'ipad' ) !== false || strpos( $ua, 'blackberry' ) !== false)
776
				return false;
777
			else
778
				return true;
779
		} else {
780
			return false;
781
		}
782
	}
783
784
	/*
785
	 * Detects if the current browser is Opera Mobile or Mini.
786
	 * DEPRECATED: use is_opera_mobile or is_opera_mini
787
	 *
788
	 * Opera Mini 5 Beta: Opera/9.80 (J2ME/MIDP; Opera Mini/5.0.15650/756; U; en) Presto/2.2.0
789
	 * Opera Mini 8: Opera/8.01 (J2ME/MIDP; Opera Mini/3.0.6306/1528; en; U; ssr)
790
	 */
791
	static function is_OperaMobile() {
792
		_deprecated_function( __FUNCTION__, 'always', 'is_opera_mini() or is_opera_mobile()' );
793
794
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
795
		return false;
796
797
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
798
799
		if ( strpos( $ua, 'opera' ) !== false ) {
800
			if ( ( strpos( $ua, 'mini' ) !== false ) || ( strpos( $ua,'mobi'  ) !== false ) )
801
				return true;
802
			else
803
				return false;
804
		} else {
805
			return false;
806
		}
807
	}
808
809
	/*
810
	 * Detects if the current browser is a Windows Phone 7 device.
811
	 * ex: Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; LG; GW910)
812
	 */
813 View Code Duplication
	static function is_WindowsPhone7() {
814
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
815
			return false;
816
817
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
818
819
		if ( strpos( $ua, 'windows phone os 7' ) === false ) {
820
			return false;
821
		} else {
822
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
823
	   			return false;
824
	   		else
825
	   			return true;
826
		}
827
	}
828
829
	/*
830
	 * Detects if the current browser is a Windows Phone 8 device.
831
	 * ex: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; ARM; Touch; IEMobile/10.0; <Manufacturer>; <Device> [;<Operator>])
832
	 */
833
	static function is_windows_phone_8() {
834
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
835
			return false;
836
837
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
838
		if ( strpos( $ua, 'windows phone 8' ) === false ) {
839
			return false;
840
		} else {
841
			return true;
842
		}
843
	}
844
845
846
	/*
847
	 * Detects if the current browser is on a Palm device running the new WebOS. This EXCLUDES TouchPad.
848
	 *
849
	 * 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
850
	 * 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
851
	 *
852
	 */
853 View Code Duplication
	static function is_PalmWebOS() {
854
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
855
			return false;
856
857
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
858
859
		if ( strpos( $ua, 'webos' ) === false ) {
860
	   		return false;
861
		} else {
862
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
863
	   			return false;
864
	   		else
865
	   			return true;
866
		}
867
	}
868
869
	/*
870
	 * Detects if the current browser is the HP TouchPad default browser. This excludes phones wt WebOS.
871
	 *
872
	 * 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
873
	 * 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
874
	 *
875
	 */
876
	static function is_TouchPad() {
877
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
878
		return false;
879
880
		$http_user_agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
881
		if ( false !== strpos( $http_user_agent, 'hp-tablet' )  || false !== strpos( $http_user_agent, 'hpwos' ) || false !== strpos( $http_user_agent, 'touchpad' ) ) {
882
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
883
	   			return false;
884
	   		else
885
	   			return true;
886
		}
887
		else
888
			return false;
889
	}
890
891
892
	/*
893
	 * Detects if the current browser is the Series 60 Open Source Browser.
894
	 *
895
	 * 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
896
	 *
897
	 * 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
898
	 *
899
	 * 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
900
	 *
901
	 */
902
	static function is_S60_OSSBrowser() {
903
904
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
905
		return false;
906
907
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
908
		if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
909
	   		return false;
910
911
		$pos_webkit = strpos( $agent, 'webkit' );
912
		if ( $pos_webkit !== false ) {
913
			//First, test for WebKit, then make sure it's either Symbian or S60.
914
			if ( strpos( $agent, 'symbian' ) !== false || strpos( $agent, 'series60' ) !== false ) {
915
		   			return true;
916
			} else
917
				return false;
918 View Code Duplication
		} elseif ( strpos( $agent, 'symbianos' ) !== false && strpos( $agent,'series60' ) !== false ) {
919
			return true;
920
		} elseif ( strpos( $agent, 'nokia' ) !== false && strpos( $agent,'series60' ) !== false ) {
921
			return true;
922
		}
923
924
	    return false;
925
	}
926
927
	/*
928
	 *
929
	 * Detects if the device platform is the Symbian Series 60.
930
	 *
931
	 */
932
	static function is_symbian_platform() {
933
934
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
935
		return false;
936
937
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
938
939
		$pos_webkit = strpos( $agent, 'webkit' );
940
		if ( $pos_webkit !== false ) {
941
			//First, test for WebKit, then make sure it's either Symbian or S60.
942
			if ( strpos( $agent, 'symbian' ) !== false || strpos( $agent, 'series60' ) !== false ) {
943
		   			return true;
944
			} else
945
				return false;
946 View Code Duplication
		} elseif ( strpos( $agent, 'symbianos' ) !== false && strpos( $agent,'series60' ) !== false ) {
947
			return true;
948
		} elseif ( strpos( $agent, 'nokia' ) !== false && strpos( $agent,'series60' ) !== false ) {
949
			return true;
950
		} elseif ( strpos( $agent, 'opera mini' ) !== false ) {
951
			if( strpos( $agent,'symbianos' ) !== false || strpos( $agent,'symbos' ) !== false || strpos( $agent,'series 60' ) !== false )
952
			return true;
953
		}
954
955
	    return false;
956
	}
957
958
	/*
959
	 *
960
	 * Detects if the device platform is the Symbian Series 40.
961
	 * Nokia Browser for Series 40 is a proxy based browser, previously known as Ovi Browser.
962
	 * This browser will report 'NokiaBrowser' in the header, however some older version will also report 'OviBrowser'.
963
	 *
964
	 */
965 View Code Duplication
	static function is_symbian_s40_platform() {
966
967
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
968
		return false;
969
970
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
971
972
		if ( strpos( $agent, 'series40' ) !== false ) {
973
			if( strpos( $agent,'nokia' ) !== false || strpos( $agent,'ovibrowser' ) !== false || strpos( $agent,'nokiabrowser' ) !== false )
974
			return true;
975
		}
976
977
	    return false;
978
	}
979
980 View Code Duplication
	static function is_J2ME_platform() {
981
982
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
983
			return false;
984
985
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
986
987
		if ( strpos( $agent, 'j2me/midp' ) !== false ) {
988
			return true;
989
		} elseif ( strpos( $agent, 'midp' ) !== false && strpos( $agent, 'cldc' ) ) {
990
			return true;
991
		}
992
993
	    return false;
994
	}
995
996
997
	/*
998
	 * Detects if the current UA is on one of the Maemo-based Nokia Internet Tablets.
999
	 */
1000
	static function is_MaemoTablet() {
1001
1002
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1003
		return false;
1004
1005
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1006
1007
		$pos_maemo = strpos( $agent, 'maemo' );
1008
		if ( $pos_maemo === false ) return false;
1009
1010
		//Must be Linux + Tablet, or else it could be something else.
1011 View Code Duplication
		if ( strpos( $agent, 'tablet' ) !== false && strpos( $agent, 'linux' ) !== false ) {
1012
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1013
	   			return false;
1014
	   		else
1015
	   			return true;
1016
		} else
1017
			return false;
1018
	}
1019
1020
	/*
1021
	 * Detects if the current UA is a MeeGo device (Nokia Smartphone).
1022
	 */
1023 View Code Duplication
	static function is_MeeGo() {
1024
1025
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1026
			return false;
1027
1028
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1029
1030
		if ( strpos( $ua, 'meego' ) === false ) {
1031
	   		return false;
1032
		} else {
1033
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1034
	   			return false;
1035
	   		else
1036
	   			return true;
1037
		}
1038
	}
1039
1040
1041
	/*
1042
	 is_webkit() can be used to check the User Agent for an webkit generic browser
1043
	 */
1044 View Code Duplication
	static function is_webkit() {
1045
1046
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1047
		return false;
1048
1049
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1050
1051
		$pos_webkit = strpos( $agent, 'webkit' );
1052
1053
		if ( $pos_webkit !== false )
1054
			return true;
1055
		else
1056
			return false;
1057
	}
1058
1059
    /**
1060
     * Detects if the current browser is the Native Android browser.
1061
     * @return boolean true if the browser is Android otherwise false
1062
     */
1063 View Code Duplication
	static function is_android() {
1064
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1065
			return false;
1066
1067
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1068
		$pos_android = strpos( $agent, 'android' );
1069
		if ( $pos_android !== false ) {
1070
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1071
	   			return false;
1072
	   		else
1073
	   			return true;
1074
		}
1075
		else
1076
			return false;
1077
	}
1078
1079
1080
	/**
1081
	 * Detects if the current browser is the Native Android Tablet browser.
1082
	 * 	Assumes 'Android' should be in the user agent, but not 'mobile'
1083
	 *
1084
	 * @return boolean true if the browser is Android and not 'mobile' otherwise false
1085
	 */
1086
	static function is_android_tablet( ) {
1087
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1088
			return false;
1089
1090
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1091
1092
		$pos_android = strpos( $agent, 'android' );
1093
		$pos_mobile = strpos( $agent, 'mobile' );
1094
		$post_android_app = strpos( $agent, 'wp-android' );
1095
1096
		if ( $pos_android !== false && $pos_mobile === false && $post_android_app === false ) {
1097
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1098
				return false;
1099
			else
1100
				return true;
1101
		} else
1102
			return false;
1103
	}
1104
1105
	/**
1106
	 * Detects if the current browser is the Kindle Fire Native browser.
1107
	 *
1108
	 * 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
1109
	 * 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
1110
	 *
1111
	 * @return boolean true if the browser is Kindle Fire Native browser otherwise false
1112
	 */
1113
	static function is_kindle_fire( ) {
1114
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1115
			return false;
1116
1117
		$agent    = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1118
		$pos_silk = strpos( $agent, 'silk/' );
1119
		$pos_silk_acc = strpos( $agent, 'silk-accelerated=' );
1120
		if ( $pos_silk !== false && $pos_silk_acc !== false )
1121
	   		return true;
1122
		else
1123
			return false;
1124
	}
1125
1126
1127
/**
1128
 	* Detects if the current browser is the Kindle Touch Native browser
1129
 	*
1130
 	* 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+
1131
 	*
1132
 	* @return boolean true if the browser is Kindle monochrome Native browser otherwise false
1133
 	*/
1134 View Code Duplication
 	static function is_kindle_touch( ) {
1135
 		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1136
 			return false;
1137
 		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1138
 		$pos_kindle_touch = strpos( $agent, 'kindle/3.0+' );
1139
 		if ( $pos_kindle_touch !== false && self::is_kindle_fire() === false )
1140
 			return true;
1141
 		else
1142
 			return false;
1143
 		}
1144
1145
1146
	// Detect if user agent is the WordPress.com Windows 8 app (used ONLY on the custom oauth stylesheet)
1147 View Code Duplication
	static function is_windows8_auth( ) {
1148
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1149
			return false;
1150
1151
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1152
		$pos = strpos( $agent, 'msauthhost' );
1153
		if ( $pos !== false )
1154
	   		return true;
1155
		else
1156
			return false;
1157
	}
1158
1159
	// Detect if user agent is the WordPress.com Windows 8 app.
1160 View Code Duplication
	static function is_wordpress_for_win8( ) {
1161
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1162
			return false;
1163
1164
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1165
		$pos   = strpos( $agent, 'wp-windows8' );
1166
		if ( $pos !== false )
1167
			return true;
1168
		else
1169
			return false;
1170
	}
1171
1172
1173
	/*
1174
	 * is_blackberry_tablet() can be used to check the User Agent for a RIM blackberry tablet
1175
	 * The user agent of the BlackBerry® Tablet OS follows a format similar to the following:
1176
	 * 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+
1177
	 *
1178
	 */
1179
	static function is_blackberry_tablet() {
1180
1181
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1182
			return false;
1183
1184
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1185
		$pos_playbook = stripos( $agent, 'PlayBook' );
1186
		$pos_rim_tablet = stripos( $agent, 'RIM Tablet' );
1187
1188
		if ( ($pos_playbook === false) || ($pos_rim_tablet === false) )
1189
		{
1190
			return false;
1191
		} else {
1192
			return true;
1193
		}
1194
	}
1195
1196
	/*
1197
	 is_blackbeberry() can be used to check the User Agent for a blackberry device
1198
	 Note that opera mini on BB matches this rule.
1199
	 */
1200 View Code Duplication
	static function is_blackbeberry() {
1201
1202
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1203
			return false;
1204
1205
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1206
1207
		$pos_blackberry = strpos( $agent, 'blackberry' );
1208
		if ( $pos_blackberry !== false ) {
1209
			if ( self::is_opera_mini() || self::is_opera_mobile() || self::is_firefox_mobile() )
1210
				return false;
1211
			else
1212
				return true;
1213
		} else {
1214
			return false;
1215
		}
1216
	}
1217
1218
	/*
1219
	 is_blackberry_10() can be used to check the User Agent for a BlackBerry 10 device.
1220
	*/
1221
	static function is_blackberry_10() {
1222
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1223
		return ( strpos( $agent, 'bb10' ) !== false ) && ( strpos( $agent, 'mobile' ) !== false );
1224
	}
1225
1226
	/**
1227
	 * Retrieve the blackberry OS version.
1228
	 *
1229
	 * Return strings are from the following list:
1230
	 * - blackberry-10
1231
	 * - blackberry-7
1232
	 * - blackberry-6
1233
	 * - blackberry-torch //only the first edition. The 2nd edition has the OS7 onboard and doesn't need any special rule.
1234
	 * - blackberry-5
1235
	 * - blackberry-4.7
1236
	 * - blackberry-4.6
1237
	 * - blackberry-4.5
1238
	 *
1239
	 * @return string Version of the BB OS.
1240
	 * If version is not found, get_blackbeberry_OS_version will return boolean false.
1241
	 */
1242
	static function get_blackbeberry_OS_version() {
1243
1244
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1245
			return false;
1246
1247
		if ( self::is_blackberry_10() ) {
1248
			return 'blackberry-10';
1249
		}
1250
1251
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1252
1253
		$pos_blackberry = stripos( $agent, 'blackberry' );
1254
		if ( $pos_blackberry === false ) {
1255
			// not a blackberry device
1256
			return false;
1257
		}
1258
1259
		// blackberry devices OS 6.0 or higher
1260
		// Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+
1261
		// Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1+
1262
		// Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0 Mobile Safari/534.11+
1263
		$pos_webkit = stripos( $agent, 'webkit' );
1264
		if ( $pos_webkit !== false ) {
1265
			// detected blackberry webkit browser
1266
			$pos_torch = stripos( $agent, 'BlackBerry 9800' );
1267
			if ( $pos_torch !== false ) {
1268
				return 'blackberry-torch'; // match the torch first edition. the 2nd edition should use the OS7 and doesn't need any special rule
1269
			} else {
1270
				// detecting the BB OS version for devices running OS 6.0 or higher
1271
				if ( preg_match( '#Version\/([\d\.]+)#i', $agent, $matches ) ) {
1272
					$version = $matches[1];
1273
					$version_num = explode( '.', $version );
1274
					if ( is_array( $version_num ) === false || count( $version_num ) <= 1 ) {
1275
						return 'blackberry-6'; // not a BB device that match our rule.
1276
					} else {
1277
						return 'blackberry-' . $version_num[0];
1278
					}
1279
				} else {
1280
					// if doesn't match returns the minimun version with a webkit browser. we should never fall here.
1281
					return 'blackberry-6'; // not a BB device that match our rule.
1282
				}
1283
			}
1284
		}
1285
1286
		// blackberry devices <= 5.XX
1287
		// BlackBerry9000/5.0.0.93 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/179
1288
		if ( preg_match( '#BlackBerry\w+\/([\d\.]+)#i', $agent, $matches ) ) {
1289
			$version = $matches[1];
1290
		} else {
1291
			return false; //not a BB device that match our rule.
1292
		}
1293
1294
		$version_num = explode( '.', $version );
1295
1296 View Code Duplication
		if ( is_array( $version_num ) === false || count( $version_num ) <= 1 ) {
1297
			return false;
1298
		}
1299
		if ( $version_num[0] == 5 ) {
1300
			return 'blackberry-5';
1301
		} elseif ( $version_num[0] == 4 && $version_num[1] == 7 ) {
1302
			return 'blackberry-4.7';
1303
		} elseif ( $version_num[0] == 4 && $version_num[1] == 6 ) {
1304
			return 'blackberry-4.6';
1305
		} elseif ( $version_num[0] == 4 && $version_num[1] == 5 ) {
1306
			return 'blackberry-4.5';
1307
		} else {
1308
			return false;
1309
		}
1310
1311
	}
1312
1313
	/**
1314
	 * Retrieve the blackberry browser version.
1315
	 *
1316
	 * Return string are from the following list:
1317
	 * - blackberry-10
1318
	 * - blackberry-webkit
1319
	 * - blackberry-5
1320
	 * - blackberry-4.7
1321
	 * - blackberry-4.6
1322
	 *
1323
	 * @return string Type of the BB browser.
1324
	 * If browser's version is not found, detect_blackbeberry_browser_version will return boolean false.
1325
	 */
1326
	static function detect_blackberry_browser_version() {
1327
1328
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
1329
			return false;
1330
		}
1331
1332
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1333
1334
		if ( self::is_blackberry_10() ) {
1335
			return 'blackberry-10';
1336
		}
1337
1338
		$pos_blackberry = strpos( $agent, 'blackberry' );
1339
		if ( $pos_blackberry === false ) {
1340
			// not a blackberry device
1341
			return false;
1342
		}
1343
1344
		$pos_webkit = strpos( $agent, 'webkit' );
1345
1346
		if ( ! ( $pos_webkit === false ) ) {
1347
			return 'blackberry-webkit';
1348
		} else {
1349
			if ( preg_match( '#BlackBerry\w+\/([\d\.]+)#i', $agent, $matches ) ) {
1350
				$version = $matches[1];
1351
			} else {
1352
				return false; // not a BB device that match our rule.
1353
			}
1354
1355
			$version_num = explode( '.', $version );
1356
1357 View Code Duplication
			if ( is_array( $version_num ) === false || count( $version_num ) <= 1 ) {
1358
				return false;
1359
			}
1360
1361
			if ( $version_num[0] == 5 ) {
1362
				return 'blackberry-5';
1363
			} elseif ( $version_num[0] == 4 && $version_num[1] == 7 ) {
1364
				return 'blackberry-4.7';
1365
			} elseif ( $version_num[0] == 4 && $version_num[1] == 6 ) {
1366
				return 'blackberry-4.6';
1367
			} else {
1368
				// A very old BB device is found or this is a BB device that doesn't match our rules.
1369
				return false;
1370
			}
1371
		}
1372
1373
	}
1374
1375
	// Checks if a visitor is coming from one of the WordPress mobile apps
1376
	static function is_mobile_app() {
1377
1378
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) )
1379
			return false;
1380
1381
		$agent = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1382
1383
		if ( isset( $_SERVER['X_USER_AGENT'] ) && preg_match( '|wp-webos|', $_SERVER['X_USER_AGENT'] ) )
1384
			return true; //wp4webos 1.1 or higher
1385
1386
		$app_agents = array( 'wp-android', 'wp-blackberry', 'wp-iphone', 'wp-nokia', 'wp-webos', 'wp-windowsphone' );
1387
		// the mobile reader on iOS has an incorrect UA when loading the reader
1388
		// currently it is the default one provided by the iOS framework which
1389
		// causes problems with 2-step-auth
1390
		// User-Agent	WordPress/3.1.4 CFNetwork/609 Darwin/13.0.0
1391
		$app_agents[] = 'wordpress/3.1';
1392
1393
		foreach ( $app_agents as $app_agent ) {
1394
			if ( false !== strpos( $agent, $app_agent ) )
1395
			return true;
1396
		}
1397
		return false;
1398
	}
1399
1400
  /*
1401
	 * Detects if the current browser is Nintendo 3DS handheld.
1402
	 *
1403
	 * example: Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7498.US
1404
	 * can differ in language, version and region
1405
	 */
1406
	static function is_Nintendo_3DS() {
1407
	 	if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
1408
			return false;
1409
		}
1410
1411
		$ua = strtolower( $_SERVER['HTTP_USER_AGENT'] );
1412
		if ( strpos( $ua, 'nintendo 3ds' ) !== false ) {
1413
	   		return true;
1414
		}
1415
		return false;
1416
	}
1417
1418
	/**
1419
	 * Was the current request made by a known bot?
1420
	 *
1421
	 * @return boolean
1422
	 */
1423
	static function is_bot() {
1424
		static $is_bot = null;
1425
1426
		if ( is_null( $is_bot ) ) {
1427
			$is_bot = Jetpack_User_Agent_Info::is_bot_user_agent( $_SERVER['HTTP_USER_AGENT'] );
1428
		}
1429
1430
		return $is_bot;
1431
	}
1432
1433
	/**
1434
	 * Is the given user-agent a known bot?
1435
	 * 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.
1436
	 *
1437
	 * @param $ua (string) A user-agent string
1438
	 * @return boolean
1439
	 */
1440
	static function is_bot_user_agent( $ua = null ) {
1441
1442
		if ( empty( $ua ) )
1443
			return false;
1444
1445
		$bot_agents = array(
1446
			'alexa', 'altavista', 'ask jeeves', 'attentio', 'baiduspider', 'bingbot', 'chtml generic', 'crawler', 'fastmobilecrawl',
1447
			'feedfetcher-google', 'firefly', 'froogle', 'gigabot', 'googlebot', 'googlebot-mobile', 'heritrix', 'ia_archiver', 'irlbot',
1448
			'iescholar', 'infoseek', 'jumpbot', 'lycos', 'mediapartners', 'mediobot', 'motionbot', 'msnbot', 'mshots', 'openbot',
1449
			'pss-webkit-request', 'pythumbnail', 'scooter', 'slurp', 'snapbot', 'spider', 'taptubot', 'technoratisnoop',
1450
			'teoma', 'twiceler', 'yahooseeker', 'yahooysmcm', 'yammybot', 'ahrefsbot', 'pingdom.com_bot', 'kraken', 'yandexbot',
1451
			'twitterbot', 'tweetmemebot', 'openhosebot', 'queryseekerspider', 'linkdexbot', 'grokkit-crawler',
1452
			'livelapbot', 'germcrawler', 'domaintunocrawler', 'grapeshotcrawler', 'cloudflare-alwaysonline',
1453
		);
1454
1455
		foreach ( $bot_agents as $bot_agent ) {
1456
			if ( false !== stripos( $ua, $bot_agent ) ) {
1457
				return true;
1458
			}
1459
		}
1460
1461
		return false;
1462
	}
1463
1464
1465
1466
}
1467