Source for file browser.php

Documentation is available at browser.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Platform
  4.  * @subpackage  Environment
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('JPATH_PLATFORM'or die;
  11.  
  12. /**
  13.  * Browser class, provides capability information about the current web client.
  14.  *
  15.  * Browser identification is performed by examining the HTTP_USER_AGENT
  16.  * environment variable provided by the web server.
  17.  *
  18.  * This class has many influences from the lib/Browser.php code in
  19.  * version 3 of Horde by Chuck Hagenbuch and Jon Parise.
  20.  *
  21.  * @package     Joomla.Platform
  22.  * @subpackage  Environment
  23.  * @since       11.1
  24.  */
  25. class JBrowser
  26. {
  27.     /**
  28.      * @var    integer  Major version number
  29.      * @since  12.1
  30.      */
  31.     protected $majorVersion = 0;
  32.  
  33.     /**
  34.      * @var    integer  Minor version number
  35.      * @since  12.1
  36.      */
  37.     protected $minorVersion = 0;
  38.  
  39.     /**
  40.      * @var    string  Browser name.
  41.      * @since  12.1
  42.      */
  43.     protected $browser = '';
  44.  
  45.     /**
  46.      * @var    string  Full user agent string.
  47.      * @since  12.1
  48.      */
  49.     protected $agent = '';
  50.  
  51.     /**
  52.      * @var    string  Lower-case user agent string
  53.      * @since  12.1
  54.      */
  55.     protected $lowerAgent = '';
  56.  
  57.     /**
  58.      * @var    string  HTTP_ACCEPT string.
  59.      * @since  12.1
  60.      */
  61.     protected $accept = '';
  62.  
  63.     /**
  64.      * @var    array  Parsed HTTP_ACCEPT string
  65.      * @since  12.1
  66.      */
  67.     protected $acceptParsed = array();
  68.  
  69.     /**
  70.      * @var    string  Platform the browser is running on
  71.      * @since  12.1
  72.      */
  73.     protected $platform = '';
  74.  
  75.     /**
  76.      * @var    array  Known robots.
  77.      * @since  12.1
  78.      */
  79.     protected $robots = array(
  80.         /* The most common ones. */
  81.         'Googlebot',
  82.         'msnbot',
  83.         'Slurp',
  84.         'Yahoo',
  85.         /* The rest alphabetically. */
  86.         'Arachnoidea',
  87.         'ArchitextSpider',
  88.         'Ask Jeeves',
  89.         'B-l-i-t-z-Bot',
  90.         'Baiduspider',
  91.         'BecomeBot',
  92.         'cfetch',
  93.         'ConveraCrawler',
  94.         'ExtractorPro',
  95.         'FAST-WebCrawler',
  96.         'FDSE robot',
  97.         'fido',
  98.         'geckobot',
  99.         'Gigabot',
  100.         'Girafabot',
  101.         'grub-client',
  102.         'Gulliver',
  103.         'HTTrack',
  104.         'ia_archiver',
  105.         'InfoSeek',
  106.         'kinjabot',
  107.         'KIT-Fireball',
  108.         'larbin',
  109.         'LEIA',
  110.         'lmspider',
  111.         'Lycos_Spider',
  112.         'Mediapartners-Google',
  113.         'MuscatFerret',
  114.         'NaverBot',
  115.         'OmniExplorer_Bot',
  116.         'polybot',
  117.         'Pompos',
  118.         'Scooter',
  119.         'Teoma',
  120.         'TheSuBot',
  121.         'TurnitinBot',
  122.         'Ultraseek',
  123.         'ViolaBot',
  124.         'webbandit',
  125.         'www.almaden.ibm.com/cs/crawler',
  126.         'ZyBorg');
  127.  
  128.     /**
  129.      * @var    boolean  Is this a mobile browser?
  130.      * @since  12.1
  131.      */
  132.     protected $mobile = false;
  133.  
  134.     /**
  135.      * List of viewable image MIME subtypes.
  136.      * This list of viewable images works for IE and Netscape/Mozilla.
  137.      *
  138.      * @var    array 
  139.      * @since  12.1
  140.      */
  141.     protected $images = array('jpeg''gif''png''pjpeg''x-png''bmp');
  142.  
  143.     /**
  144.      * @var    array  JBrowser instances container.
  145.      * @since  11.3
  146.      */
  147.     protected static $instances array();
  148.  
  149.     /**
  150.      * Create a browser instance (constructor).
  151.      *
  152.      * @param   string  $userAgent  The browser string to parse.
  153.      * @param   string  $accept     The HTTP_ACCEPT settings to use.
  154.      *
  155.      * @since   11.1
  156.      */
  157.     public function __construct($userAgent null$accept null)
  158.     {
  159.         $this->match($userAgent$accept);
  160.     }
  161.  
  162.     /**
  163.      * Returns the global Browser object, only creating it
  164.      * if it doesn't already exist.
  165.      *
  166.      * @param   string  $userAgent  The browser string to parse.
  167.      * @param   string  $accept     The HTTP_ACCEPT settings to use.
  168.      *
  169.      * @return  JBrowser  The Browser object.
  170.      *
  171.      * @since   11.1
  172.      */
  173.     public static function getInstance($userAgent null$accept null)
  174.     {
  175.         $signature serialize(array($userAgent$accept));
  176.  
  177.         if (empty(self::$instances[$signature]))
  178.         {
  179.             self::$instances[$signaturenew JBrowser($userAgent$accept);
  180.         }
  181.  
  182.         return self::$instances[$signature];
  183.     }
  184.  
  185.     /**
  186.      * Parses the user agent string and inititializes the object with
  187.      * all the known features and quirks for the given browser.
  188.      *
  189.      * @param   string  $userAgent  The browser string to parse.
  190.      * @param   string  $accept     The HTTP_ACCEPT settings to use.
  191.      *
  192.      * @return  void 
  193.      *
  194.      * @since   11.1
  195.      */
  196.     public function match($userAgent null$accept null)
  197.     {
  198.         // Set our agent string.
  199.         if (is_null($userAgent))
  200.         {
  201.             if (isset($_SERVER['HTTP_USER_AGENT']))
  202.             {
  203.                 $this->agent = trim($_SERVER['HTTP_USER_AGENT']);
  204.             }
  205.         }
  206.         else
  207.         {
  208.             $this->agent = $userAgent;
  209.         }
  210.  
  211.         $this->lowerAgent = strtolower($this->agent);
  212.  
  213.         // Set our accept string.
  214.         if (is_null($accept))
  215.         {
  216.             if (isset($_SERVER['HTTP_ACCEPT']))
  217.             {
  218.                 $this->accept = strtolower(trim($_SERVER['HTTP_ACCEPT']));
  219.             }
  220.         }
  221.         else
  222.         {
  223.             $this->accept = strtolower($accept);
  224.         }
  225.  
  226.         if (!empty($this->agent))
  227.         {
  228.             $this->_setPlatform();
  229.  
  230.             if (strpos($this->lowerAgent'mobileexplorer'!== false
  231.                 || strpos($this->lowerAgent'openwave'!== false
  232.                 || strpos($this->lowerAgent'opera mini'!== false
  233.                 || strpos($this->lowerAgent'opera mobi'!== false
  234.                 || strpos($this->lowerAgent'operamini'!== false)
  235.             {
  236.                 $this->mobile = true;
  237.             }
  238.             elseif (preg_match('|Opera[/ ]([0-9.]+)|'$this->agent$version))
  239.             {
  240.                 $this->setBrowser('opera');
  241.                 list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  242.  
  243.                 /* Due to changes in Opera UA, we need to check Version/xx.yy,
  244.                  * but only if version is > 9.80. See: http://dev.opera.com/articles/view/opera-ua-string-changes/ */
  245.                 if ($this->majorVersion == && $this->minorVersion >= 80)
  246.                 {
  247.                     $this->identifyBrowserVersion();
  248.                 }
  249.             }
  250.             elseif (preg_match('|Chrome[/ ]([0-9.]+)|'$this->agent$version))
  251.             {
  252.                 $this->setBrowser('chrome');
  253.                 list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  254.             }
  255.             elseif (preg_match('|CrMo[/ ]([0-9.]+)|'$this->agent$version))
  256.             {
  257.                 $this->setBrowser('chrome');
  258.                 list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  259.             }
  260.             elseif (preg_match('|CriOS[/ ]([0-9.]+)|'$this->agent$version))
  261.             {
  262.                 $this->setBrowser('chrome');
  263.                 list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  264.                 $this->mobile = true;
  265.             }
  266.             elseif (strpos($this->lowerAgent'elaine/'!== false
  267.                 || strpos($this->lowerAgent'palmsource'!== false
  268.                 || strpos($this->lowerAgent'digital paths'!== false)
  269.             {
  270.                 $this->setBrowser('palm');
  271.                 $this->mobile = true;
  272.             }
  273.             elseif ((preg_match('|MSIE ([0-9.]+)|'$this->agent$version)) || (preg_match('|Internet Explorer/([0-9.]+)|'$this->agent$version)))
  274.             {
  275.                 $this->setBrowser('msie');
  276.  
  277.                 if (strpos($version[1]'.'!== false)
  278.                 {
  279.                     list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  280.                 }
  281.                 else
  282.                 {
  283.                     $this->majorVersion = $version[1];
  284.                     $this->minorVersion = 0;
  285.                 }
  286.  
  287.                 /* Some Handhelds have their screen resolution in the
  288.                  * user agent string, which we can use to look for
  289.                  * mobile agents.
  290.                  */
  291.                 if (preg_match('/; (120x160|240x280|240x320|320x320)\)/'$this->agent))
  292.                 {
  293.                     $this->mobile = true;
  294.                 }
  295.             }
  296.             elseif (preg_match('|amaya/([0-9.]+)|'$this->agent$version))
  297.             {
  298.                 $this->setBrowser('amaya');
  299.                 $this->majorVersion = $version[1];
  300.  
  301.                 if (isset($version[2]))
  302.                 {
  303.                     $this->minorVersion = $version[2];
  304.                 }
  305.             }
  306.             elseif (preg_match('|ANTFresco/([0-9]+)|'$this->agent$version))
  307.             {
  308.                 $this->setBrowser('fresco');
  309.             }
  310.             elseif (strpos($this->lowerAgent'avantgo'!== false)
  311.             {
  312.                 $this->setBrowser('avantgo');
  313.                 $this->mobile = true;
  314.             }
  315.             elseif (preg_match('|Konqueror/([0-9]+)|'$this->agent$version|| preg_match('|Safari/([0-9]+)\.?([0-9]+)?|'$this->agent$version))
  316.             {
  317.                 // Konqueror and Apple's Safari both use the KHTML
  318.                 // rendering engine.
  319.                 $this->setBrowser('konqueror');
  320.                 $this->majorVersion = $version[1];
  321.  
  322.                 if (isset($version[2]))
  323.                 {
  324.                     $this->minorVersion = $version[2];
  325.                 }
  326.  
  327.                 if (strpos($this->agent'Safari'!== false && $this->majorVersion >= 60)
  328.                 {
  329.                     // Safari.
  330.                     $this->setBrowser('safari');
  331.                     $this->identifyBrowserVersion();
  332.                 }
  333.             }
  334.             elseif (preg_match('|Mozilla/([0-9.]+)|'$this->agent$version))
  335.             {
  336.                 $this->setBrowser('mozilla');
  337.  
  338.                 list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  339.             }
  340.             elseif (preg_match('|Lynx/([0-9]+)|'$this->agent$version))
  341.             {
  342.                 $this->setBrowser('lynx');
  343.             }
  344.             elseif (preg_match('|Links \(([0-9]+)|'$this->agent$version))
  345.             {
  346.                 $this->setBrowser('links');
  347.             }
  348.             elseif (preg_match('|HotJava/([0-9]+)|'$this->agent$version))
  349.             {
  350.                 $this->setBrowser('hotjava');
  351.             }
  352.             elseif (strpos($this->agent'UP/'!== false || strpos($this->agent'UP.B'!== false || strpos($this->agent'UP.L'!== false)
  353.             {
  354.                 $this->setBrowser('up');
  355.                 $this->mobile = true;
  356.             }
  357.             elseif (strpos($this->agent'Xiino/'!== false)
  358.             {
  359.                 $this->setBrowser('xiino');
  360.                 $this->mobile = true;
  361.             }
  362.             elseif (strpos($this->agent'Palmscape/'!== false)
  363.             {
  364.                 $this->setBrowser('palmscape');
  365.                 $this->mobile = true;
  366.             }
  367.             elseif (strpos($this->agent'Nokia'!== false)
  368.             {
  369.                 $this->setBrowser('nokia');
  370.                 $this->mobile = true;
  371.             }
  372.             elseif (strpos($this->agent'Ericsson'!== false)
  373.             {
  374.                 $this->setBrowser('ericsson');
  375.                 $this->mobile = true;
  376.             }
  377.             elseif (strpos($this->lowerAgent'wap'!== false)
  378.             {
  379.                 $this->setBrowser('wap');
  380.                 $this->mobile = true;
  381.             }
  382.             elseif (strpos($this->lowerAgent'docomo'!== false || strpos($this->lowerAgent'portalmmm'!== false)
  383.             {
  384.                 $this->setBrowser('imode');
  385.                 $this->mobile = true;
  386.             }
  387.             elseif (strpos($this->agent'BlackBerry'!== false)
  388.             {
  389.                 $this->setBrowser('blackberry');
  390.                 $this->mobile = true;
  391.             }
  392.             elseif (strpos($this->agent'MOT-'!== false)
  393.             {
  394.                 $this->setBrowser('motorola');
  395.                 $this->mobile = true;
  396.             }
  397.             elseif (strpos($this->lowerAgent'j-'!== false)
  398.             {
  399.                 $this->setBrowser('mml');
  400.                 $this->mobile = true;
  401.             }
  402.         }
  403.     }
  404.  
  405.     /**
  406.      * Match the platform of the browser.
  407.      *
  408.      * This is a pretty simplistic implementation, but it's intended
  409.      * to let us tell what line breaks to send, so it's good enough
  410.      * for its purpose.
  411.      *
  412.      * @return  void 
  413.      *
  414.      * @since   11.1
  415.      */
  416.     protected function _setPlatform()
  417.     {
  418.         if (strpos($this->lowerAgent'wind'!== false)
  419.         {
  420.             $this->platform = 'win';
  421.         }
  422.         elseif (strpos($this->lowerAgent'mac'!== false)
  423.         {
  424.             $this->platform = 'mac';
  425.         }
  426.         else
  427.         {
  428.             $this->platform = 'unix';
  429.         }
  430.     }
  431.  
  432.     /**
  433.      * Return the currently matched platform.
  434.      *
  435.      * @return  string  The user's platform.
  436.      *
  437.      * @since   11.1
  438.      */
  439.     public function getPlatform()
  440.     {
  441.         return $this->platform;
  442.     }
  443.  
  444.     /**
  445.      * Set browser version, not by engine version
  446.      * Fallback to use when no other method identify the engine version
  447.      *
  448.      * @return  void 
  449.      *
  450.      * @since   11.1
  451.      */
  452.     protected function identifyBrowserVersion()
  453.     {
  454.         if (preg_match('|Version[/ ]([0-9.]+)|'$this->agent$version))
  455.         {
  456.             list ($this->majorVersion$this->minorVersionexplode('.'$version[1]);
  457.  
  458.             return;
  459.         }
  460.  
  461.         // Can't identify browser version
  462.         $this->majorVersion = 0;
  463.         $this->minorVersion = 0;
  464.         JLog::add("Can't identify browser version. Agent: " $this->agentJLog::NOTICE);
  465.     }
  466.  
  467.     /**
  468.      * Sets the current browser.
  469.      *
  470.      * @param   string  $browser  The browser to set as current.
  471.      *
  472.      * @return  void 
  473.      *
  474.      * @since   11.1
  475.      */
  476.     public function setBrowser($browser)
  477.     {
  478.         $this->browser = $browser;
  479.     }
  480.  
  481.     /**
  482.      * Retrieve the current browser.
  483.      *
  484.      * @return  string  The current browser.
  485.      *
  486.      * @since   11.1
  487.      */
  488.     public function getBrowser()
  489.     {
  490.         return $this->browser;
  491.     }
  492.  
  493.     /**
  494.      * Retrieve the current browser's major version.
  495.      *
  496.      * @return  integer  The current browser's major version
  497.      *
  498.      * @since   11.1
  499.      */
  500.     public function getMajor()
  501.     {
  502.         return $this->majorVersion;
  503.     }
  504.  
  505.     /**
  506.      * Retrieve the current browser's minor version.
  507.      *
  508.      * @return  integer  The current browser's minor version.
  509.      *
  510.      * @since   11.1
  511.      */
  512.     public function getMinor()
  513.     {
  514.         return $this->minorVersion;
  515.     }
  516.  
  517.     /**
  518.      * Retrieve the current browser's version.
  519.      *
  520.      * @return  string  The current browser's version.
  521.      *
  522.      * @since   11.1
  523.      */
  524.     public function getVersion()
  525.     {
  526.         return $this->majorVersion . '.' $this->minorVersion;
  527.     }
  528.  
  529.     /**
  530.      * Return the full browser agent string.
  531.      *
  532.      * @return  string  The browser agent string
  533.      *
  534.      * @since   11.1
  535.      */
  536.     public function getAgentString()
  537.     {
  538.         return $this->agent;
  539.     }
  540.  
  541.     /**
  542.      * Returns the server protocol in use on the current server.
  543.      *
  544.      * @return  string  The HTTP server protocol version.
  545.      *
  546.      * @since   11.1
  547.      */
  548.     public function getHTTPProtocol()
  549.     {
  550.         if (isset($_SERVER['SERVER_PROTOCOL']))
  551.         {
  552.             if (($pos strrpos($_SERVER['SERVER_PROTOCOL']'/')))
  553.             {
  554.                 return substr($_SERVER['SERVER_PROTOCOL']$pos 1);
  555.             }
  556.         }
  557.  
  558.         return null;
  559.     }
  560.  
  561.     /**
  562.      * Determines if a browser can display a given MIME type.
  563.      *
  564.      * Note that  image/jpeg and image/pjpeg *appear* to be the same
  565.      * entity, but Mozilla doesn't seem to want to accept the latter.
  566.      * For our purposes, we will treat them the same.
  567.      *
  568.      * @param   string  $mimetype  The MIME type to check.
  569.      *
  570.      * @return  boolean  True if the browser can display the MIME type.
  571.      *
  572.      * @since   11.1
  573.      */
  574.     public function isViewable($mimetype)
  575.     {
  576.         $mimetype strtolower($mimetype);
  577.         list ($type$subtypeexplode('/'$mimetype);
  578.  
  579.         if (!empty($this->accept))
  580.         {
  581.             $wildcard_match false;
  582.  
  583.             if (strpos($this->accept$mimetype!== false)
  584.             {
  585.                 return true;
  586.             }
  587.  
  588.             if (strpos($this->accept'*/*'!== false)
  589.             {
  590.                 $wildcard_match true;
  591.  
  592.                 if ($type != 'image')
  593.                 {
  594.                     return true;
  595.                 }
  596.             }
  597.  
  598.             // Deal with Mozilla pjpeg/jpeg issue
  599.             if ($this->isBrowser('mozilla'&& ($mimetype == 'image/pjpeg'&& (strpos($this->accept'image/jpeg'!== false))
  600.             {
  601.                 return true;
  602.             }
  603.  
  604.             if (!$wildcard_match)
  605.             {
  606.                 return false;
  607.             }
  608.         }
  609.  
  610.         if (!$this->hasFeature('images'|| ($type != 'image'))
  611.         {
  612.             return false;
  613.         }
  614.  
  615.         return (in_array($subtype$this->images));
  616.     }
  617.  
  618.     /**
  619.      * Determine if the given browser is the same as the current.
  620.      *
  621.      * @param   string  $browser  The browser to check.
  622.      *
  623.      * @return  boolean  Is the given browser the same as the current?
  624.      *
  625.      * @since   11.1
  626.      */
  627.     public function isBrowser($browser)
  628.     {
  629.         return ($this->browser === $browser);
  630.     }
  631.  
  632.     /**
  633.      * Determines if the browser is a robot or not.
  634.      *
  635.      * @return  boolean  True if browser is a known robot.
  636.      *
  637.      * @since   11.1
  638.      */
  639.     public function isRobot()
  640.     {
  641.         foreach ($this->robots as $robot)
  642.         {
  643.             if (strpos($this->agent$robot!== false)
  644.             {
  645.                 return true;
  646.             }
  647.         }
  648.  
  649.         return false;
  650.     }
  651.  
  652.     /**
  653.      * Determines if the browser is mobile version or not.
  654.      *
  655.      * @return boolean  True if browser is a known mobile version.
  656.      *
  657.      * @since   11.1
  658.      */
  659.     public function isMobile()
  660.     {
  661.         return $this->mobile;
  662.     }
  663.  
  664.     /**
  665.      * Determine if we are using a secure (SSL) connection.
  666.      *
  667.      * @return  boolean  True if using SSL, false if not.
  668.      *
  669.      * @since   11.1
  670.      * @deprecated  13.3 (Platform) & 4.0 (CMS) - Use the isSSLConnection method on the application object.
  671.      */
  672.     public function isSSLConnection()
  673.     {
  674.         JLog::add('JBrowser::isSSLConnection() is deprecated. Use the isSSLConnection method on the application object instead.',
  675.             JLog::WARNING'deprecated');
  676.  
  677.         return ((isset($_SERVER['HTTPS']&& ($_SERVER['HTTPS'== 'on')) || getenv('SSL_PROTOCOL_VERSION'));
  678.     }
  679. }

Documentation generated on Tue, 19 Nov 2013 14:54:46 +0100 by phpDocumentor 1.4.3