<?php /* * Copyright 2010, Anthony Hand * File version date: November 28, 2010 * * LICENSE INFORMATION * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http:// www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the License. * * ABOUT THIS PROJECT * Project Owner: Anthony Hand * Email: [email protected] * Web Site: http:// www.mobileesp.com * Source Files: http:// code.google.com/p/mobileesp/ * Versions of this code are available for: * PHP, JavaScript, Java, ASP.NET (C#), and Ruby */ /** The UserAgentInfo class encapsulates information about * a browser's connection to your web site. * You can use it to find out whether the browser asking for * your site's content is probably running on a mobile device. * The methods were written so you can be as granular as you want. * For example, enquiring whether it's as specific as an iPod Touch or * as general as a smartphone class device. * The object's methods return 1 for true, or 0 for false. * @author Anthony Hand */ class UserAgentInfo { private static $me = null; private $useragent = ""; private $httpaccept = ""; // Standardized values for true and false. private $true = 1; private $false = 0; // Initialize some initial smartphone string variables. private $engineWebKit = 'webkit'; private $deviceIphone = 'iphone'; private $deviceIpod = 'ipod'; private $deviceIpad = 'ipad'; private $deviceMacPpc = 'macintosh'; // Used for disambiguation private $deviceAndroid = 'android'; private $deviceGoogleTV = 'googletv'; private $deviceNuvifone = 'nuvifone'; // Garmin Nuvifone private $deviceSymbian = 'symbian'; private $deviceS60 = 'series60'; private $deviceS70 = 'series70'; private $deviceS80 = 'series80'; private $deviceS90 = 'series90'; private $deviceWinPhone7 = 'windows phone os 7'; private $deviceWinMob = 'windows ce'; private $deviceWindows = 'windows'; private $deviceIeMob = 'iemobile'; private $devicePpc = 'ppc'; // Stands for PocketPC private $enginePie = 'wm5 pie'; // An old Windows Mobile private $deviceBB = 'blackberry'; private $vndRIM = 'vnd.rim'; // Detectable when BB devices emulate IE or Firefox private $deviceBBStorm = 'blackberry95'; // Storm 1 and 2 private $deviceBBBold = 'blackberry97'; // Bold private $deviceBBTour = 'blackberry96'; // Tour private $deviceBBCurve = 'blackberry89'; // Curve2 private $deviceBBTorch = 'blackberry 98'; // Torch private $devicePalm = 'palm'; private $deviceWebOS = 'webos'; // For Palm's new WebOS devices private $engineBlazer = 'blazer'; // Old Palm browser private $engineXiino = 'xiino'; // Another old Palm private $deviceKindle = 'kindle'; // Amazon Kindle, eInk one. // Initialize variables for mobile-specific content. private $vndwap = 'vnd.wap'; private $wml = 'wml'; // Initialize variables for other random devices and mobile browsers. private $deviceBrew = 'brew'; private $deviceDanger = 'danger'; private $deviceHiptop = 'hiptop'; private $devicePlaystation = 'playstation'; private $deviceNintendoDs = 'nitro'; private $deviceNintendo = 'nintendo'; private $deviceWii = 'wii'; private $deviceXbox = 'xbox'; private $deviceArchos = 'archos'; private $engineOpera = 'opera'; // Popular browser private $engineNetfront = 'netfront'; // Common embedded OS browser private $engineUpBrowser = 'up.browser'; // common on some phones private $engineOpenWeb = 'openweb'; // Transcoding by OpenWave server private $deviceMidp = 'midp'; // a mobile Java technology private $uplink = 'up.link'; private $engineTelecaQ = 'teleca q'; // a modern feature phone browser private $devicePda = 'pda'; // some devices report themselves as PDAs private $mini = 'mini'; // Some mobile browsers put 'mini' in their names. private $mobile = 'mobile'; // Some mobile browsers put 'mobile' in their user agent strings. private $mobi = 'mobi'; // Some mobile browsers put 'mobi' in their user agent strings. // Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets. private $maemo = 'maemo'; private $maemoTablet = 'tablet'; private $linux = 'linux'; private $qtembedded = 'qt embedded'; // for Sony Mylo and others private $mylocom2 = 'com2'; // for Sony Mylo also // In some UserAgents, the only clue is the manufacturer. private $manuSonyEricsson = "sonyericsson"; private $manuericsson = "ericsson"; private $manuSamsung1 = "sec-sgh"; private $manuSony = "sony"; private $manuHtc = "htc"; // Popular Android and WinMo manufacturer // In some UserAgents, the only clue is the operator. private $svcDocomo = "docomo"; private $svcKddi = "kddi"; private $svcVodafone = "vodafone"; // Disambiguation strings. private $disUpdate = "update"; // P vs. update /** The constructor. Initializes several default variables. */ protected function __construct() { $this->useragent = strtolower($_SERVER['HTTP_USER_AGENT']); $this->httpaccept = strtolower($_SERVER['HTTP_ACCEPT']); } /** Get the singleton UserAgentInfo object. * @return UserAgentInfo */ public static function get() { if (is_null(self::$me)) self::$me = new self(); return self::$me; } /** Detects if the current device is an iPhone. */ public function DetectIphone() { if (stripos($this->useragent, $this->deviceIphone) > -1) { // The iPad and iPod Touch say they're an iPhone! So let's disambiguate. if ($this->DetectIpad() == $this->true || $this->DetectIpod() == $this->true) { return $this->false; } else return $this->true; } else return $this->false; } /** Detects if the current device is an iPod Touch. */ public function DetectIpod() { if (stripos($this->useragent, $this->deviceIpod) > -1) return $this->true; else return $this->false; } /** Detects if the current device is an iPad tablet. */ public function DetectIpad() { if (stripos($this->useragent, $this->deviceIpad) > -1 && $this->DetectWebkit() == $this->true) return $this->true; else return $this->false; } /** Detects if the current device is an iPhone or iPod Touch. */ public function DetectIphoneOrIpod() { // We repeat the searches here because some iPods may report // themselves as an iPhone, which would be okay. if (stripos($this->useragent, $this->deviceIphone) > -1 || stripos($this->useragent, $this->deviceIpod) > -1) return $this->true; else return $this->false; } /** Detects if the current device is an Android OS-based device. */ public function DetectAndroid() { if (stripos($this->useragent, $this->deviceAndroid) > -1) return $this->true; else return $this->false; } /** Detects if the current device is an Android OS-based device and * the browser is based on WebKit. */ public function DetectAndroidWebKit() { if ($this->DetectAndroid() == $this->true) { if ($this->DetectWebkit() == $this->true) { return $this->true; } else return $this->false; } else return $this->false; } /** Detects if the current device is a GoogleTV. */ public function DetectGoogleTV() { if (stripos($this->useragent, $this->deviceGoogleTV) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is based on WebKit. */ public function DetectWebkit() { if (stripos($this->useragent, $this->engineWebKit) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is the Nokia S60 Open Source Browser. */ public function DetectS60OssBrowser() { // First, test for WebKit, then make sure it's either Symbian or S60. if ($this->DetectWebkit() == $this->true) { if (stripos($this->useragent, $this->deviceSymbian) > -1 || stripos($this->useragent, $this->deviceS60) > -1) { return $this->true; } else return $this->false; } else return $this->false; } /** Detects if the current device is any Symbian OS-based device, * including older S60, Series 70, Series 80, Series 90, and UIQ, * or other browsers running on these devices. */ public function DetectSymbianOS() { if (stripos($this->useragent, $this->deviceSymbian) > -1 || stripos($this->useragent, $this->deviceS60) > -1 || stripos($this->useragent, $this->deviceS70) > -1 || stripos($this->useragent, $this->deviceS80) > -1 || stripos($this->useragent, $this->deviceS90) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is a Windows Phone 7 device. */ public function DetectWindowsPhone7() { if (stripos($this->useragent, $this->deviceWinPhone7) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is a Windows Mobile device. * Excludes Windows Phone 7 devices. * Focuses on Windows Mobile 6.xx and earlier. */ public function DetectWindowsMobile() { if ($this->DetectWindowsPhone7() == $this->true) return $this->false; // Most devices use 'Windows CE', but some report 'iemobile' // and some older ones report as 'PIE' for Pocket IE. if (stripos($this->useragent, $this->deviceWinMob) > -1 || stripos($this->useragent, $this->deviceIeMob) > -1 || stripos($this->useragent, $this->enginePie) > -1) return $this->true; // Test for Windows Mobile PPC but not old Macintosh PowerPC. if (stripos($this->useragent, $this->devicePpc) > -1 && !(stripos($this->useragent, $this->deviceMacPpc) > 1)) return $this->true; // Test for certain Windwos Mobile-based HTC devices. if (stripos($this->useragent, $this->manuHtc) > -1 && stripos($this->useragent, $this->deviceWindows) > -1) return $this->true; if ($this->DetectWapWml() == $this->true && stripos($this->useragent, $this->deviceWindows) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is a BlackBerry of some sort. */ public function DetectBlackBerry() { if (stripos($this->useragent, $this->deviceBB) > -1) return $this->true; if (stripos($this->httpaccept, $this->vndRIM) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is a BlackBerry device AND uses a * WebKit-based browser. These are signatures for the new BlackBerry OS 6. * Examples: Torch */ public function DetectBlackBerryWebKit() { if ((stripos($this->useragent, $this->deviceBB) > -1) && (stripos($this->useragent, $this->engineWebKit) > -1)) { return $this->true; } else return $this->false; } /** Detects if the current browser is a BlackBerry Touch * device, such as the Storm or Torch. */ public function DetectBlackBerryTouch() { if ((stripos($this->useragent, $this->deviceBBStorm) > -1) || (stripos($this->useragent, $this->deviceBBTorch) > -1)) return $this->true; else return $this->false; } /** Detects if the current browser is a BlackBerry OS 5 device AND * has a more capable recent browser. * Examples, Storm, Bold, Tour, Curve2 * Excludes the new BlackBerry OS 6 browser!! */ public function DetectBlackBerryHigh() { // Disambiguate for BlackBerry OS 6 (WebKit) browser if ($this->DetectBlackBerryWebKit() == $this->true) return $this->false; if ($this->DetectBlackBerry() == $this->true) { if (($this->DetectBlackBerryTouch() == $this->true) || stripos($this->useragent, $this->deviceBBBold) > -1 || stripos($this->useragent, $this->deviceBBTour) > -1 || stripos($this->useragent, $this->deviceBBCurve) > -1) { return $this->true; } else return $this->false; } else return $this->false; } /** Detects if the current browser is a BlackBerry device AND * has an older, less capable browser. * Examples: Pearl, 8800, Curve1. */ public function DetectBlackBerryLow() { if ($this->DetectBlackBerry() == $this->true) { // Assume that if it's not in the High tier, then it's Low. if ($this->DetectBlackBerryHigh() == $this->true) return $this->false; else return $this->true; } else return $this->false; } /** Detects if the current browser is on a PalmOS device. */ public function DetectPalmOS() { // Most devices nowadays report as 'Palm', but some older ones reported as Blazer or Xiino. if (stripos($this->useragent, $this->devicePalm) > -1 || stripos($this->useragent, $this->engineBlazer) > -1 || stripos($this->useragent, $this->engineXiino) > -1) { // Make sure it's not WebOS first if ($this->DetectPalmWebOS() == $this->true) return $this->false; else return $this->true; } else return $this->false; } /** Detects if the current browser is on a Palm device * running the new WebOS. */ public function DetectPalmWebOS() { if (stripos($this->useragent, $this->deviceWebOS) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is a * Garmin Nuvifone. */ public function DetectGarminNuvifone() { if (stripos($this->useragent, $this->deviceNuvifone) > -1) return $this->true; else return $this->false; } /** Check to see whether the device is any device * in the 'smartphone' category. */ public function DetectSmartphone() { if ($this->DetectIphoneOrIpod() == $this->true) return $this->true; if ($this->DetectS60OssBrowser() == $this->true) return $this->true; if ($this->DetectSymbianOS() == $this->true) return $this->true; if ($this->DetectAndroid() == $this->true) return $this->true; if ($this->DetectWindowsMobile() == $this->true) return $this->true; if ($this->DetectWindowsPhone7() == $this->true) return $this->true; if ($this->DetectBlackBerry() == $this->true) return $this->true; if ($this->DetectPalmWebOS() == $this->true) return $this->true; if ($this->DetectPalmOS() == $this->true) return $this->true; if ($this->DetectGarminNuvifone() == $this->true) return $this->true; else return $this->false; } /** Detects whether the device is a Brew-powered device. */ public function DetectBrewDevice() { if (stripos($this->useragent, $this->deviceBrew) > -1) return $this->true; else return $this->false; } /** Detects the Danger Hiptop device. */ public function DetectDangerHiptop() { if (stripos($this->useragent, $this->deviceDanger) > -1 || stripos($this->useragent, $this->deviceHiptop) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is Opera Mobile or Mini. */ public function DetectOperaMobile() { if (stripos($this->useragent, $this->engineOpera) > -1) { if ((stripos($this->useragent, $this->mini) > -1) || (stripos($this->useragent, $this->mobi) > -1)) return $this->true; else return $this->false; } else return $this->false; } /** Detects whether the device supports WAP or WML. */ public function DetectWapWml() { if (stripos($this->httpaccept, $this->vndwap) > -1 || stripos($this->httpaccept, $this->wml) > -1) return $this->true; else return $this->false; } /** Detects if the current device is an Amazon Kindle. */ public function DetectKindle() { if (stripos($this->useragent, $this->deviceKindle) > -1) return $this->true; else return $this->false; } /** The quick way to detect for a mobile device. * Will probably detect most recent/current mid-tier Feature Phones * as well as smartphone-class devices. Excludes Apple iPads. */ public function DetectMobileQuick() { // Let's say no if it's an iPad, which contains 'mobile' in its user agent. if ($this->DetectiPad() == $this->true) return $this->false; // Most mobile browsing is done on smartphones if ($this->DetectSmartphone() == $this->true) return $this->true; if ($this->DetectWapWml() == $this->true) return $this->true; if ($this->DetectBrewDevice() == $this->true) return $this->true; if ($this->DetectOperaMobile() == $this->true) return $this->true; if (stripos($this->useragent, $this->engineNetfront) > -1) return $this->true; if (stripos($this->useragent, $this->engineUpBrowser) > -1) return $this->true; if (stripos($this->useragent, $this->engineOpenWeb) > -1) return $this->true; if ($this->DetectDangerHiptop() == $this->true) return $this->true; if ($this->DetectMidpCapable() == $this->true) return $this->true; if ($this->DetectMaemoTablet() == $this->true) return $this->true; if ($this->DetectArchos() == $this->true) return $this->true; if ((stripos($this->useragent, $this->devicePda) > -1) && (stripos($this->useragent, $this->disUpdate) < 0)) // no index found return $this->true; if (stripos($this->useragent, $this->mobile) > -1) return $this->true; else return $this->false; } /** Detects if the current device is a Sony Playstation. */ public function DetectSonyPlaystation() { if (stripos($this->useragent, $this->devicePlaystation) > -1) return $this->true; else return $this->false; } /** Detects if the current device is a Nintendo game device. */ public function DetectNintendo() { if (stripos($this->useragent, $this->deviceNintendo) > -1 || stripos($this->useragent, $this->deviceWii) > -1 || stripos($this->useragent, $this->deviceNintendoDs) > -1) return $this->true; else return $this->false; } /** Detects if the current device is a Microsoft Xbox. */ public function DetectXbox() { if (stripos($this->useragent, $this->deviceXbox) > -1) return $this->true; else return $this->false; } /** Detects if the current device is an Internet-capable game console. */ public function DetectGameConsole() { if ($this->DetectSonyPlaystation() == $this->true) return $this->true; else if ($this->DetectNintendo() == $this->true) return $this->true; else if ($this->DetectXbox() == $this->true) return $this->true; else return $this->false; } /** Detects if the current device supports MIDP, a mobile Java technology. */ public function DetectMidpCapable() { if (stripos($this->useragent, $this->deviceMidp) > -1 || stripos($this->httpaccept, $this->deviceMidp) > -1) return $this->true; else return $this->false; } /** Detects if the current device is on one of the Maemo-based Nokia Internet Tablets. */ public function DetectMaemoTablet() { if (stripos($this->useragent, $this->maemo) > -1) return $this->true; // Must be Linux + Tablet, or else it could be something else. if (stripos($this->useragent, $this->maemoTablet) > -1 && stripos($this->useragent, $this->linux) > -1) return $this->true; else return $this->false; } /** Detects if the current device is an Archos media player/Internet tablet. */ public function DetectArchos() { if (stripos($this->useragent, $this->deviceArchos) > -1) return $this->true; else return $this->false; } /** Detects if the current browser is a Sony Mylo device. */ public function DetectSonyMylo() { if (stripos($this->useragent, $this->manuSony) > -1) { if ((stripos($this->useragent, $this->qtembedded) > -1) || (stripos($this->useragent, $this->mylocom2) > -1)) { return $this->true; } else return $this->false; } else return $this->false; } /** The longer and more thorough way to detect for a mobile device. * Will probably detect most feature phones, * smartphone-class devices, Internet Tablets, * Internet-enabled game consoles, etc. * This ought to catch a lot of the more obscure and older devices, also -- * but no promises on thoroughness! */ public function DetectMobileLong() { if ($this->DetectMobileQuick() == $this->true) return $this->true; if ($this->DetectGameConsole() == $this->true) return $this->true; if ($this->DetectSonyMylo() == $this->true) return $this->true; // Detect older phones from certain manufacturers and operators. if (stripos($this->useragent, $this->uplink) > -1) return $this->true; if (stripos($this->useragent, $this->manuSonyEricsson) > -1) return $this->true; if (stripos($this->useragent, $this->manuericsson) > -1) return $this->true; if (stripos($this->useragent, $this->manuSamsung1) > -1) return $this->true; if (stripos($this->useragent, $this->svcDocomo) > -1) return $this->true; if (stripos($this->useragent, $this->svcKddi) > -1) return $this->true; if (stripos($this->useragent, $this->svcVodafone) > -1) return $this->true; else return $this->false; } /** The quick way to detect for a tier of devices. * This method detects for devices which can * display iPhone-optimized web content. * Includes iPhone, iPod Touch, Android, WebOS, etc. */ public function DetectTierIphone() { if ($this->DetectIphoneOrIpod() == $this->true) return $this->true; if ($this->DetectAndroid() == $this->true) return $this->true; if ($this->DetectAndroidWebKit() == $this->true) return $this->true; if ($this->DetectWindowsPhone7() == $this->true) return $this->true; if ($this->DetectBlackBerryWebKit() == $this->true) return $this->true; if ($this->DetectPalmWebOS() == $this->true) return $this->true; if ($this->DetectGarminNuvifone() == $this->true) return $this->true; if ($this->DetectMaemoTablet() == $this->true) return $this->true; else return $this->false; } /** The quick way to detect for a tier of devices. * This method detects for devices which are likely to be capable * of viewing CSS content optimized for the iPhone, * but may not necessarily support JavaScript. * Excludes all iPhone Tier devices. */ public function DetectTierRichCss() { if ($this->DetectMobileQuick() == $this->true) { if ($this->DetectTierIphone() == $this->true) return $this->false; // The following devices are explicitly ok. if ($this->DetectWebkit() == $this->true) // Any WebKit return $this->true; if ($this->DetectS60OssBrowser() == $this->true) return $this->true; // Note: 'High' BlackBerry devices ONLY if ($this->DetectBlackBerryHigh() == $this->true) return $this->true; if ($this->DetectWindowsMobile() == $this->true) return $this->true; if (stripos($this->useragent, $this->engineTelecaQ) > -1) return $this->true; // default else return $this->false; } else return $this->false; } /** The quick way to detect for a tier of devices. * This method detects for all other types of phones, * but excludes the iPhone and RichCSS Tier devices. */ public function DetectTierOtherPhones() { if ($this->DetectMobileLong() == $this->true) { // Exclude devices in the other 2 categories if ($this->DetectTierIphone() == $this->true) return $this->false; if ($this->DetectTierRichCss() == $this->true) return $this->false; // Otherwise, it's a YES else return $this->true; } else return $this->false; } } ?>