Completed
Push — fix/min-php-everywhere ( 582b89...e9c8a1 )
by
unknown
07:08
created

Jetpack_User_Agent_Info::is_Nintendo_3DS()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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