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

Source for file phpSniff.class.php

Documentation is available at phpSniff.class.php

  1. <?php
  2. /**
  3.  *  PHP Client Sniffer (phpsniff)
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Lesser General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Lesser General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Lesser General Public
  16.  *  License along with this library; if not, write to the Free Software
  17.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  *  @author Roger Raymond <epsilon7@users.sourceforge.net>
  20.  *  @version $Id: phpSniff.class.php 20884 2006-12-22 10:28:34Z markwest $
  21.  *  @copyright Copyright &copy; 2002-2004 Roger Raymond
  22.  *  @package phpSniff
  23.  *  @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
  24.  *  @filesource
  25.  */
  26. /**
  27.  *  PHP Sniffer Class
  28.  *
  29.  *  Used to determine the browser and other associated properies
  30.  *  using nothing other than the HTTP_USER_AGENT value supplied by a
  31.  *  user's web browser.
  32.  *
  33.  *  @package phpSniff
  34.  *  @access public
  35.  *  @author Roger Raymond <epsilon7@users.sourceforge.net>
  36.  */
  37. class phpSniff
  38. {
  39.  
  40.     /**
  41.      * @access private
  42.      * @var string 
  43.      */
  44.     var $_version '2.1.4';
  45.  
  46.     /**
  47.      *  $_temp_file_path
  48.      *      default : /tmp/
  49.      *      desc    : directory writable by the server to store cookie check files.
  50.      *              : trailing slash is needed. only used if you use the check cookie routine
  51.      *
  52.      *  @access public
  53.      *  @var string 
  54.      */
  55.     var $_temp_file_path        = '/tmp/'// with trailing slash
  56.  
  57.     /**
  58.      *  $_check_cookies
  59.      *      default : null
  60.      *      desc    : Allow for the script to redirect the browser in order
  61.      *              : to check for cookies.   In order for this to work, this
  62.      *              : class must be instantiated before any headers are sent.
  63.      *
  64.      *  @access public
  65.      *  @var string 
  66.      */
  67.     var $_check_cookies         = NULL;
  68.  
  69.     /**
  70.      *  $_default_language
  71.      *      default : en-us
  72.      *      desc    : language to report as if no languages are found
  73.      *  @access public
  74.      *  @var string 
  75.      */
  76.     var $_default_language      = 'en-us';
  77.  
  78.     /**
  79.      *  default : null
  80.      *  Allow for browser to Masquerade as another. (ie: Opera identifies as MSIE 5.0)
  81.      *
  82.      *  @access public
  83.      *  @var string 
  84.      */
  85.     var $_allow_masquerading    = NULL;
  86.  
  87.     /**
  88.      *  @access private
  89.      *  @var string 
  90.      */
  91.     var $_php_version           '';
  92.  
  93.  
  94.     /**
  95.      *  2D Array of browsers we wish to search for in key => value pairs.
  96.      *  <pre>
  97.      *  key   = browser to search for [as in HTTP_USER_AGENT]
  98.      *  value = value to return as 'browser' property
  99.      *  </pre>
  100.      *
  101.      *  @access public
  102.      *  @var array 
  103.      */
  104.     var $_browsers = array(
  105.         'microsoft internet explorer' => 'IE',
  106.         'msie'                        => 'IE',
  107.         'netscape6'                   => 'NS',
  108.         'netscape'                    => 'NS',
  109.         'galeon'                      => 'GA',
  110.         'phoenix'                     => 'PX',
  111.         'mozilla firebird'            => 'FB',
  112.         'firebird'                    => 'FB',
  113.         'firefox'                     => 'FX',
  114.         'chimera'                     => 'CH',
  115.         'camino'                      => 'CA',
  116.         'epiphany'                    => 'EP',
  117.         'safari'                      => 'SF',
  118.         'k-meleon'                    => 'KM',
  119.         'mozilla'                     => 'MZ',
  120.         'opera'                       => 'OP',
  121.         'konqueror'                   => 'KQ',
  122.         'icab'                        => 'IC',
  123.         'lynx'                        => 'LX',
  124.         'links'                       => 'LI',
  125.         'ncsa mosaic'                 => 'MO',
  126.         'amaya'                       => 'AM',
  127.         'omniweb'                     => 'OW',
  128.         'hotjava'                      => 'HJ',
  129.         'browsex'                     => 'BX',
  130.         'amigavoyager'                => 'AV',
  131.         'amiga-aweb'                  => 'AW',
  132.         'ibrowse'                     => 'IB'
  133.         );
  134.  
  135.     /**
  136.      *  $_javascript_versions
  137.      *      desc    : 2D Array of javascript version supported by which browser
  138.      *              : in key => value pairs.
  139.      *              : key   = javascript version
  140.      *              : value = search parameter for browsers that support the
  141.      *              :         javascript version listed in the key (comma delimited)
  142.      *              :         note: the search parameters rely on the values
  143.      *              :               set in the $_browsers array
  144.      *  @access public
  145.      *  @var array 
  146.      */
  147.     var $_javascript_versions = array(
  148.         '1.5'   =>  'NS5+,MZ,PX,FB,FX,GA,CH,CA,SF,KQ3+,KM,EP'// browsers that support JavaScript 1.5
  149.         '1.4'   =>  '',
  150.         '1.3'   =>  'NS4.05+,OP5+,IE5+',
  151.         '1.2'   =>  'NS4+,IE4+',
  152.         '1.1'   =>  'NS3+,OP,KQ',
  153.         '1.0'   =>  'NS2+,IE3+',
  154.         '0'     =>    'LI,LX,HJ'
  155.         );
  156.  
  157.     /**
  158.      *  $_browser_features
  159.      *      desc    : 2D Array of browser features supported by which browser
  160.      *              : in key => value pairs.
  161.      *              : key   = feature
  162.      *              : value = search parameter for browsers that support the
  163.      *              :         feature listed in the key (comma delimited)
  164.      *              :         note: the search parameters rely on the values
  165.      *              :               set in the $_browsers array
  166.      *  @access public
  167.      *  @var string 
  168.      */
  169.     var $_browser_features = array(
  170.         /**
  171. /**
  172.          *    the following are true by default
  173.          *    (see phpSniff.core.php $_feature_set array)
  174.          *    browsers listed here will be set to false
  175.          **/
  176.  
  177.         'html'        =>    '',
  178.         'images'    =>    'LI,LX',
  179.         'frames'     =>    'LX',
  180.         'tables'    =>    '',
  181.         'java'        =>    'OP3,LI,LX,NS1,MO,IE1,IE2',
  182.         'plugins'    =>    'IE1,IE2,LI,LX',
  183.         /**
  184. /**
  185.          *    the following are false by default
  186.          *    (see phpSniff.core.php $_feature_set array)
  187.          *    browsers listed here will be set to true
  188.          **/
  189.  
  190.         'css2'        =>    'NS5+,IE5+,MZ,PX,FB,FX,CH,CA,SF,GA,KQ3+,OP7+,KM,EP',
  191.         'css1'        =>    'NS4+,IE4+,MZ,PX,FB,FX,CH,CA,SF,GA,KQ,OP7+,KM,EP',
  192.         'iframes'    =>    'LI,IE3+,NS5+,MZ,PX,FB,FX,CH,CA,SF,GA,KQ,OP7+,KM,EP',
  193.         'xml'        =>    'IE5+,NS5+,MZ,PX,FB,FX,CH,CA,SF,GA,KQ,OP7+,KM,EP',
  194.         'dom'        =>    'IE5+,NS5+,MZ,PX,FB,FX,CH,CA,SF,GA,KQ,OP7+,KM,EP',
  195.         'hdml'        =>    '',
  196.         'wml'        =>    ''
  197.         );
  198.  
  199.     /**
  200.      *
  201.      *  $_browser_quirks
  202.      *      desc    : 2D Array of browser quirks present in which browser
  203.      *              : in key => value pairs.
  204.      *              : key   = quirk
  205.      *              : value = search parameter for browsers that feature the
  206.      *              :         quirk listed in the key (comma delimited)
  207.      *              :         note: the search parameters rely on the values
  208.      *              :               set in the $_browsers array
  209.      *  @access public
  210.      *  @var string 
  211.      */
  212.     var $_browser_quirks = array(
  213.         'must_cache_forms'            =>    'NS,MZ,FB,PX,FX',
  214.         'avoid_popup_windows'        =>    'IE3,LI,LX',
  215.         'cache_ssl_downloads'        =>    'IE',
  216.         'break_disposition_header'    =>    'IE5.5',
  217.         'empty_file_input_value'    =>    'KQ',
  218.         'scrollbar_in_way'            =>    'IE6'
  219.         );
  220.  
  221.     /**
  222.      *  @access private
  223.      *  @var array 
  224.      */
  225.     var $_browser_info array(
  226.         'ua'         => '',
  227.         'browser'    => 'Unknown',
  228.         'version'    => 0,
  229.         'maj_ver'    => 0,
  230.         'min_ver'    => 0,
  231.         'letter_ver' => '',
  232.         'javascript' => '0.0',
  233.         'platform'   => 'Unknown',
  234.         'os'         => 'Unknown',
  235.         'ip'         => 'Unknown',
  236.         'cookies'    => 'Unknown'// remains for backwards compatability
  237.         'ss_cookies' => 'Unknown',
  238.         'st_cookies' => 'Unknown',
  239.         'language'   => '',
  240.         'long_name'  => '',
  241.         'gecko'      => '',
  242.         'gecko_ver'  => ''
  243.         );
  244.  
  245.     /**
  246.      *  @access private
  247.      *  @var array 
  248.      */
  249.     var $_feature_set array(
  250.         'html'         =>    true,
  251.         'images'     =>    true,
  252.         'frames'      =>    true,
  253.         'tables'     =>    true,
  254.         'java'         =>    true,
  255.         'plugins'     => true,
  256.         'iframes'     => false,
  257.         'css2'         =>    false,
  258.         'css1'         =>    false,
  259.         'xml'         =>    false,
  260.         'dom'         =>    false,
  261.         'wml'         =>    false,
  262.         'hdml'         =>    false
  263.         );
  264.  
  265.     /**
  266.      *  @access private
  267.      *  @var array 
  268.      */
  269.     var $_quirks array(
  270.         'must_cache_forms'            =>    false,
  271.         'avoid_popup_windows'        =>    false,
  272.         'cache_ssl_downloads'        =>    false,
  273.         'break_disposition_header'    =>    false,
  274.         'empty_file_input_value'    =>    false,
  275.         'scrollbar_in_way'            =>    false
  276.         );
  277.  
  278.     /**
  279.      *  @access private
  280.      *  @var boolean 
  281.      */
  282.     var $_get_languages_ran_once false;
  283.     /**
  284.      *  @access private
  285.      *  @var string 
  286.      */
  287.     var $_browser_search_regex '([a-z]+)([0-9]*)([0-9.]*)(up|dn|\+|\-)?';
  288.     /**
  289.      *  @access private
  290.      *  @var string 
  291.      */
  292.     var $_language_search_regex '([a-z-]{2,})';
  293.     /**
  294.      *  @access private
  295.      *  @var string 
  296.      */
  297.     var $_browser_regex;
  298.  
  299.     /**
  300.      *  Performs some basic initialization and returns and object
  301.      *  @param string User Agent to parse
  302.      *  @param mixed array of settings
  303.      *           [check_cookies, default_language, allow_masqeurading]
  304.      *
  305.      *  @return object phpSniff object
  306.      */
  307.  
  308.     function phpSniff($UA='',$settings true)
  309.     {   //  populate the HTTP_USER_AGENT string
  310.         //  20020425 :: rraymond
  311.         //      routine for easier configuration of the client at runtime
  312.         if (is_array($settings)) {
  313.             $run true;
  314.             extract($settings);
  315.             $this->_check_cookies = $check_cookies;
  316.             $this->_default_language = $default_language;
  317.             $this->_allow_masquerading = $allow_masquerading;
  318.         else {
  319.             // for backwards compatibility with 2.0.x series
  320.             $run = (bool) $settings;
  321.         }
  322.  
  323.         // if the user agent is empty, see if it exists somewhere
  324.         if (empty($UA)) {
  325.             if (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) {
  326.                 $UA $HTTP_SERVER_VARS['HTTP_USER_AGENT'];
  327.             elseif (isset($_SERVER['HTTP_USER_AGENT'])) {
  328.                 $UA $_SERVER['HTTP_USER_AGENT'];
  329.             else {
  330.                 // try to use the getenv function as a last resort
  331.                 $UA getenv('HTTP_USER_AGENT');
  332.             }
  333.         }
  334.  
  335.         // if it's still empty, just return false as there is nothing to do
  336.         if (empty($UA)) return false;
  337.  
  338.         $this->_set_browser('ua',$UA);
  339.         if ($run$this->init();
  340.     }
  341.  
  342.     function init ()
  343.     {
  344.         //  collect the ip
  345.             $this->_get_ip();
  346.         //  run the cookie check routine first
  347.         //  [note: method only runs if allowed]
  348.             $this->_test_cookies();
  349.         //  rip the user agent to pieces
  350.             $this->_get_browser_info();
  351.         //    gecko build
  352.             $this->_get_gecko();
  353.         //  look for other languages
  354.             $this->_get_languages();
  355.         //  establish the operating platform
  356.             $this->_get_os_info();
  357.         //  determine javascript version
  358.             $this->_get_javascript();
  359.         //    determine current feature set
  360.             $this->_get_features();
  361.         //    point out any quirks
  362.             $this->_get_quirks();
  363.     }
  364.  
  365.     /**
  366.      *  turn the cookie check routine on or off
  367.      *  @param bool true or false
  368.      */
  369.     function check_cookies($yn)
  370.     {
  371.         $this->_check_cookies = (bool) $yn;
  372.     }
  373.  
  374.     /**
  375.      *  allow browser masquerading
  376.      *  @param bool true or false
  377.      */
  378.     function allow_masquerading($yn)
  379.     {
  380.         $this->_allow_masquerading = (bool) $yn;
  381.     }
  382.  
  383.     /**
  384.      *  set the default browser language
  385.      *  @param string valid language (ex: en-us)
  386.      */
  387.     function default_language($language)
  388.     {
  389.         $this->_default_language = $language;
  390.     }
  391.  
  392.     /**
  393.      *  property
  394.      *  @param string property to return . optional (null returns entire array)
  395.      *  @return mixed array/string entire array or value of property
  396.      ***/
  397.     function property ($p=null)
  398.     {   if ($p==null)
  399.         {   return $this->_browser_info;
  400.         }
  401.         else
  402.         {   return $this->_browser_info[strtolower($p)];
  403.         }
  404.     }
  405.  
  406.     /**
  407.      *  get_property is an alias for property
  408.      *  @param string property to return . optional (null returns entire array)
  409.      *  @return mixed array/string entire array or value of property
  410.      ***/
  411.     function get_property ($p)
  412.     {    return $this->property($p);
  413.     }
  414.  
  415.     /**
  416.      *  is
  417.      *  @param string search phrase format = l:lang;b:browser
  418.      *  @return bool true on success
  419.      *   ex: $client->is('b:OP5Up');
  420.      ***/
  421.     function is ($s)
  422.     {   // perform language search
  423.         if (preg_match('/l:'.$this->_language_search_regex.'/i',$s,$match))
  424.         {   if ($matchreturn $this->_perform_language_search($match);
  425.         }
  426.         // perform browser search
  427.         elseif (preg_match('/b:'.$this->_browser_search_regex.'/i',$s,$match))
  428.         {   if ($matchreturn $this->_perform_browser_search($match);
  429.         }
  430.         return false;
  431.     }
  432.  
  433.     /**
  434.      *    browser_is
  435.      *    @param string search phrase for browser
  436.      *  @return bool true on success
  437.      *   ex: $client->browser_is('OP5Up');
  438.      ***/
  439.     function browser_is ($s)
  440.     {    preg_match('/'.$this->_browser_search_regex.'/i',$s,$match);
  441.         if ($matchreturn $this->_perform_browser_search($match);
  442.     }
  443.  
  444.     /**
  445.      *    language_is
  446.      *    @param string search phrase for language
  447.      *  @return bool true on success
  448.      *   ex: $client->language_is('en-US');
  449.      ***/
  450.     function language_is ($s)
  451.     {    preg_match('/'.$this->_language_search_regex.'/i',$s,$match);
  452.         if ($matchreturn $this->_perform_language_search($match);
  453.     }
  454.  
  455.     /**
  456.      *    checks to see if the browser supports any of the following features:
  457.      *  <ul>
  458.      *      <li>html
  459.      *      <li>images
  460.      *      <li>frames
  461.      *      <li>tables
  462.      *      <li>plugins
  463.      *      <li>iframes
  464.      *      <li>css2
  465.      *      <li>css1
  466.      *      <li>xml
  467.      *      <li>dom
  468.      *      <li>wml
  469.      *      <li>hdml
  470.      *  </ul>
  471.      *  <code>ex: $client->has_feature('html');</code>
  472.      *    @param string feature we're checking on
  473.      *  @return bool true on success
  474.  
  475.      ***/
  476.     function has_feature ($s)
  477.     {    return $this->_feature_set[$s];
  478.     }
  479.  
  480.     /**
  481.      *    checks to see if the browser has any of the following quirks:
  482.      *  <ul>
  483.      *      <li>must_cache_forms
  484.      *      <li>avoid_popup_windows
  485.      *      <li>cache_ssl_downloads
  486.      *      <li>break_disposition_header
  487.      *      <li>empty_file_input_value
  488.      *      <li>scrollbar_in_way
  489.      *  </ul>
  490.      *  <code>ex: $client->has_quirk('avoid_popup_windows');</code>
  491.      *    @param string quirk we're looking for
  492.      *  @return bool true on success
  493.      ***/
  494.     function has_quirk ($s)
  495.     {    return $this->_quirks[$s];
  496.     }
  497.  
  498.     /**
  499.      *  _perform_browser_search
  500.      *  @param string what we're searching for
  501.      *  @return bool true on success
  502.      *  @access private
  503.      ***/
  504.     function _perform_browser_search ($data)
  505.     {   $search array();
  506.         $search['phrase']         = isset($data[0]$data[0'';
  507.         $search['name']           = isset($data[1]strtolower($data[1]'';
  508.         $search['maj_ver']       = isset($data[2]$data[2'';
  509.         $search['min_ver']       = isset($data[3]$data[3'';
  510.         $search['direction']    = isset($data[4]strtolower($data[4]'';
  511.  
  512.         $looking_for $search['maj_ver'].$search['min_ver'];
  513.         if ($search['name'== 'aol' || $search['name'== 'webtv'{
  514.             return stristr($this->_browser_info['ua'],$search['name']);
  515.         elseif ($this->_browser_info['browser'== $search['name'|| $search['name'== 'gecko'{
  516.             if (strtolower($search['name']== 'gecko'{
  517.                 $what_we_are $this->_browser_info['gecko_ver'];
  518.             else {
  519.                 $majv $search['maj_ver'$this->_browser_info['maj_ver''';
  520.                 $minv $search['min_ver'$this->_browser_info['min_ver''';
  521.                 $what_we_are $majv.$minv;
  522.             }
  523.             if (($search['direction'== 'up' || $search['direction'== '+')
  524.                && ($what_we_are >= $looking_for))
  525.             {   return true;
  526.             }
  527.             elseif (($search['direction'== 'dn' || $search['direction'== '-')
  528.                    && ($what_we_are <= $looking_for))
  529.             {    return true;
  530.             }
  531.             elseif ($what_we_are == $looking_for)
  532.             {   return true;
  533.             }
  534.         }
  535.         return false;
  536.     }
  537.  
  538.     /**
  539.      *  @access private
  540.      */
  541.     function _perform_language_search ($data)
  542.     {   // if we've not grabbed the languages, then do so.
  543.         $this->_get_languages();
  544.         return stristr($this->_browser_info['language'],$data[1]);
  545.     }
  546.  
  547.     /**
  548.      *  @access private
  549.      */
  550.     function _get_languages ()
  551.     {   // capture available languages and insert into container
  552.         if (!$this->_get_languages_ran_once)
  553.         {   if ($languages getenv('HTTP_ACCEPT_LANGUAGE'))
  554.             {   $languages preg_replace('/(;q=[0-9]+.[0-9]+)/i','',$languages);
  555.             }
  556.             else
  557.             {   $languages $this->_default_language;
  558.             }
  559.             $this->_set_browser('language',$languages);
  560.             $this->_get_languages_ran_once true;
  561.         }
  562.     }
  563.  
  564.     /**
  565.      *  @access private
  566.      */
  567.     function _get_os_info ()
  568.     {   // regexes to use
  569.         $regex_windows  '/([^dar]win[dows]*)[\s]?([0-9a-z]*)[\w\s]?([a-z0-9.]*)/i';
  570.         $regex_mac      '/(68[k0]{1,3})|(ppc mac os x)|([p\S]{1,5}pc)|(darwin)/i';
  571.         $regex_os2      '/os\/2|ibm-webexplorer/i';
  572.         $regex_sunos    '/(sun|i86)[os\s]*([0-9]*)/i';
  573.         $regex_irix     '/(irix)[\s]*([0-9]*)/i';
  574.         $regex_hpux     '/(hp-ux)[\s]*([0-9]*)/i';
  575.         $regex_aix      '/aix([0-9]*)/i';
  576.         $regex_dec      '/dec|osfl|alphaserver|ultrix|alphastation/i';
  577.         $regex_vms      '/vax|openvms/i';
  578.         $regex_sco      '/sco|unix_sv/i';
  579.         $regex_linux    '/x11|inux/i';
  580.         $regex_bsd      '/(free)?(bsd)/i';
  581.         $regex_amiga    '/amiga[os]?/i';
  582.  
  583.         // look for Windows Box
  584.         if (preg_match_all($regex_windows,$this->_browser_info['ua'],$match))
  585.         {   /** Windows has some of the most ridiculous HTTP_USER_AGENT strings */
  586.             //$match[1][count($match[0])-1];
  587.             $v  $match[2][count($match[0])-1];
  588.             $v2 $match[3][count($match[0])-1];
  589.             // Establish NT 5.1 as Windows XP
  590.                 if (stristr($v,'NT'&& $v2 == 5.1$v 'xp';
  591.             // Establish NT 5.0 and Windows 2000 as win2k
  592.                 elseif ($v == '2000'$v '2k';
  593.                 elseif (stristr($v,'NT'&& $v2 == 5.0$v '2k';
  594.             // Establish 9x 4.90 as Windows 98
  595.                 elseif (stristr($v,'9x'&& $v2 == 4.9$v '98';
  596.             // See if we're running windows 3.1
  597.                 elseif ($v.$v2 == '16bit'$v '31';
  598.             // otherwise display as is (31,95,98,NT,ME,XP)
  599.                 else $v .= $v2;
  600.             // update browser info container array
  601.             if (empty($v)) $v 'win';
  602.             $this->_set_browser('os',strtolower($v));
  603.             $this->_set_browser('platform','win');
  604.         }
  605.         //  look for amiga OS
  606.         elseif (preg_match($regex_amiga,$this->_browser_info['ua'],$match))
  607.         {   $this->_set_browser('platform','amiga');
  608.             if (stristr($this->_browser_info['ua'],'morphos')) {
  609.                 // checking for MorphOS
  610.                 $this->_set_browser('os','morphos');
  611.             elseif (stristr($this->_browser_info['ua'],'mc680x0')) {
  612.                 // checking for MC680x0
  613.                 $this->_set_browser('os','mc680x0');
  614.             elseif (stristr($this->_browser_info['ua'],'ppc')) {
  615.                 // checking for PPC
  616.                 $this->_set_browser('os','ppc');
  617.             elseif (preg_match('/(AmigaOS [\.1-9]?)/i',$this->_browser_info['ua'],$match)) {
  618.                 // checking for AmigaOS version string
  619.                 $this->_set_browser('os',$match[1]);
  620.             }
  621.         }
  622.         // look for OS2
  623.         elseif preg_match($regex_os2,$this->_browser_info['ua']))
  624.         {   $this->_set_browser('os','os2');
  625.             $this->_set_browser('platform','os2');
  626.         }
  627.         // look for mac
  628.         // sets: platform = mac ; os = 68k or ppc
  629.         elseif preg_match($regex_mac,$this->_browser_info['ua'],$match) )
  630.         {   $this->_set_browser('platform','mac');
  631.             $os !empty($match[1]'68k' '';
  632.             $os !empty($match[2]'osx' $os;
  633.             $os !empty($match[3]'ppc' $os;
  634.             $os !empty($match[4]'osx' $os;
  635.             $this->_set_browser('os',$os);
  636.         }
  637.         //  look for *nix boxes
  638.         //  sunos sets: platform = *nix ; os = sun|sun4|sun5|suni86
  639.         elseif (preg_match($regex_sunos,$this->_browser_info['ua'],$match))
  640.         {   $this->_set_browser('platform','*nix');
  641.  
  642.             if (!stristr('sun',$match[1])) $match[1'sun'.$match[1];
  643.             $this->_set_browser('os',$match[1].$match[2]);
  644.         }
  645.         //  irix sets: platform = *nix ; os = irix|irix5|irix6|...
  646.         elseif (preg_match($regex_irix,$this->_browser_info['ua'],$match))
  647.         {   $this->_set_browser('platform','*nix');
  648.             $this->_set_browser('os',$match[1].$match[2]);
  649.         }
  650.         //  hp-ux sets: platform = *nix ; os = hpux9|hpux10|...
  651.         elseif (preg_match($regex_hpux,$this->_browser_info['ua'],$match))
  652.         {   $this->_set_browser('platform','*nix');
  653.             $match[1str_replace('-','',$match[1]);
  654.             $match[2= (int) $match[2];
  655.             $this->_set_browser('os',$match[1].$match[2]);
  656.         }
  657.         //  aix sets: platform = *nix ; os = aix|aix1|aix2|aix3|...
  658.         elseif (preg_match($regex_aix,$this->_browser_info['ua'],$match))
  659.         {   $this->_set_browser('platform','*nix');
  660.             $this->_set_browser('os','aix'.$match[1]);
  661.         }
  662.         //  dec sets: platform = *nix ; os = dec
  663.         elseif (preg_match($regex_dec,$this->_browser_info['ua'],$match))
  664.         {   $this->_set_browser('platform','*nix');
  665.             $this->_set_browser('os','dec');
  666.         }
  667.         //  vms sets: platform = *nix ; os = vms
  668.         elseif (preg_match($regex_vms,$this->_browser_info['ua'],$match))
  669.         {   $this->_set_browser('platform','*nix');
  670.             $this->_set_browser('os','vms');
  671.         }
  672.         //  sco sets: platform = *nix ; os = sco
  673.         elseif (preg_match($regex_sco,$this->_browser_info['ua'],$match))
  674.         {   $this->_set_browser('platform','*nix');
  675.             $this->_set_browser('os','sco');
  676.         }
  677.         //  unixware sets: platform = *nix ; os = unixware
  678.         elseif (stristr($this->_browser_info['ua'],'unix_system_v'))
  679.         {   $this->_set_browser('platform','*nix');
  680.             $this->_set_browser('os','unixware');
  681.         }
  682.         //  mpras sets: platform = *nix ; os = mpras
  683.         elseif (stristr($this->_browser_info['ua'],'ncr'))
  684.         {   $this->_set_browser('platform','*nix');
  685.             $this->_set_browser('os','mpras');
  686.         }
  687.         //  reliant sets: platform = *nix ; os = reliant
  688.         elseif (stristr($this->_browser_info['ua'],'reliantunix'))
  689.         {   $this->_set_browser('platform','*nix');
  690.             $this->_set_browser('os','reliant');
  691.         }
  692.         //  sinix sets: platform = *nix ; os = sinix
  693.         elseif (stristr($this->_browser_info['ua'],'sinix'))
  694.         {   $this->_set_browser('platform','*nix');
  695.             $this->_set_browser('os','sinix');
  696.         }
  697.         //  bsd sets: platform = *nix ; os = bsd|freebsd
  698.         elseif (preg_match($regex_bsd,$this->_browser_info['ua'],$match))
  699.         {   $this->_set_browser('platform','*nix');
  700.             $this->_set_browser('os',$match[1].$match[2]);
  701.         }
  702.         //  last one to look for
  703.         //  linux sets: platform = *nix ; os = linux
  704.         elseif (preg_match($regex_linux,$this->_browser_info['ua'],$match))
  705.         {   $this->_set_browser('platform','*nix');
  706.             $this->_set_browser('os','linux');
  707.         }
  708.     }
  709.  
  710.     /**
  711.      *  @access private
  712.      */
  713.     function _get_browser_info ()
  714.     {   $this->_build_regex();
  715.         if (preg_match_all($this->_browser_regex,$this->_browser_info['ua'],$results))
  716.         {   // get the position of the last browser found
  717.             $count count($results[0])-1;
  718.             // if we're allowing masquerading, revert to the next to last browser found
  719.             // if possible, otherwise stay put
  720.             if ($this->_allow_masquerading && $count 0$count--;
  721.             // insert findings into the container
  722.             $this->_set_browser('browser',$this->_get_short_name($results[1][$count]));
  723.             $this->_set_browser('long_name',$results[1][$count]);
  724.             $this->_set_browser('maj_ver',$results[2][$count]);
  725.             // parse the minor version string and look for alpha chars
  726.             preg_match('/([.\0-9]+)?([\.a-z0-9]+)?/i',$results[3][$count],$match);
  727.             if (isset($match[1])) {
  728.                 $this->_set_browser('min_ver',$match[1]);
  729.             else {
  730.                 $this->_set_browser('min_ver','.0');
  731.             }
  732.             if (isset($match[2])) $this->_set_browser('letter_ver',$match[2]);
  733.             // insert findings into container
  734.             $this->_set_browser('version',$this->_browser_info['maj_ver'].$this->property('min_ver'));
  735.         }
  736.     }
  737.  
  738.     /**
  739.      *  @access private
  740.      */
  741.     function _get_ip ()
  742.     {   if (getenv('HTTP_CLIENT_IP'))
  743.         {   $ip getenv('HTTP_CLIENT_IP');
  744.         }
  745.         else
  746.         {   $ip getenv('REMOTE_ADDR');
  747.         }
  748.         $this->_set_browser('ip',$ip);
  749.     }
  750.  
  751.     /**
  752.      *  @access private
  753.      */
  754.     function _build_regex ()
  755.     {   $browsers '';
  756.         while(list($k,each($this->_browsers))
  757.         {   if (!empty($browsers)) $browsers .= "|";
  758.             $browsers .= $k;
  759.         }
  760.         $version_string "[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?";
  761.         $this->_browser_regex "/($browsers)$version_string/i";
  762.     }
  763.  
  764.     /**
  765.      *  @access private
  766.      */
  767.     function _get_short_name ($long_name)
  768.     {   return $this->_browsers[strtolower($long_name)];
  769.     }
  770.  
  771.     /**
  772.      *  @access private
  773.      */
  774.     // medianes :: new test cookie routine
  775.     function _test_cookies()
  776.     {   global $HTTP_COOKIE_VARS;
  777.         $cookies array();
  778.         if (isset($_COOKIE)) {
  779.             $cookies $_COOKIE;
  780.         elseif (isset($HTTP_COOKIE_VARS)) {
  781.             $cookies $HTTP_COOKIE_VARS;
  782.         }
  783.         if ($this->_check_cookies)
  784.         {   $fp @fopen($this->_temp_file_path.$this->property('ip'),'r');
  785.             if (!$fp)
  786.             {   $fp @fopen($this->_temp_file_path.$this->property('ip'),'a');
  787.                 // make sure we have a valid file pointer
  788.                 if ($fp{
  789.                     fclose($fp);
  790.                     setcookie('phpSniff_session','ss',0,'/');
  791.                     setcookie('phpSniff_stored','st',time()+3600*24*365,'/');
  792.                     $QS=getenv('QUERY_STRING');
  793.                     $script_path=getenv('PATH_INFO')?getenv('PATH_INFO'):getenv('SCRIPT_NAME');
  794.                     if (is_integer($pos=strpos(strrev($script_path),"php.xedni/"))&&!$pos{
  795.                         $script_path=strrev(substr(strrev($script_path),9));
  796.                     }
  797.                 }
  798.                 $location='http://'.getenv('SERVER_NAME').$script_path.($QS==''?'':'?'.$QS);
  799.                 header("Location: $location");
  800.                 exit;
  801.             elseif ($fp{
  802.                 // we only want to proceed if we have a file pointer
  803.                 unlink($this->_temp_file_path.$this->property('ip'));
  804.                 fclose($fp);
  805.                 $this->_set_browser('ss_cookies',isset($cookies['phpSniff_session'])?'true':'false');
  806.                 $this->_set_browser('st_cookies',isset($cookies['phpSniff_stored'])?'true':'false');
  807.                 // delete the old cookies
  808.                 setcookie('phpSniff_session','',0,'/');
  809.                 setcookie('phpSniff_stored','',0,'/');
  810.             }
  811.         }
  812.     }
  813.  
  814.     /**
  815.      *  @access private
  816.      */
  817.     function _get_javascript()
  818.     {   $set=false;
  819.         // see if we have any matches
  820.         while(list($version,$browsereach($this->_javascript_versions))
  821.         {   $browser explode(',',$browser);
  822.             while(list(,$searcheach($browser))
  823.             {   if ($this->is('b:'.$search))
  824.                 {   $this->_set_browser('javascript',$version);
  825.                     $set true;
  826.                     break;
  827.                 }
  828.             }
  829.         if ($setbreak;
  830.         }
  831.     }
  832.  
  833.     /**
  834.      *  @access private
  835.      */
  836.     function _get_features ()
  837.     {    while(list($feature,$browsereach($this->_browser_features))
  838.         {    $browser explode(',',$browser);
  839.             while(list(,$searcheach($browser))
  840.             {    if ($this->browser_is($search))
  841.                 {    $this->_set_feature($feature);
  842.                     break;
  843.                 }
  844.             }
  845.         }
  846.     }
  847.  
  848.     /**
  849.      *  @access private
  850.      */
  851.     function _get_quirks ()
  852.     {    while(list($quirk,$browsereach($this->_browser_quirks))
  853.         {    $browser explode(',',$browser);
  854.             while(list(,$searcheach($browser))
  855.             {    if ($this->browser_is($search))
  856.                 {    $this->_set_quirk($quirk);
  857.                     break;
  858.                 }
  859.             }
  860.         }
  861.     }
  862.  
  863.     /**
  864.      *  @access private
  865.      */
  866.     function _get_gecko ()
  867.     {    if (preg_match('/gecko\/([0-9]+)/i',$this->property('ua'),$match))
  868.         {    $this->_set_browser('gecko',$match[1]);
  869.             if (preg_match('/rv[: ]?([0-9a-z.+]+)/i',$this->property('ua'),$mozv)) {
  870.                 // mozilla release
  871.                 $this->_set_browser('gecko_ver',$mozv[1]);
  872.             elseif (preg_match('/(m[0-9]+)/i',$this->property('ua'),$mozv)) {
  873.                 // mozilla milestone version
  874.                 $this->_set_browser('gecko_ver',$mozv[1]);
  875.             }
  876.             // if this is a mozilla browser, get the rv: information
  877.             if ($this->browser_is($this->_get_short_name('mozilla'))) {
  878.                 if (preg_match('/([0-9]+)([\.0-9]+)([a-z0-9+]?)/i',$mozv[1],$match)) {
  879.                     $this->_set_browser('version',$mozv[1]);
  880.                     $this->_set_browser('maj_ver',$match[1]);
  881.                     $this->_set_browser('min_ver',$match[2]);
  882.                     $this->_set_browser('letter_ver',$match[3]);
  883.                 }
  884.             }
  885.         elseif ($this->is('b:'.$this->_get_short_name('mozilla'))) {
  886.             // this is probably a netscape browser or compatible
  887.             $this->_set_browser('long_name','netscape');
  888.             $this->_set_browser('browser',$this->_get_short_name('netscape'));
  889.         }
  890.     }
  891.  
  892.     /**
  893.      *  @access private
  894.      */
  895.     function _set_browser ($k,$v)
  896.     {   $this->_browser_info[strtolower($k)strtolower($v);
  897.     }
  898.  
  899.     /**
  900.      *  @access private
  901.      */
  902.     function _set_feature ($k)
  903.     {   $this->_feature_set[strtolower($k)!$this->_feature_set[strtolower($k)];
  904.     }
  905.  
  906.     /**
  907.      *  @access private
  908.      */
  909.     function _set_quirk ($k)
  910.     {   $this->_quirks[strtolower($k)true;
  911.     }
  912. }
  913. ?>

Documentation generated on Fri, 18 Jul 2008 21:48:23 +0200 by phpDocumentor 1.4.1