1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 13 14 15 16 17 18 19 20 21 22
23 class JBrowser
24 {
25 26 27 28
29 protected $majorVersion = 0;
30
31 32 33 34
35 protected $minorVersion = 0;
36
37 38 39 40
41 protected $browser = '';
42
43 44 45 46
47 protected $agent = '';
48
49 50 51 52
53 protected $lowerAgent = '';
54
55 56 57 58
59 protected $accept = '';
60
61 62 63 64
65 protected $acceptParsed = array();
66
67 68 69 70
71 protected $platform = '';
72
73 74 75 76
77 protected $robots = array(
78
79 'Googlebot',
80 'msnbot',
81 'Slurp',
82 'Yahoo',
83
84 'Arachnoidea',
85 'ArchitextSpider',
86 'Ask Jeeves',
87 'B-l-i-t-z-Bot',
88 'Baiduspider',
89 'BecomeBot',
90 'cfetch',
91 'ConveraCrawler',
92 'ExtractorPro',
93 'FAST-WebCrawler',
94 'FDSE robot',
95 'fido',
96 'geckobot',
97 'Gigabot',
98 'Girafabot',
99 'grub-client',
100 'Gulliver',
101 'HTTrack',
102 'ia_archiver',
103 'InfoSeek',
104 'kinjabot',
105 'KIT-Fireball',
106 'larbin',
107 'LEIA',
108 'lmspider',
109 'Lycos_Spider',
110 'Mediapartners-Google',
111 'MuscatFerret',
112 'NaverBot',
113 'OmniExplorer_Bot',
114 'polybot',
115 'Pompos',
116 'Scooter',
117 'Teoma',
118 'TheSuBot',
119 'TurnitinBot',
120 'Ultraseek',
121 'ViolaBot',
122 'webbandit',
123 'www.almaden.ibm.com/cs/crawler',
124 'ZyBorg',
125 );
126
127 128 129 130
131 protected $mobile = false;
132
133 134 135 136 137 138 139
140 protected $images = array('jpeg', 'gif', 'png', 'pjpeg', 'x-png', 'bmp');
141
142 143 144 145
146 protected static $instances = array();
147
148 149 150 151 152 153 154 155
156 public function __construct($userAgent = null, $accept = null)
157 {
158 $this->match($userAgent, $accept);
159 }
160
161 162 163 164 165 166 167 168 169 170 171
172 public static function getInstance($userAgent = null, $accept = null)
173 {
174 $signature = serialize(array($userAgent, $accept));
175
176 if (empty(self::$instances[$signature]))
177 {
178 self::$instances[$signature] = new JBrowser($userAgent, $accept);
179 }
180
181 return self::$instances[$signature];
182 }
183
184 185 186 187 188 189 190 191 192 193 194
195 public function match($userAgent = null, $accept = null)
196 {
197
198 if (is_null($userAgent))
199 {
200 if (isset($_SERVER['HTTP_USER_AGENT']))
201 {
202 $this->agent = trim($_SERVER['HTTP_USER_AGENT']);
203 }
204 }
205 else
206 {
207 $this->agent = $userAgent;
208 }
209
210 $this->lowerAgent = strtolower($this->agent);
211
212
213 if (is_null($accept))
214 {
215 if (isset($_SERVER['HTTP_ACCEPT']))
216 {
217 $this->accept = strtolower(trim($_SERVER['HTTP_ACCEPT']));
218 }
219 }
220 else
221 {
222 $this->accept = strtolower($accept);
223 }
224
225 if (!empty($this->agent))
226 {
227 $this->_setPlatform();
228
229 230 231 232
233 if (strpos($this->agent, 'MOT-') !== false
234 || strpos($this->lowerAgent, 'j-') !== false
235 || preg_match('/(mobileexplorer|openwave|opera mini|opera mobi|operamini|avantgo|wap|elaine)/i', $this->agent)
236 || preg_match('/(iPhone|iPod|iPad|Android|Mobile|Phone|BlackBerry|Xiino|Palmscape|palmsource)/i', $this->agent)
237 || preg_match('/(Nokia|Ericsson|docomo|digital paths|portalmmm|CriOS[\/ ]([0-9.]+))/i', $this->agent)
238 || preg_match('/(UP|UP.B|UP.L)/', $this->agent)
239 || preg_match('/; (120x160|240x280|240x320|320x320)\)/', $this->agent))
240 {
241 $this->mobile = true;
242 }
243
244
245
246 if (preg_match('|Edge/([0-9.]+)|', $this->agent, $version))
247 {
248 $this->setBrowser('edge');
249
250 if (strpos($version[1], '.') !== false)
251 {
252 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
253 }
254 else
255 {
256 $this->majorVersion = $version[1];
257 $this->minorVersion = 0;
258 }
259 }
260 elseif (preg_match('|Opera[/ ]([0-9.]+)|', $this->agent, $version))
261 {
262 $this->setBrowser('opera');
263 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
264
265 266
267 if ($this->majorVersion == 9 && $this->minorVersion >= 80)
268 {
269 $this->identifyBrowserVersion();
270 }
271 }
272
273
274 elseif (preg_match('/OPR[\/ ]([0-9.]+)/', $this->agent, $version))
275 {
276 $this->setBrowser('opera');
277 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
278 }
279 elseif (preg_match('/Chrome[\/ ]([0-9.]+)|CrMo[\/ ]([0-9.]+)|CriOS[\/ ]([0-9.]+)/i', $this->agent, $version))
280 {
281 $this->setBrowser('chrome');
282 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
283 }
284 elseif (strpos($this->lowerAgent, 'elaine/') !== false
285 || strpos($this->lowerAgent, 'palmsource') !== false
286 || strpos($this->lowerAgent, 'digital paths') !== false)
287 {
288 $this->setBrowser('palm');
289 }
290 elseif ((preg_match('/MSIE ([0-9.]+)|Internet Explorer\/([0-9.]+)|Trident\/([0-9.]+)/i', $this->agent, $version)))
291 {
292 $this->setBrowser('msie');
293
294
295 if (strpos($version[0], 'Trident') !== false && strpos($version[0], 'rv:') !== false)
296 {
297 preg_match('|rv:([0-9.]+)|', $this->agent, $version);
298 }
299
300 if (strpos($version[1], '.') !== false)
301 {
302 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
303 }
304 else
305 {
306 $this->majorVersion = $version[1];
307 $this->minorVersion = 0;
308 }
309 }
310 elseif (preg_match('|amaya/([0-9.]+)|', $this->agent, $version))
311 {
312 $this->setBrowser('amaya');
313 $this->majorVersion = $version[1];
314
315 if (isset($version[2]))
316 {
317 $this->minorVersion = $version[2];
318 }
319 }
320 elseif (preg_match('|ANTFresco/([0-9]+)|', $this->agent, $version))
321 {
322 $this->setBrowser('fresco');
323 }
324 elseif (strpos($this->lowerAgent, 'avantgo') !== false)
325 {
326 $this->setBrowser('avantgo');
327 }
328 elseif (preg_match('|[Kk]onqueror/([0-9]+)|', $this->agent, $version) || preg_match('|Safari/([0-9]+)\.?([0-9]+)?|', $this->agent, $version))
329 {
330
331
332 $this->setBrowser('konqueror');
333 $this->majorVersion = $version[1];
334
335 if (isset($version[2]))
336 {
337 $this->minorVersion = $version[2];
338 }
339
340 if (strpos($this->agent, 'Safari') !== false && $this->majorVersion >= 60)
341 {
342
343 $this->setBrowser('safari');
344 $this->identifyBrowserVersion();
345 }
346 }
347 elseif (preg_match('|Mozilla/([0-9.]+)|', $this->agent, $version))
348 {
349 $this->setBrowser('mozilla');
350
351 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
352 }
353 elseif (preg_match('|Lynx/([0-9]+)|', $this->agent, $version))
354 {
355 $this->setBrowser('lynx');
356 }
357 elseif (preg_match('|Links \(([0-9]+)|', $this->agent, $version))
358 {
359 $this->setBrowser('links');
360 }
361 elseif (preg_match('|HotJava/([0-9]+)|', $this->agent, $version))
362 {
363 $this->setBrowser('hotjava');
364 }
365 elseif (strpos($this->agent, 'UP/') !== false || strpos($this->agent, 'UP.B') !== false || strpos($this->agent, 'UP.L') !== false)
366 {
367 $this->setBrowser('up');
368 }
369 elseif (strpos($this->agent, 'Xiino/') !== false)
370 {
371 $this->setBrowser('xiino');
372 }
373 elseif (strpos($this->agent, 'Palmscape/') !== false)
374 {
375 $this->setBrowser('palmscape');
376 }
377 elseif (strpos($this->agent, 'Nokia') !== false)
378 {
379 $this->setBrowser('nokia');
380 }
381 elseif (strpos($this->agent, 'Ericsson') !== false)
382 {
383 $this->setBrowser('ericsson');
384 }
385 elseif (strpos($this->lowerAgent, 'wap') !== false)
386 {
387 $this->setBrowser('wap');
388 }
389 elseif (strpos($this->lowerAgent, 'docomo') !== false || strpos($this->lowerAgent, 'portalmmm') !== false)
390 {
391 $this->setBrowser('imode');
392 }
393 elseif (strpos($this->agent, 'BlackBerry') !== false)
394 {
395 $this->setBrowser('blackberry');
396 }
397 elseif (strpos($this->agent, 'MOT-') !== false)
398 {
399 $this->setBrowser('motorola');
400 }
401 elseif (strpos($this->lowerAgent, 'j-') !== false)
402 {
403 $this->setBrowser('mml');
404 }
405 }
406 }
407
408 409 410 411 412 413 414 415 416 417 418
419 protected function _setPlatform()
420 {
421 if (strpos($this->lowerAgent, 'wind') !== false)
422 {
423 $this->platform = 'win';
424 }
425 elseif (strpos($this->lowerAgent, 'mac') !== false)
426 {
427 $this->platform = 'mac';
428 }
429 else
430 {
431 $this->platform = 'unix';
432 }
433 }
434
435 436 437 438 439 440 441
442 public function getPlatform()
443 {
444 return $this->platform;
445 }
446
447 448 449 450 451 452 453 454
455 protected function identifyBrowserVersion()
456 {
457 if (preg_match('|Version[/ ]([0-9.]+)|', $this->agent, $version))
458 {
459 list ($this->majorVersion, $this->minorVersion) = explode('.', $version[1]);
460
461 return;
462 }
463
464
465 $this->majorVersion = 0;
466 $this->minorVersion = 0;
467 }
468
469 470 471 472 473 474 475 476 477
478 public function setBrowser($browser)
479 {
480 $this->browser = $browser;
481 }
482
483 484 485 486 487 488 489
490 public function getBrowser()
491 {
492 return $this->browser;
493 }
494
495 496 497 498 499 500 501
502 public function getMajor()
503 {
504 return $this->majorVersion;
505 }
506
507 508 509 510 511 512 513
514 public function getMinor()
515 {
516 return $this->minorVersion;
517 }
518
519 520 521 522 523 524 525
526 public function getVersion()
527 {
528 return $this->majorVersion . '.' . $this->minorVersion;
529 }
530
531 532 533 534 535 536 537
538 public function getAgentString()
539 {
540 return $this->agent;
541 }
542
543 544 545 546 547 548 549
550 public function getHTTPProtocol()
551 {
552 if (isset($_SERVER['SERVER_PROTOCOL']))
553 {
554 if (($pos = strrpos($_SERVER['SERVER_PROTOCOL'], '/')))
555 {
556 return substr($_SERVER['SERVER_PROTOCOL'], $pos + 1);
557 }
558 }
559
560 return;
561 }
562
563 564 565 566 567 568 569 570 571 572 573 574 575
576 public function isViewable($mimetype)
577 {
578 $mimetype = strtolower($mimetype);
579 list ($type, $subtype) = explode('/', $mimetype);
580
581 if (!empty($this->accept))
582 {
583 $wildcard_match = false;
584
585 if (strpos($this->accept, $mimetype) !== false)
586 {
587 return true;
588 }
589
590 if (strpos($this->accept, '*/*') !== false)
591 {
592 $wildcard_match = true;
593
594 if ($type != 'image')
595 {
596 return true;
597 }
598 }
599
600
601 if ($this->isBrowser('mozilla') && ($mimetype == 'image/pjpeg') && (strpos($this->accept, 'image/jpeg') !== false))
602 {
603 return true;
604 }
605
606 if (!$wildcard_match)
607 {
608 return false;
609 }
610 }
611
612 if ($type != 'image')
613 {
614 return false;
615 }
616
617 return in_array($subtype, $this->images);
618 }
619
620 621 622 623 624 625 626 627 628
629 public function isBrowser($browser)
630 {
631 return $this->browser === $browser;
632 }
633
634 635 636 637 638 639 640
641 public function isRobot()
642 {
643 foreach ($this->robots as $robot)
644 {
645 if (strpos($this->agent, $robot) !== false)
646 {
647 return true;
648 }
649 }
650
651 return false;
652 }
653
654 655 656 657 658 659 660
661 public function isMobile()
662 {
663 return $this->mobile;
664 }
665
666 667 668 669 670 671 672 673
674 public function isSSLConnection()
675 {
676 JLog::add(
677 'JBrowser::isSSLConnection() is deprecated. Use the isSSLConnection method on the application object instead.',
678 JLog::WARNING,
679 'deprecated'
680 );
681
682 return (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on')) || getenv('SSL_PROTOCOL_VERSION');
683 }
684 }
685