Source for file UserAgentUtils.php
Documentation is available at UserAgentUtils.php
* Tera_WURFL - PHP MySQL driven WURFL
* Tera-WURFL was written by Steve Kamerman, and is based on the
* Java WURFL Evolution package by Luca Passani and WURFL PHP Tools by Andrea Trassati.
* This version uses a MySQL database to store the entire WURFL file, multiple patch
* files, and a persistent caching mechanism to provide extreme performance increases.
* @author Steve Kamerman <stevekamerman AT gmail.com>
* @version Stable 2.1.3 $Date: 2010/09/18 15:43:21
* @license http://www.mozilla.org/MPL/ MPL Vesion 1.1
* Provides static functions for working with User Agents
public static $WORST_MATCH = 7;
* Find the matching Device ID for a given User Agent using RIS (Reduction in String)
* @param string User Agent
* @param int How short the strings are allowed to get before a match is abandoned
* @param UserAgentMatcher The UserAgentMatcher instance that is matching the User Agent
* @return string WURFL ID
public static function risMatch($ua,$tolerance,UserAgentMatcher $matcher){
$devices = & $matcher->deviceList;
// Narrow results to those that match the tolerance level
while($curlen >= $tolerance){
foreach($devices as $testID => $testUA){
// Comparing substrings may be faster, but you would need to use strcmp() on the subs anyway,
// so this is probably the fastest - maybe preg /^$test/ would be faster???
//echo "testUA: $testUA, ua: $ua\n<br/>";
if(strpos($testUA,$ua) === 0){
* Find the matching Device ID for a given User Agent using LD (Leveshtein Distance)
* @param string User Agent
* @param int Tolerance that is still considered a match
* @param UserAgentMatcher The UserAgentMatcher instance that is matching the User Agent
* @return string WURFL ID
public static function ldMatch($ua,$tolerance= null,$matcher){
// PHP Leveshtein Distance Function
$tolerance = self::$WORST_MATCH;
$devices = & $matcher->deviceList;
$key = array_search($ua,$devices);
foreach($devices as $testID => $testUA){
$current = levenshtein($ua,$testUA);
//echo "<hr/>$ua<br/>$testUA<br/>LD: $current<br/>";
* Number of slashes ('/') found in the given user agent
* @param String User Agent
* The character position of the first slash. If there are no slashes, returns string length
* @param String User Agent
* @return int Character position
$position = strpos($userAgent,'/');
return ($position!== false)? $position: strlen($userAgent);
* The character position of the second slash. If there is no second slash, returns string length
* @param String User Agent
* @return int Character position
$first = strpos($userAgent,'/');
$position = strpos($userAgent,'/',$first);
return ($position!== false)? $position: strlen($userAgent);
* The character position of the first space. If there are no spaces, returns string length
* @param String User Agent
* @return int Character position
$position = strpos($userAgent,' ');
return ($position!== false)? $position: strlen($userAgent);
* The character position of the first open parenthisis. If there are no open parenthisis, returns string length
* @param String User Agent
* @return int Character position
$position = strpos($userAgent,'(');
return ($position!== false)? $position: strlen($userAgent);
* Removes garbage from user agent string
* @param String User agent
* @return String User agent
$ua = self::removeUPLinkFromUA($ua);
$ua = preg_replace('/\/SN\d{15}/','/SNXXXXXXXXXXXXXXX',$ua);
// Remove locale identifier
$ua = preg_replace('/([ ;])[a-zA-Z]{2}-[a-zA-Z]{2}([ ;\)])/','$1xx-xx$2',$ua);
$ua = self::normalizeBlackberry($ua);
* Normalizes BlackBerry user agent strings
* @param String User agent
* @return String User agent
$pos = strpos($ua,'BlackBerry');
if($pos !== false && $pos > 0) $ua = substr($ua,$pos);
* Removes UP.Link traces from user agent strings
* @param String User agent
* @return String User agent
// Remove the gateway signatures from UA (UP.Link/x.x.x)
$index = strpos($ua,'UP.Link');
// Return the UA up to the UP.Link/xxxxxx part
* Removes Vodafone garbage from user agent string
* @param String User agent
* @return String User agent
* Check if user agent contains string or array of strings
* @param String User agent
* @param Mixed String or Array of strings
if(strpos($ua,$part)!== false){
return (strpos($ua,$find)!== false);
* Returns the character position (index) of the target string in the given user agent, starting from a given index. If target is not in user agent, returns length of user agent.
* @param String User agent
* @param String Target string to search for
* @param int Character postition in the user agent at which to start looking for the target
* @return int Character position (index) or user agent length
if($startingIndex === false) {
$pos = strpos($ua, $target, $startingIndex);
return ($pos === false)? $length : $pos;
* The character postition of the Nth occurance of a target string in a user agent
* @param String User agent
* @param String Target string to search for in user agent
* @param int The Nth occurence to find
* @return int Character position
$index = strpos($ua, $needle, $index + 1);
$index = is_int($index)? $index: - 1;
}while($found < $ordinal);
* Checks for traces of mobile device signatures and returns an appropriate generic WURFL Device ID
* @param String User agent
* @return String WURFL ID
//before we give up and return generic, one last
//attempt to catch well-behaved Nokia and Openwave browsers!
if(self::checkIfContains($ua,'UP.Browser/7'))
return 'opwv_v7_generic';
if(self::checkIfContains($ua,'UP.Browser/6'))
return 'opwv_v6_generic';
if(self::checkIfContains($ua,'UP.Browser/5'))
if(self::checkIfContains($ua,'UP.Browser/4'))
if(self::checkIfContains($ua,'UP.Browser/3'))
if(self::checkIfContains($ua,'Series60'))
return 'nokia_generic_series60';
if(self::checkIfContains($ua,'Mozilla/4.0'))
return 'generic_web_browser';
if(self::checkIfContains($ua,'Mozilla/5.0'))
return 'generic_web_browser';
if(self::checkIfContains($ua,'Mozilla/6.0'))
return 'generic_web_browser';
* The given user agent is definitely from a mobile device
* @param String User agent
$lowerua = strtolower($ua);
if(self::isDesktopBrowser($ua)){
// Screen resolution in UA
* The given user agent is definitely from a desktop browser
* @param String User agent
if(strpos($lowerua, $browser_signature) !== false){
* The given user agent is definitely from a bot/crawler
* @param String User agent
public static function isRobot($ua){
if(strstr($lowerua, $browser_signature)){
public static function LD($s,$t){
// PHP's levenshtein() function requires arguments to be <= 255 chars
|