//www.telstra.com.au/home-phone/thub-2/
'TelstraTablet' => 'T-Hub2',
'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bTP750\b|\bQTAQZ3\b',
);
/**
* List of mobile Operating Systems.
*
* @var array
*/
protected static $operatingSystems = array(
'AndroidOS' => 'Android',
'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
// @reference: http://en.wikipedia.org/wiki/Windows_Mobile
'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
// @reference: http://en.wikipedia.org/wiki/Windows_Phone
// http://wifeng.cn/?r=blog&a=view&id=106
// http://nicksnettravels.builttoroam.com/post/2011/01/10/Bogus-Windows-Phone-7-User-Agent-String.aspx
// http://msdn.microsoft.com/library/ms537503.aspx
// https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
'WindowsPhoneOS' => 'Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;',
'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
// http://en.wikipedia.org/wiki/MeeGo
// @todo: research MeeGo in UAs
'MeeGoOS' => 'MeeGo',
// http://en.wikipedia.org/wiki/Maemo
// @todo: research Maemo in UAs
'MaemoOS' => 'Maemo',
'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b', // '|Java/' produces bug #135
'webOS' => 'webOS|hpwOS',
'badaOS' => '\bBada\b',
'BREWOS' => 'BREW',
);
/**
* List of mobile User Agents.
*
* IMPORTANT: This is a list of only mobile browsers.
* Mobile Detect 2.x supports only mobile browsers,
* it was never designed to detect all browsers.
* The change will come in 2017 in the 3.x release for PHP7.
*
* @var array
*/
protected static $browsers = array(
//'Vivaldi' => 'Vivaldi',
// @reference: https://developers.google.com/chrome/mobile/docs/user-agent
'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
'Dolfin' => '\bDolfin\b',
'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
'Skyfire' => 'Skyfire',
'Edge' => 'Mobile Safari/[.0-9]* Edge',
'IE' => 'IEMobile|MSIEMobile',
// |Trident/[.0-9]+
'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS',
'Bolt' => 'bolt',
'TeaShark' => 'teashark',
'Blazer' => 'Blazer',
// @reference: http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariWebContent/OptimizingforSafarioniPhone/OptimizingforSafarioniPhone.html#//apple_ref/doc/uid/TP40006517-SW3
'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari',
// http://en.wikipedia.org/wiki/Midori_(web_browser)
//'Midori' => 'midori',
//'Tizen' => 'Tizen',
'UCBrowser' => 'UC.*Browser|UCWEB',
'baiduboxapp' => 'baiduboxapp',
'baidubrowser' => 'baidubrowser',
// https://github.com/serbanghita/Mobile-Detect/issues/7
'DiigoBrowser' => 'DiigoBrowser',
// http://www.puffinbrowser.com/index.php
'Puffin' => 'Puffin',
// http://mercury-browser.com/index.html
'Mercury' => '\bMercury\b',
// http://en.wikipedia.org/wiki/Obigo_Browser
'ObigoBrowser' => 'Obigo',
// http://en.wikipedia.org/wiki/NetFront
'NetFront' => 'NF-Browser',
// @reference: http://en.wikipedia.org/wiki/Minimo
// http://en.wikipedia.org/wiki/Vision_Mobile_Browser
'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger',
// @reference: https://en.wikipedia.org/wiki/Pale_Moon_(web_browser)
'PaleMoon' => 'Android.*PaleMoon|Mobile.*PaleMoon',
);
/**
* Utilities.
*
* @var array
*/
protected static $utilities = array(
// Experimental. When a mobile device wants to switch to 'Desktop Mode'.
// http://scottcate.com/technology/windows-phone-8-ie10-desktop-or-mobile/
// https://github.com/serbanghita/Mobile-Detect/issues/57#issuecomment-15024011
// https://developers.facebook.com/docs/sharing/best-practices
'Bot' => 'Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom',
'MobileBot' => 'Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker/M1A1-R2D2',
'DesktopMode' => 'WPDesktop',
'TV' => 'SonyDTV|HbbTV', // experimental
'WebKit' => '(webkit)[ /]([\w.]+)',
// @todo: Include JXD consoles.
'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\b',
'Watch' => 'SM-V700',
);
/**
* All possible HTTP headers that represent the
* User-Agent string.
*
* @var array
*/
protected static $uaHttpHeaders = array(
// The default User-Agent string.
'HTTP_USER_AGENT',
// Header can occur on devices using Opera Mini.
'HTTP_X_OPERAMINI_PHONE_UA',
// Vodafone specific header: http://www.seoprinciple.com/mobile-web-community-still-angry-at-vodafone/24/
'HTTP_X_DEVICE_USER_AGENT',
'HTTP_X_ORIGINAL_USER_AGENT',
'HTTP_X_SKYFIRE_PHONE',
'HTTP_X_BOLT_PHONE_UA',
'HTTP_DEVICE_STOCK_UA',
'HTTP_X_UCBROWSER_DEVICE_UA',
);
/**
* The individual segments that could exist in a User-Agent string. VER refers to the regular
* expression defined in the constant self::VER.
*
* @var array
*/
protected static $properties = array(
// Build
'Mobile' => 'Mobile/[VER]',
'Build' => 'Build/[VER]',
'Version' => 'Version/[VER]',
'VendorID' => 'VendorID/[VER]',
// Devices
'iPad' => 'iPad.*CPU[a-z ]+[VER]',
'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
'iPod' => 'iPod.*CPU[a-z ]+[VER]',
//'BlackBerry' => array('BlackBerry[VER]', 'BlackBerry [VER];'),
'Kindle' => 'Kindle/[VER]',
// Browser
'Chrome' => array( 'Chrome/[VER]', 'CriOS/[VER]', 'CrMo/[VER]' ),
'Coast' => array( 'Coast/[VER]' ),
'Dolfin' => 'Dolfin/[VER]',
// @reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox
'Firefox' => array( 'Firefox/[VER]', 'FxiOS/[VER]' ),
'Fennec' => 'Fennec/[VER]',
// http://msdn.microsoft.com/en-us/library/ms537503(v=vs.85).aspx
// https://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx
'Edge' => 'Edge/[VER]',
'IE' => array( 'IEMobile/[VER];', 'IEMobile [VER]', 'MSIE [VER];', 'Trident/[0-9.]+;.*rv:[VER]' ),
// http://en.wikipedia.org/wiki/NetFront
'NetFront' => 'NetFront/[VER]',
'NokiaBrowser' => 'NokiaBrowser/[VER]',
'Opera' => array( ' OPR/[VER]', 'Opera Mini/[VER]', 'Version/[VER]' ),
'Opera Mini' => 'Opera Mini/[VER]',
'Opera Mobi' => 'Version/[VER]',
'UC Browser' => 'UC Browser[VER]',
'MQQBrowser' => 'MQQBrowser/[VER]',
'MicroMessenger' => 'MicroMessenger/[VER]',
'baiduboxapp' => 'baiduboxapp/[VER]',
'baidubrowser' => 'baidubrowser/[VER]',
'SamsungBrowser' => 'SamsungBrowser/[VER]',
'Iron' => 'Iron/[VER]',
// @note: Safari 7534.48.3 is actually Version 5.1.
// @note: On BlackBerry the Version is overwriten by the OS.
'Safari' => array( 'Version/[VER]', 'Safari/[VER]' ),
'Skyfire' => 'Skyfire/[VER]',
'Tizen' => 'Tizen/[VER]',
'Webkit' => 'webkit[ /][VER]',
'PaleMoon' => 'PaleMoon/[VER]',
// Engine
'Gecko' => 'Gecko/[VER]',
'Trident' => 'Trident/[VER]',
'Presto' => 'Presto/[VER]',
'Goanna' => 'Goanna/[VER]',
// OS
'iOS' => ' \bi?OS\b [VER][ ;]{1}',
'Android' => 'Android [VER]',
'BlackBerry' => array( 'BlackBerry[\w]+/[VER]', 'BlackBerry.*Version/[VER]', 'Version/[VER]' ),
'BREW' => 'BREW [VER]',
'Java' => 'Java/[VER]',
// @reference: http://windowsteamblog.com/windows_phone/b/wpdev/archive/2011/08/29/introducing-the-ie9-on-windows-phone-mango-user-agent-string.aspx
// @reference: http://en.wikipedia.org/wiki/Windows_NT#Releases
'Windows Phone OS' => array( 'Windows Phone OS [VER]', 'Windows Phone [VER]' ),
'Windows Phone' => 'Windows Phone [VER]',
'Windows CE' => 'Windows CE/[VER]',
// http://social.msdn.microsoft.com/Forums/en-US/windowsdeveloperpreviewgeneral/thread/6be392da-4d2f-41b4-8354-8dcee20c85cd
'Windows NT' => 'Windows NT [VER]',
'Symbian' => array( 'SymbianOS/[VER]', 'Symbian/[VER]' ),
'webOS' => array( 'webOS/[VER]', 'hpwOS/[VER];' ),
);
/**
* A cache for resolved matches
* @var array
*/
protected $cache = array();
/**
* The User-Agent HTTP header is stored in here.
* @var string
*/
protected $userAgent = null;
/**
* HTTP headers in the PHP-flavor. So HTTP_USER_AGENT and SERVER_SOFTWARE.
* @var array
*/
protected $httpHeaders = array();
/**
* CloudFront headers. E.g. CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer & CloudFront-Is-Tablet-Viewer.
* @var array
*/
protected $cloudfrontHeaders = array();
/**
* The matching Regex.
* This is good for debug.
* @var string
*/
protected $matchingRegex = null;
/**
* The matches extracted from the regex expression.
* This is good for debug.
* @var string
*/
protected $matchesArray = null;
/**
* The detection type, using self::DETECTION_TYPE_MOBILE or self::DETECTION_TYPE_EXTENDED.
*
* @deprecated since version 2.6.9
*
* @var string
*/
protected $detectionType = self::DETECTION_TYPE_MOBILE;
/**
* Construct an instance of this class.
*
* @param array $headers Specify the headers as injection. Should be PHP _SERVER flavored.
* If left empty, will use the global _SERVER['HTTP_*'] vars instead.
* @param string $userAgent Inject the User-Agent header. If null, will use HTTP_USER_AGENT
* from the $headers array instead.
*/
public function __construct(
array $headers = null, $userAgent = null
) {
$this->setHttpHeaders( $headers );
$this->setUserAgent( $userAgent );
}
/**
* Get the current script version.
* This is useful for the demo.php file,
* so people can check on what version they are testing
* for mobile devices.
*
* @return string The version number in semantic version format.
*/
public static function getScriptVersion() {
return self::VERSION;
}
/**
* Retrieve the list of known phone devices.
*
* @return array List of phone devices.
*/
public static function getPhoneDevices() {
return self::$phoneDevices;
}
/**
* Retrieve the list of known tablet devices.
*
* @return array List of tablet devices.
*/
public static function getTabletDevices() {
return self::$tabletDevices;
}
/**
* Alias for getBrowsers() method.
*
* @return array List of user agents.
*/
public static function getUserAgents() {
return self::getBrowsers();
}
/**
* Retrieve the list of known browsers. Specifically, the user agents.
*
* @return array List of browsers / user agents.
*/
public static function getBrowsers() {
return self::$browsers;
}
/**
* Retrieve the list of known utilities.
*
* @return array List of utilities.
*/
public static function getUtilities() {
return self::$utilities;
}
/**
* Retrieve the list of mobile operating systems.
*
* @return array The list of mobile operating systems.
*/
public static function getOperatingSystems() {
return self::$operatingSystems;
}
/**
* Retrieves the HTTP headers.
*
* @return array
*/
public function getHttpHeaders() {
return $this->httpHeaders;
}
/**
* Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers.
*
* @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract
* the headers. The default null is left for backwards compatibility.
*/
public function setHttpHeaders( $httpHeaders = null ) {
// use global _SERVER if $httpHeaders aren't defined
if ( ! is_array( $httpHeaders ) || ! count( $httpHeaders ) ) {
$httpHeaders = $_SERVER;
}
// clear existing headers
$this->httpHeaders = array();
// Only save HTTP headers. In PHP land, that means only _SERVER vars that
// start with HTTP_.
foreach ( $httpHeaders as $key => $value ) {
if ( substr( $key, 0, 5 ) === 'HTTP_' ) {
$this->httpHeaders[ $key ] = $value;
}
}
// In case we're dealing with CloudFront, we need to know.
$this->setCfHeaders( $httpHeaders );
}
/**
* Retrieves a particular header. If it doesn't exist, no exception/error is caused.
* Simply null is returned.
*
* @param string $header The name of the header to retrieve. Can be HTTP compliant such as
* "User-Agent" or "X-Device-User-Agent" or can be php-esque with the
* all-caps, HTTP_ prefixed, underscore seperated awesomeness.
*
* @return string|null The value of the header.
*/
public function getHttpHeader( $header ) {
// are we using PHP-flavored headers?
if ( strpos( $header, '_' ) === false ) {
$header = str_replace( '-', '_', $header );
$header = strtoupper( $header );
}
// test the alternate, too
$altHeader = 'HTTP_' . $header;
//Test both the regular and the HTTP_ prefix
if ( isset( $this->httpHeaders[ $header ] ) ) {
return $this->httpHeaders[ $header ];
} elseif ( isset( $this->httpHeaders[ $altHeader ] ) ) {
return $this->httpHeaders[ $altHeader ];
}
return null;
}
/**
* Get all possible HTTP headers that
* can contain the User-Agent string.
*
* @return array List of HTTP headers.
*/
public function getUaHttpHeaders() {
return self::$uaHttpHeaders;
}
/**
* Set CloudFront headers
* http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device
*
* @param array $cfHeaders List of HTTP headers
*
* @return boolean If there were CloudFront headers to be set
*/
public function setCfHeaders( $cfHeaders = null ) {
// use global _SERVER if $cfHeaders aren't defined
if ( ! is_array( $cfHeaders ) || ! count( $cfHeaders ) ) {
$cfHeaders = $_SERVER;
}
// clear existing headers
$this->cloudfrontHeaders = array();
// Only save CLOUDFRONT headers. In PHP land, that means only _SERVER vars that
// start with cloudfront-.
$response = false;
foreach ( $cfHeaders as $key => $value ) {
if ( substr( strtolower( $key ), 0, 16 ) === 'http_cloudfront_' ) {
$this->cloudfrontHeaders[ strtoupper( $key ) ] = $value;
$response = true;
}
}
return $response;
}
public function getMatchingRegex() {
return $this->matchingRegex;
}
public function getMatchesArray() {
return $this->matchesArray;
}
/**
* Magic overloading method.
*
* @method boolean is[...]()
* @param string $name
* @param array $arguments
*
* @return mixed
* @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
*/
public function __call( $name, $arguments ) {
// make sure the name starts with 'is', otherwise
if ( substr( $name, 0, 2 ) !== 'is' ) {
throw new BadMethodCallException( "No such method exists: $name" );
}
$this->setDetectionType( self::DETECTION_TYPE_MOBILE );
$key = substr( $name, 2 );
return $this->matchUAAgainstKey( $key );
}
/**
* Set the detection type. Must be one of self::DETECTION_TYPE_MOBILE or
* self::DETECTION_TYPE_EXTENDED. Otherwise, nothing is set.
*
* @deprecated since version 2.6.9
*
* @param string $type The type. Must be a self::DETECTION_TYPE_* constant. The default
* parameter is null which will default to self::DETECTION_TYPE_MOBILE.
*/
public function setDetectionType( $type = null ) {
if ( $type === null ) {
$type = self::DETECTION_TYPE_MOBILE;
}
if ( $type !== self::DETECTION_TYPE_MOBILE && $type !== self::DETECTION_TYPE_EXTENDED ) {
return;
}
$this->detectionType = $type;
}
/**
* Search for a certain key in the rules array.
* If the key is found then try to match the corresponding
* regex against the User-Agent.
*
* @param string $key
*
* @return boolean
*/
protected function matchUAAgainstKey( $key ) {
// Make the keys lowercase so we can match: isIphone(), isiPhone(), isiphone(), etc.
$key = strtolower( $key );
if ( false === isset( $this->cache[ $key ] ) ) {
// change the keys to lower case
$_rules = array_change_key_case( $this->getRules() );
if ( false === empty( $_rules[ $key ] ) ) {
$this->cache[ $key ] = $this->match( $_rules[ $key ] );
}
if ( false === isset( $this->cache[ $key ] ) ) {
$this->cache[ $key ] = false;
}
}
return $this->cache[ $key ];
}
/**
* Retrieve the current set of rules.
*
* @deprecated since version 2.6.9
*
* @return array
*/
public function getRules() {
if ( $this->detectionType == self::DETECTION_TYPE_EXTENDED ) {
return self::getMobileDetectionRulesExtended();
} else {
return self::getMobileDetectionRules();
}
}
/**
* Method gets the mobile detection rules + utilities.
* The reason this is separate is because utilities rules
* don't necessary imply mobile. This method is used inside
* the new $detect->is('stuff') method.
*
* @deprecated since version 2.6.9
*
* @return array All the rules + extended.
*/
public function getMobileDetectionRulesExtended() {
static $rules;
if ( ! $rules ) {
// Merge all rules together.
$rules = array_merge( self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers, self::$utilities );
}
return $rules;
}
/**
* Method gets the mobile detection rules. This method is used for the magic methods $detect->is*().
*
* @deprecated since version 2.6.9
*
* @return array All the rules (but not extended).
*/
public static function getMobileDetectionRules() {
static $rules;
if ( ! $rules ) {
$rules = array_merge( self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers );
}
return $rules;
}
/**
* Some detection rules are relative (not standard),
* because of the diversity of devices, vendors and
* their conventions in representing the User-Agent or
* the HTTP headers.
*
* This method will be used to check custom regexes against
* the User-Agent string.
*
* @param $regex
* @param string $userAgent
*
* @return bool
*
* @todo: search in the HTTP headers too.
*/
public function match( $regex, $userAgent = null ) {
$match = (bool) preg_match( sprintf( '#%s#is', $regex ), ( false === empty( $userAgent ) ? $userAgent : $this->userAgent ), $matches );
// If positive match is found, store the results for debug.
if ( $match ) {
$this->matchingRegex = $regex;
$this->matchesArray = $matches;
}
return $match;
}
/**
* Check if the device is a tablet.
* Return true if any type of tablet device is detected.
*
* @param string $userAgent deprecated
* @param array $httpHeaders deprecated
*
* @return bool
*/
public function isTablet( $userAgent = null, $httpHeaders = null ) {
// Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
if ( $this->getUserAgent() === 'Amazon CloudFront' ) {
$cfHeaders = $this->getCfHeaders();
if ( array_key_exists( 'HTTP_CLOUDFRONT_IS_TABLET_VIEWER', $cfHeaders ) && $cfHeaders['HTTP_CLOUDFRONT_IS_TABLET_VIEWER'] === 'true' ) {
return true;
}
}
$this->setDetectionType( self::DETECTION_TYPE_MOBILE );
foreach ( self::$tabletDevices as $_regex ) {
if ( $this->match( $_regex, $userAgent ) ) {
return true;
}
}
return false;
}
/**
* Retrieve the User-Agent.
*
* @return string|null The user agent if it's set.
*/
public function getUserAgent() {
return $this->userAgent;
}
/**
* Set the User-Agent to be used.
*
* @param string $userAgent The user agent string to set.
*
* @return string|null
*/
public function setUserAgent( $userAgent = null ) {
// Invalidate cache due to #375
$this->cache = array();
if ( false === empty( $userAgent ) ) {
return $this->userAgent = $userAgent;
} else {
$this->userAgent = null;
foreach ( $this->getUaHttpHeaders() as $altHeader ) {
if ( false === empty( $this->httpHeaders[ $altHeader ] ) ) { // @todo: should use getHttpHeader(), but it would be slow. (Serban)
$this->userAgent .= $this->httpHeaders[ $altHeader ] . ' ';
}
}
if ( ! empty( $this->userAgent ) ) {
return $this->userAgent = trim( $this->userAgent );
}
}
if ( is_array( $this->getCfHeaders() ) && count( $this->getCfHeaders() ) > 0 ) {
return $this->userAgent = 'Amazon CloudFront';
}
return $this->userAgent = null;
}
/**
* Retrieves the cloudfront headers.
*
* @return array
*/
public function getCfHeaders() {
return $this->cloudfrontHeaders;
}
/**
* Retrieve the mobile grading, using self::MOBILE_GRADE_* constants.
*
* @return string One of the self::MOBILE_GRADE_* constants.
*/
public function mobileGrade() {
$isMobile = $this->isMobile();
if ( // Apple iOS 4-7.0 – Tested on the original iPad (4.3 / 5.0), iPad 2 (4.3 / 5.1 / 6.1), iPad 3 (5.1 / 6.0), iPad Mini (6.1), iPad Retina (7.0), iPhone 3GS (4.3), iPhone 4 (4.3 / 5.1), iPhone 4S (5.1 / 6.0), iPhone 5 (6.0), and iPhone 5S (7.0)
$this->is( 'iOS' ) && $this->version( 'iPad', self::VERSION_TYPE_FLOAT ) >= 4.3 || $this->is( 'iOS' ) && $this->version( 'iPhone', self::VERSION_TYPE_FLOAT ) >= 4.3 || $this->is( 'iOS' ) && $this->version( 'iPod', self::VERSION_TYPE_FLOAT ) >= 4.3 ||
// Android 2.1-2.3 - Tested on the HTC Incredible (2.2), original Droid (2.2), HTC Aria (2.1), Google Nexus S (2.3). Functional on 1.5 & 1.6 but performance may be sluggish, tested on Google G1 (1.5)
// Android 3.1 (Honeycomb) - Tested on the Samsung Galaxy Tab 10.1 and Motorola XOOM
// Android 4.0 (ICS) - Tested on a Galaxy Nexus. Note: transition performance can be poor on upgraded devices
// Android 4.1 (Jelly Bean) - Tested on a Galaxy Nexus and Galaxy 7
( $this->version( 'Android', self::VERSION_TYPE_FLOAT ) > 2.1 && $this->is( 'Webkit' ) ) ||
// Windows Phone 7.5-8 - Tested on the HTC Surround (7.5), HTC Trophy (7.5), LG-E900 (7.5), Nokia 800 (7.8), HTC Mazaa (7.8), Nokia Lumia 520 (8), Nokia Lumia 920 (8), HTC 8x (8)
$this->version( 'Windows Phone OS', self::VERSION_TYPE_FLOAT ) >= 7.5 ||
// Tested on the Torch 9800 (6) and Style 9670 (6), BlackBerry® Torch 9810 (7), BlackBerry Z10 (10)
$this->is( 'BlackBerry' ) && $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) >= 6.0 || // Blackberry Playbook (1.0-2.0) - Tested on PlayBook
$this->match( 'Playbook.*Tablet' ) ||
// Palm WebOS (1.4-3.0) - Tested on the Palm Pixi (1.4), Pre (1.4), Pre 2 (2.0), HP TouchPad (3.0)
( $this->version( 'webOS', self::VERSION_TYPE_FLOAT ) >= 1.4 && $this->match( 'Palm|Pre|Pixi' ) ) || // Palm WebOS 3.0 - Tested on HP TouchPad
$this->match( 'hp.*TouchPad' ) ||
// Firefox Mobile 18 - Tested on Android 2.3 and 4.1 devices
( $this->is( 'Firefox' ) && $this->version( 'Firefox', self::VERSION_TYPE_FLOAT ) >= 18 ) ||
// Chrome for Android - Tested on Android 4.0, 4.1 device
( $this->is( 'Chrome' ) && $this->is( 'AndroidOS' ) && $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 4.0 ) ||
// Skyfire 4.1 - Tested on Android 2.3 device
( $this->is( 'Skyfire' ) && $this->version( 'Skyfire', self::VERSION_TYPE_FLOAT ) >= 4.1 && $this->is( 'AndroidOS' ) && $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 2.3 ) ||
// Opera Mobile 11.5-12: Tested on Android 2.3
( $this->is( 'Opera' ) && $this->version( 'Opera Mobi', self::VERSION_TYPE_FLOAT ) >= 11.5 && $this->is( 'AndroidOS' ) ) ||
// Meego 1.2 - Tested on Nokia 950 and N9
$this->is( 'MeeGoOS' ) ||
// Tizen (pre-release) - Tested on early hardware
$this->is( 'Tizen' ) ||
// Samsung Bada 2.0 - Tested on a Samsung Wave 3, Dolphin browser
// @todo: more tests here!
$this->is( 'Dolfin' ) && $this->version( 'Bada', self::VERSION_TYPE_FLOAT ) >= 2.0 ||
// UC Browser - Tested on Android 2.3 device
( ( $this->is( 'UC Browser' ) || $this->is( 'Dolfin' ) ) && $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 2.3 ) ||
// Kindle 3 and Fire - Tested on the built-in WebKit browser for each
( $this->match( 'Kindle Fire' ) || $this->is( 'Kindle' ) && $this->version( 'Kindle', self::VERSION_TYPE_FLOAT ) >= 3.0 ) ||
// Nook Color 1.4.1 - Tested on original Nook Color, not Nook Tablet
$this->is( 'AndroidOS' ) && $this->is( 'NookTablet' ) ||
// Chrome Desktop 16-24 - Tested on OS X 10.7 and Windows 7
$this->version( 'Chrome', self::VERSION_TYPE_FLOAT ) >= 16 && ! $isMobile ||
// Safari Desktop 5-6 - Tested on OS X 10.7 and Windows 7
$this->version( 'Safari', self::VERSION_TYPE_FLOAT ) >= 5.0 && ! $isMobile ||
// Firefox Desktop 10-18 - Tested on OS X 10.7 and Windows 7
$this->version( 'Firefox', self::VERSION_TYPE_FLOAT ) >= 10.0 && ! $isMobile ||
// Internet Explorer 7-9 - Tested on Windows XP, Vista and 7
$this->version( 'IE', self::VERSION_TYPE_FLOAT ) >= 7.0 && ! $isMobile ||
// Opera Desktop 10-12 - Tested on OS X 10.7 and Windows 7
$this->version( 'Opera', self::VERSION_TYPE_FLOAT ) >= 10 && ! $isMobile ) {
return self::MOBILE_GRADE_A;
}
if ( $this->is( 'iOS' ) && $this->version( 'iPad', self::VERSION_TYPE_FLOAT ) < 4.3 || $this->is( 'iOS' ) && $this->version( 'iPhone', self::VERSION_TYPE_FLOAT ) < 4.3 || $this->is( 'iOS' ) && $this->version( 'iPod', self::VERSION_TYPE_FLOAT ) < 4.3 ||
// Blackberry 5.0: Tested on the Storm 2 9550, Bold 9770
$this->is( 'Blackberry' ) && $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) >= 5 && $this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) < 6 ||
//Opera Mini (5.0-6.5) - Tested on iOS 3.2/4.3 and Android 2.3
( $this->version( 'Opera Mini', self::VERSION_TYPE_FLOAT ) >= 5.0 && $this->version( 'Opera Mini', self::VERSION_TYPE_FLOAT ) <= 7.0 && ( $this->version( 'Android', self::VERSION_TYPE_FLOAT ) >= 2.3 || $this->is( 'iOS' ) ) ) ||
// Nokia Symbian^3 - Tested on Nokia N8 (Symbian^3), C7 (Symbian^3), also works on N97 (Symbian^1)
$this->match( 'NokiaN8|NokiaC7|N97.*Series60|Symbian/3' ) ||
// @todo: report this (tested on Nokia N71)
$this->version( 'Opera Mobi', self::VERSION_TYPE_FLOAT ) >= 11 && $this->is( 'SymbianOS' ) ) {
return self::MOBILE_GRADE_B;
}
if ( // Blackberry 4.x - Tested on the Curve 8330
$this->version( 'BlackBerry', self::VERSION_TYPE_FLOAT ) <= 5.0 || // Windows Mobile - Tested on the HTC Leo (WinMo 5.2)
$this->match( 'MSIEMobile|Windows CE.*Mobile' ) || $this->version( 'Windows Mobile', self::VERSION_TYPE_FLOAT ) <= 5.2 ||
// Tested on original iPhone (3.1), iPhone 3 (3.2)
$this->is( 'iOS' ) && $this->version( 'iPad', self::VERSION_TYPE_FLOAT ) <= 3.2 || $this->is( 'iOS' ) && $this->version( 'iPhone', self::VERSION_TYPE_FLOAT ) <= 3.2 || $this->is( 'iOS' ) && $this->version( 'iPod', self::VERSION_TYPE_FLOAT ) <= 3.2 ||
// Internet Explorer 7 and older - Tested on Windows XP
$this->version( 'IE', self::VERSION_TYPE_FLOAT ) <= 7.0 && ! $isMobile ) {
return self::MOBILE_GRADE_C;
}
// All older smartphone platforms and featurephones - Any device that doesn't support media queries
// will receive the basic, C grade experience.
return self::MOBILE_GRADE_C;
}
/**
* Check if the device is mobile.
* Returns true if any type of mobile device detected, including special ones
*
* @param null $userAgent deprecated
* @param null $httpHeaders deprecated
*
* @return bool
*/
public function isMobile( $userAgent = null, $httpHeaders = null ) {
if ( $httpHeaders ) {
$this->setHttpHeaders( $httpHeaders );
}
if ( $userAgent ) {
$this->setUserAgent( $userAgent );
}
// Check specifically for cloudfront headers if the useragent === 'Amazon CloudFront'
if ( $this->getUserAgent() === 'Amazon CloudFront' ) {
$cfHeaders = $this->getCfHeaders();
if ( array_key_exists( 'HTTP_CLOUDFRONT_IS_MOBILE_VIEWER', $cfHeaders ) && $cfHeaders['HTTP_CLOUDFRONT_IS_MOBILE_VIEWER'] === 'true' ) {
return true;
}
}
$this->setDetectionType( self::DETECTION_TYPE_MOBILE );
if ( $this->checkHttpHeadersForMobile() ) {
return true;
} else {
return $this->matchDetectionRulesAgainstUA();
}
}
/**
* Check the HTTP headers for signs of mobile.
* This is the fastest mobile check possible; it's used
* inside isMobile() method.
*
* @return bool
*/
public function checkHttpHeadersForMobile() {
foreach ( $this->getMobileHeaders() as $mobileHeader => $matchType ) {
if ( isset( $this->httpHeaders[ $mobileHeader ] ) ) {
if ( is_array( $matchType['matches'] ) ) {
foreach ( $matchType['matches'] as $_match ) {
if ( strpos( $this->httpHeaders[ $mobileHeader ], $_match ) !== false ) {
return true;
}
}
return false;
} else {
return true;
}
}
}
return false;
}
public function getMobileHeaders() {
return self::$mobileHeaders;
}
/**
* Find a detection rule that matches the current User-agent.
*
* @param null $userAgent deprecated
*
* @return boolean
*/
protected function matchDetectionRulesAgainstUA( $userAgent = null ) {
// Begin general search.
foreach ( $this->getRules() as $_regex ) {
if ( empty( $_regex ) ) {
continue;
}
if ( $this->match( $_regex, $userAgent ) ) {
return true;
}
}
return false;
}
/**
* This method checks for a certain property in the
* userAgent.
* @todo: The httpHeaders part is not yet used.
*
* @param string $key
* @param string $userAgent deprecated
* @param string $httpHeaders deprecated
*
* @return bool|int|null
*/
public function is( $key, $userAgent = null, $httpHeaders = null ) {
// Set the UA and HTTP headers only if needed (eg. batch mode).
if ( $httpHeaders ) {
$this->setHttpHeaders( $httpHeaders );
}
if ( $userAgent ) {
$this->setUserAgent( $userAgent );
}
$this->setDetectionType( self::DETECTION_TYPE_EXTENDED );
return $this->matchUAAgainstKey( $key );
}
/**
* Check the version of the given property in the User-Agent.
* Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31)
*
* @param string $propertyName The name of the property. See self::getProperties() array
* keys for all possible properties.
* @param string $type Either self::VERSION_TYPE_STRING to get a string value or
* self::VERSION_TYPE_FLOAT indicating a float value. This parameter
* is optional and defaults to self::VERSION_TYPE_STRING. Passing an
* invalid parameter will default to the this type as well.
*
* @return string|float The version of the property we are trying to extract.
*/
public function version( $propertyName, $type = self::VERSION_TYPE_STRING ) {
if ( empty( $propertyName ) ) {
return false;
}
// set the $type to the default if we don't recognize the type
if ( $type !== self::VERSION_TYPE_STRING && $type !== self::VERSION_TYPE_FLOAT ) {
$type = self::VERSION_TYPE_STRING;
}
$properties = self::getProperties();
// Check if the property exists in the properties array.
if ( true === isset( $properties[ $propertyName ] ) ) {
// Prepare the pattern to be matched.
// Make sure we always deal with an array (string is converted).
$properties[ $propertyName ] = (array) $properties[ $propertyName ];
foreach ( $properties[ $propertyName ] as $propertyMatchString ) {
$propertyPattern = str_replace( '[VER]', self::VER, $propertyMatchString );
// Identify and extract the version.
preg_match( sprintf( '#%s#is', $propertyPattern ), $this->userAgent, $match );
if ( false === empty( $match[1] ) ) {
$version = ( $type == self::VERSION_TYPE_FLOAT ? $this->prepareVersionNo( $match[1] ) : $match[1] );
return $version;
}
}
}
return false;
}
/**
* Get the properties array.
*
* @return array
*/
public static function getProperties() {
return self::$properties;
}
/**
* Prepare the version number.
*
* @todo Remove the error supression from str_replace() call.
*
* @param string $ver The string version, like "2.6.21.2152";
*
* @return float
*/
public function prepareVersionNo( $ver ) {
$ver = str_replace( array( '_', ' ', '/' ), '.', $ver );
$arrVer = explode( '.', $ver, 2 );
if ( isset( $arrVer[1] ) ) {
$arrVer[1] = @str_replace( '.', '', $arrVer[1] ); // @todo: treat strings versions.
}
return (float) implode( '.', $arrVer );
}
}
Fatal error: Uncaught Error: Class 'WCCT_Mobile_Detect' not found in /home/wesuppor/brandaholic.com.pk/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/finale-woocommerce-sales-countdown-timer-discount-plugin-lite.php:251
Stack trace:
#0 /home/wesuppor/brandaholic.com.pk/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/finale-woocommerce-sales-countdown-timer-discount-plugin-lite.php(220): WCCT_Core->wcct_mobile_check()
#1 /home/wesuppor/brandaholic.com.pk/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/finale-woocommerce-sales-countdown-timer-discount-plugin-lite.php(161): WCCT_Core->load_hooks()
#2 /home/wesuppor/brandaholic.com.pk/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/finale-woocommerce-sales-countdown-timer-discount-plugin-lite.php(328): WCCT_Core->__construct()
#3 /home/wesuppor/brandaholic.com.pk/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/finale-woocommerce-sales-countdown-timer-discount-plugin-lite. in /home/wesuppor/brandaholic.com.pk/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/finale-woocommerce-sales-countdown-timer-discount-plugin-lite.php on line 251