Completed
Push — add/jetpack-mobile-package ( 4a9724...5b8bc4 )
by
unknown
12:25 queued 04:47
created

Device_Detection::is_smartphone()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Device detection for Jetpack.
4
 *
5
 * @package automattic/jetpack-device-detection
6
 */
7
8
namespace Automattic\Jetpack;
9
10
/**
11
 * Class Device_Detection
12
 *
13
 * Determine if the current User Agent matches the passed $kind.
14
 */
15
class Device_Detection {
16
17
	/**
18
	 * Returns information about the current device accessing the page.
19
	 *
20
	 * @param string $ua (Optional) User-Agent string.
21
	 *
22
	 * @return array Device information.
23
	 *
24
	 * array(
25
	 *  'is_phone'            => (bool) Whether the current device is a mobile phone.
26
	 *  'is_smartphone'       => (bool) Whether the current device is a smartphone.
27
	 *  'is_tablet'           => (bool) Whether the current device is a tablet device.
28
	 *  'is_handheld'         => (bool) Whether the current device is a handheld device.
29
	 *  'is_desktop'          => (bool) Whether the current device is a laptop / desktop device.
30
	 *  'platform'            => (string) Detected platform.
31
	 *  'is_phone_matched_ua' => (string) Matched UA.
32
	 * );
33
	 */
34
	public static function get_info( $ua = '' ) {
35
		$ua_info = new Jetpack_User_Agent_Info( $ua );
36
37
		$info = array(
38
			'is_phone'            => self::is_mobile( 'any', false, $ua_info ),
39
			'is_phone_matched_ua' => self::is_mobile( 'any', true, $ua_info ),
40
			'is_smartphone'       => self::is_mobile( 'smart', false, $ua_info ),
41
			'is_tablet'           => $ua_info->is_tablet(),
42
			'platform'            => $ua_info->get_platform(),
43
		);
44
45
		$info['is_handheld'] = $info['is_phone'] || $info['is_tablet'];
46
		$info['is_desktop']  = ! $info['is_handheld'];
47
48
		if ( function_exists( 'apply_filters' ) ) {
49
			$info = apply_filters( 'jetpack_device_detection_get_info', $info, $ua, $ua_info );
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $ua.

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...
50
		}
51
		return $info;
52
	}
53
54
	/**
55
	 * Detects phone devices.
56
	 *
57
	 * @param string $ua User-Agent string.
58
	 *
59
	 * @return bool
60
	 */
61
	public static function is_phone( $ua = '' ) {
62
		$device_info = self::get_info( $ua );
63
		return true === $device_info['is_phone'];
64
	}
65
66
	/**
67
	 * Detects smartphone devices.
68
	 *
69
	 * @param string $ua User-Agent string.
70
	 *
71
	 * @return bool
72
	 */
73
	public static function is_smartphone( $ua = '' ) {
74
		$device_info = self::get_info( $ua );
75
		return true === $device_info['is_smartphone'];
76
	}
77
78
	/**
79
	 * Detects tablet devices.
80
	 *
81
	 * @param string $ua User-Agent string.
82
	 *
83
	 * @return bool
84
	 */
85
	public static function is_tablet( $ua = '' ) {
86
		$device_info = self::get_info( $ua );
87
		return true === $device_info['is_tablet'];
88
	}
89
90
	/**
91
	 * Detects desktop devices.
92
	 *
93
	 * @param string $ua User-Agent string.
94
	 *
95
	 * @return bool
96
	 */
97
	public static function is_desktop( $ua = '' ) {
98
		$device_info = self::get_info( $ua );
99
		return true === $device_info['is_desktop'];
100
	}
101
102
	/**
103
	 * Detects handheld (i.e. phone + tablet) devices.
104
	 *
105
	 * @param string $ua User-Agent string.
106
	 *
107
	 * @return bool
108
	 */
109
	public static function is_handheld( $ua = '' ) {
110
		$device_info = self::get_info( $ua );
111
		return true === $device_info['is_handheld'];
112
	}
113
114
	/**
115
	 * Determine if the current User Agent matches the passed $kind.
116
	 *
117
	 * @param string                  $kind                 Category of mobile device to check for. Either: any, dumb, smart.
118
	 * @param bool                    $return_matched_agent Boolean indicating if the UA should be returned.
119
	 * @param Jetpack_User_Agent_Info $ua_info              Boolean indicating if the UA should be returned.
120
	 *
121
	 * @return bool|string Boolean indicating if current UA matches $kind. If `$return_matched_agent` is true, returns the UA string.
122
	 */
123
	private static function is_mobile( $kind = 'any', $return_matched_agent = false, $ua_info ) {
124
		$kinds         = array(
125
			'smart' => false,
126
			'dumb'  => false,
127
			'any'   => false,
128
		);
129
		$first_run     = true;
130
		$matched_agent = '';
131
132
		// If an invalid kind is passed in, reset it to default.
133
		if ( ! isset( $kinds[ $kind ] ) ) {
134
				$kind = 'any';
135
		}
136
137
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) || strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'ipad' ) ) {
138
			return false;
139
		}
140
141
		// Remove Samsung Galaxy tablets (SCH-I800) from being mobile devices
142
		if ( strpos( strtolower( $_SERVER['HTTP_USER_AGENT'] ), 'sch-i800' ) ) {
143
			return false;
144
		}
145
146
		if ( $ua_info->is_android_tablet() && false === $ua_info->is_kindle_touch() ) {
147
			return false;
148
		}
149
150
		if ( $ua_info->is_blackberry_tablet() ) {
151
			return false;
152
		}
153
154
		if ( $first_run ) {
155
			$first_run = false;
0 ignored issues
show
Unused Code introduced by
$first_run is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

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