Completed
Push — fix/gulp-env ( ec4107...cf0b47 )
by
unknown
133:51 queued 124:05
created

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

Complexity

Conditions 24
Paths 433

Size

Total Lines 106
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 24
eloc 45
c 1
b 0
f 0
nc 433
nop 2
dl 0
loc 106
rs 3.3953

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