Browser_Detection
[ class tree: Browser_Detection ] [ index: Browser_Detection ] [ all elements ]

Source for file BrowserDetection.php

Documentation is available at BrowserDetection.php

  1. <?php
  2.  
  3. /**
  4.  * Browser detection class file.
  5.  * This file contains everything required to use the BrowserDetection class.
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
  8.  * Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any
  9.  * later version (if any).
  10.  *
  11.  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
  12.  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  13.  * details at: http://www.gnu.org/licenses/lgpl.html
  14.  *
  15.  * @package Browser_Detection
  16.  * @version 2.5.1
  17.  * @last-modified November 28, 2016
  18.  * @author Alexandre Valiquette
  19.  * @copyright Copyright (c) 2016, Wolfcast
  20.  * @link http://wolfcast.com/
  21.  */
  22.  
  23.  
  24. /**
  25.  * The BrowserDetection class facilitates the identification of the user's environment such as Web browser, version,
  26.  * platform or if it's a mobile device.
  27.  *
  28.  * Typical usage:
  29.  *
  30.  * $browser = new BrowserDetection();
  31.  * if ($browser->getName() == BrowserDetection::BROWSER_FIREFOX &&
  32.  *     $browser->compareVersions($browser->getVersion(), '5.0') >= 0) {
  33.  *     echo 'You are using FireFox version 5 or greater.';
  34.  * }
  35.  *
  36.  * The class is an updated version of Chris Schuld's Browser class version 1.9 which is unmaintained since August 20th,
  37.  * 2010. Chris' class was based on the original work from Gary White.
  38.  *
  39.  * Updates:
  40.  *
  41.  * 2016-11-28: Version 2.5.1
  42.  *  + Better detection of 64-bit platforms.
  43.  *
  44.  * 2016-08-19: Version 2.5.0
  45.  *  + Platform version and platform version name are now supported for Mac.
  46.  *  + Fixed platform version name for Android.
  47.  *
  48.  * 2016-08-02: Version 2.4.0
  49.  *  + Platform version and platform version name are now supported for Android.
  50.  *  + Added support for the Samsung Internet browser.
  51.  *  + Added support for the Vivaldi browser.
  52.  *  + Better support for legacy Windows versions.
  53.  *
  54.  * 2016-02-11: Version 2.3.0
  55.  *  + WARNING! Breaking change: public method getBrowser() is renamed to getName().
  56.  *  + WARNING! Breaking change: changed the compareVersions() return values to be more in line with other libraries.
  57.  *  + You can now get the exact platform version (name or version numbers) on which the browser is run on with
  58.  *    getPlatformVersion(). Only working with Windows operating systems at the moment.
  59.  *  + You can now determine if the browser is executed from a 64-bit platform with is64bitPlatform().
  60.  *  + Better detection of mobile platform for Googlebot.
  61.  *
  62.  * 2016-01-04: Version 2.2.0
  63.  *  + Added support for Microsoft Edge.
  64.  *
  65.  * 2014-12-30: Version 2.1.2
  66.  *  + Better detection of Opera.
  67.  *
  68.  * 2014-07-11: Version 2.1.1
  69.  *  + Better detection of mobile devices and platforms.
  70.  *
  71.  * 2014-06-04: Version 2.1.0
  72.  *  + Added support for IE 11+.
  73.  *
  74.  * 2013-05-27: Version 2.0.0 which is (almost) a complete rewrite based on Chris Schuld's Browser class version 1.9 plus
  75.  * changes below.
  76.  *  + Added support for Opera Mobile
  77.  *  + Added support for the Windows Phone (formerly Windows Mobile) platform
  78.  *  + Added support for BlackBerry Tablet OS and BlackBerry 10
  79.  *  + Added support for the Symbian platform
  80.  *  + Added support for Bingbot
  81.  *  + Added support for the Yahoo! Multimedia crawler
  82.  *  + Removed iPhone/iPad/iPod browsers since there are not browsers but platforms - test them with getPlatform()
  83.  *  + Removed support for Shiretoko (Firefox 3.5 alpha/beta) and MSN Browser
  84.  *  + Merged Nokia and Nokia S60
  85.  *  + Updated some deprecated browser names
  86.  *  + Many public methods are now protected
  87.  *  + Documentation updated
  88.  *
  89.  * 2010-07-04:
  90.  *  + Added detection of IE compatibility view - test with getIECompatibilityView()
  91.  *  + Added support for all (deprecated) Netscape versions
  92.  *  + Added support for Safari < 3.0
  93.  *  + Better Firefox version parsing
  94.  *  + Better Opera version parsing
  95.  *  + Better Mozilla detection
  96.  *
  97.  * @package Browser_Detection
  98.  * @version 2.5.1
  99.  * @last-modified November 28, 2016
  100.  * @author Alexandre Valiquette, Chris Schuld, Gary White
  101.  * @copyright Copyright (c) 2016, Wolfcast
  102.  * @license http://www.gnu.org/licenses/lgpl.html
  103.  * @link http://wolfcast.com/
  104.  * @link http://wolfcast.com/open-source/browser-detection/tutorial.php
  105.  * @link http://chrisschuld.com/
  106.  * @link http://www.apptools.com/phptools/browser/
  107.  */
  108. {
  109.  
  110.     /**#@+
  111.      * Constant for the name of the Web browser.
  112.      */
  113.     const BROWSER_AMAYA 'Amaya';
  114.     const BROWSER_ANDROID 'Android';
  115.     const BROWSER_BINGBOT 'Bingbot';
  116.     const BROWSER_BLACKBERRY 'BlackBerry';
  117.     const BROWSER_CHROME 'Chrome';
  118.     const BROWSER_EDGE 'Edge';
  119.     const BROWSER_FIREBIRD 'Firebird';
  120.     const BROWSER_FIREFOX 'Firefox';
  121.     const BROWSER_GALEON 'Galeon';
  122.     const BROWSER_GOOGLEBOT 'Googlebot';
  123.     const BROWSER_ICAB 'iCab';
  124.     const BROWSER_ICECAT 'GNU IceCat';
  125.     const BROWSER_ICEWEASEL 'GNU IceWeasel';
  126.     const BROWSER_IE 'Internet Explorer';
  127.     const BROWSER_IE_MOBILE 'Internet Explorer Mobile';
  128.     const BROWSER_KONQUEROR 'Konqueror';
  129.     const BROWSER_LYNX 'Lynx';
  130.     const BROWSER_MOZILLA 'Mozilla';
  131.     const BROWSER_MSNBOT 'MSNBot';
  132.     const BROWSER_MSNTV 'MSN TV';
  133.     const BROWSER_NETPOSITIVE 'NetPositive';
  134.     const BROWSER_NETSCAPE 'Netscape';
  135.     const BROWSER_NOKIA 'Nokia Browser';
  136.     const BROWSER_OMNIWEB 'OmniWeb';
  137.     const BROWSER_OPERA 'Opera';
  138.     const BROWSER_OPERA_MINI 'Opera Mini';
  139.     const BROWSER_OPERA_MOBILE 'Opera Mobile';
  140.     const BROWSER_PHOENIX 'Phoenix';
  141.     const BROWSER_SAFARI 'Safari';
  142.     const BROWSER_SAMSUNG 'Samsung Internet';
  143.     const BROWSER_SLURP 'Yahoo! Slurp';
  144.     const BROWSER_TABLET_OS 'BlackBerry Tablet OS';
  145.     const BROWSER_UNKNOWN 'unknown';
  146.     const BROWSER_VIVALDI 'Vivaldi';
  147.     const BROWSER_W3CVALIDATOR 'W3C Validator';
  148.     const BROWSER_YAHOO_MM 'Yahoo! Multimedia';
  149.     /**#@-*/
  150.  
  151.     /**#@+
  152.      * Constant for the name of the platform of the Web browser.
  153.      */
  154.     const PLATFORM_ANDROID 'Android';
  155.     const PLATFORM_BEOS 'BeOS';
  156.     const PLATFORM_BLACKBERRY 'BlackBerry';
  157.     const PLATFORM_FREEBSD 'FreeBSD';
  158.     const PLATFORM_IPAD 'iPad';
  159.     const PLATFORM_IPHONE 'iPhone';
  160.     const PLATFORM_IPOD 'iPod';
  161.     const PLATFORM_LINUX 'Linux';
  162.     const PLATFORM_MACINTOSH 'Macintosh';
  163.     const PLATFORM_NETBSD 'NetBSD';
  164.     const PLATFORM_NOKIA 'Nokia';
  165.     const PLATFORM_OPENBSD 'OpenBSD';
  166.     const PLATFORM_OPENSOLARIS 'OpenSolaris';
  167.     const PLATFORM_OS2 'OS/2';
  168.     const PLATFORM_SUNOS 'SunOS';
  169.     const PLATFORM_SYMBIAN 'Symbian';
  170.     const PLATFORM_UNKNOWN 'unknown';
  171.     const PLATFORM_VERSION_UNKNOWN 'unknown';
  172.     const PLATFORM_WINDOWS 'Windows';
  173.     const PLATFORM_WINDOWS_CE 'Windows CE';
  174.     const PLATFORM_WINDOWS_PHONE 'Windows Phone';
  175.     /**#@-*/
  176.  
  177.     /**
  178.      * Version unknown constant.
  179.      */
  180.     const VERSION_UNKNOWN 'unknown';
  181.  
  182.  
  183.     /**
  184.      * @var string 
  185.      * @access private
  186.      */
  187.     private $_agent = '';
  188.  
  189.     /**
  190.      * @var string 
  191.      * @access private
  192.      */
  193.     private $_aolVersion = '';
  194.  
  195.     /**
  196.      * @var string 
  197.      * @access private
  198.      */
  199.     private $_browserName = '';
  200.  
  201.     /**
  202.      * @var string 
  203.      * @access private
  204.      */
  205.     private $_compatibilityViewName = '';
  206.  
  207.     /**
  208.      * @var string 
  209.      * @access private
  210.      */
  211.     private $_compatibilityViewVer = '';
  212.  
  213.     /**
  214.      * @var boolean 
  215.      * @access private
  216.      */
  217.     private $_is64bit = false;
  218.  
  219.     /**
  220.      * @var boolean 
  221.      * @access private
  222.      */
  223.     private $_isAol = false;
  224.  
  225.     /**
  226.      * @var boolean 
  227.      * @access private
  228.      */
  229.     private $_isMobile = false;
  230.  
  231.     /**
  232.      * @var boolean 
  233.      * @access private
  234.      */
  235.     private $_isRobot = false;
  236.  
  237.     /**
  238.      * @var string 
  239.      * @access private
  240.      */
  241.     private $_platform = '';
  242.  
  243.     /**
  244.      * @var string 
  245.      * @access private
  246.      */
  247.     private $_platformVersion = '';
  248.  
  249.     /**
  250.      * @var string 
  251.      * @access private
  252.      */
  253.     private $_version = '';
  254.  
  255.  
  256.     //--- MAGIC METHODS ------------------------------------------------------------------------------------------------
  257.  
  258.  
  259.     /**
  260.      * BrowserDetection class constructor.
  261.      * @param string $useragent (optional) The user agent to work with. Leave empty for the current user agent
  262.      *  (contained in $_SERVER['HTTP_USER_AGENT']).
  263.      */
  264.     public function __construct($useragent '')
  265.     {
  266.         $this->setUserAgent($useragent);
  267.     }
  268.  
  269.     /**
  270.      * Determine how the class will react when it is treated like a string.
  271.      * @return string Returns an HTML formatted string with a summary of the browser informations.
  272.      */
  273.     public function __toString()
  274.     {
  275.         $result '';
  276.  
  277.         $values array();
  278.         $values[array('label' => 'User agent''value' => $this->getUserAgent());
  279.         $values[array('label' => 'Browser name''value' => $this->getName());
  280.         $values[array('label' => 'Browser version''value' => $this->getVersion());
  281.         $values[array('label' => 'Platform family''value' => $this->getPlatform());
  282.         $values[array('label' => 'Platform version''value' => $this->getPlatformVersion(true));
  283.         $values[array('label' => 'Platform version name''value' => $this->getPlatformVersion());
  284.         $values[array('label' => 'Platform is 64-bit''value' => $this->is64bitPlatform('true' 'false');
  285.         $values[array('label' => 'Is mobile''value' => $this->isMobile('true' 'false');
  286.         $values[array('label' => 'Is robot''value' => $this->isRobot('true' 'false');
  287.         $values[array('label' => 'IE is in compatibility view''value' => $this->isInIECompatibilityView('true' 'false');
  288.         $values[array('label' => 'Emulated IE version''value' => $this->isInIECompatibilityView($this->getIECompatibilityView('Not applicable');
  289.         $values[array('label' => 'Is Chrome Frame''value' => $this->isChromeFrame('true' 'false');
  290.         $values[array('label' => 'Is AOL optimized''value' => $this->isAol('true' 'false');
  291.         $values[array('label' => 'AOL version''value' => $this->isAol($this->getAolVersion('Not applicable');
  292.  
  293.         foreach ($values as $currVal{
  294.             $result .= '<strong>' htmlspecialchars($currVal['label']ENT_NOQUOTES':</strong> ' $currVal['value''<br />' PHP_EOL;
  295.         }
  296.  
  297.         return $result;
  298.     }
  299.  
  300.  
  301.     //--- PUBLIC MEMBERS -----------------------------------------------------------------------------------------------
  302.  
  303.  
  304.     /**
  305.      * Compare two version number strings.
  306.      * @param string $sourceVer The source version number.
  307.      * @param string $compareVer The version number to compare with the source version number.
  308.      * @return int Returns -1 if $sourceVer < $compareVer, 0 if $sourceVer == $compareVer or 1 if $sourceVer >
  309.      *  $compareVer.
  310.      */
  311.     public function compareVersions($sourceVer$compareVer)
  312.     {
  313.         $sourceVer explode('.'$sourceVer);
  314.         foreach ($sourceVer as $k => $v{
  315.             $sourceVer[$k$this->parseInt($v);
  316.         }
  317.  
  318.         $compareVer explode('.'$compareVer);
  319.         foreach ($compareVer as $k => $v{
  320.             $compareVer[$k$this->parseInt($v);
  321.         }
  322.  
  323.         if (count($sourceVer!= count($compareVer)) {
  324.             if (count($sourceVercount($compareVer)) {
  325.                 for ($i count($compareVer)$i count($sourceVer)$i++{
  326.                     $compareVer[$i0;
  327.                 }
  328.             else {
  329.                 for ($i count($sourceVer)$i count($compareVer)$i++{
  330.                     $sourceVer[$i0;
  331.                 }
  332.             }
  333.         }
  334.  
  335.         foreach ($sourceVer as $i => $srcVerPart{
  336.             if ($srcVerPart $compareVer[$i]{
  337.                 return 1;
  338.             else {
  339.                 if ($srcVerPart $compareVer[$i]{
  340.                     return -1;
  341.                 }
  342.             }
  343.         }
  344.  
  345.         return 0;
  346.     }
  347.  
  348.     /**
  349.      * Get the version of AOL (if any). AOL releases "optimized" Internet Explorer and Firefox versions. In the making
  350.      * they add their version number in the user agent string of these browsers.
  351.      * @return string Returns the version of AOL or an empty string if no AOL version was found.
  352.      */
  353.     public function getAolVersion()
  354.     {
  355.         return $this->_aolVersion;
  356.     }
  357.  
  358.     /**
  359.      * Get the name of the browser. All of the return values are class constants. You can compare them like this:
  360.      * $myBrowserInstance->getName() == BrowserDetection::BROWSER_FIREFOX.
  361.      * @return string Returns the name of the browser.
  362.      */
  363.     public function getName()
  364.     {
  365.         return $this->_browserName;
  366.     }
  367.  
  368.     /**
  369.      * Get the name and version of the browser emulated in the compatibility view mode (if any). Since Internet
  370.      * Explorer 8, IE can be put in compatibility mode to make websites that were created for older browsers, especially
  371.      * IE 6 and 7, look better in IE 8+ which renders web pages closer to the standards and thus differently from those
  372.      * older versions of IE.
  373.      * @param boolean $asArray (optional) Determines if the return value must be an array (true) or a string (false).
  374.      * @return mixed If a string was requested, the function returns the name and version of the browser emulated in the
  375.      *  compatibility view mode or an empty string if the browser is not in compatibility view mode. If an array was
  376.      *  requested, an array with the keys 'browser' and 'version' is returned.
  377.      */
  378.     public function getIECompatibilityView($asArray false)
  379.     {
  380.         if ($asArray{
  381.             return array('browser' => $this->_compatibilityViewName'version' => $this->_compatibilityViewVer);
  382.         else {
  383.             return trim($this->_compatibilityViewName . ' ' $this->_compatibilityViewVer);
  384.         }
  385.     }
  386.  
  387.     /**
  388.      * Get the name of the platform family on which the browser is run on (such as Windows, Apple, iPhone, etc.). All of
  389.      * the return values are class constants. You can compare them like this:
  390.      * $myBrowserInstance->getPlatform() == BrowserDetection::PLATFORM_ANDROID.
  391.      * @return string Returns the name of the platform or BrowserDetection::PLATFORM_UNKNOWN if unknown.
  392.      */
  393.     public function getPlatform()
  394.     {
  395.         return $this->_platform;
  396.     }
  397.  
  398.     /**
  399.      * Get the platform version on which the browser is run on. It can be returned as a string number like 'NT 6.3' or
  400.      * as a name like 'Windows 8.1'. When returning version string numbers for Windows NT OS families the number is
  401.      * prefixed by 'NT ' to differentiate from older Windows 3.x & 9x release. At the moment only the Windows and
  402.      * Android operating systems are supported.
  403.      * @param boolean $returnVersionNumbers (optional) Determines if the return value must be versions numbers as a
  404.      *  string (true) or the version name (false).
  405.      * @param boolean $returnServerFlavor (optional) Since some Windows NT versions have the same values, this flag
  406.      *  determines if the Server flavor is returned or not. For instance Windows 8.1 and Windows Server 2012 R2 both use
  407.      *  version 6.3. This parameter is only useful when testing for Windows.
  408.      * @return string Returns the version name/version numbers of the platform or the constant PLATFORM_VERSION_UNKNOWN
  409.      *  if unknown.
  410.      */
  411.     public function getPlatformVersion($returnVersionNumbers false$returnServerFlavor false)
  412.     {
  413.         if ($this->_platformVersion == self::PLATFORM_VERSION_UNKNOWN || $this->_platformVersion == ''{
  414.             return self::PLATFORM_VERSION_UNKNOWN;
  415.         }
  416.  
  417.         if ($returnVersionNumbers{
  418.             return $this->_platformVersion;
  419.         else {
  420.             switch ($this->getPlatform()) {
  421.                 case self::PLATFORM_WINDOWS:
  422.                     if (substr($this->_platformVersion03== 'NT '{
  423.                         return $this->windowsNTVerToStr(substr($this->_platformVersion3)$returnServerFlavor);
  424.                     else {
  425.                         return $this->windowsVerToStr($this->_platformVersion);
  426.                     }
  427.                     break;
  428.  
  429.                 case self::PLATFORM_MACINTOSH:
  430.                     return $this->macVerToStr($this->_platformVersion);
  431.                     break;
  432.  
  433.                 case self::PLATFORM_ANDROID:
  434.                     return $this->androidVerToStr($this->_platformVersion);
  435.                     break;
  436.  
  437.                 defaultreturn self::PLATFORM_VERSION_UNKNOWN;
  438.             }
  439.         }
  440.     }
  441.  
  442.     /**
  443.      * Get the user agent value used by the class to determine the browser details.
  444.      * @return string The user agent string.
  445.      */
  446.     public function getUserAgent()
  447.     {
  448.         return $this->_agent;
  449.     }
  450.  
  451.     /**
  452.      * Get the version of the browser.
  453.      * @return string Returns the version of the browser or BrowserDetection::VERSION_UNKNOWN if unknown.
  454.      */
  455.     public function getVersion()
  456.     {
  457.         return $this->_version;
  458.     }
  459.  
  460.     /**
  461.      * Determine if the browser is executed from a 64-bit platform. Keep in mind that not all platforms/browsers report
  462.      * this and the result may not always be accurate.
  463.      * @return boolean Returns true if the browser is executed from a 64-bit platform.
  464.      */
  465.     public function is64bitPlatform()
  466.     {
  467.         return $this->_is64bit;
  468.     }
  469.  
  470.     /**
  471.      * Determine if the browser is from AOL. AOL releases "optimized" Internet Explorer and Firefox versions. In the
  472.      * making they add their details in the user agent string of these browsers.
  473.      * @return boolean Returns true if the browser is from AOL, false otherwise.
  474.      */
  475.     public function isAol()
  476.     {
  477.         return $this->_isAol;
  478.     }
  479.  
  480.     /**
  481.      * Determine if the browser runs Google Chrome Frame (it's a plug-in designed for Internet Explorer 6+ based on the
  482.      * open-source Chromium project - it's like a Chrome browser within IE).
  483.      * @return boolean Returns true if the browser is using Google Chrome Frame, false otherwise.
  484.      */
  485.     public function isChromeFrame()
  486.     {
  487.         return stripos($this->_agent'chromeframe'!== false;
  488.     }
  489.  
  490.     /**
  491.      * Determine if the browser is in compatibility view or not. Since Internet Explorer 8, IE can be put in
  492.      * compatibility mode to make websites that were created for older browsers, especially IE 6 and 7, look better in
  493.      * IE 8+ which renders web pages closer to the standards and thus differently from those older versions of IE.
  494.      * @return boolean Returns true if the browser is in compatibility view, false otherwise.
  495.      */
  496.     public function isInIECompatibilityView()
  497.     {
  498.         return ($this->_compatibilityViewName != ''|| ($this->_compatibilityViewVer != '');
  499.     }
  500.  
  501.     /**
  502.      * Determine if the browser is from a mobile device or not.
  503.      * @return boolean Returns true if the browser is from a mobile device, false otherwise.
  504.      */
  505.     public function isMobile()
  506.     {
  507.         return $this->_isMobile;
  508.     }
  509.  
  510.     /**
  511.      * Determine if the browser is a robot (Googlebot, Bingbot, Yahoo! Slurp...) or not.
  512.      * @return boolean Returns true if the browser is a robot, false otherwise.
  513.      */
  514.     public function isRobot()
  515.     {
  516.         return $this->_isRobot;
  517.     }
  518.  
  519.     /**
  520.      * Set the user agent to use with the class.
  521.      * @param string $agentString (optional) The value of the user agent. If an empty string is sent (default),
  522.      *  $_SERVER['HTTP_USER_AGENT'] will be used.
  523.      */
  524.     public function setUserAgent($agentString '')
  525.     {
  526.         if (!is_string($agentString|| trim($agentString== ''{
  527.             if (array_key_exists('HTTP_USER_AGENT'$_SERVER&& is_string($_SERVER['HTTP_USER_AGENT'])) {
  528.                 $agentString $_SERVER['HTTP_USER_AGENT'];
  529.             else {
  530.                 $agentString '';
  531.             }
  532.         }
  533.  
  534.         $this->reset();
  535.         $this->_agent = $agentString;
  536.         $this->detect();
  537.     }
  538.  
  539.  
  540.     //--- PROTECTED MEMBERS --------------------------------------------------------------------------------------------
  541.  
  542.  
  543.     /**
  544.      * Convert the Android version numbers to the operating system name. For instance '1.6' returns 'Donut'.
  545.      * @access protected
  546.      * @param string $androidVer The Android version numbers as a string.
  547.      * @return string The operating system name or the constant PLATFORM_VERSION_UNKNOWN if nothing match the version
  548.      *  numbers.
  549.      */
  550.     protected function androidVerToStr($androidVer)
  551.     {
  552.         //https://en.wikipedia.org/wiki/Android_version_history
  553.  
  554.         if ($this->compareVersions($androidVer'7'>= && $this->compareVersions($androidVer'8'0{
  555.             return 'Nougat';
  556.         else if ($this->compareVersions($androidVer'6'>= && $this->compareVersions($androidVer'7'0{
  557.             return 'Marshmallow';
  558.         else if ($this->compareVersions($androidVer'5'>= && $this->compareVersions($androidVer'6'0{
  559.             return 'Lollipop';
  560.         else if ($this->compareVersions($androidVer'4.4'>= && $this->compareVersions($androidVer'5'0{
  561.             return 'KitKat';
  562.         else if ($this->compareVersions($androidVer'4.1'>= && $this->compareVersions($androidVer'4.4'0{
  563.             return 'Jelly Bean';
  564.         else if ($this->compareVersions($androidVer'4'>= && $this->compareVersions($androidVer'4.1'0{
  565.             return 'Ice Cream Sandwich';
  566.         else if ($this->compareVersions($androidVer'3'>= && $this->compareVersions($androidVer'4'0{
  567.             return 'Honeycomb';
  568.         else if ($this->compareVersions($androidVer'2.3'>= && $this->compareVersions($androidVer'3'0{
  569.             return 'Gingerbread';
  570.         else if ($this->compareVersions($androidVer'2.2'>= && $this->compareVersions($androidVer'2.3'0{
  571.             return 'Froyo';
  572.         else if ($this->compareVersions($androidVer'2'>= && $this->compareVersions($androidVer'2.2'0{
  573.             return 'Eclair';
  574.         else if ($this->compareVersions($androidVer'1.6'>= && $this->compareVersions($androidVer'2'0{
  575.             return 'Donut';
  576.         else if ($this->compareVersions($androidVer'1.5'>= && $this->compareVersions($androidVer'1.6'0{
  577.             return 'Cupcake';
  578.         else {
  579.             return self::PLATFORM_VERSION_UNKNOWN//Unknown/unnamed Android version
  580.         }
  581.     }
  582.  
  583.     /**
  584.      * Determine if the browser is the Amaya Web editor or not.
  585.      * @access protected
  586.      * @link http://www.w3.org/Amaya/
  587.      * @return boolean Returns true if the browser is Amaya, false otherwise.
  588.      */
  589.     protected function checkBrowserAmaya()
  590.     {
  591.         return $this->checkSimpleBrowserUA('amaya'$this->_agentself::BROWSER_AMAYA);
  592.     }
  593.  
  594.     /**
  595.      * Determine if the browser is the Android browser (based on the WebKit layout engine and coupled with Chrome's
  596.      * JavaScript engine) or not.
  597.      * @access protected
  598.      * @return boolean Returns true if the browser is the Android browser, false otherwise.
  599.      */
  600.     protected function checkBrowserAndroid()
  601.     {
  602.         //Android don't use the standard "Android/1.0", it uses "Android 1.0;" instead
  603.         return $this->checkSimpleBrowserUA('Android'$this->_agentself::BROWSER_ANDROIDtrue);
  604.     }
  605.  
  606.     /**
  607.      * Determine if the browser is the Bingbot crawler or not.
  608.      * @access protected
  609.      * @link http://www.bing.com/webmaster/help/which-crawlers-does-bing-use-8c184ec0
  610.      * @return boolean Returns true if the browser is Bingbot, false otherwise.
  611.      */
  612.     protected function checkBrowserBingbot()
  613.     {
  614.         return $this->checkSimpleBrowserUA('bingbot'$this->_agentself::BROWSER_BINGBOTfalsetrue);
  615.     }
  616.  
  617.     /**
  618.      * Determine if the browser is the BlackBerry browser or not.
  619.      * @access protected
  620.      * @link http://supportforums.blackberry.com/t5/Web-and-WebWorks-Development/How-to-detect-the-BlackBerry-Browser/ta-p/559862
  621.      * @return boolean Returns true if the browser is the BlackBerry browser, false otherwise.
  622.      */
  623.     protected function checkBrowserBlackBerry()
  624.     {
  625.         $found false;
  626.  
  627.         //Tablet OS check
  628.         if ($this->checkSimpleBrowserUA('RIM Tablet OS'$this->_agentself::BROWSER_TABLET_OStrue)) {
  629.             return true;
  630.         }
  631.  
  632.         //Version 6, 7 & 10 check (versions 8 & 9 does not exists)
  633.         if ($this->checkBrowserUAWithVersion(array('BlackBerry''BB10')$this->_agentself::BROWSER_BLACKBERRYtrue)) {
  634.             if ($this->getVersion(== self::VERSION_UNKNOWN{
  635.                 $found true;
  636.             else {
  637.                 return true;
  638.             }
  639.         }
  640.  
  641.         //Version 4.2 to 5.0 check
  642.         if ($this->checkSimpleBrowserUA('BlackBerry'$this->_agentself::BROWSER_BLACKBERRYtrue)) {
  643.             if ($this->getVersion(== self::VERSION_UNKNOWN{
  644.                 $found true;
  645.             else {
  646.                 return true;
  647.             }
  648.         }
  649.  
  650.         return $found;
  651.     }
  652.  
  653.     /**
  654.      * Determine if the browser is Chrome or not.
  655.      * @access protected
  656.      * @link http://www.google.com/chrome/
  657.      * @return boolean Returns true if the browser is Chrome, false otherwise.
  658.      */
  659.     protected function checkBrowserChrome()
  660.     {
  661.         return $this->checkSimpleBrowserUA('Chrome'$this->_agentself::BROWSER_CHROME);
  662.     }
  663.  
  664.     /**
  665.      * Determine if the browser is Edge or not.
  666.      * @access protected
  667.      * @return boolean Returns true if the browser is Edge, false otherwise.
  668.      */
  669.     protected function checkBrowserEdge()
  670.     {
  671.         return $this->checkSimpleBrowserUA('Edge'$this->_agentself::BROWSER_EDGE);
  672.     }
  673.  
  674.     /**
  675.      * Determine if the browser is Firebird or not. Firebird was the name of Firefox from version 0.6 to 0.7.1.
  676.      * @access protected
  677.      * @return boolean Returns true if the browser is Firebird, false otherwise.
  678.      */
  679.     protected function checkBrowserFirebird()
  680.     {
  681.         return $this->checkSimpleBrowserUA('Firebird'$this->_agentself::BROWSER_FIREBIRD);
  682.     }
  683.  
  684.     /**
  685.      * Determine if the browser is Firefox or not.
  686.      * @access protected
  687.      * @link http://www.mozilla.org/en-US/firefox/new/
  688.      * @return boolean Returns true if the browser is Firefox, false otherwise.
  689.      */
  690.     protected function checkBrowserFirefox()
  691.     {
  692.         //Safari heavily matches with Firefox, ensure that Safari is filtered out...
  693.         if (preg_match('/.*Firefox[ (\/]*([a-z0-9.-]*)/i'$this->_agent$matches&&
  694.                 stripos($this->_agent'Safari'=== false{
  695.             $this->setBrowser(self::BROWSER_FIREFOX);
  696.             $this->setVersion($matches[1]);
  697.             $this->setMobile(false);
  698.             $this->setRobot(false);
  699.  
  700.             return true;
  701.         }
  702.  
  703.         return false;
  704.     }
  705.  
  706.     /**
  707.      * Determine if the browser is Galeon or not. The browser was discontinued on September 27, 2008.
  708.      * @access protected
  709.      * @link http://en.wikipedia.org/wiki/Galeon
  710.      * @return boolean Returns true if the browser is Galeon, false otherwise.
  711.      */
  712.     protected function checkBrowserGaleon()
  713.     {
  714.         return $this->checkSimpleBrowserUA('Galeon'$this->_agentself::BROWSER_GALEON);
  715.     }
  716.  
  717.     /**
  718.      * Determine if the browser is the Googlebot crawler or not.
  719.      * @access protected
  720.      * @return boolean Returns true if the browser is Googlebot, false otherwise.
  721.      */
  722.     protected function checkBrowserGooglebot()
  723.     {
  724.         if ($this->checkSimpleBrowserUA('Googlebot'$this->_agentself::BROWSER_GOOGLEBOTfalsetrue)) {
  725.             if (strpos(strtolower($this->_agent)'googlebot-mobile'!== false{
  726.                 $this->setMobile(true);
  727.             }
  728.  
  729.             return true;
  730.         }
  731.  
  732.         return false;
  733.     }
  734.  
  735.     /**
  736.      * Determine if the browser is iCab or not.
  737.      * @access protected
  738.      * @link http://www.icab.de/
  739.      * @return boolean Returns true if the browser is iCab, false otherwise.
  740.      */
  741.     protected function checkBrowserIcab()
  742.     {
  743.         //Some (early) iCab versions don't use the standard "iCab/1.0", they uses "iCab 1.0;" instead
  744.         return $this->checkSimpleBrowserUA('iCab'$this->_agentself::BROWSER_ICAB);
  745.     }
  746.  
  747.     /**
  748.      * Determine if the browser is GNU IceCat (formerly known as GNU IceWeasel) or not.
  749.      * @access protected
  750.      * @link http://www.gnu.org/software/gnuzilla/
  751.      * @return boolean Returns true if the browser is GNU IceCat, false otherwise.
  752.      */
  753.     protected function checkBrowserIceCat()
  754.     {
  755.         return $this->checkSimpleBrowserUA('IceCat'$this->_agentself::BROWSER_ICECAT);
  756.     }
  757.  
  758.     /**
  759.      * Determine if the browser is GNU IceWeasel (now know as GNU IceCat) or not.
  760.      * @access protected
  761.      * @see checkBrowserIceCat()
  762.      * @return boolean Returns true if the browser is GNU IceWeasel, false otherwise.
  763.      */
  764.     protected function checkBrowserIceWeasel()
  765.     {
  766.         return $this->checkSimpleBrowserUA('Iceweasel'$this->_agentself::BROWSER_ICEWEASEL);
  767.     }
  768.  
  769.     /**
  770.      * Determine if the browser is Internet Explorer or not.
  771.      * @access protected
  772.      * @link http://www.microsoft.com/ie/
  773.      * @link http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
  774.      * @return boolean Returns true if the browser is Internet Explorer, false otherwise.
  775.      */
  776.     protected function checkBrowserInternetExplorer()
  777.     {
  778.         //Test for Internet Explorer Mobile (formerly Pocket Internet Explorer)
  779.         if ($this->checkSimpleBrowserUA(array('IEMobile''MSPIE')$this->_agentself::BROWSER_IE_MOBILEtrue)) {
  780.             return true;
  781.         }
  782.  
  783.         //Several browsers uses IE compatibility UAs filter these browsers out (but after testing for IE Mobile)
  784.         if ($this->containString($this->_agentarray('Opera''BlackBerry''Nokia'))) {
  785.             return false;
  786.         }
  787.  
  788.         //Test for Internet Explorer 1
  789.         if ($this->checkSimpleBrowserUA('Microsoft Internet Explorer'$this->_agentself::BROWSER_IE)) {
  790.             if ($this->getVersion(== self::VERSION_UNKNOWN{
  791.                 if (preg_match('/308|425|426|474|0b1/i'$this->_agent)) {
  792.                     $this->setVersion('1.5');
  793.                 else {
  794.                     $this->setVersion('1.0');
  795.                 }
  796.             }
  797.             return true;
  798.         }
  799.  
  800.         //Test for Internet Explorer 2+
  801.         if ($this->containString($this->_agentarray('MSIE''Trident'))) {
  802.             $version '';
  803.  
  804.             if (stripos($this->_agent'Trident'!== false{
  805.                 //Test for Internet Explorer 11+ (check the rv: string)
  806.                 if (stripos($this->_agent'rv:'!== false{
  807.                     if ($this->checkSimpleBrowserUA('Trident'$this->_agentself::BROWSER_IEfalsefalse'rv:')) {
  808.                         return true;
  809.                     }
  810.                 else {
  811.                     //Test for Internet Explorer 8, 9 & 10 (check the Trident string)
  812.                     if (preg_match('/Trident\/([\d]+)/i'$this->_agent$foundVersion)) {
  813.                         //Trident started with version 4.0 on IE 8
  814.                         $verFromTrident $this->parseInt($foundVersion[1]4;
  815.                         if ($verFromTrident >= 8{
  816.                             $version $verFromTrident '.0';
  817.                         }
  818.                     }
  819.                 }
  820.  
  821.                 //If we have the IE version from Trident, we can check for the compatibility view mode
  822.                 if ($version != ''{
  823.                     $emulatedVer '';
  824.                     preg_match_all('/MSIE\s*([^\s;$]+)/i'$this->_agent$foundVersions);
  825.                     foreach ($foundVersions[1as $currVer{
  826.                         //Keep the lowest MSIE version for the emulated version (in compatibility view mode)
  827.                         if ($emulatedVer == '' || $this->compareVersions($emulatedVer$currVer== 1{
  828.                             $emulatedVer $currVer;
  829.                         }
  830.                     }
  831.                     //Set the compatibility view mode if $version != $emulatedVer
  832.                     if ($this->compareVersions($version$emulatedVer!= 0{
  833.                         $this->_compatibilityViewName = self::BROWSER_IE;
  834.                         $this->_compatibilityViewVer = $this->cleanVersion($emulatedVer);
  835.                     }
  836.                 }
  837.             }
  838.  
  839.             //Test for Internet Explorer 2-7 versions if needed
  840.             if ($version == ''{
  841.                 preg_match_all('/MSIE\s+([^\s;$]+)/i'$this->_agent$foundVersions);
  842.                 foreach ($foundVersions[1as $currVer{
  843.                     //Keep the highest MSIE version
  844.                     if ($version == '' || $this->compareVersions($version$currVer== -1{
  845.                         $version $currVer;
  846.                     }
  847.                 }
  848.             }
  849.  
  850.             $this->setBrowser(self::BROWSER_IE);
  851.             $this->setVersion($version);
  852.             $this->setMobile(false);
  853.             $this->setRobot(false);
  854.  
  855.             return true;
  856.         }
  857.  
  858.         return false;
  859.     }
  860.  
  861.     /**
  862.      * Determine if the browser is Konqueror or not.
  863.      * @access protected
  864.      * @link http://www.konqueror.org/
  865.      * @return boolean Returns true if the browser is Konqueror, false otherwise.
  866.      */
  867.     protected function checkBrowserKonqueror()
  868.     {
  869.         return $this->checkSimpleBrowserUA('Konqueror'$this->_agentself::BROWSER_KONQUEROR);
  870.     }
  871.  
  872.     /**
  873.      * Determine if the browser is Lynx or not. It is the oldest web browser currently in general use and development.
  874.      * It is a text-based only Web browser.
  875.      * @access protected
  876.      * @link http://en.wikipedia.org/wiki/Lynx
  877.      * @return boolean Returns true if the browser is Lynx, false otherwise.
  878.      */
  879.     protected function checkBrowserLynx()
  880.     {
  881.         return $this->checkSimpleBrowserUA('Lynx'$this->_agentself::BROWSER_LYNX);
  882.     }
  883.  
  884.     /**
  885.      * Determine if the browser is Mozilla or not.
  886.      * @access protected
  887.      * @return boolean Returns true if the browser is Mozilla, false otherwise.
  888.      */
  889.     protected function checkBrowserMozilla()
  890.     {
  891.         return $this->checkSimpleBrowserUA('Mozilla'$this->_agentself::BROWSER_MOZILLAfalsefalse'rv:');
  892.     }
  893.  
  894.     /**
  895.      * Determine if the browser is the MSNBot crawler or not. In October 2010 it was replaced by the Bingbot robot.
  896.      * @access protected
  897.      * @see checkBrowserBingbot()
  898.      * @return boolean Returns true if the browser is MSNBot, false otherwise.
  899.      */
  900.     protected function checkBrowserMsnBot()
  901.     {
  902.         return $this->checkSimpleBrowserUA('msnbot'$this->_agentself::BROWSER_MSNBOTfalsetrue);
  903.     }
  904.  
  905.     /**
  906.      * Determine if the browser is MSN TV (formerly WebTV) or not.
  907.      * @access protected
  908.      * @link http://en.wikipedia.org/wiki/MSN_TV
  909.      * @return boolean Returns true if the browser is WebTv, false otherwise.
  910.      */
  911.     protected function checkBrowserMsnTv()
  912.     {
  913.         return $this->checkSimpleBrowserUA('webtv'$this->_agentself::BROWSER_MSNTV);
  914.     }
  915.  
  916.     /**
  917.      * Determine if the browser is NetPositive or not. The browser is discontinued since November 2001.
  918.      * @access protected
  919.      * @link http://en.wikipedia.org/wiki/NetPositive
  920.      * @return boolean Returns true if the browser is NetPositive, false otherwise.
  921.      */
  922.     protected function checkBrowserNetPositive()
  923.     {
  924.         return $this->checkSimpleBrowserUA('NetPositive'$this->_agentself::BROWSER_NETPOSITIVE);
  925.     }
  926.  
  927.     /**
  928.      * Determine if the browser is Netscape or not. Official support for this browser ended on March 1st, 2008.
  929.      * @access protected
  930.      * @link http://en.wikipedia.org/wiki/Netscape
  931.      * @return boolean Returns true if the browser is Netscape, false otherwise.
  932.      */
  933.     protected function checkBrowserNetscape()
  934.     {
  935.         //BlackBerry & Nokia UAs can conflict with Netscape UAs
  936.         if ($this->containString($this->_agentarray('BlackBerry''Nokia'))) {
  937.             return false;
  938.         }
  939.  
  940.         //Netscape v6 to v9 check
  941.         if ($this->checkSimpleBrowserUA(array('Netscape''Navigator''Netscape6')$this->_agentself::BROWSER_NETSCAPE)) {
  942.             return true;
  943.         }
  944.  
  945.         //Netscape v1-4 (v5 don't exists)
  946.         $found false;
  947.         if (stripos($this->_agent'Mozilla'!== false && stripos($this->_agent'rv:'=== false{
  948.             $version '';
  949.             $verParts explode('/'stristr($this->_agent'Mozilla'));
  950.             if (count($verParts1{
  951.                 $verParts explode(' '$verParts[1]);
  952.                 $verParts explode('.'$verParts[0]);
  953.  
  954.                 $majorVer $this->parseInt($verParts[0]);
  955.                 if ($majorVer && $majorVer 5{
  956.                     $version implode('.'$verParts);
  957.                     $found true;
  958.  
  959.                     if (strtolower(substr($version-4)) == '-sgi'{
  960.                         $version substr($version0-4);
  961.                     else {
  962.                         if (strtolower(substr($version-4)) == 'gold'{
  963.                             $version substr($version0-4' Gold'//Doubles spaces (if any) will be normalized by setVersion()
  964.                         }
  965.                     }
  966.                 }
  967.             }
  968.         }
  969.  
  970.         if ($found{
  971.             $this->setBrowser(self::BROWSER_NETSCAPE);
  972.             $this->setVersion($version);
  973.             $this->setMobile(false);
  974.             $this->setRobot(false);
  975.         }
  976.  
  977.         return $found;
  978.     }
  979.  
  980.     /**
  981.      * Determine if the browser is a Nokia browser or not.
  982.      * @access protected
  983.      * @link http://www.developer.nokia.com/Community/Wiki/User-Agent_headers_for_Nokia_devices
  984.      * @return boolean Returns true if the browser is a Nokia browser, false otherwise.
  985.      */
  986.     protected function checkBrowserNokia()
  987.     {
  988.         if ($this->containString($this->_agentarray('Nokia5800''Nokia5530''Nokia5230'))) {
  989.             $this->setBrowser(self::BROWSER_NOKIA);
  990.             $this->setVersion('7.0');
  991.             $this->setMobile(true);
  992.             $this->setRobot(false);
  993.  
  994.             return true;
  995.         }
  996.  
  997.         if ($this->checkSimpleBrowserUA(array('NokiaBrowser''BrowserNG''Series60''S60''S40OviBrowser')$this->_agentself::BROWSER_NOKIAtrue)) {
  998.             return true;
  999.         }
  1000.  
  1001.         return false;
  1002.     }
  1003.  
  1004.     /**
  1005.      * Determine if the browser is OmniWeb or not.
  1006.      * @access protected
  1007.      * @link http://www.omnigroup.com/products/omniweb/
  1008.      * @return boolean Returns true if the browser is OmniWeb, false otherwise.
  1009.      */
  1010.     protected function checkBrowserOmniWeb()
  1011.     {
  1012.         if ($this->checkSimpleBrowserUA('OmniWeb'$this->_agentself::BROWSER_OMNIWEB)) {
  1013.             //Some versions of OmniWeb prefix the version number with "v"
  1014.             if ($this->getVersion(!= self::VERSION_UNKNOWN && strtolower(substr($this->getVersion()01)) == 'v'{
  1015.                 $this->setVersion(substr($this->getVersion()1));
  1016.             }
  1017.             return true;
  1018.         }
  1019.  
  1020.         return false;
  1021.     }
  1022.  
  1023.     /**
  1024.      * Determine if the browser is Opera or not.
  1025.      * @access protected
  1026.      * @link http://www.opera.com/
  1027.      * @link http://www.opera.com/mini/
  1028.      * @link http://www.opera.com/mobile/
  1029.      * @link http://my.opera.com/community/openweb/idopera/
  1030.      * @return boolean Returns true if the browser is Opera, false otherwise.
  1031.      */
  1032.     protected function checkBrowserOpera()
  1033.     {
  1034.         if ($this->checkBrowserUAWithVersion('Opera Mobi'$this->_agentself::BROWSER_OPERA_MOBILEtrue)) {
  1035.             return true;
  1036.         }
  1037.  
  1038.         if ($this->checkSimpleBrowserUA('Opera Mini'$this->_agentself::BROWSER_OPERA_MINItrue)) {
  1039.             return true;
  1040.         }
  1041.  
  1042.         $version '';
  1043.         $found $this->checkBrowserUAWithVersion('Opera'$this->_agentself::BROWSER_OPERA);
  1044.         if ($found && $this->getVersion(!= self::VERSION_UNKNOWN{
  1045.             $version $this->getVersion();
  1046.         }
  1047.  
  1048.         if (!$found || $version == ''{
  1049.             if ($this->checkSimpleBrowserUA('Opera'$this->_agentself::BROWSER_OPERA)) {
  1050.                 return true;
  1051.             }
  1052.         }
  1053.  
  1054.         if (!$found && $this->checkSimpleBrowserUA('Chrome'$this->_agentself::BROWSER_CHROME) ) {
  1055.             if ($this->checkSimpleBrowserUA('OPR/'$this->_agentself::BROWSER_OPERA)) {
  1056.                 return true;
  1057.             }
  1058.         }
  1059.  
  1060.         return $found;
  1061.     }
  1062.  
  1063.     /**
  1064.      * Determine if the browser is Phoenix or not. Phoenix was the name of Firefox from version 0.1 to 0.5.
  1065.      * @access protected
  1066.      * @return boolean Returns true if the browser is Phoenix, false otherwise.
  1067.      */
  1068.     protected function checkBrowserPhoenix()
  1069.     {
  1070.         return $this->checkSimpleBrowserUA('Phoenix'$this->_agentself::BROWSER_PHOENIX);
  1071.     }
  1072.  
  1073.     /**
  1074.      * Determine what is the browser used by the user.
  1075.      * @access protected
  1076.      * @return boolean Returns true if the browser has been identified, false otherwise.
  1077.      */
  1078.     protected function checkBrowsers()
  1079.     {
  1080.         //Changing the check order can break the class detection results!
  1081.         return
  1082.                /* Major browsers and browsers that need to be detected in a special order */
  1083.                $this->checkBrowserMsnTv(||            /* MSN TV is based on IE so we must check for MSN TV before IE */
  1084.                $this->checkBrowserInternetExplorer(||
  1085.                $this->checkBrowserOpera(||            /* Opera must be checked before Firefox, Netscape and Chrome to avoid conflicts */
  1086.                $this->checkBrowserEdge(||             /* Edge must be checked before Firefox, Safari and Chrome to avoid conflicts */
  1087.                $this->checkBrowserVivaldi(||          /* Vivaldi must be checked before Chrome and Safari to avoid conflicts */
  1088.                $this->checkBrowserSamsung(||          /* Samsung Internet browser must be checked before Chrome and Safari to avoid conflicts */
  1089.                $this->checkBrowserChrome(||           /* Chrome must be checked before Netscaoe and Mozilla to avoid conflicts */
  1090.                $this->checkBrowserOmniWeb(||          /* OmniWeb must be checked before Safari (on which it's based on) and Netscape (since it have Mozilla UAs) */
  1091.                $this->checkBrowserIcab(||             /* Check iCab before Netscape since iCab have Mozilla UAs */
  1092.                $this->checkBrowserNetPositive(||      /* Check NetPositive before Netscape since NetPositive have Mozilla UAs */
  1093.                $this->checkBrowserNetscape(||         /* Must be checked before Firefox since Netscape 8-9 are based on Firefox */
  1094.                $this->checkBrowserIceCat(||           /* Check IceCat and IceWeasel before Firefox since they are GNU builds of Firefox */
  1095.                $this->checkBrowserIceWeasel(||
  1096.                $this->checkBrowserGaleon(||           /* Galeon is based on Firefox and needs to be tested before Firefox is tested */
  1097.                $this->checkBrowserFirefox(||
  1098.                /* Current browsers that don't need to be detected in any special order */
  1099.                $this->checkBrowserKonqueror(||
  1100.                $this->checkBrowserLynx(||
  1101.                $this->checkBrowserAmaya(||
  1102.                /* Mobile */
  1103.                $this->checkBrowserAndroid(||
  1104.                $this->checkBrowserBlackBerry(||
  1105.                $this->checkBrowserNokia(||
  1106.                /* Bots */
  1107.                $this->checkBrowserGooglebot(||
  1108.                $this->checkBrowserBingbot(||
  1109.                $this->checkBrowserMsnBot(||
  1110.                $this->checkBrowserSlurp(||
  1111.                $this->checkBrowserYahooMultimedia(||
  1112.                $this->checkBrowserW3CValidator(||
  1113.                /* WebKit base check (after most other checks) */
  1114.                $this->checkBrowserSafari(||
  1115.                /* Deprecated browsers that don't need to be detected in any special order */
  1116.                $this->checkBrowserFirebird(||
  1117.                $this->checkBrowserPhoenix(||
  1118.                /* Mozilla is such an open standard that it must be checked last */
  1119.                $this->checkBrowserMozilla();
  1120.     }
  1121.  
  1122.     /**
  1123.      * Determine if the browser is Safari or not.
  1124.      * @access protected
  1125.      * @link http://www.apple.com/safari/
  1126.      * @link http://web.archive.org/web/20080514173941/http://developer.apple.com/internet/safari/uamatrix.html
  1127.      * @link http://en.wikipedia.org/wiki/Safari_version_history#Release_history
  1128.      * @return boolean Returns true if the browser is Safari, false otherwise.
  1129.      */
  1130.     protected function checkBrowserSafari()
  1131.     {
  1132.         $version '';
  1133.  
  1134.         //Check for current versions of Safari
  1135.         $found $this->checkBrowserUAWithVersion(array('Safari''AppleWebKit')$this->_agentself::BROWSER_SAFARI);
  1136.         if ($found && $this->getVersion(!= self::VERSION_UNKNOWN{
  1137.             $version $this->getVersion();
  1138.         }
  1139.  
  1140.         //Safari 1-2 didn't had a "Version" string in the UA, only a WebKit build and/or Safari build, extract version from these...
  1141.         if (!$found || $version == ''{
  1142.             if (preg_match('/.*Safari[ (\/]*([a-z0-9.-]*)/i'$this->_agent$matches)) {
  1143.                 $version $this->safariBuildToSafariVer($matches[1]);
  1144.                 $found true;
  1145.             }
  1146.         }
  1147.         if (!$found || $version == ''{
  1148.             if (preg_match('/.*AppleWebKit[ (\/]*([a-z0-9.-]*)/i'$this->_agent$matches)) {
  1149.                 $version $this->webKitBuildToSafariVer($matches[1]);
  1150.                 $found true;
  1151.             }
  1152.         }
  1153.  
  1154.         if ($found{
  1155.             $this->setBrowser(self::BROWSER_SAFARI);
  1156.             $this->setVersion($version);
  1157.             $this->setMobile(false);
  1158.             $this->setRobot(false);
  1159.         }
  1160.  
  1161.         return $found;
  1162.     }
  1163.  
  1164.     /**
  1165.      * Determine if the browser is the Samsung Internet browser or not.
  1166.      * @access protected
  1167.      * @return boolean Returns true if the browser is the the Samsung Internet browser, false otherwise.
  1168.      */
  1169.     protected function checkBrowserSamsung()
  1170.     {
  1171.         return $this->checkSimpleBrowserUA('SamsungBrowser'$this->_agentself::BROWSER_SAMSUNGtrue);
  1172.     }
  1173.  
  1174.     /**
  1175.      * Determine if the browser is the Yahoo! Slurp crawler or not.
  1176.      * @access protected
  1177.      * @return boolean Returns true if the browser is Yahoo! Slurp, false otherwise.
  1178.      */
  1179.     protected function checkBrowserSlurp()
  1180.     {
  1181.         return $this->checkSimpleBrowserUA('Yahoo! Slurp'$this->_agentself::BROWSER_SLURPfalsetrue);
  1182.     }
  1183.  
  1184.     /**
  1185.      * Test the user agent for a specific browser that use a "Version" string (like Safari and Opera). The user agent
  1186.      * should look like: "Version/1.0 Browser name/123.456" or "Browser name/123.456 Version/1.0".
  1187.      * @access protected
  1188.      * @param mixed $uaNameToLookFor The string (or array of strings) representing the browser name to find in the user
  1189.      *  agent.
  1190.      * @param string $userAgent The user agent string to work with.
  1191.      * @param string $browserName The literal browser name. Always use a class constant!
  1192.      * @param boolean $isMobile (optional) Determines if the browser is from a mobile device.
  1193.      * @param boolean $isRobot (optional) Determines if the browser is a robot or not.
  1194.      * @return boolean Returns true if we found the browser we were looking for, false otherwise.
  1195.      */
  1196.     protected function checkBrowserUAWithVersion($uaNameToLookFor$userAgent$browserName$isMobile false$isRobot false)
  1197.     {
  1198.         if (!is_array($uaNameToLookFor)) {
  1199.             $uaNameToLookFor array($uaNameToLookFor);
  1200.         }
  1201.  
  1202.         foreach ($uaNameToLookFor as $currUANameToLookFor{
  1203.             if (stripos($userAgent$currUANameToLookFor!== false{
  1204.                 $version '';
  1205.                 $verParts explode('/'stristr($this->_agent'Version'));
  1206.                 if (count($verParts1{
  1207.                     $verParts explode(' '$verParts[1]);
  1208.                     $version $verParts[0];
  1209.                 }
  1210.  
  1211.                 $this->setBrowser($browserName);
  1212.                 $this->setVersion($version);
  1213.  
  1214.                 $this->setMobile($isMobile);
  1215.                 $this->setRobot($isRobot);
  1216.  
  1217.                 return true;
  1218.             }
  1219.         }
  1220.  
  1221.         return false;
  1222.     }
  1223.  
  1224.     /**
  1225.      * Determine if the browser is Vivaldi or not.
  1226.      * @access protected
  1227.      * @return boolean Returns true if the browser is Vivaldi, false otherwise.
  1228.      */
  1229.     protected function checkBrowserVivaldi()
  1230.     {
  1231.         return $this->checkSimpleBrowserUA('Vivaldi'$this->_agentself::BROWSER_VIVALDI);
  1232.     }
  1233.  
  1234.     /**
  1235.      * Determine if the browser is the W3C Validator or not.
  1236.      * @access protected
  1237.      * @link http://validator.w3.org/
  1238.      * @return boolean Returns true if the browser is the W3C Validator, false otherwise.
  1239.      */
  1240.     protected function checkBrowserW3CValidator()
  1241.     {
  1242.         //Since the W3C validates pages with different robots we will prefix our versions with the part validated on the page...
  1243.  
  1244.         //W3C Link Checker (prefixed with "Link-")
  1245.         if ($this->checkSimpleBrowserUA('W3C-checklink'$this->_agentself::BROWSER_W3CVALIDATORfalsetrue)) {
  1246.             if ($this->getVersion(!= self::VERSION_UNKNOWN{
  1247.                 $this->setVersion('Link-' $this->getVersion());
  1248.             }
  1249.             return true;
  1250.         }
  1251.  
  1252.         //W3C CSS Validation Service (prefixed with "CSS-")
  1253.         if ($this->checkSimpleBrowserUA('Jigsaw'$this->_agentself::BROWSER_W3CVALIDATORfalsetrue)) {
  1254.             if ($this->getVersion(!= self::VERSION_UNKNOWN{
  1255.                 $this->setVersion('CSS-' $this->getVersion());
  1256.             }
  1257.             return true;
  1258.         }
  1259.  
  1260.         //W3C mobileOK Checker (prefixed with "mobileOK-")
  1261.         if ($this->checkSimpleBrowserUA('W3C-mobileOK'$this->_agentself::BROWSER_W3CVALIDATORfalsetrue)) {
  1262.             if ($this->getVersion(!= self::VERSION_UNKNOWN{
  1263.                 $this->setVersion('mobileOK-' $this->getVersion());
  1264.             }
  1265.             return true;
  1266.         }
  1267.  
  1268.         //W3C Markup Validation Service (no prefix)
  1269.         return $this->checkSimpleBrowserUA('W3C_Validator'$this->_agentself::BROWSER_W3CVALIDATORfalsetrue);
  1270.     }
  1271.  
  1272.     /**
  1273.      * Determine if the browser is the Yahoo! multimedia crawler or not.
  1274.      * @access protected
  1275.      * @return boolean Returns true if the browser is the Yahoo! multimedia crawler, false otherwise.
  1276.      */
  1277.     protected function checkBrowserYahooMultimedia()
  1278.     {
  1279.         return $this->checkSimpleBrowserUA('Yahoo-MMCrawler'$this->_agentself::BROWSER_YAHOO_MMfalsetrue);
  1280.     }
  1281.  
  1282.     /**
  1283.      * Determine if the user is using an AOL "optimized" browser or not.
  1284.      * @access protected
  1285.      * @return boolean Returns true if the browser is AOL optimized, false otherwise.
  1286.      */
  1287.     protected function checkForAol()
  1288.     {
  1289.         //AOL UAs don't use the "AOL/1.0" format, they uses "AOL 1.0; AOLBuild 100.00;"
  1290.         if (stripos($this->_agent'AOL '!== false{
  1291.             $version '';
  1292.             $verParts explode('AOL 'stristr($this->_agent'AOL '));
  1293.             if (count($verParts1{
  1294.                 $verParts explode(' '$verParts[1]);
  1295.                 $version $verParts[0];
  1296.             }
  1297.  
  1298.             $this->setAol(true);
  1299.             $this->setAolVersion($version);
  1300.  
  1301.             return true;
  1302.         else {
  1303.             $this->setAol(false);
  1304.             $this->setAolVersion('');
  1305.  
  1306.             return false;
  1307.         }
  1308.     }
  1309.  
  1310.     /**
  1311.      * Determine the user's platform.
  1312.      * @access protected
  1313.      */
  1314.     protected function checkPlatform()
  1315.     {
  1316.         /* Mobile platforms */
  1317.         if ($this->containString($this->_agentarray('Windows Phone''IEMobile'))) /* Check Windows Phone (formerly Windows Mobile) before Windows */
  1318.             $this->setPlatform(self::PLATFORM_WINDOWS_PHONE);
  1319.             $this->setMobile(true);
  1320.         else if (stripos($this->_agent'Windows CE'!== false/* Check Windows CE before Windows */
  1321.             $this->setPlatform(self::PLATFORM_WINDOWS_CE);
  1322.             $this->setMobile(true);
  1323.         else if (stripos($this->_agent'iPhone'!== false{     /* Check iPad/iPod/iPhone before Macintosh */
  1324.             $this->setPlatform(self::PLATFORM_IPHONE);
  1325.             $this->setMobile(true);
  1326.         else if (stripos($this->_agent'iPad'!== false{
  1327.             $this->setPlatform(self::PLATFORM_IPAD);
  1328.             $this->setMobile(true);
  1329.         else if (stripos($this->_agent'iPod'!== false{
  1330.             $this->setPlatform(self::PLATFORM_IPOD);
  1331.             $this->setMobile(true);
  1332.         else if (stripos($this->_agent'Android'!== false{
  1333.             $this->setPlatform(self::PLATFORM_ANDROID);
  1334.             $this->setMobile(true);
  1335.         else if (stripos($this->_agent'Symbian'!== false{
  1336.             $this->setPlatform(self::PLATFORM_SYMBIAN);
  1337.             $this->setMobile(true);
  1338.         else if ($this->containString($this->_agentarray('BlackBerry''BB10''RIM Tablet OS'))) {
  1339.             $this->setPlatform(self::PLATFORM_BLACKBERRY);
  1340.             $this->setMobile(true);
  1341.         else if (stripos($this->_agent'Nokia'!== false{
  1342.             $this->setPlatform(self::PLATFORM_NOKIA);
  1343.             $this->setMobile(true);
  1344.  
  1345.         /* Desktop platforms */
  1346.         else if (stripos($this->_agent'Windows'!== false{
  1347.             $this->setPlatform(self::PLATFORM_WINDOWS);
  1348.         else if (stripos($this->_agent'Macintosh'!== false{
  1349.             $this->setPlatform(self::PLATFORM_MACINTOSH);
  1350.         else if (stripos($this->_agent'Linux'!== false{
  1351.             $this->setPlatform(self::PLATFORM_LINUX);
  1352.         else if (stripos($this->_agent'FreeBSD'!== false{
  1353.             $this->setPlatform(self::PLATFORM_FREEBSD);
  1354.         else if (stripos($this->_agent'OpenBSD'!== false{
  1355.             $this->setPlatform(self::PLATFORM_OPENBSD);
  1356.         else if (stripos($this->_agent'NetBSD'!== false{
  1357.             $this->setPlatform(self::PLATFORM_NETBSD);
  1358.  
  1359.         /* Discontinued */
  1360.         else if (stripos($this->_agent'OpenSolaris'!== false{
  1361.             $this->setPlatform(self::PLATFORM_OPENSOLARIS);
  1362.         else if (stripos($this->_agent'OS/2'!== false{
  1363.             $this->setPlatform(self::PLATFORM_OS2);
  1364.         else if (stripos($this->_agent'BeOS'!== false{
  1365.             $this->setPlatform(self::PLATFORM_BEOS);
  1366.         else if (stripos($this->_agent'SunOS'!== false{
  1367.             $this->setPlatform(self::PLATFORM_SUNOS);
  1368.  
  1369.         /* Generic */
  1370.         else if (stripos($this->_agent'Win'!== false{
  1371.             $this->setPlatform(self::PLATFORM_WINDOWS);
  1372.         else if (stripos($this->_agent'Mac'!== false{
  1373.             $this->setPlatform(self::PLATFORM_MACINTOSH);
  1374.         }
  1375.  
  1376.         //Check if it's a 64-bit platform
  1377.         if ($this->containString($this->_agentarray('WOW64''Win64''AMD64''x86_64''x86-64''ia64''IRIX64',
  1378.                 'ppc64''sparc64''x64;''x64_64'))) {
  1379.             $this->set64bit(true);
  1380.         }
  1381.  
  1382.         $this->checkPlatformVersion();
  1383.     }
  1384.  
  1385.     /**
  1386.      * Determine the user's platform version.
  1387.      * @access protected
  1388.      */
  1389.     protected function checkPlatformVersion()
  1390.     {
  1391.         $result '';
  1392.  
  1393.         switch ($this->getPlatform()) {
  1394.             case self::PLATFORM_WINDOWS:
  1395.                 if (preg_match('/Windows NT\s*([^\s;\)$]+)/i'$this->_agent$foundVersion)) {
  1396.                     //Windows NT family
  1397.                     $result 'NT ' $foundVersion[1];
  1398.                 else {
  1399.                     //Windows 3.x / 9x family
  1400.                     //https://support.microsoft.com/en-us/kb/158238
  1401.  
  1402.                     if ($this->containString($this->_agentarray('Win 9x 4.90''Windows ME'))) {
  1403.                         $result '4.90.3000'//Windows Me version range from 4.90.3000 to 4.90.3000A
  1404.                     else if (stripos($this->_agent'Windows 98'!== false{
  1405.                         $result '4.10'//Windows 98 version range from 4.10.1998 to 4.10.2222B
  1406.                     else if (stripos($this->_agent'Windows 95'!== false{
  1407.                         $result '4.00'//Windows 95 version range from 4.00.950 to 4.03.1214
  1408.                     else if (preg_match('/Windows 3\.([^\s;\)$]+)/i'$this->_agent$foundVersion)) {
  1409.                         $result '3.' $foundVersion[1];
  1410.                     else if (stripos($this->_agent'Win16'!== false{
  1411.                         $result '3.1';
  1412.                     }
  1413.                 }
  1414.                 break;
  1415.  
  1416.             case self::PLATFORM_MACINTOSH:
  1417.                 if (preg_match('/Mac OS X\s*([^\s;\)$]+)/i'$this->_agent$foundVersion)) {
  1418.                     $result str_replace('_''.'$foundVersion[1]);
  1419.                 else if (stripos($this->_agent'Mac OS X'!== false{
  1420.                     $result '10';
  1421.                 }
  1422.                 break;
  1423.  
  1424.             case self::PLATFORM_ANDROID:
  1425.                 if (preg_match('/Android\s+([^\s;$]+)/i'$this->_agent$foundVersion)) {
  1426.                     $result $foundVersion[1];
  1427.                 }
  1428.                 break;
  1429.         }
  1430.  
  1431.         if (trim($result== ''{
  1432.             $result self::PLATFORM_VERSION_UNKNOWN;
  1433.         }
  1434.         $this->setPlatformVersion($result);
  1435.     }
  1436.  
  1437.     /**
  1438.      * Test the user agent for a specific browser where the browser name is immediately followed by the version number.
  1439.      * The user agent should look like: "Browser name/1.0" or "Browser 1.0;".
  1440.      * @access protected
  1441.      * @param mixed $uaNameToLookFor The string (or array of strings) representing the browser name to find in the user
  1442.      *  agent.
  1443.      * @param string $userAgent The user agent string to work with.
  1444.      * @param string $browserName The literal browser name. Always use a class constant!
  1445.      * @param boolean $isMobile (optional) Determines if the browser is from a mobile device.
  1446.      * @param boolean $isRobot (optional) Determines if the browser is a robot or not.
  1447.      * @param string $separator (optional) The separator string used to split the browser name and the version number in
  1448.      *  the user agent.
  1449.      * @return boolean Returns true if we found the browser we were looking for, false otherwise.
  1450.      */
  1451.     protected function checkSimpleBrowserUA($uaNameToLookFor$userAgent$browserName$isMobile false$isRobot false$separator '/')
  1452.     {
  1453.         if (!is_array($uaNameToLookFor)) {
  1454.             $uaNameToLookFor array($uaNameToLookFor);
  1455.         }
  1456.  
  1457.         foreach ($uaNameToLookFor as $currUANameToLookFor{
  1458.             if (stripos($userAgent$currUANameToLookFor!== false{
  1459.                 //Many browsers don't use the standard "Browser/1.0" format, they uses "Browser 1.0;" instead
  1460.                 if (stripos($userAgent$currUANameToLookFor $separator=== false{
  1461.                     $userAgent str_ireplace($currUANameToLookFor ' '$currUANameToLookFor $separator$this->_agent);
  1462.                 }
  1463.  
  1464.                 $version '';
  1465.                 $verParts explode($separatorstristr($userAgent$currUANameToLookFor));
  1466.                 if (count($verParts1{
  1467.                     $verParts explode(' '$verParts[1]);
  1468.                     $version $verParts[0];
  1469.                 }
  1470.  
  1471.                 $this->setBrowser($browserName);
  1472.                 $this->setVersion($version);
  1473.  
  1474.                 $this->setMobile($isMobile);
  1475.                 $this->setRobot($isRobot);
  1476.  
  1477.                 return true;
  1478.             }
  1479.         }
  1480.  
  1481.         return false;
  1482.     }
  1483.  
  1484.     /**
  1485.      * Find if one or more substring is contained in a string.
  1486.      * @param string $haystack The string to search in.
  1487.      * @param mixed $needle The string to search for. Can be a string or an array of strings if multiples values are to
  1488.      *  be searched.
  1489.      * @param boolean $insensitive (optional) Determines if we do a case-sensitive search (false) or a case-insensitive one
  1490.      *  (true).
  1491.      * @return boolean Returns true if the needle (or one of the needles) has been found in the haystack, false
  1492.      *  otherwise.
  1493.      */
  1494.     protected function containString($haystack$needle$insensitive true)
  1495.     {
  1496.         if (!is_array($needle)) {
  1497.             $needle array($needle);
  1498.         }
  1499.  
  1500.         foreach ($needle as $currNeedle{
  1501.             if ($insensitive{
  1502.                 $found stripos($haystack$currNeedle!== false;
  1503.             else {
  1504.                 $found strpos($haystack$currNeedle!== false;
  1505.             }
  1506.  
  1507.             if ($found{
  1508.                 return true;
  1509.             }
  1510.         }
  1511.  
  1512.         return false;
  1513.     }
  1514.  
  1515.     /**
  1516.      * Detect the user environment from the details in the user agent string.
  1517.      * @access protected
  1518.      */
  1519.     protected function detect()
  1520.     {
  1521.         $this->checkBrowsers();
  1522.         $this->checkPlatform()//Check the platform after the browser since some platforms can change the mobile value
  1523.         $this->checkForAol();
  1524.     }
  1525.  
  1526.     /**
  1527.      * Clean a version string from unwanted characters.
  1528.      * @access protected
  1529.      * @param string $version The version string to clean.
  1530.      * @return string Returns the cleaned version number string.
  1531.      */
  1532.     protected function cleanVersion($version)
  1533.     {
  1534.         //Clear anything that is in parentheses (and the parentheses themselves) - will clear started but unclosed ones too
  1535.         $cleanVer preg_replace('/\([^)]+\)?/'''$version);
  1536.         //Replace with a space any character which is NOT an alphanumeric, dot (.), hyphen (-), underscore (_) or space
  1537.         $cleanVer preg_replace('/[^0-9.a-zA-Z_ -]/'' '$cleanVer);
  1538.         //Remove trailing and leading spaces
  1539.         $cleanVer trim($cleanVer);
  1540.         //Remove double spaces if any
  1541.         while (strpos($cleanVer'  '!== false{
  1542.             $cleanVer str_replace('  '' '$cleanVer);
  1543.         }
  1544.  
  1545.         return $cleanVer;
  1546.     }
  1547.  
  1548.     /**
  1549.      * Convert the macOS version numbers to the operating system name. For instance '10.7' returns 'Mac OS X Lion'.
  1550.      * @access protected
  1551.      * @param string $macVer The macOS version numbers as a string.
  1552.      * @return string The operating system name or the constant PLATFORM_VERSION_UNKNOWN if nothing match the version
  1553.      *  numbers.
  1554.      */
  1555.     protected function macVerToStr($macVer)
  1556.     {
  1557.         //https://en.wikipedia.org/wiki/OS_X#Release_history
  1558.  
  1559.         if ($this->_platformVersion === '10'{
  1560.             return 'Mac OS X'//Unspecified Mac OS X version
  1561.         else if ($this->compareVersions($macVer'10.12'>= && $this->compareVersions($macVer'10.13'0{
  1562.             return 'macOS Sierra';
  1563.         else if ($this->compareVersions($macVer'10.11'>= && $this->compareVersions($macVer'10.12'0{
  1564.             return 'OS X El Capitan';
  1565.         else if ($this->compareVersions($macVer'10.10'>= && $this->compareVersions($macVer'10.11'0{
  1566.             return 'OS X Yosemite';
  1567.         else if ($this->compareVersions($macVer'10.9'>= && $this->compareVersions($macVer'10.10'0{
  1568.             return 'OS X Mavericks';
  1569.         else if ($this->compareVersions($macVer'10.8'>= && $this->compareVersions($macVer'10.9'0{
  1570.             return 'OS X Mountain Lion';
  1571.         else if ($this->compareVersions($macVer'10.7'>= && $this->compareVersions($macVer'10.8'0{
  1572.             return 'Mac OS X Lion';
  1573.         else if ($this->compareVersions($macVer'10.6'>= && $this->compareVersions($macVer'10.7'0{
  1574.             return 'Mac OS X Snow Leopard';
  1575.         else if ($this->compareVersions($macVer'10.5'>= && $this->compareVersions($macVer'10.6'0{
  1576.             return 'Mac OS X Leopard';
  1577.         else if ($this->compareVersions($macVer'10.4'>= && $this->compareVersions($macVer'10.5'0{
  1578.             return 'Mac OS X Tiger';
  1579.         else if ($this->compareVersions($macVer'10.3'>= && $this->compareVersions($macVer'10.4'0{
  1580.             return 'Mac OS X Panther';
  1581.         else if ($this->compareVersions($macVer'10.2'>= && $this->compareVersions($macVer'10.3'0{
  1582.             return 'Mac OS X Jaguar';
  1583.         else if ($this->compareVersions($macVer'10.1'>= && $this->compareVersions($macVer'10.2'0{
  1584.             return 'Mac OS X Puma';
  1585.         else if ($this->compareVersions($macVer'10.0'>= && $this->compareVersions($macVer'10.1'0{
  1586.             return 'Mac OS X Cheetah';
  1587.         else {
  1588.             return self::PLATFORM_VERSION_UNKNOWN//Unknown/unnamed Mac OS version
  1589.         }
  1590.     }
  1591.  
  1592.     /**
  1593.      * Get the integer value of a string variable.
  1594.      * @access protected
  1595.      * @param string $intStr The scalar value being converted to an integer.
  1596.      * @return int The integer value of $intStr on success, or 0 on failure.
  1597.      */
  1598.     protected function parseInt($intStr)
  1599.     {
  1600.         return intval($intStr10);
  1601.     }
  1602.  
  1603.     /**
  1604.      * Reset all the properties of the class.
  1605.      * @access protected
  1606.      */
  1607.     protected function reset()
  1608.     {
  1609.         $this->_agent = '';
  1610.         $this->_aolVersion = '';
  1611.         $this->_browserName = self::BROWSER_UNKNOWN;
  1612.         $this->_compatibilityViewName = '';
  1613.         $this->_compatibilityViewVer = '';
  1614.         $this->_is64bit = false;
  1615.         $this->_isAol = false;
  1616.         $this->_isMobile = false;
  1617.         $this->_isRobot = false;
  1618.         $this->_platform = self::PLATFORM_UNKNOWN;
  1619.         $this->_platformVersion = self::PLATFORM_VERSION_UNKNOWN;
  1620.         $this->_version = self::VERSION_UNKNOWN;
  1621.     }
  1622.  
  1623.     /**
  1624.      * Convert a Safari build number to a Safari version number.
  1625.      * @access protected
  1626.      * @param string $version A string representing the version number.
  1627.      * @link http://web.archive.org/web/20080514173941/http://developer.apple.com/internet/safari/uamatrix.html
  1628.      * @return string Returns the Safari version string. If the version can't be determined, an empty string is
  1629.      *  returned.
  1630.      */
  1631.     protected function safariBuildToSafariVer($version)
  1632.     {
  1633.         $verParts explode('.'$version);
  1634.  
  1635.         //We need a 3 parts version (version 2 will becomes 2.0.0)
  1636.         while (count($verParts3{
  1637.             $verParts[0;
  1638.         }
  1639.         foreach ($verParts as $i => $currPart{
  1640.             $verParts[$i$this->parseInt($currPart);
  1641.         }
  1642.  
  1643.         switch ($verParts[0]{
  1644.             case 419$result '2.0.4';
  1645.                 break;
  1646.             case 417$result '2.0.3';
  1647.                 break;
  1648.             case 416$result '2.0.2';
  1649.                 break;
  1650.  
  1651.             case 412:
  1652.                 if ($verParts[1>= 5{
  1653.                     $result '2.0.1';
  1654.                 else {
  1655.                     $result '2.0';
  1656.                 }
  1657.                 break;
  1658.  
  1659.             case 312:
  1660.                 if ($verParts[1>= 5{
  1661.                     $result '1.3.2';
  1662.                 else {
  1663.                     if ($verParts[1>= 3{
  1664.                         $result '1.3.1';
  1665.                     else {
  1666.                         $result '1.3';
  1667.                     }
  1668.                 }
  1669.                 break;
  1670.  
  1671.             case 125:
  1672.                 if ($verParts[1>= 11{
  1673.                     $result '1.2.4';
  1674.                 else {
  1675.                     if ($verParts[1>= 9{
  1676.                         $result '1.2.3';
  1677.                     else {
  1678.                         if ($verParts[1>= 7{
  1679.                             $result '1.2.2';
  1680.                         else {
  1681.                             $result '1.2';
  1682.                         }
  1683.                     }
  1684.                 }
  1685.                 break;
  1686.  
  1687.             case 100:
  1688.                 if ($verParts[1>= 1{
  1689.                     $result '1.1.1';
  1690.                 else {
  1691.                     $result '1.1';
  1692.                 }
  1693.                 break;
  1694.  
  1695.             case 85:
  1696.                 if ($verParts[1>= 8{
  1697.                     $result '1.0.3';
  1698.                 else {
  1699.                     if ($verParts[1>= 7{
  1700.                         $result '1.0.2';
  1701.                     else {
  1702.                         $result '1.0';
  1703.                     }
  1704.                 }
  1705.                 break;
  1706.  
  1707.             case 73$result '0.9';
  1708.                 break;
  1709.             case 51$result '0.8.1';
  1710.                 break;
  1711.             case 48$result '0.8';
  1712.                 break;
  1713.  
  1714.             default$result '';
  1715.         }
  1716.  
  1717.         return $result;
  1718.     }
  1719.  
  1720.     /**
  1721.      * Set if the browser is executed from a 64-bit platform.
  1722.      * @access protected
  1723.      * @param boolean $is64bit Value that tells if the browser is executed from a 64-bit platform.
  1724.      */
  1725.     protected function set64bit($is64bit)
  1726.     {
  1727.         $this->_is64bit = $is64bit == true;
  1728.     }
  1729.  
  1730.     /**
  1731.      * Set the browser to be from AOL or not.
  1732.      * @access protected
  1733.      * @param boolean $isAol Value that tells if the browser is AOL or not.
  1734.      */
  1735.     protected function setAol($isAol)
  1736.     {
  1737.         $this->_isAol = $isAol == true;
  1738.     }
  1739.  
  1740.     /**
  1741.      * Set the version of AOL.
  1742.      * @access protected
  1743.      * @param string $version The version of AOL (will be cleaned).
  1744.      */
  1745.     protected function setAolVersion($version)
  1746.     {
  1747.         $cleanVer $this->cleanVersion($version);
  1748.  
  1749.         $this->_aolVersion = $cleanVer;
  1750.     }
  1751.  
  1752.     /**
  1753.      * Set the name of the browser.
  1754.      * @access protected
  1755.      * @param string $browserName The name of the browser.
  1756.      */
  1757.     protected function setBrowser($browserName)
  1758.     {
  1759.         $this->_browserName = $browserName;
  1760.     }
  1761.  
  1762.     /**
  1763.      * Set the browser to be from a mobile device or not.
  1764.      * @access protected
  1765.      * @param boolean $isMobile (optional) Value that tells if the browser is on a mobile device or not.
  1766.      */
  1767.     protected function setMobile($isMobile true)
  1768.     {
  1769.         $this->_isMobile = $isMobile == true;
  1770.     }
  1771.  
  1772.     /**
  1773.      * Set the platform on which the browser is on.
  1774.      * @access protected
  1775.      * @param string $platform The name of the platform.
  1776.      */
  1777.     protected function setPlatform($platform)
  1778.     {
  1779.         $this->_platform = $platform;
  1780.     }
  1781.  
  1782.     /**
  1783.      * Set the platform version on which the browser is on.
  1784.      * @access protected
  1785.      * @param string $platformVer The version numbers of the platform.
  1786.      */
  1787.     protected function setPlatformVersion($platformVer)
  1788.     {
  1789.         $this->_platformVersion = $platformVer;
  1790.     }
  1791.  
  1792.     /**
  1793.      * Set the browser to be a robot (crawler) or not.
  1794.      * @access protected
  1795.      * @param boolean $isRobot (optional) Value that tells if the browser is a robot or not.
  1796.      */
  1797.     protected function setRobot($isRobot true)
  1798.     {
  1799.         $this->_isRobot = $isRobot == true;
  1800.     }
  1801.  
  1802.     /**
  1803.      * Set the version of the browser.
  1804.      * @access protected
  1805.      * @param string $version The version of the browser.
  1806.      */
  1807.     protected function setVersion($version)
  1808.     {
  1809.         $cleanVer $this->cleanVersion($version);
  1810.  
  1811.         if ($cleanVer == ''{
  1812.             $this->_version = self::VERSION_UNKNOWN;
  1813.         else {
  1814.             $this->_version = $cleanVer;
  1815.         }
  1816.     }
  1817.  
  1818.     /**
  1819.      * Convert a WebKit build number to a Safari version number.
  1820.      * @access protected
  1821.      * @param string $version A string representing the version number.
  1822.      * @link http://web.archive.org/web/20080514173941/http://developer.apple.com/internet/safari/uamatrix.html
  1823.      * @return string Returns the Safari version string. If the version can't be determined, an empty string is
  1824.      *  returned.
  1825.      */
  1826.     protected function webKitBuildToSafariVer($version)
  1827.     {
  1828.         $verParts explode('.'$version);
  1829.  
  1830.         //We need a 3 parts version (version 2 will becomes 2.0.0)
  1831.         while (count($verParts3{
  1832.             $verParts[0;
  1833.         }
  1834.         foreach ($verParts as $i => $currPart{
  1835.             $verParts[$i$this->parseInt($currPart);
  1836.         }
  1837.  
  1838.         switch ($verParts[0]{
  1839.             case 419$result '2.0.4';
  1840.                 break;
  1841.  
  1842.             case 418:
  1843.                 if ($verParts[1>= 8{
  1844.                     $result '2.0.4';
  1845.                 else {
  1846.                     $result '2.0.3';
  1847.                 }
  1848.                 break;
  1849.  
  1850.             case 417$result '2.0.3';
  1851.                 break;
  1852.  
  1853.             case 416$result '2.0.2';
  1854.                 break;
  1855.  
  1856.             case 412:
  1857.                 if ($verParts[1>= 7{
  1858.                     $result '2.0.1';
  1859.                 else {
  1860.                     $result '2.0';
  1861.                 }
  1862.                 break;
  1863.  
  1864.             case 312:
  1865.                 if ($verParts[1>= 8{
  1866.                     $result '1.3.2';
  1867.                 else {
  1868.                     if ($verParts[1>= 5{
  1869.                         $result '1.3.1';
  1870.                     else {
  1871.                         $result '1.3';
  1872.                     }
  1873.                 }
  1874.                 break;
  1875.  
  1876.             case 125:
  1877.                 if ($this->compareVersions('5.4'$verParts[1'.' $verParts[2]== -1{
  1878.                     $result '1.2.4'//125.5.5+
  1879.                 else {
  1880.                     if ($verParts[1>= 4{
  1881.                         $result '1.2.3';
  1882.                     else {
  1883.                         if ($verParts[1>= 2{
  1884.                             $result '1.2.2';
  1885.                         else {
  1886.                             $result '1.2';
  1887.                         }
  1888.                     }
  1889.                 }
  1890.                 break;
  1891.  
  1892.             //WebKit 100 can be either Safari 1.1 (Safari build 100) or 1.1.1 (Safari build 100.1)
  1893.             //for this reason, check the Safari build before the WebKit build.
  1894.             case 100$result '1.1.1';
  1895.                 break;
  1896.  
  1897.             case 85:
  1898.                 if ($verParts[1>= 8{
  1899.                     $result '1.0.3';
  1900.                 else {
  1901.                     if ($verParts[1>= 7{
  1902.                         //WebKit 85.7 can be either Safari 1.0 (Safari build 85.5) or 1.0.2 (Safari build 85.7)
  1903.                         //for this reason, check the Safari build before the WebKit build.
  1904.                         $result '1.0.2';
  1905.                     else {
  1906.                         $result '1.0';
  1907.                     }
  1908.                 }
  1909.                 break;
  1910.  
  1911.             case 73$result '0.9';
  1912.                 break;
  1913.             case 51$result '0.8.1';
  1914.                 break;
  1915.             case 48$result '0.8';
  1916.                 break;
  1917.  
  1918.             default$result '';
  1919.         }
  1920.  
  1921.         return $result;
  1922.     }
  1923.  
  1924.     /**
  1925.      * Convert the Windows NT family version numbers to the operating system name. For instance '5.1' returns
  1926.      * 'Windows XP'.
  1927.      * @access protected
  1928.      * @param string $winVer The Windows NT family version numbers as a string.
  1929.      * @param boolean $returnServerFlavor (optional) Since some Windows NT versions have the same values, this flag
  1930.      *  determines if the Server flavor is returned or not. For instance Windows 8.1 and Windows Server 2012 R2 both use
  1931.      *  version 6.3.
  1932.      * @return string The operating system name or the constant PLATFORM_VERSION_UNKNOWN if nothing match the version
  1933.      *  numbers.
  1934.      */
  1935.     protected function windowsNTVerToStr($winVer$returnServerFlavor false)
  1936.     {
  1937.         //https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
  1938.  
  1939.         $cleanWinVer explode('.'$winVer);
  1940.         while (count($cleanWinVer2{
  1941.             array_pop($cleanWinVer);
  1942.         }
  1943.         $cleanWinVer implode('.'$cleanWinVer);
  1944.  
  1945.         if ($this->compareVersions($cleanWinVer'11'>= 0{
  1946.             //Future versions of Windows
  1947.             return self::PLATFORM_WINDOWS ' ' $winVer;
  1948.         else if ($this->compareVersions($cleanWinVer'10'>= 0{
  1949.             //Current version of Windows
  1950.             return $returnServerFlavor (self::PLATFORM_WINDOWS ' Server 2016'(self::PLATFORM_WINDOWS ' 10');
  1951.         else if ($this->compareVersions($cleanWinVer'7'0{
  1952.             if ($this->compareVersions($cleanWinVer'6.3'== 0{
  1953.                 return $returnServerFlavor (self::PLATFORM_WINDOWS ' Server 2012 R2'(self::PLATFORM_WINDOWS ' 8.1');
  1954.             else if ($this->compareVersions($cleanWinVer'6.2'== 0{
  1955.                 return $returnServerFlavor (self::PLATFORM_WINDOWS ' Server 2012'(self::PLATFORM_WINDOWS ' 8');
  1956.             else if ($this->compareVersions($cleanWinVer'6.1'== 0{
  1957.                 return $returnServerFlavor (self::PLATFORM_WINDOWS ' Server 2008 R2'(self::PLATFORM_WINDOWS ' 7');
  1958.             else if ($this->compareVersions($cleanWinVer'6'== 0{
  1959.                 return $returnServerFlavor (self::PLATFORM_WINDOWS ' Server 2008'(self::PLATFORM_WINDOWS ' Vista');
  1960.             else if ($this->compareVersions($cleanWinVer'5.2'== 0{
  1961.                 return $returnServerFlavor (self::PLATFORM_WINDOWS ' Server 2003 / ' self::PLATFORM_WINDOWS ' Server 2003 R2'(self::PLATFORM_WINDOWS ' XP x64 Edition');
  1962.             else if ($this->compareVersions($cleanWinVer'5.1'== 0{
  1963.                 return self::PLATFORM_WINDOWS ' XP';
  1964.             else if ($this->compareVersions($cleanWinVer'5'== 0{
  1965.                 return self::PLATFORM_WINDOWS ' 2000';
  1966.             else if ($this->compareVersions($cleanWinVer'5'&& $this->compareVersions($cleanWinVer'3'>= 0{
  1967.                 return self::PLATFORM_WINDOWS ' NT ' $winVer;
  1968.             }
  1969.         }
  1970.  
  1971.         return self::PLATFORM_VERSION_UNKNOWN//Invalid Windows NT version
  1972.     }
  1973.  
  1974.     /**
  1975.      * Convert the Windows 3.x & 9x family version numbers to the operating system name. For instance '4.10.1998'
  1976.      * returns 'Windows 98'.
  1977.      * @access protected
  1978.      * @param string $winVer The Windows 3.x or 9x family version numbers as a string.
  1979.      * @return string The operating system name or the constant PLATFORM_VERSION_UNKNOWN if nothing match the version
  1980.      *  numbers.
  1981.      */
  1982.     protected function windowsVerToStr($winVer)
  1983.     {
  1984.         //https://support.microsoft.com/en-us/kb/158238
  1985.  
  1986.         if ($this->compareVersions($winVer'4.90'>= && $this->compareVersions($winVer'4.91'0{
  1987.             return self::PLATFORM_WINDOWS ' Me'//Normally range from 4.90.3000 to 4.90.3000A
  1988.         else if ($this->compareVersions($winVer'4.10'>= && $this->compareVersions($winVer'4.11'0{
  1989.             return self::PLATFORM_WINDOWS ' 98'//Normally range from 4.10.1998 to 4.10.2222B
  1990.         else if ($this->compareVersions($winVer'4'>= && $this->compareVersions($winVer'4.04'0{
  1991.             return self::PLATFORM_WINDOWS ' 95'//Normally range from 4.00.950 to 4.03.1214
  1992.         else if ($this->compareVersions($winVer'3.1'== || $this->compareVersions($winVer'3.11'== 0{
  1993.             return self::PLATFORM_WINDOWS ' ' $winVer;
  1994.         else if ($this->compareVersions($winVer'3.10'== 0{
  1995.             return self::PLATFORM_WINDOWS ' 3.1';
  1996.         else {
  1997.             return self::PLATFORM_VERSION_UNKNOWN//Invalid Windows version
  1998.         }
  1999.     }
  2000. }

Documentation generated on Mon, 28 Nov 2016 10:05:55 -0500 by phpDocumentor 1.4.3