forked from quentin389/UserAgentInfo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UserAgentInfo.class.php
618 lines (535 loc) · 15.9 KB
/
UserAgentInfo.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
<?php
/**
* Class containing information about a single user agent string.
*
* This class should provide means of identifying any data present in user agent string that can be used for practical purposes.
*
* The most important values you can get are:
*
* ->getUserAgentString() - return the source user agent string, using this is NOT the same as using HTTP_USER_AGENT
* because Mobile_Detect can take this value from other http header fields
*
* ->isMobile(), ->isMobileTablet(), ->isMobileAndroid(), ->isMobileAppleIos() - allows a full user device identification for mobile redirects:
* if ($ua->isMobileAndroid() && !$ua->isMobileTablet()) echo 'Android Phone';
* if ($ua->isMobileAndroid() && $ua->isMobileTablet()) echo 'Android Tablet';
* if ($ua->isMobileAppleIos() && !$ua->isMobileTablet()) echo 'iPhone';
* if ($ua->isMobileAppleIos() && $ua->isMobileTablet()) echo 'iPad';
* if ($ua->isMobile() && !$ua->isMobileAndroid() && !$ua->isMobileAppleIos()) echo 'Meh, some other mobile device';
*
* ->isBanned() - it's a bot you probably want to ban right away; it may be an e-mail scrapper, fake user agent (someone is trying to conceal his identity), etc.
*
* ->isBot() - a very useful check to both save in your logs and serve slightly different content, for example disable dynamic images loading for spiders;
* be careful, never hide or show any user readable content only to bots or you'll get banned from Google!
*
* ->isIEVersion(...) - separate old Internet Explorer versions from other browsers, for example to show 'you are using an outdated browser' notice
*
* ->renderInfoBrowser(), ->renderInfoDevice(), ->renderInfoOs() - to get a human readable information about user browser, device or operating system
* ->renderInfoAll() - get all the above values in one string, very usefull to include if you show information about given user for your internal purposes;
* for example when users report bugs to via forms on your website
*
* @author Mikołaj Misiurewicz <[email protected]>
*
* @link https://github.com/quentin389/UserAgentInfo
*
*/
class UserAgentInfo
{
/**
* The names could be more descriptive but we're saving this object in cache, so the shorter the better.
*/
protected $user_agent;
protected $browser; // browser family
protected $browser_major;
protected $browser_minor;
protected $browser_patch;
protected $device_family;
protected $device_version;
protected $os; // os family
protected $os_major;
protected $os_minor;
protected $os_patch;
protected $is_banned;
protected $is_mobile;
protected $is_mobile_tablet;
protected $is_bot;
protected $is_bot_reader;
protected $is_64_bit_os;
protected $is_64_bit_browser;
protected $mobile_grade;
protected $_id_level;
protected $_data_version;
/**
* @param string $user_agent
* @param UserAgentInfoPeer::ID_LEVEL_* $identification_level
* @param string $data_version
* @param array $params
*/
public function __construct($user_agent, $identification_level, $data_version, array $params)
{
$this->user_agent = $user_agent;
$this->browser = $params['browser'];
$this->browser_major = $params['browser_major'];
$this->browser_minor = $params['browser_minor'];
$this->browser_patch = $params['browser_patch'];
$this->device_family = $params['device_family'];
$this->device_version = $params['device_version'];
$this->os = $params['os'];
$this->os_major = $params['os_major'];
$this->os_minor = $params['os_minor'];
$this->os_patch = $params['os_patch'];
$this->is_banned = $params['is_banned'];
$this->is_mobile = $params['is_mobile'];
$this->is_mobile_tablet = $params['is_mobile_tablet'];
$this->is_bot = $params['is_bot'];
$this->is_bot_reader = $params['is_bot_reader'];
$this->is_64_bit_os = $params['is_64_bit_os'];
$this->is_64_bit_browser = $params['is_64_bit_browser'];
$this->mobile_grade = $params['mobile_grade'];
$this->_id_level = $identification_level;
$this->_data_version = $data_version;
}
/**
* Was the user agent identified at least a little bit or not at all?
*
* @return boolean
*/
public function isIdentified()
{
return UserAgentInfoPeer::ID_LEVEL_NONE != $this->_id_level;
}
/**
* Was the user agent idenified fully?
*
* @return boolean
*/
public function isIdentifiedFully()
{
return UserAgentInfoPeer::ID_LEVEL_FULL == $this->_id_level;
}
/**
* Is this a mobile device?
*
* @return boolean
*/
public function isMobile()
{
return $this->is_mobile;
}
/**
* Is this a mobile device AND a tablet?
*
* Not all tablets will identify as such by default. Some will be indistinguishable from desktop computers.
*
* @return boolean
*/
public function isMobileTablet()
{
return $this->is_mobile_tablet;
}
/**
* Is the operating system Android (which also means it's a mobile device)?
*
* @return boolean
*/
public function isMobileAndroid()
{
return $this->is_mobile && 'Android' == $this->os;
}
/**
* Is the operating system Apple iOS (which also means it's a mobile device)?
*
* iOS means you've probably encountered iPad or iPhone (->isMobileTablet() will tell you which one)
*
* @return boolean
*/
public function isMobileAppleIos()
{
return $this->is_mobile && 'iOS' == $this->os;
}
/**
* Was the mobile grade detected at all?
*
* @return boolean
*/
public function isMobileGradeRated()
{
return UserAgentInfoPeer::MOBILE_GRADE_UNKNOWN != $this->mobile_grade;
}
/**
* Is this a grade A mobile device?
*
* Grade A mobile device should support all the latest technologies like HTML5, CSS3, full JavaScript with AJAX.
*
* Do not assume that only devices with mobile grade A have full latest technologies support because some devices
* may stay unidentified.
* If you want to find out which devices most likely do NOT support all technologies check:
* if ($ua->isMobileGradeRated() && !$ua->isMobileGradeA())
*
* This value is experimental.
*
* @return boolean
*/
public function isMobileGradeA()
{
return UserAgentInfoPeer::MOBILE_GRADE_A == $this->mobile_grade;
}
/**
* Is this a really, really bad bot which you should ban right away?
* (and then verify what you've done, because you are a responsible person)
*
* @return boolean
*/
public function isBanned()
{
return $this->is_banned;
}
/**
* Is this a bot? (crawler, spider, scrapper or other type of bot)
*
* If this check returns false then the user agent is most likely a user browser.
* Unless it wasn't identified at all, then we don't know anything (check using ->isIdentified()).
*
* @return boolean
*/
public function isBot()
{
return $this->is_bot;
}
/**
* Is this a bot AND it's designed to read RSS, ATOM and other kinds of syndication feeds?
*
* @return boolean
*/
public function isBotReader()
{
return $this->is_bot_reader;
}
/**
* Is this a 64 bit browser?
*
* @return boolean
*/
public function isBrowser64bit()
{
return $this->is_64_bit_browser;
}
/**
* Is this a 64 bit system?
*
* @return boolean
*/
public function isOs64bit()
{
return $this->is_64_bit_os;
}
/**
* Detect Internet Explorer version.
*
* $this->isIEVersion(7, false) - is this desktop IE 7?
* $this->isIEVersion(8, true) - is this desktop IE 8 or lower?
*
* @param integer $include_version the IE major version number you want to check for
* @param boolean $also_match_lower do you want to check just for $include_version or also for all older IE versions?
* @param boolean $include_mobile include only desktop IE in the check or also a mobile versions?
*
* I'm not sure if setting $include_mobile to true makes any sense. I never had to create any specific code for mobile IE...
*
* @return boolean - false if this is not an Internet Explorer or its version doesn't match the filter
*/
public function isIEVersion($include_version, $also_match_lower, $include_mobile = false)
{
if (empty($this->browser_major) || $this->browser_major > $include_version)
{
return false;
}
if (!$also_match_lower && $this->browser_major < $include_version)
{
return false;
}
if (UserAgentInfoPeer::UA_IE_DESKTOP != $this->browser && (!$include_mobile || UserAgentInfoPeer::UA_IE_MOBILE != $this->browser))
{
return false;
}
return true;
}
/**
* Return user agent string that this class returns information about.
*
* @return string
*/
public function getUserAgentString()
{
return $this->user_agent;
}
/**
* Get the browser name / type ('Firefox', 'Chrome', etc.)
*
* @return string
*/
public function getBrowserName()
{
return $this->browser;
}
/**
* Get the browser major version number.
*
* @return string (usually an integer string)
*/
public function getBrowserVersionMajor()
{
return $this->browser_major;
}
/**
* Get the browser minor version number.
*
* @return string
*/
public function getBrowserVersionMinor()
{
return $this->browser_minor;
}
/**
* Get the browser patch version number (the part written after the major and minor version).
*
* @return string
*/
public function getBrowserVersionPatch()
{
return $this->browser_patch;
}
/**
* Get the browser version.
*
* @param boolean $detailed_version whether to also return the patch version part or just major and minor part
*
* @return string
*/
public function getBrowserVersion($detailed_version = false)
{
if (!$this->browser_major)
{
return '';
}
$version = $this->browser_major;
if ('' != $this->browser_minor)
{
$version .= UserAgentInfoPeer::SEPARATOR_VERSION . $this->browser_minor;
if ($detailed_version && '' != $this->browser_patch)
{
$version .= UserAgentInfoPeer::SEPARATOR_VERSION . $this->browser_patch;
}
}
return $version;
}
/**
* Get the device family name (eg. Samsung, Nokia, iPhone, iPad, Kindle).
*
* That will usually work only for mobile devices. You can't really detect a device type using desktop browsers user agent strings.
*
* @return string
*/
public function getDeviceFamily()
{
return $this->device_family;
}
/**
* Get the device version or something we think may be a device version.
* This may or may not return specific phone models and stuff like that.
*
* Same as with ->getDeviceFamily() will only work for mobile devices, not desktop computers.
*
* @return string
*/
public function getDeviceVersion()
{
return $this->device_version;
}
/**
* Get the operating system name, which is either a generic name (Linux, Ubuntu, Android, Mac OS X, ...)
* or a specific Windows version (Windows XP, Windows 8, etc.)
*
* @return string
*/
public function getOsName()
{
return $this->os;
}
/**
* Get the operating system major version number.
* Value is empty for Windows.
*
* @return string (usually an integer string)
*/
public function getOsVersionMajor()
{
return $this->os_major;
}
/**
* Get the operating system minor version number.
*
* @return string
*/
public function getOsVersionMinor()
{
return $this->os_minor;
}
/**
* Get the operating system patch version number (the part written after the major and minor version).
*
* @return string
*/
public function getOsVersionPatch()
{
return $this->os_patch;
}
/**
* Get the operating system version.
*
* @param boolean $detailed_version whether to also return the patch version part or just major and minor part
*
* @return string
*/
public function getOsVersion($detailed_version = false)
{
if (!$this->os_major)
{
return '';
}
$version = $this->os_major;
if ('' != $this->os_minor)
{
$version .= UserAgentInfoPeer::SEPARATOR_VERSION . $this->os_minor;
if ($detailed_version && '' != $this->os_patch)
{
$version .= UserAgentInfoPeer::SEPARATOR_VERSION . $this->os_patch;
}
}
return $version;
}
/**
* Get mobile grade identified by UserAgentInfoPeer::MOBILE_GRADE_*
*
* @return UserAgentInfoPeer::MOBILE_GRADE_*
*/
public function getMobileGrade()
{
return $this->mobile_grade;
}
/**
* Get a combined version of all source data used to identify this user agent.
*
* If this version changes then it's time to regenerate the data from source.
*
* This value is human readable so you can check which source system has what version.
*
* @return string
*/
public function getDataVersion()
{
return $this->_data_version;
}
/**
* Render human readable information about the browser, operating system and device, for example:
* 'Mobile Safari 6.3, iOS 6.1, iPhone'
*
* It's a string combined from the data available for browser, os and device.
* It does not include boolean checks info like 'isMobile' or 'isBot'.
*
* @param string $detailed_versions whether to print very detailed browser and os version numbers or not
*
* @return string
*/
public function renderInfoAll($detailed_versions = false)
{
$info = array();
if ($info_browser = self::renderInfoBrowser($detailed_versions))
{
$info[] = $info_browser;
}
if ($info_os = self::renderInfoOs($detailed_versions))
{
$info[] = $info_os;
}
if ($info_device = self::renderInfoDevice())
{
$info[] = $info_device;
}
return implode(', ', $info);
}
/**
* Render human readable information about the browser, for example 'Opera 12.16 (64 bit)'.
*
* @param string $detailed_versions whether to print very detailed version number or not
*
* @return string
*/
public function renderInfoBrowser($detailed_version = false)
{
$info = $this->browser;
if ('' != $info)
{
$version = $this->getBrowserVersion($detailed_version);
if ($version)
{
$info .= ' ' . $version;
}
if ($this->is_64_bit_browser)
{
$info .= ' (' . UserAgentInfoPeer::NAME_64_BIT . ')';
}
}
return $info;
}
/**
* Render human readable information about user device name and version, for example 'Samsung GT-I9000'.
*
* This information should be available for most mobile devices, but not for desktop computers.
*
* @return string
*/
public function renderInfoDevice()
{
$name = array();
if ($this->device_family)
{
if ($this->device_version)
{
if ('-' == substr($this->device_version, 0, 1))
{
return $this->device_family . $this->device_version;
}
return $this->device_family . ' ' . $this->device_version;
}
return $this->device_family;
}
if ($this->device_version)
{
return $this->device_version;
}
return '';
}
/**
* Render human readable information about the operating system, for example 'Windows 7 (64 bit)' or 'Windows XP'.
*
* @param string $detailed_versions whether to print very detailed version number or not
*
* @return string
*/
public function renderInfoOs($detailed_version = false)
{
$info = $this->os;
if ('' != $info)
{
$version = $this->getOsVersion($detailed_version);
if ($version)
{
$info .= ' ' . $version;
}
if ($this->is_64_bit_os)
{
$info .= ' (' . UserAgentInfoPeer::NAME_64_BIT . ')';
}
}
return $info;
}
}