Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

License

Content on this site is copyright © 2005 - 2008 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5. Some parts of this website may be subject to other licenses.
Source code for file /joomla/environment/browser.php

Documentation is available at browser.php

  1. <?php
  2. /**
  3. @version      $Id: browser.php 9764 2007-12-30 07:48:11Z ircmaxell $
  4. @package      Joomla.Framework
  5. @subpackage   Environment
  6. @copyright    Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
  7. @license      GNU/GPL, see LICENSE.php
  8. *  Joomla! is free software. This version may have been modified pursuant
  9. *  to the GNU General Public License, and as distributed it includes or
  10. *  is derivative of works licensed under the GNU General Public License or
  11. *  other free or open source software licenses.
  12. *  See COPYRIGHT.php for copyright notices and details.
  13. */
  14.  
  15. // Check to ensure this file is within the rest of the framework
  16. defined('JPATH_BASE'or die();
  17.  
  18. /**
  19.  * Browser class, provides capability information about the current web client.
  20.  *
  21.  * Browser identification is performed by examining the HTTP_USER_AGENT
  22.  * environment variable provided by the web server.
  23.  *
  24.  * This class has many influences from the lib/Browser.php code in
  25.  * version 3 of Horde.
  26.  *
  27.  * @author  Chuck Hagenbuch <chuck@horde.org>
  28.  * @author  Jon Parise <jon@horde.org>
  29.  * @author  Johan Janssens <johan.janssens@joomla.org>
  30.  *
  31.  * @package     Joomla.Framework
  32.  * @subpackage  Environment
  33.  * @since       1.5
  34.  */
  35.  
  36. class JBrowser extends JObject
  37. {
  38.     /**
  39.      * Major version number.
  40.      *
  41.      * @var integer 
  42.      */
  43.     var $_majorVersion = 0;
  44.  
  45.     /**
  46.      * Minor version number.
  47.      *
  48.      * @var integer 
  49.      */
  50.     var $_minorVersion = 0;
  51.  
  52.     /**
  53.      * Browser name.
  54.      *
  55.      * @var string 
  56.      */
  57.     var $_browser = '';
  58.  
  59.     /**
  60.      * Full user agent string.
  61.      *
  62.      * @var string 
  63.      */
  64.     var $_agent = '';
  65.  
  66.     /**
  67.      * Lower-case user agent string.
  68.      *
  69.      * @var string 
  70.      */
  71.     var $_lowerAgent = '';
  72.  
  73.     /**
  74.      * HTTP_ACCEPT string
  75.      *
  76.      * @var string 
  77.      */
  78.     var $_accept = '';
  79.  
  80.      /**
  81.      * Platform the browser is running on.
  82.      *
  83.      * @var string 
  84.      */
  85.     var $_platform = '';
  86.  
  87.     /**
  88.      * Known robots.
  89.      *
  90.      * @var array 
  91.      */
  92.     var $_robots = array(
  93.         /* The most common ones. */
  94.         
  95.         'Googlebot',
  96.         'msnbot',
  97.         'Slurp',
  98.         'Yahoo',
  99.         /* The rest alphabetically. */
  100.         
  101.         'Arachnoidea',
  102.         'ArchitextSpider',
  103.         'Ask Jeeves',
  104.         'B-l-i-t-z-Bot',
  105.         'Baiduspider',
  106.         'BecomeBot',
  107.         'cfetch',
  108.         'ConveraCrawler',
  109.         'ExtractorPro',
  110.         'FAST-WebCrawler',
  111.         'FDSE robot',
  112.         'fido',
  113.         'geckobot',
  114.         'Gigabot',
  115.         'Girafabot',
  116.         'grub-client',
  117.         'Gulliver',
  118.         'HTTrack',
  119.         'ia_archiver',
  120.         'InfoSeek',
  121.         'kinjabot',
  122.         'KIT-Fireball',
  123.         'larbin',
  124.         'LEIA',
  125.         'lmspider',
  126.         'Lycos_Spider',
  127.         'Mediapartners-Google',
  128.         'MuscatFerret',
  129.         'NaverBot',
  130.         'OmniExplorer_Bot',
  131.         'polybot',
  132.         'Pompos',
  133.         'Scooter',
  134.         'Teoma',
  135.         'TheSuBot',
  136.         'TurnitinBot',
  137.         'Ultraseek',
  138.         'ViolaBot',
  139.         'webbandit',
  140.         'www.almaden.ibm.com/cs/crawler',
  141.         'ZyBorg',
  142.     );
  143.  
  144.     /**
  145.      * Is this a mobile browser?
  146.      *
  147.      * @var boolean 
  148.      */
  149.     var $_mobile = false;
  150.  
  151.     /**
  152.      * Features.
  153.      *
  154.      * @var array 
  155.      */
  156.     var $_features = array(
  157.         'html'          => true,
  158.         'hdml'          => false,
  159.         'wml'           => false,
  160.         'images'        => true,
  161.         'iframes'       => false,
  162.         'frames'        => true,
  163.         'tables'        => true,
  164.         'java'          => true,
  165.         'javascript'    => true,
  166.         'dom'           => false,
  167.         'utf'           => false,
  168.         'rte'           => false,
  169.         'homepage'      => false,
  170.         'accesskey'     => false,
  171.         'optgroup'      => false,
  172.         'xmlhttpreq'    => false,
  173.         'cite'          => false,
  174.         'xhtml+xml'     => false,
  175.         'mathml'        => false,
  176.         'svg'           => false
  177.     );
  178.  
  179.     /**
  180.      * Quirks
  181.      *
  182.      * @var array 
  183.      */
  184.     var $_quirks = array(
  185.         'avoid_popup_windows'           => false,
  186.         'break_disposition_header'      => false,
  187.         'break_disposition_filename'    => false,
  188.         'broken_multipart_form'         => false,
  189.         'cache_same_url'                => false,
  190.         'cache_ssl_downloads'           => false,
  191.         'double_linebreak_textarea'     => false,
  192.         'empty_file_input_value'        => false,
  193.         'must_cache_forms'              => false,
  194.         'no_filename_spaces'            => false,
  195.         'no_hidden_overflow_tables'     => false,
  196.         'ow_gui_1.3'                    => false,
  197.         'png_transparency'              => false,
  198.         'scrollbar_in_way'              => false,
  199.         'scroll_tds'                    => false,
  200.         'windowed_controls'             => false,
  201.     );
  202.  
  203.     /**
  204.      * List of viewable image MIME subtypes.
  205.      * This list of viewable images works for IE and Netscape/Mozilla.
  206.      *
  207.      * @var array 
  208.      */
  209.     var $_images = array('jpeg''gif''png''pjpeg''x-png''bmp');
  210.  
  211.  
  212.     /**
  213.      * Create a browser instance (Constructor).
  214.      *
  215.      * @param string $userAgent  The browser string to parse.
  216.      * @param string $accept     The HTTP_ACCEPT settings to use.
  217.      */
  218.     function __construct($userAgent null$accept null)
  219.     {
  220.         $this->match($userAgent$accept);
  221.     }
  222.  
  223.     /**
  224.      * Returns a reference to the global Browser object, only creating it
  225.      * if it doesn't already exist.
  226.      *
  227.      * This method must be invoked as:
  228.      *      <pre>  $browser = &JBrowser::getInstance([$userAgent[, $accept]]);</pre>
  229.      *
  230.      * @access public
  231.      * @param string $userAgent  The browser string to parse.
  232.      * @param string $accept     The HTTP_ACCEPT settings to use.
  233.      * @return JBrowser  The Browser object.
  234.      */
  235.     function &getInstance($userAgent null$accept null)
  236.     {
  237.         static $instances;
  238.  
  239.         if (!isset($instances)) {
  240.             $instances array();
  241.         }
  242.  
  243.         $signature serialize(array($userAgent$accept));
  244.  
  245.         if (empty($instances[$signature])) {
  246.             $instances[$signaturenew JBrowser($userAgent$accept);
  247.         }
  248.  
  249.         return $instances[$signature];
  250.     }
  251.  
  252.    /**
  253.      * Parses the user agent string and inititializes the object with
  254.      * all the known features and quirks for the given browser.
  255.      *
  256.      * @param string $userAgent  The browser string to parse.
  257.      * @param string $accept     The HTTP_ACCEPT settings to use.
  258.      */
  259.     function match($userAgent null$accept null)
  260.     {
  261.         // Set our agent string.
  262.         if (is_null($userAgent)) {
  263.             if (isset($_SERVER['HTTP_USER_AGENT'])) {
  264.                 $this->_agent = trim($_SERVER['HTTP_USER_AGENT']);
  265.             }
  266.         else {
  267.             $this->_agent = $userAgent;
  268.         }
  269.         $this->_lowerAgent = strtolower($this->_agent);
  270.  
  271.         // Set our accept string.
  272.         if (is_null($accept)) {
  273.             if (isset($_SERVER['HTTP_ACCEPT'])) {
  274.                 $this->_accept = strtolower(trim($_SERVER['HTTP_ACCEPT']));
  275.             }
  276.         else {
  277.             $this->_accept = strtolower($accept);
  278.         }
  279.  
  280.  
  281.         // Check if browser excepts content type xhtml+xml
  282.         if (strpos($this->_accept'application/xhtml+xml')) {
  283.             $this->setFeature('xhtml+xml');
  284.         }
  285.  
  286.         // Check for a mathplayer plugin is installed, so we can use MathML on several browsers
  287.         if (strpos($this->_lowerAgent'mathplayer'!== false{
  288.             $this->setFeature('mathml');
  289.         }
  290.  
  291.         // Check for UTF support.
  292.         if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
  293.             $this->setFeature('utf'strpos(strtolower($_SERVER['HTTP_ACCEPT_CHARSET'])'utf'!== false);
  294.         }
  295.  
  296.         if (!empty($this->_agent)) {
  297.             $this->_setPlatform();
  298.  
  299.             if (strpos($this->_lowerAgent'mobileexplorer'!== false ||
  300.                 strpos($this->_lowerAgent'openwave'!== false ||
  301.                 strpos($this->_lowerAgent'opera mini'!== false ||
  302.                 strpos($this->_lowerAgent'operamini'!== false{
  303.                 $this->setFeature('frames'false);
  304.                 $this->setFeature('javascript'false);
  305.                 $this->setQuirk('avoid_popup_windows');
  306.                 $this->_mobile = true;
  307.             elseif (preg_match('|Opera[/ ]([0-9.]+)|'$this->_agent$version)) {
  308.                         $this->setBrowser('opera');
  309.                         list($this->_majorVersion$this->_minorVersionexplode('.'$version[1]);
  310.                         $this->setFeature('javascript'true);
  311.                         $this->setQuirk('no_filename_spaces');
  312.  
  313.                 if ($this->_majorVersion >= 7{
  314.                     $this->setFeature('dom');
  315.                     $this->setFeature('iframes');
  316.                     $this->setFeature('accesskey');
  317.                     $this->setFeature('optgroup');
  318.                     $this->setQuirk('double_linebreak_textarea');
  319.                 }
  320.             elseif (strpos($this->_lowerAgent'elaine/'!== false ||
  321.                         strpos($this->_lowerAgent'palmsource'!== false ||
  322.                         strpos($this->_lowerAgent'digital paths'!== false{
  323.                 $this->setBrowser('palm');
  324.                 $this->setFeature('images'false);
  325.                 $this->setFeature('frames'false);
  326.                 $this->setFeature('javascript'false);
  327.                 $this->setQuirk('avoid_popup_windows');
  328.                 $this->_mobile = true;
  329.             elseif ((preg_match('|MSIE ([0-9.]+)|'$this->_agent$version)) ||
  330.                         (preg_match('|Internet Explorer/([0-9.]+)|'$this->_agent$version))) {
  331.  
  332.                 $this->setBrowser('msie');
  333.                 $this->setQuirk('cache_ssl_downloads');
  334.                 $this->setQuirk('cache_same_url');
  335.                 $this->setQuirk('break_disposition_filename');
  336.  
  337.                 if (strpos($version[1]'.'!== false{
  338.                     list($this->_majorVersion$this->_minorVersionexplode('.'$version[1]);
  339.                 else {
  340.                     $this->_majorVersion = $version[1];
  341.                     $this->_minorVersion = 0;
  342.                 }
  343.  
  344.                 /* IE (< 7) on Windows does not support alpha transparency in
  345.                  * PNG images. */
  346.                 if (($this->_majorVersion < 7&&
  347.                     preg_match('/windows/i'$this->_agent)) {
  348.                     $this->setQuirk('png_transparency');
  349.                 }
  350.  
  351.                 /* Some Handhelds have their screen resolution in the
  352.                  * user agent string, which we can use to look for
  353.                  * mobile agents. */
  354.                 if (preg_match('/; (120x160|240x280|240x320|320x320)\)/'$this->_agent)) {
  355.                     $this->_mobile = true;
  356.                 }
  357.  
  358.                 switch ($this->_majorVersion{
  359.                 case 7:
  360.                     $this->setFeature('javascript'1.4);
  361.                     $this->setFeature('dom');
  362.                     $this->setFeature('iframes');
  363.                     $this->setFeature('utf');
  364.                     $this->setFeature('rte');
  365.                     $this->setFeature('homepage');
  366.                     $this->setFeature('accesskey');
  367.                     $this->setFeature('optgroup');
  368.                     $this->setFeature('xmlhttpreq');
  369.                     $this->setQuirk('scrollbar_in_way');
  370.                     break;
  371.  
  372.                 case 6:
  373.                     $this->setFeature('javascript'1.4);
  374.                     $this->setFeature('dom');
  375.                     $this->setFeature('iframes');
  376.                     $this->setFeature('utf');
  377.                     $this->setFeature('rte');
  378.                     $this->setFeature('homepage');
  379.                     $this->setFeature('accesskey');
  380.                     $this->setFeature('optgroup');
  381.                     $this->setFeature('xmlhttpreq');
  382.                     $this->setQuirk('scrollbar_in_way');
  383.                     $this->setQuirk('broken_multipart_form');
  384.                     $this->setQuirk('windowed_controls');
  385.                     break;
  386.  
  387.                 case 5:
  388.                     if ($this->getPlatform(== 'mac'{
  389.                         $this->setFeature('javascript'1.2);
  390.                         $this->setFeature('optgroup');
  391.                     else {
  392.                         // MSIE 5 for Windows.
  393.                         $this->setFeature('javascript'1.4);
  394.                         $this->setFeature('dom');
  395.                         $this->setFeature('xmlhttpreq');
  396.                         if ($this->_minorVersion >= 5{
  397.                             $this->setFeature('rte');
  398.                             $this->setQuirk('windowed_controls');
  399.                         }
  400.                     }
  401.                     $this->setFeature('iframes');
  402.                     $this->setFeature('utf');
  403.                     $this->setFeature('homepage');
  404.                     $this->setFeature('accesskey');
  405.                     if ($this->_minorVersion == 5{
  406.                         $this->setQuirk('break_disposition_header');
  407.                         $this->setQuirk('broken_multipart_form');
  408.                     }
  409.                     break;
  410.  
  411.                 case 4:
  412.                     $this->setFeature('javascript'1.2);
  413.                     $this->setFeature('accesskey');
  414.                     if ($this->_minorVersion > 0{
  415.                         $this->setFeature('utf');
  416.                     }
  417.                     break;
  418.  
  419.                 case 3:
  420.                     $this->setFeature('javascript'1.5);
  421.                     $this->setQuirk('avoid_popup_windows');
  422.                     break;
  423.                 }
  424.             elseif (preg_match('|amaya/([0-9.]+)|'$this->_agent$version)) {
  425.                 $this->setBrowser('amaya');
  426.                 $this->_majorVersion = $version[1];
  427.                 if (isset($version[2])) {
  428.                     $this->