"", "browser" => "Unknown", "version" => 0, "maj_ver" => 0, "min_ver" => 0, "letter_ver" => "", "javascript" => "0.0", "platform" => "Unknown", "os" => "Unknown", "ip" => "Unknown", "cookies" => "Unknown", // remains for backwards compatability "ss_cookies" => "Unknown", "st_cookies" => "Unknown", "language" => "", "long_name" => "", "gecko" => "", "gecko_ver" => "", ]; var $_feature_set = [ "html" => true, "images" => true, "frames" => true, "tables" => true, "java" => true, "plugins" => true, "iframes" => false, "css2" => false, "css1" => false, "xml" => false, "dom" => false, "wml" => false, "hdml" => false, ]; var $_quirks = [ "must_cache_forms" => false, "avoid_popup_windows" => false, "cache_ssl_downloads" => false, "break_disposition_header" => false, "empty_file_input_value" => false, "scrollbar_in_way" => false, ]; var $_get_languages_ran_once = false; var $_browser_search_regex = '([a-z]+)([0-9]*)([0-9.]*)(up|dn|\+|\-)?'; var $_language_search_regex = "([a-z-]{2,})"; /** * init * this method starts the madness **/ function init () { // collect the ip $this->_get_ip(); // run the cookie check routine first // [note: method only runs if allowed] $this->_test_cookies(); // rip the user agent to pieces $this->_get_browser_info(); // gecko build $this->_get_gecko(); // look for other languages $this->_get_languages(); // establish the operating platform $this->_get_os_info(); // determine javascript version $this->_get_javascript(); // determine current feature set $this->_get_features(); // point out any quirks $this->_get_quirks(); } /** * property * @param $p property to return . optional (null returns entire array) * @return array/string entire array or value of property **/ function property ($p=null) { if($p==null) { return $this->_browser_info; } return $this->_browser_info[strtolower($p)]; } /** * get_property * alias for property **/ function get_property ($p) { return $this->property($p); } /** * is * @param $s string search phrase format = l:lang;b:browser * @return bool true on success * ex: $client->is('b:OP5Up'); **/ function is ($s) { // perform language search if(preg_match("/l:".$this->_language_search_regex."/i",$s,$match)) { if($match) return $this->_perform_language_search($match); } // perform browser search elseif(preg_match("/b:".$this->_browser_search_regex."/i",$s,$match)) { if($match) return $this->_perform_browser_search($match); } return false; } /** * browser_is * @param $s string search phrase for browser * @return bool true on success * ex: $client->browser_is('OP5Up'); **/ function browser_is ($s) { preg_match("/".$this->_browser_search_regex."/i",$s,$match); if($match) return $this->_perform_browser_search($match); } /** * language_is * @param $s string search phrase for language * @return bool true on success * ex: $client->language_is('en-US'); **/ function language_is ($s) { preg_match("/".$this->_language_search_regex."/i",$s,$match); if($match) return $this->_perform_language_search($match); } /** * has_feature * @param $s string feature we're checking on * @return bool true on success * ex: $client->has_feature('html'); **/ function has_feature ($s) { return $this->_feature_set[$s]; } /** * has_quirk * @param $s string quirk we're looking for * @return bool true on success * ex: $client->has_quirk('avoid_popup_windows'); **/ function has_quirk ($s) { return $this->_quirks[$s]; } /** * _perform_browser_search * @param $data string what we're searching for * @return bool true on success * @private **/ function _perform_browser_search ($data) { $search = []; $search["phrase"] = $data[0] ?? ""; $search["name"] = isset($data[1]) ? strtolower($data[1]) : ""; $search["maj_ver"] = $data[2] ?? ""; $search["min_ver"] = $data[3] ?? ""; $search["direction"] = isset($data[4]) ? strtolower($data[4]) : ""; $looking_for = $search["maj_ver"].$search["min_ver"]; if($search["name"] == "aol" || $search["name"] == "webtv") { return stristr($this->_browser_info["ua"],$search["name"]); } elseif($this->_browser_info["browser"] == $search["name"]) { $majv = $search["maj_ver"] ? $this->_browser_info["maj_ver"] : ""; $minv = $search["min_ver"] ? $this->_browser_info["min_ver"] : ""; $what_we_are = $majv.$minv; if(($search["direction"] == "up" || $search["direction"] == "+") && ($what_we_are >= $looking_for)) { return true; } elseif(($search["direction"] == "dn" || $search["direction"] == "-") && ($what_we_are <= $looking_for)) { return true; } elseif($what_we_are == $looking_for) { return true; } } return false; } function _perform_language_search ($data) { // if we've not grabbed the languages, then do so. $this->_get_languages(); return stristr($this->_browser_info["language"],$data[1]); } function _get_languages () { // capture available languages and insert into container if(!$this->_get_languages_ran_once) { if($languages = getenv("HTTP_ACCEPT_LANGUAGE")) { $languages = preg_replace("/(;q=[0-9]+.[0-9]+)/i","",$languages); } else { $languages = $this->_default_language; } $this->_set_browser("language",$languages); $this->_get_languages_ran_once = true; } } function _get_os_info () { // regexes to use $regex_windows = '/([^dar]win[dows]*)[\s]?([0-9a-z]*)[\w\s]?([a-z0-9.]*)/i'; $regex_mac = '/(68[k0]{1,3})|(ppc mac os x)|([p\S]{1,5}pc)|(darwin)/i'; $regex_os2 = '/os\/2|ibm-webexplorer/i'; $regex_sunos = '/(sun|i86)[os\s]*([0-9]*)/i'; $regex_irix = '/(irix)[\s]*([0-9]*)/i'; $regex_hpux = '/(hp-ux)[\s]*([0-9]*)/i'; $regex_aix = "/aix([0-9]*)/i"; $regex_dec = "/dec|osfl|alphaserver|ultrix|alphastation/i"; $regex_vms = "/vax|openvms/i"; $regex_sco = "/sco|unix_sv/i"; $regex_linux = "/x11|inux/i"; $regex_bsd = "/(free)?(bsd)/i"; $regex_amiga = "/amiga[os]?/i"; // look for Windows Box if(preg_match_all($regex_windows,$this->_browser_info["ua"],$match)) { /** Windows has some of the most ridiculous HTTP_USER_AGENT strings */ //$match[1][count($match[0])-1]; $v = $match[2][count($match[0])-1]; $v2 = $match[3][count($match[0])-1]; // Establish NT 5.1 as Windows XP if(stristr($v,"NT") && $v2 == 5.1) $v = "xp"; // Establish NT 5.0 and Windows 2000 as win2k elseif($v == "2000") $v = "2k"; elseif(stristr($v,"NT") && $v2 == 5.0) $v = "2k"; // Establish 9x 4.90 as Windows 98 elseif(stristr($v,"9x") && $v2 == 4.9) $v = "98"; // See if we're running windows 3.1 elseif($v.$v2 == "16bit") $v = "31"; // otherwise display as is (31,95,98,NT,ME,XP) else $v .= $v2; // update browser info container array if(empty($v)) $v = "win"; $this->_set_browser("os",strtolower($v)); $this->_set_browser("platform","win"); } // look for amiga OS elseif(preg_match($regex_amiga,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","amiga"); if(stristr($this->_browser_info["ua"],"morphos")) { // checking for MorphOS $this->_set_browser("os","morphos"); } elseif(stristr($this->_browser_info["ua"],"mc680x0")) { // checking for MC680x0 $this->_set_browser("os","mc680x0"); } elseif(stristr($this->_browser_info["ua"],"ppc")) { // checking for PPC $this->_set_browser("os","ppc"); } elseif(preg_match('/(AmigaOS [\.1-9]?)/i',$this->_browser_info["ua"],$match)) { // checking for AmigaOS version string $this->_set_browser("os",$match[1]); } } // look for OS2 elseif( preg_match($regex_os2,$this->_browser_info["ua"])) { $this->_set_browser("os","os2"); $this->_set_browser("platform","os2"); } // look for mac // sets: platform = mac ; os = 68k or ppc elseif( preg_match($regex_mac,$this->_browser_info["ua"],$match) ) { $this->_set_browser("platform","mac"); $os = !empty($match[1]) ? "68k" : ""; $os = !empty($match[2]) ? "osx" : $os; $os = !empty($match[3]) ? "ppc" : $os; $os = !empty($match[4]) ? "osx" : $os; $this->_set_browser("os",$os); } // look for *nix boxes // sunos sets: platform = *nix ; os = sun|sun4|sun5|suni86 elseif(preg_match($regex_sunos,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); if(!stristr("sun",$match[1])) $match[1] = "sun".$match[1]; $this->_set_browser("os",$match[1].$match[2]); } // irix sets: platform = *nix ; os = irix|irix5|irix6|... elseif(preg_match($regex_irix,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os",$match[1].$match[2]); } // hp-ux sets: platform = *nix ; os = hpux9|hpux10|... elseif(preg_match($regex_hpux,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $match[1] = str_replace("-","",$match[1]); $match[2] = (int) $match[2]; $this->_set_browser("os",$match[1].$match[2]); } // aix sets: platform = *nix ; os = aix|aix1|aix2|aix3|... elseif(preg_match($regex_aix,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","aix".$match[1]); } // dec sets: platform = *nix ; os = dec elseif(preg_match($regex_dec,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","dec"); } // vms sets: platform = *nix ; os = vms elseif(preg_match($regex_vms,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","vms"); } // sco sets: platform = *nix ; os = sco elseif(preg_match($regex_sco,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","sco"); } // unixware sets: platform = *nix ; os = unixware elseif(stristr($this->_browser_info["ua"],"unix_system_v")) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","unixware"); } // mpras sets: platform = *nix ; os = mpras elseif(stristr($this->_browser_info["ua"],"ncr")) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","mpras"); } // reliant sets: platform = *nix ; os = reliant elseif(stristr($this->_browser_info["ua"],"reliantunix")) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","reliant"); } // sinix sets: platform = *nix ; os = sinix elseif(stristr($this->_browser_info["ua"],"sinix")) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","sinix"); } // bsd sets: platform = *nix ; os = bsd|freebsd elseif(preg_match($regex_bsd,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os",$match[1].$match[2]); } // last one to look for // linux sets: platform = *nix ; os = linux elseif(preg_match($regex_linux,$this->_browser_info["ua"],$match)) { $this->_set_browser("platform","*nix"); $this->_set_browser("os","linux"); } } function _get_browser_info () { $this->_build_regex(); if(preg_match_all($this->_browser_regex,$this->_browser_info["ua"],$results)) { // get the position of the last browser found $count = count($results[0])-1; // if we're allowing masquerading, revert to the next to last browser found // if possible, otherwise stay put if($this->_allow_masquerading && $count > 0) $count--; // insert findings into the container $this->_set_browser("browser",$this->_get_short_name($results[1][$count])); $this->_set_browser("long_name",$results[1][$count]); $this->_set_browser("maj_ver",$results[2][$count]); // parse the minor version string and look for alpha chars preg_match('/([.\0-9]+)?([\.a-z0-9]+)?/i',$results[3][$count],$match); if(isset($match[1])) { $this->_set_browser("min_ver",$match[1]); } else { $this->_set_browser("min_ver",".0"); } if(isset($match[2])) $this->_set_browser("letter_ver",$match[2]); // insert findings into container $this->_set_browser("version",$this->_browser_info["maj_ver"].$this->property("min_ver")); } } function _get_ip () { if(getenv("HTTP_CLIENT_IP")) { $ip = getenv("HTTP_CLIENT_IP"); } else { $ip = getenv("REMOTE_ADDR"); } $this->_set_browser("ip",$ip); } function _build_regex () { $browsers = ""; while(list($k,) = each($this->_browsers)) { if(!empty($browsers)) $browsers .= "|"; $browsers .= $k; } $version_string = "[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?"; $this->_browser_regex = "/($browsers)$version_string/i"; } function _get_short_name ($long_name) { return $this->_browsers[strtolower($long_name)]; } // medianes :: new test cookie routine function _test_cookies() { global $HTTP_COOKIE_VARS; $cookies = []; if(isset($_COOKIE)) { $cookies = $_COOKIE; } elseif(isset($HTTP_COOKIE_VARS)) { $cookies = $HTTP_COOKIE_VARS; } if($this->_check_cookies) { $fp = @fopen($this->_temp_file_path.$this->property("ip"),"r"); if(!$fp) { $fp = @fopen($this->_temp_file_path.$this->property("ip"),"a"); fclose($fp); setcookie("phpSniff_session","ss",0,"/"); setcookie("phpSniff_stored","st",time()+3600*24*365,"/"); $QS=getenv("QUERY_STRING"); $script_path=getenv("PATH_INFO")?getenv("PATH_INFO"):getenv("SCRIPT_NAME"); if(is_integer($pos=strpos(strrev($script_path),"php.xedni/"))&&!$pos) { $script_path=strrev(substr(strrev($script_path),9)); } $location="http://".getenv("SERVER_NAME").$script_path.($QS==""?"":"?".$QS); header("Location: $location"); exit; } unlink($this->_temp_file_path.$this->property("ip")); fclose($fp); $this->_set_browser("ss_cookies",isset($cookies["phpSniff_session"])?"true":"false"); $this->_set_browser("st_cookies",isset($cookies["phpSniff_stored"])?"true":"false"); // delete the old cookies setcookie("phpSniff_session","",0,"/"); setcookie("phpSniff_stored","",0,"/"); } } function _get_javascript() { $set=false; // see if we have any matches while(list($version,$browser) = each($this->_javascript_versions)) { $browser = explode(",",$browser); while(list(,$search) = each($browser)) { if($this->is("b:".$search)) { $this->_set_browser("javascript",$version); $set = true; break; } } if($set) break; } } function _get_features () { while(list($feature,$browser) = each($this->_browser_features)) { $browser = explode(",",$browser); while(list(,$search) = each($browser)) { if($this->browser_is($search)) { $this->_set_feature($feature); break; } } } } function _get_quirks () { while(list($quirk,$browser) = each($this->_browser_quirks)) { $browser = explode(",",$browser); while(list(,$search) = each($browser)) { if($this->browser_is($search)) { $this->_set_quirk($quirk); break; } } } } function _get_gecko () { if(preg_match('/gecko\/([0-9]+)/i',$this->property("ua"),$match)) { $this->_set_browser("gecko",$match[1]); if (preg_match("/rv[: ]?([0-9a-z.+]+)/i",$this->property("ua"),$mozv)) { // mozilla release $this->_set_browser("gecko_ver",$mozv[1]); } elseif (preg_match("/(m[0-9]+)/i",$this->property("ua"),$mozv)) { // mozilla milestone version $this->_set_browser("gecko_ver",$mozv[1]); } // if this is a mozilla browser, get the rv: information if($this->browser_is($this->_get_short_name("mozilla"))) { if( !empty( $mozv[1] ) && preg_match('/([0-9]+)([\.0-9]+)([a-z0-9+]?)/i',$mozv[1],$match)) { $this->_set_browser("version",$mozv[1]); $this->_set_browser("maj_ver",$match[1]); $this->_set_browser("min_ver",$match[2]); $this->_set_browser("letter_ver",$match[3]); } } } elseif($this->is("b:".$this->_get_short_name("mozilla"))) { // this is probably a netscape browser or compatible $this->_set_browser("long_name","netscape"); $this->_set_browser("browser",$this->_get_short_name("netscape")); } } function _set_browser ($k,$v) { $this->_browser_info[strtolower($k)] = strtolower($v); } function _set_feature ($k) { $this->_feature_set[strtolower($k)] = !$this->_feature_set[strtolower($k)]; } function _set_quirk ($k) { $this->_quirks[strtolower($k)] = true; } } ?>