Completed
Push — add/jetpack-mobile-package ( d1f5cd )
by
unknown
07:53
created

get_blackbeberry_OS_version()   D

Complexity

Conditions 19
Paths 14

Size

Total Lines 71

Duplication

Lines 3
Ratio 4.23 %

Importance

Changes 0
Metric Value
cc 19
nc 14
nop 0
dl 3
loc 71
rs 4.5166
c 0
b 0
f 0

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
 * Mobile detection for Jetpack.
4
 *
5
 * @package automattic/jetpack-mobile
6
 */
7
8
namespace Automattic\Jetpack;
9
10
/**
11
 * Class Automattic\Jetpack\Mobile
12
 *
13
 * @todo Description.
14
 */
15
class Mobile {
16
17
	/**
18
	 * Determine if the current User Agent matches the passed $kind
19
	 *
20
	 * @param string $kind Category of mobile device to check for.
21
	 *                         Either: any, dumb, smart.
22
	 * @param bool   $return_matched_agent Boolean indicating if the UA should be returned
23
	 *
24
	 * @return bool|string Boolean indicating if current UA matches $kind. If
25
	 *                              $return_matched_agent is true, returns the UA string
26
	 */
27
	public static function is_mobile( $kind = 'any', $return_matched_agent = false ) {
28
		static $kinds         = array(
29
			'smart' => false,
30
			'dumb'  => false,
31
			'any'   => false,
32
		);
33
		static $first_run     = true;
34
		static $matched_agent = '';
35
36
		// If an invalid kind is passed in, reset it to default.
37
		if ( ! isset( $kinds[ $kind ] ) ) {
38
				$kind = 'any';
39
		}
40
41
		if ( function_exists( 'apply_filters' ) ) {
42
			/**
43
			 * Filter the value of jetpack_is_mobile before it is calculated.
44
			 *
45
			 * Passing a truthy value to the filter will short-circuit determining the
46
			 * mobile type, returning the passed value instead.
47
			 *
48
			 * @since  4.2.0
49
			 *
50
			 * @param bool|string $matches Boolean if current UA matches $kind or not. If
51
			 *                             $return_matched_agent is true, should return the UA string
52
			 * @param string      $kind Category of mobile device being checked
53
			 * @param bool        $return_matched_agent Boolean indicating if the UA should be returned
54
			 */
55
			$pre = apply_filters( 'pre_jetpack_is_mobile', null, $kind, $return_matched_agent );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $kind.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
56
57
			if ( null !== $pre ) {
58
				return $pre;
59
			}
60
		}
61
62
		$ua_info = new Jetpack_User_Agent_Info();
63
64
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) || strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'ipad' ) ) {
65
			return false;
66
		}
67
68
		// Remove Samsung Galaxy tablets (SCH-I800) from being mobile devices
69
		if ( strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'sch-i800' ) ) {
70
			return false;
71
		}
72
73
		if ( $ua_info->is_android_tablet() && false === $ua_info->is_kindle_touch() ) {
74
			return false;
75
		}
76
77
		if ( $ua_info->is_blackberry_tablet() ) {
78
			return false;
79
		}
80
81
		if ( $first_run ) {
82
			$first_run = false;
83
84
			// checks for iPhoneTier devices & RichCSS devices
85
			if ( $ua_info->isTierIphone() || $ua_info->isTierRichCSS() ) {
86
				$kinds['smart'] = true;
87
				$matched_agent  = $ua_info->matched_agent;
88
			}
89
90
			if ( ! $kinds['smart'] ) {
91
				// if smart, we are not dumb so no need to check
92
				$dumb_agents = $ua_info->dumb_agents;
93
				$agent       = strtolower( $_SERVER['HTTP_USER_AGENT'] );
94
95
				foreach ( $dumb_agents as $dumb_agent ) {
96
					if ( false !== strpos( $agent, $dumb_agent ) ) {
97
						$kinds['dumb'] = true;
98
						$matched_agent = $dumb_agent;
99
100
						break;
101
					}
102
				}
103
104
				if ( ! $kinds['dumb'] ) {
105
					if ( isset( $_SERVER['HTTP_X_WAP_PROFILE'] ) ) {
106
						$kinds['dumb'] = true;
107
						$matched_agent = 'http_x_wap_profile';
108
					} elseif ( isset( $_SERVER['HTTP_ACCEPT'] ) && ( preg_match( '/wap\.|\.wap/i', $_SERVER['HTTP_ACCEPT'] ) || false !== strpos( strtolower( $_SERVER['HTTP_ACCEPT'] ), 'application/vnd.wap.xhtml+xml' ) ) ) {
109
						$kinds['dumb'] = true;
110
						$matched_agent = 'vnd.wap.xhtml+xml';
111
					}
112
				}
113
			}
114
115
			if ( $kinds['dumb'] || $kinds['smart'] ) {
116
				$kinds['any'] = true;
117
			}
118
		}
119
120
		$value = $kinds[ $kind ];
121
122
		if ( $return_matched_agent ) {
123
			$value = $matched_agent;
124
		}
125
126
		if ( function_exists( 'apply_filters' ) ) {
127
			/**
128
			 * Filter the value of jetpack_is_mobile
129
			 *
130
			 * @since  4.2.0
131
			 *
132
			 * @param bool|string $matches Boolean if current UA matches $kind or not. If
133
			 *                             $return_matched_agent is true, should return the UA string
134
			 * @param string      $kind Category of mobile device being checked
135
			 * @param bool        $return_matched_agent Boolean indicating if the UA should be returned
136
			 */
137
			$value = apply_filters( 'jetpack_is_mobile', $value, $kind, $return_matched_agent );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $kind.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

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