source: trunk/include/mdetect.php @ 29839

Last change on this file since 29839 was 28068, checked in by rvelices, 11 years ago

bug 3058: update mdetect for windows 8 mobile etc ...

File size: 40.2 KB
Line 
1<?php
2
3/* *******************************************
4// Copyright 2010-2013, Anthony Hand
5//
6// File version 2013.10.27 (October 27, 2013)
7//      Updates:
8//      - Made minor update to the InitDeviceScan. Should check Tablet Tier first, then iPhone Tier, then Quick Mobile.
9//
10// File version 2013.08.01 (August 1, 2013)
11//      Updates:
12//      - Updated DetectMobileQuick(). Moved the 'Exclude Tablets' logic to the top of the method to fix a logic bug.
13//
14// File version 2013.07.13 (July 13, 2013)
15//      Updates:
16//      - Added support for Tizen: variable and DetectTizen().
17//      - Added support for Meego: variable and DetectMeego().
18//      - Added support for Windows Phone 8: variable and DetectWindowsPhone8().
19//      - Added a generic Windows Phone method: DetectWindowsPhone().
20//      - Added support for BlackBerry 10 OS: variable and DetectBlackBerry10Phone().
21//      - Added support for PlayStation Vita handheld: variable and DetectGamingHandheld().
22//      - Updated DetectTierIphone(). Added Tizen; updated the Windows Phone, BB10, and PS Vita support.
23//      - Updated DetectWindowsMobile(). Uses generic DetectWindowsPhone() method rather than WP7.
24//      - Updated DetectSmartphone(). Uses the IsTierIphone variable.
25//      - Updated DetectSonyMylo() with more efficient code.
26//      - Removed DetectGarminNuvifone() from DetectTierIphone(). How many are left in market in 2013? It is detected as a RichCSS Tier device.
27//      - Removed the deviceXoom variable. It was unused.
28//      - Added detection support for the Obigo mobile browser to DetectMobileQuick().
29//
30//
31// LICENSE INFORMATION
32// Licensed under the Apache License, Version 2.0 (the "License");
33// you may not use this file except in compliance with the License.
34// You may obtain a copy of the License at
35//        http://www.apache.org/licenses/LICENSE-2.0
36// Unless required by applicable law or agreed to in writing,
37// software distributed under the License is distributed on an
38// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
39// either express or implied. See the License for the specific
40// language governing permissions and limitations under the License.
41//
42//
43// ABOUT THIS PROJECT
44//   Project Owner: Anthony Hand
45//   Email: anthony.hand@gmail.com
46//   Web Site: http://www.mobileesp.com
47//   Source Files: http://code.google.com/p/mobileesp/
48//   
49//   Versions of this code are available for:
50//      PHP, JavaScript, Java, ASP.NET (C#), and Ruby
51//
52// *******************************************
53*/
54
55
56
57//**************************
58// The uagent_info class encapsulates information about
59//   a browser's connection to your web site.
60//   You can use it to find out whether the browser asking for
61//   your site's content is probably running on a mobile device.
62//   The methods were written so you can be as granular as you want.
63//   For example, enquiring whether it's as specific as an iPod Touch or
64//   as general as a smartphone class device.
65//   The object's methods return 1 for true, or 0 for false.
66class uagent_info
67{
68   var $useragent = "";
69   var $httpaccept = "";
70
71   //standardized values for true and false.
72   var $true = 1;
73   var $false = 0;
74
75   //Let's store values for quickly accessing the same info multiple times. InitCompleted
76   var $initCompleted = 0; //Stores whether we're currently initializing the most popular functions.
77   var $isWebkit = 0; //Stores the result of DetectWebkit()
78   var $isMobilePhone = 0; //Stores the result of DetectMobileQuick()
79   var $isIphone = 0; //Stores the result of DetectIphone()
80   var $isAndroid = 0; //Stores the result of DetectAndroid()
81   var $isAndroidPhone = 0; //Stores the result of DetectAndroidPhone()
82   var $isTierTablet = 0; //Stores the result of DetectTierTablet()
83   var $isTierIphone = 0; //Stores the result of DetectTierIphone()
84   var $isTierRichCss = 0; //Stores the result of DetectTierRichCss()
85   var $isTierGenericMobile = 0; //Stores the result of DetectTierOtherPhones()
86
87   //Initialize some initial smartphone string variables.
88   var $engineWebKit = 'webkit';
89
90   var $deviceIphone = 'iphone';
91   var $deviceIpod = 'ipod';
92   var $deviceIpad = 'ipad';
93   var $deviceMacPpc = 'macintosh'; //Used for disambiguation
94
95   var $deviceAndroid = 'android';
96   var $deviceGoogleTV = 'googletv';
97   var $deviceHtcFlyer = 'htc_flyer'; //HTC Flyer
98   
99   var $deviceWinPhone7 = 'windows phone os 7'; 
100   var $deviceWinPhone8 = 'windows phone 8'; 
101   var $deviceWinMob = 'windows ce';
102   var $deviceWindows = 'windows'; 
103   var $deviceIeMob = 'iemobile';
104   var $devicePpc = 'ppc'; //Stands for PocketPC
105   var $enginePie = 'wm5 pie'; //An old Windows Mobile
106   
107   var $deviceBB = 'blackberry';   
108   var $deviceBB10 = 'bb10'; //For the new BB 10 OS
109   var $vndRIM = 'vnd.rim'; //Detectable when BB devices emulate IE or Firefox
110   var $deviceBBStorm = 'blackberry95';  //Storm 1 and 2
111   var $deviceBBBold = 'blackberry97'; //Bold 97x0 (non-touch)
112   var $deviceBBBoldTouch = 'blackberry 99'; //Bold 99x0 (touchscreen)
113   var $deviceBBTour = 'blackberry96'; //Tour
114   var $deviceBBCurve = 'blackberry89'; //Curve2
115   var $deviceBBCurveTouch = 'blackberry 938'; //Curve Touch
116   var $deviceBBTorch = 'blackberry 98'; //Torch
117   var $deviceBBPlaybook = 'playbook'; //PlayBook tablet
118   
119   var $deviceSymbian = 'symbian';
120   var $deviceS60 = 'series60';
121   var $deviceS70 = 'series70';
122   var $deviceS80 = 'series80';
123   var $deviceS90 = 'series90';
124   
125   var $devicePalm = 'palm';
126   var $deviceWebOS = 'webos'; //For Palm's line of WebOS devices
127   var $deviceWebOShp = 'hpwos'; //For HP's line of WebOS devices
128   var $engineBlazer = 'blazer'; //Old Palm browser
129   var $engineXiino = 'xiino'; //Another old Palm
130   
131   var $deviceNuvifone = 'nuvifone'; //Garmin Nuvifone
132   var $deviceBada = 'bada'; //Samsung's Bada OS
133   var $deviceTizen = 'tizen'; //Tizen OS
134   var $deviceMeego = 'meego'; //Meego OS
135
136   var $deviceKindle = 'kindle'; //Amazon Kindle, eInk one
137   var $engineSilk = 'silk-accelerated'; //Amazon's accelerated Silk browser for Kindle Fire
138   
139   //Initialize variables for mobile-specific content.
140   var $vndwap = 'vnd.wap';
141   var $wml = 'wml';   
142   
143   //Initialize variables for other random devices and mobile browsers.
144   var $deviceTablet = 'tablet'; //Generic term for slate and tablet devices
145   var $deviceBrew = 'brew';
146   var $deviceDanger = 'danger';
147   var $deviceHiptop = 'hiptop';
148   var $devicePlaystation = 'playstation';
149   var $devicePlaystationVita = 'vita';
150   var $deviceNintendoDs = 'nitro';
151   var $deviceNintendo = 'nintendo';
152   var $deviceWii = 'wii';
153   var $deviceXbox = 'xbox';
154   var $deviceArchos = 'archos';
155   
156   var $engineOpera = 'opera'; //Popular browser
157   var $engineNetfront = 'netfront'; //Common embedded OS browser
158   var $engineUpBrowser = 'up.browser'; //common on some phones
159   var $engineOpenWeb = 'openweb'; //Transcoding by OpenWave server
160   var $deviceMidp = 'midp'; //a mobile Java technology
161   var $uplink = 'up.link';
162   var $engineTelecaQ = 'teleca q'; //a modern feature phone browser
163   var $engineObigo = 'obigo'; //W 10 is a modern feature phone browser
164   
165   var $devicePda = 'pda'; //some devices report themselves as PDAs
166   var $mini = 'mini';  //Some mobile browsers put 'mini' in their names.
167   var $mobile = 'mobile'; //Some mobile browsers put 'mobile' in their user agent strings.
168   var $mobi = 'mobi'; //Some mobile browsers put 'mobi' in their user agent strings.
169   
170   //Use Maemo, Tablet, and Linux to test for Nokia's Internet Tablets.
171   var $maemo = 'maemo';
172   var $linux = 'linux';
173   var $qtembedded = 'qt embedded'; //for Sony Mylo and others
174   var $mylocom2 = 'com2'; //for Sony Mylo also
175   
176   //In some UserAgents, the only clue is the manufacturer.
177   var $manuSonyEricsson = "sonyericsson";
178   var $manuericsson = "ericsson";
179   var $manuSamsung1 = "sec-sgh";
180   var $manuSony = "sony";
181   var $manuHtc = "htc";
182
183   //In some UserAgents, the only clue is the operator.
184   var $svcDocomo = "docomo";
185   var $svcKddi = "kddi";
186   var $svcVodafone = "vodafone";
187
188   //Disambiguation strings.
189   var $disUpdate = "update"; //pda vs. update
190
191
192   //**************************
193   //The constructor. Allows the latest PHP (5.0+) to locate a constructor object and initialize the object.
194   function __construct()
195   {
196         $this->uagent_info();
197   }
198
199
200   //**************************
201   //The object initializer. Initializes several default variables.
202   function uagent_info()
203   { 
204         $this->useragent = isset($_SERVER['HTTP_USER_AGENT'])?strtolower($_SERVER['HTTP_USER_AGENT']):'';
205         $this->httpaccept = isset($_SERVER['HTTP_ACCEPT'])?strtolower($_SERVER['HTTP_ACCEPT']):'';
206               
207         //Let's initialize some values to save cycles later.
208         $this->InitDeviceScan();
209   }
210   
211   //**************************
212   // Initialize Key Stored Values.
213   function InitDeviceScan()
214   {
215        //Save these properties to speed processing
216        global $isWebkit, $isIphone, $isAndroid, $isAndroidPhone;
217        $this->isWebkit = $this->DetectWebkit();
218        $this->isIphone = $this->DetectIphone();
219        $this->isAndroid = $this->DetectAndroid();
220        $this->isAndroidPhone = $this->DetectAndroidPhone();
221       
222        //These tiers are the most useful for web development
223        global $isMobilePhone, $isTierTablet, $isTierIphone;
224        $this->isTierTablet = $this->DetectTierTablet(); //Do first
225        $this->isTierIphone = $this->DetectTierIphone(); //Do second
226        $this->isMobilePhone = $this->DetectMobileQuick(); //Do third
227       
228        //Optional: Comment these out if you NEVER use them.
229        global $isTierRichCss, $isTierGenericMobile;
230        $this->isTierRichCss = $this->DetectTierRichCss();
231        $this->isTierGenericMobile = $this->DetectTierOtherPhones();
232       
233        $this->initCompleted = $this->true;
234   }
235
236   //**************************
237   //Returns the contents of the User Agent value, in lower case.
238   function Get_Uagent()
239   { 
240       return $this->useragent;
241   }
242
243   //**************************
244   //Returns the contents of the HTTP Accept value, in lower case.
245   function Get_HttpAccept()
246   { 
247       return $this->httpaccept;
248   }
249   
250
251   //**************************
252   // Detects if the current device is an iPhone.
253   function DetectIphone()
254   {
255      if ($this->initCompleted == $this->true ||
256          $this->isIphone == $this->true)
257         return $this->isIphone;
258     
259      if (stripos($this->useragent, $this->deviceIphone) > -1)
260      {
261         //The iPad and iPod Touch say they're an iPhone. So let's disambiguate.
262         if ($this->DetectIpad() == $this->true ||
263             $this->DetectIpod() == $this->true)
264            return $this->false;
265         //Yay! It's an iPhone!
266         else
267            return $this->true; 
268      }
269      else
270         return $this->false; 
271   }
272
273   //**************************
274   // Detects if the current device is an iPod Touch.
275   function DetectIpod()
276   {
277      if (stripos($this->useragent, $this->deviceIpod) > -1)
278         return $this->true; 
279      else
280         return $this->false; 
281   }
282   
283   //**************************
284   // Detects if the current device is an iPad tablet.
285   function DetectIpad()
286   {
287      if (stripos($this->useragent, $this->deviceIpad) > -1 &&
288          $this->DetectWebkit() == $this->true)
289         return $this->true; 
290      else
291         return $this->false; 
292   }
293
294   //**************************
295   // Detects if the current device is an iPhone or iPod Touch.
296   function DetectIphoneOrIpod()
297   {
298       //We repeat the searches here because some iPods may report themselves as an iPhone, which would be okay.
299      if ($this->DetectIphone() == $this->true ||
300             $this->DetectIpod() == $this->true)
301         return $this->true; 
302      else
303         return $this->false; 
304   }
305
306   //**************************
307   // Detects *any* iOS device: iPhone, iPod Touch, iPad.
308   function DetectIos()
309   {
310      if (($this->DetectIphoneOrIpod() == $this->true) ||
311        ($this->DetectIpad() == $this->true))
312         return $this->true; 
313      else
314         return $this->false;
315   }
316
317
318   //**************************
319   // Detects *any* Android OS-based device: phone, tablet, and multi-media player.
320   // Also detects Google TV.
321   function DetectAndroid()
322   {
323      if ($this->initCompleted == $this->true ||
324          $this->isAndroid == $this->true)
325         return $this->isAndroid;
326
327      if ((stripos($this->useragent, $this->deviceAndroid) > -1)
328          || ($this->DetectGoogleTV() == $this->true))
329         return $this->true; 
330      //Special check for the HTC Flyer 7" tablet
331      if ((stripos($this->useragent, $this->deviceHtcFlyer) > -1))
332         return $this->true; 
333      else
334         return $this->false; 
335   }
336
337   //**************************
338   // Detects if the current device is a (small-ish) Android OS-based device
339   // used for calling and/or multi-media (like a Samsung Galaxy Player).
340   // Google says these devices will have 'Android' AND 'mobile' in user agent.
341   // Ignores tablets (Honeycomb and later).
342   function DetectAndroidPhone()
343   {
344      if ($this->initCompleted == $this->true ||
345          $this->isAndroidPhone == $this->true)
346         return $this->isAndroidPhone;
347
348      if (($this->DetectAndroid() == $this->true) &&
349                (stripos($this->useragent, $this->mobile) > -1))
350         return $this->true;
351     
352      //Special check for Android phones with Opera Mobile. They should report here.
353      if (($this->DetectOperaAndroidPhone() == $this->true))
354         return $this->true; 
355      //Special check for the HTC Flyer 7" tablet. It should report here.
356      if ((stripos($this->useragent, $this->deviceHtcFlyer) > -1))
357         return $this->true;
358     
359      else
360         return $this->false; 
361   }
362
363   //**************************
364   // Detects if the current device is a (self-reported) Android tablet.
365   // Google says these devices will have 'Android' and NOT 'mobile' in their user agent.
366   function DetectAndroidTablet()
367   {
368      //First, let's make sure we're on an Android device.
369      if ($this->DetectAndroid() == $this->false)
370         return $this->false; 
371
372      //Special check for Opera Android Phones. They should NOT report here.
373      if ($this->DetectOperaMobile() == $this->true)
374         return $this->false; 
375      //Special check for the HTC Flyer 7" tablet. It should NOT report here.
376      if ((stripos($this->useragent, $this->deviceHtcFlyer) > -1))
377         return $this->false; 
378         
379      //Otherwise, if it's Android and does NOT have 'mobile' in it, Google says it's a tablet.
380      if (stripos($this->useragent, $this->mobile) > -1)
381         return $this->false;
382      else
383         return $this->true; 
384   }
385
386   //**************************
387   // Detects if the current device is an Android OS-based device and
388   //   the browser is based on WebKit.
389   function DetectAndroidWebKit()
390   {
391      if (($this->DetectAndroid() == $this->true) &&
392                ($this->DetectWebkit() == $this->true))
393         return $this->true; 
394      else
395         return $this->false; 
396   }
397
398   //**************************
399   // Detects if the current device is a GoogleTV.
400   function DetectGoogleTV()
401   {
402      if (stripos($this->useragent, $this->deviceGoogleTV) > -1)
403         return $this->true; 
404      else
405         return $this->false; 
406   }
407
408   //**************************
409   // Detects if the current browser is based on WebKit.
410   function DetectWebkit()
411   {
412      if ($this->initCompleted == $this->true ||
413          $this->isWebkit == $this->true)
414         return $this->isWebkit;
415
416      if (stripos($this->useragent, $this->engineWebKit) > -1)
417         return $this->true; 
418      else
419         return $this->false; 
420   }
421
422
423   //**************************
424   // Detects if the current browser is EITHER a
425   // Windows Phone 7.x OR 8 device.
426   function DetectWindowsPhone()
427   {
428      if (($this->DetectWindowsPhone8() == $this->true)
429                        || ($this->DetectWindowsPhone7() == $this->true))
430         return $this->true; 
431      else
432         return $this->false; 
433   }
434   
435   //**************************
436   // Detects a Windows Phone 7.x device (in mobile browsing mode).
437   function DetectWindowsPhone7()
438   {
439      if (stripos($this->useragent, $this->deviceWinPhone7) > -1)
440         return $this->true; 
441      else
442         return $this->false; 
443   }
444   
445   //**************************
446   // Detects a Windows Phone 8 device (in mobile browsing mode).
447   function DetectWindowsPhone8()
448   {
449      if (stripos($this->useragent, $this->deviceWinPhone8) > -1)
450         return $this->true; 
451      else
452         return $this->false; 
453   }
454
455   //**************************
456   // Detects if the current browser is a Windows Mobile device.
457   // Excludes Windows Phone 7 and later devices.
458   // Focuses on Windows Mobile 6.xx and earlier.
459   function DetectWindowsMobile()
460   {
461      if ($this->DetectWindowsPhone() == $this->true)
462         return $this->false;
463     
464      //Most devices use 'Windows CE', but some report 'iemobile'
465      //  and some older ones report as 'PIE' for Pocket IE.
466      if (stripos($this->useragent, $this->deviceWinMob) > -1 ||
467          stripos($this->useragent, $this->deviceIeMob) > -1 ||
468          stripos($this->useragent, $this->enginePie) > -1)
469         return $this->true; 
470      //Test for Windows Mobile PPC but not old Macintosh PowerPC.
471          if (stripos($this->useragent, $this->devicePpc) > -1
472                  && !(stripos($this->useragent, $this->deviceMacPpc) > 1))
473         return $this->true; 
474      //Test for certain Windwos Mobile-based HTC devices.
475      if (stripos($this->useragent, $this->manuHtc) > -1 &&
476          stripos($this->useragent, $this->deviceWindows) > -1)
477         return $this->true; 
478      if ($this->DetectWapWml() == $this->true &&
479          stripos($this->useragent, $this->deviceWindows) > -1) 
480         return $this->true; 
481      else
482         return $this->false; 
483   }
484
485   //**************************
486   // Detects if the current browser is any BlackBerry device.
487   // Includes BB10 OS, but excludes the PlayBook.
488   function DetectBlackBerry()
489   {
490       if ((stripos($this->useragent, $this->deviceBB) > -1) ||
491          (stripos($this->httpaccept, $this->vndRIM) > -1))
492         return $this->true;
493      if ($this->DetectBlackBerry10Phone() == $this->true) 
494         return $this->true;       
495       else
496         return $this->false; 
497   }
498   
499   //**************************
500   // Detects if the current browser is a BlackBerry 10 OS phone.
501   // Excludes tablets.
502   function DetectBlackBerry10Phone()
503   {
504       if ((stripos($this->useragent, $this->deviceBB10) > -1) &&
505          (stripos($this->useragent, $this->mobile) > -1))
506         return $this->true; 
507       else
508         return $this->false; 
509   }
510   
511   //**************************
512   // Detects if the current browser is on a BlackBerry tablet device.
513   //    Examples: PlayBook
514   function DetectBlackBerryTablet()
515   {
516      if ((stripos($this->useragent, $this->deviceBBPlaybook) > -1))
517         return $this->true; 
518      else
519        return $this->false; 
520   }
521
522   //**************************
523   // Detects if the current browser is a BlackBerry phone device AND uses a
524   //    WebKit-based browser. These are signatures for the new BlackBerry OS 6.
525   //    Examples: Torch. Includes the Playbook.
526   function DetectBlackBerryWebKit()
527   {
528      if (($this->DetectBlackBerry() == $this->true) &&
529                ($this->DetectWebkit() == $this->true))
530         return $this->true; 
531      else
532        return $this->false; 
533   }
534
535   //**************************
536   // Detects if the current browser is a BlackBerry Touch phone device with
537   //    a large screen, such as the Storm, Torch, and Bold Touch. Excludes the Playbook.
538   function DetectBlackBerryTouch()
539   { 
540       if ((stripos($this->useragent, $this->deviceBBStorm) > -1) ||
541                (stripos($this->useragent, $this->deviceBBTorch) > -1) ||
542                (stripos($this->useragent, $this->deviceBBBoldTouch) > -1) ||
543                (stripos($this->useragent, $this->deviceBBCurveTouch) > -1))
544         return $this->true; 
545       else
546         return $this->false; 
547   }
548   
549   //**************************
550   // Detects if the current browser is a BlackBerry OS 5 device AND
551   //    has a more capable recent browser. Excludes the Playbook.
552   //    Examples, Storm, Bold, Tour, Curve2
553   //    Excludes the new BlackBerry OS 6 and 7 browser!!
554   function DetectBlackBerryHigh()
555   {
556      //Disambiguate for BlackBerry OS 6 or 7 (WebKit) browser
557      if ($this->DetectBlackBerryWebKit() == $this->true)
558         return $this->false; 
559      if ($this->DetectBlackBerry() == $this->true)
560      {
561          if (($this->DetectBlackBerryTouch() == $this->true) ||
562            stripos($this->useragent, $this->deviceBBBold) > -1 ||
563            stripos($this->useragent, $this->deviceBBTour) > -1 ||
564            stripos($this->useragent, $this->deviceBBCurve) > -1)
565          {
566             return $this->true; 
567          }
568          else
569            return $this->false; 
570      }
571      else
572        return $this->false; 
573   }
574
575   //**************************
576   // Detects if the current browser is a BlackBerry device AND
577   //    has an older, less capable browser.
578   //    Examples: Pearl, 8800, Curve1.
579   function DetectBlackBerryLow()
580   {
581      if ($this->DetectBlackBerry() == $this->true)
582      {
583          //Assume that if it's not in the High tier, then it's Low.
584          if (($this->DetectBlackBerryHigh() == $this->true) ||
585                        ($this->DetectBlackBerryWebKit() == $this->true))
586             return $this->false; 
587          else
588            return $this->true; 
589      }
590      else
591        return $this->false; 
592   }
593
594
595   //**************************
596   // Detects if the current browser is the Nokia S60 Open Source Browser.
597   function DetectS60OssBrowser()
598   {
599      //First, test for WebKit, then make sure it's either Symbian or S60.
600      if ($this->DetectWebkit() == $this->true)
601      {
602        if (stripos($this->useragent, $this->deviceSymbian) > -1 ||
603            stripos($this->useragent, $this->deviceS60) > -1)
604        {
605           return $this->true;
606        }
607        else
608           return $this->false; 
609      }
610      else
611         return $this->false; 
612   }
613   
614   //**************************
615   // Detects if the current device is any Symbian OS-based device,
616   //   including older S60, Series 70, Series 80, Series 90, and UIQ,
617   //   or other browsers running on these devices.
618   function DetectSymbianOS()
619   {
620       if (stripos($this->useragent, $this->deviceSymbian) > -1 || 
621           stripos($this->useragent, $this->deviceS60) > -1 ||
622           stripos($this->useragent, $this->deviceS70) > -1 || 
623           stripos($this->useragent, $this->deviceS80) > -1 ||
624           stripos($this->useragent, $this->deviceS90) > -1)
625         return $this->true; 
626      else
627         return $this->false; 
628   }
629
630
631   //**************************
632   // Detects if the current browser is on a PalmOS device.
633   function DetectPalmOS()
634   {
635                //Make sure it's not WebOS first
636                if ($this->DetectPalmWebOS() == $this->true)
637                        return $this->false;
638
639      //Most devices nowadays report as 'Palm', but some older ones reported as Blazer or Xiino.
640      if (stripos($this->useragent, $this->devicePalm) > -1 ||
641          stripos($this->useragent, $this->engineBlazer) > -1 ||
642          stripos($this->useragent, $this->engineXiino) > -1)
643            return $this->true; 
644      else
645         return $this->false; 
646   }
647
648
649   //**************************
650   // Detects if the current browser is on a Palm device
651   //   running the new WebOS.
652   function DetectPalmWebOS()
653   {
654      if (stripos($this->useragent, $this->deviceWebOS) > -1)
655         return $this->true; 
656      else
657         return $this->false; 
658   }
659
660   //**************************
661   // Detects if the current browser is on an HP tablet running WebOS.
662   function DetectWebOSTablet()
663   {
664      if ((stripos($this->useragent, $this->deviceWebOShp) > -1)
665                        && (stripos($this->useragent, $this->deviceTablet) > -1))
666         return $this->true; 
667      else
668         return $this->false; 
669   }
670
671
672
673   //**************************
674   // Detects if the current browser is Opera Mobile or Mini.
675   function DetectOperaMobile()
676   {
677      if (stripos($this->useragent, $this->engineOpera) > -1)
678      {
679         if ((stripos($this->useragent, $this->mini) > -1) ||
680          (stripos($this->useragent, $this->mobi) > -1))
681            return $this->true; 
682         else
683            return $this->false; 
684      }
685      else
686         return $this->false; 
687   }
688
689   //**************************
690   // Detects if the current browser is Opera Mobile
691   // running on an Android phone.
692   function DetectOperaAndroidPhone()
693   {
694      if ((stripos($this->useragent, $this->engineOpera) > -1) &&
695        (stripos($this->useragent, $this->deviceAndroid) > -1) &&
696                (stripos($this->useragent, $this->mobi) > -1))
697         return $this->true; 
698      else
699         return $this->false; 
700   }
701
702   //**************************
703   // Detects if the current browser is Opera Mobile
704   // running on an Android tablet. 
705   function DetectOperaAndroidTablet()
706   {
707      if ((stripos($this->useragent, $this->engineOpera) > -1) &&
708        (stripos($this->useragent, $this->deviceAndroid) > -1) &&
709                (stripos($this->useragent, $this->deviceTablet) > -1))
710         return $this->true; 
711      else
712         return $this->false; 
713   }
714
715   //**************************
716   // Detects if the current device is an Amazon Kindle (eInk devices only).
717   // Note: For the Kindle Fire, use the normal Android methods.
718   function DetectKindle()
719   {
720      if (stripos($this->useragent, $this->deviceKindle) > -1 &&
721          $this->DetectAndroid() == $this->false)
722         return $this->true; 
723      else
724         return $this->false; 
725   }
726   
727   //**************************
728   // Detects if the current Amazon device has turned on the Silk accelerated browsing feature.
729   // Note: Typically used by the the Kindle Fire.
730   function DetectAmazonSilk()
731   {
732      if (stripos($this->useragent, $this->engineSilk) > -1)
733         return $this->true; 
734      else
735         return $this->false; 
736   }
737
738   //**************************
739   // Detects if a Garmin Nuvifone device.
740   function DetectGarminNuvifone()
741   {
742      if (stripos($this->useragent, $this->deviceNuvifone) > -1)
743         return $this->true; 
744      else
745         return $this->false; 
746   }
747   
748   //**************************
749   // Detects a device running the Bada smartphone OS from Samsung.
750   function DetectBada()
751   {
752      if (stripos($this->useragent, $this->deviceBada) > -1)
753         return $this->true; 
754      else
755         return $this->false; 
756   }
757
758   //**************************
759   // Detects a device running the Tizen smartphone OS.
760   function DetectTizen()
761   {
762      if (stripos($this->useragent, $this->deviceTizen) > -1)
763         return $this->true; 
764      else
765         return $this->false; 
766   }
767
768   //**************************
769   // Detects a device running the Meego OS.
770   function DetectMeego()
771   {
772      if (stripos($this->useragent, $this->deviceMeego) > -1)
773         return $this->true; 
774      else
775         return $this->false; 
776   }
777   
778   //**************************
779   // Detects the Danger Hiptop device.
780   function DetectDangerHiptop()
781   {
782      if (stripos($this->useragent, $this->deviceDanger) > -1 ||
783          stripos($this->useragent, $this->deviceHiptop) > -1)
784         return $this->true; 
785      else
786         return $this->false; 
787   }
788
789   //**************************
790   // Detects if the current browser is a Sony Mylo device.
791   function DetectSonyMylo()
792   {
793      if ((stripos($this->useragent, $this->manuSony) > -1) &&
794         ((stripos($this->useragent, $this->qtembedded) > -1) ||
795          (stripos($this->useragent, $this->mylocom2) > -1)))
796         return $this->true; 
797      else
798         return $this->false; 
799   }
800   
801   //**************************
802   // Detects if the current device is on one of the Maemo-based Nokia Internet Tablets.
803   function DetectMaemoTablet()
804   {
805      if (stripos($this->useragent, $this->maemo) > -1)
806         return $this->true; 
807      //For Nokia N810, must be Linux + Tablet, or else it could be something else.
808      if ((stripos($this->useragent, $this->linux) > -1)
809                && (stripos($this->useragent, $this->deviceTablet) > -1) 
810                && ($this->DetectWebOSTablet() == $this->false)
811                && ($this->DetectAndroid() == $this->false))
812         return $this->true; 
813      else
814         return $this->false; 
815   }
816
817   //**************************
818   // Detects if the current device is an Archos media player/Internet tablet.
819   function DetectArchos()
820   {
821      if (stripos($this->useragent, $this->deviceArchos) > -1)
822         return $this->true; 
823      else
824         return $this->false; 
825   }
826
827   //**************************
828   // Detects if the current device is an Internet-capable game console.
829   // Includes many handheld consoles.
830   function DetectGameConsole()
831   {
832      if (($this->DetectSonyPlaystation() == $this->true) ||
833                 ($this->DetectNintendo() == $this->true) ||
834                 ($this->DetectXbox() == $this->true))
835         return $this->true; 
836      else
837         return $this->false; 
838   }
839   
840   //**************************
841   // Detects if the current device is a Sony Playstation.
842   function DetectSonyPlaystation()
843   {
844      if (stripos($this->useragent, $this->devicePlaystation) > -1)
845         return $this->true; 
846      else
847         return $this->false; 
848   }
849
850   //**************************
851   // Detects if the current device is a handheld gaming device with
852   // a touchscreen and modern iPhone-class browser. Includes the Playstation Vita.
853   function DetectGamingHandheld()
854   {
855      if ((stripos($this->useragent, $this->devicePlaystation) > -1) &&
856         (stripos($this->useragent, $this->devicePlaystationVita) > -1))
857         return $this->true; 
858      else
859         return $this->false; 
860   }
861
862   //**************************
863   // Detects if the current device is a Nintendo game device.
864   function DetectNintendo()
865   {
866      if (stripos($this->useragent, $this->deviceNintendo) > -1 || 
867           stripos($this->useragent, $this->deviceWii) > -1 ||
868           stripos($this->useragent, $this->deviceNintendoDs) > -1)
869         return $this->true; 
870      else
871         return $this->false; 
872   }
873
874   //**************************
875   // Detects if the current device is a Microsoft Xbox.
876   function DetectXbox()
877   {
878      if (stripos($this->useragent, $this->deviceXbox) > -1)
879         return $this->true; 
880      else
881         return $this->false; 
882   }
883
884   //**************************
885   // Detects whether the device is a Brew-powered device.
886   function DetectBrewDevice()
887   {
888       if (stripos($this->useragent, $this->deviceBrew) > -1)
889         return $this->true; 
890      else
891         return $this->false; 
892   }
893   
894   //**************************
895   // Detects whether the device supports WAP or WML.
896   function DetectWapWml()
897   {
898       if (stripos($this->httpaccept, $this->vndwap) > -1 ||
899           stripos($this->httpaccept, $this->wml) > -1)
900         return $this->true; 
901      else
902         return $this->false; 
903   }
904   
905   //**************************
906   // Detects if the current device supports MIDP, a mobile Java technology.
907   function DetectMidpCapable()
908   {
909       if (stripos($this->useragent, $this->deviceMidp) > -1 || 
910           stripos($this->httpaccept, $this->deviceMidp) > -1)
911         return $this->true; 
912      else
913         return $this->false; 
914   }
915
916
917
918  //*****************************
919  // Device Classes
920  //*****************************
921   
922   //**************************
923   // Check to see whether the device is *any* 'smartphone'.
924   //   Note: It's better to use DetectTierIphone() for modern touchscreen devices.
925   function DetectSmartphone()
926   {
927      //Exclude duplicates from TierIphone
928      if (($this->DetectTierIphone() == $this->true)
929                || ($this->DetectS60OssBrowser() == $this->true)
930                || ($this->DetectSymbianOS() == $this->true) 
931                || ($this->DetectWindowsMobile() == $this->true)
932                || ($this->DetectBlackBerry() == $this->true)
933                || ($this->DetectPalmWebOS() == $this->true))
934         return $this->true; 
935      else
936         return $this->false; 
937   }
938
939   //**************************
940   // The quick way to detect for a mobile device.
941   //   Will probably detect most recent/current mid-tier Feature Phones
942   //   as well as smartphone-class devices. Excludes Apple iPads and other modern tablets.
943   function DetectMobileQuick()
944   {
945      //Let's exclude tablets
946      if ($this->isTierTablet == $this->true) 
947         return $this->false;
948     
949      if ($this->initCompleted == $this->true ||
950          $this->isMobilePhone == $this->true)
951         return $this->isMobilePhone;
952
953      //Most mobile browsing is done on smartphones
954      if ($this->DetectSmartphone() == $this->true) 
955         return $this->true;
956
957       if (stripos($this->useragent, $this->mobile) > -1)
958         return $this->true; 
959
960      if (($this->DetectWapWml() == $this->true) 
961                        || ($this->DetectBrewDevice() == $this->true) 
962                        || ($this->DetectOperaMobile() == $this->true))
963         return $this->true;
964         
965      if ((stripos($this->useragent, $this->engineObigo) > -1)
966                        || (stripos($this->useragent, $this->engineNetfront) > -1)
967                        || (stripos($this->useragent, $this->engineUpBrowser) > -1)
968                        || (stripos($this->useragent, $this->engineOpenWeb) > -1))
969         return $this->true; 
970         
971      if (($this->DetectDangerHiptop() == $this->true) 
972                        || ($this->DetectMidpCapable() == $this->true) 
973                        || ($this->DetectMaemoTablet() == $this->true) 
974                        || ($this->DetectArchos() == $this->true))
975         return $this->true; 
976
977       if ((stripos($this->useragent, $this->devicePda) > -1) &&
978                 !(stripos($this->useragent, $this->disUpdate) > -1))
979         return $this->true;
980     
981      //We also look for Kindle devices
982      if ($this->DetectKindle() == $this->true ||
983         $this->DetectAmazonSilk() == $this->true) 
984         return $this->true;
985
986      else
987         return $this->false; 
988   }
989 
990   //**************************
991   // The longer and more thorough way to detect for a mobile device.
992   //   Will probably detect most feature phones,
993   //   smartphone-class devices, Internet Tablets,
994   //   Internet-enabled game consoles, etc.
995   //   This ought to catch a lot of the more obscure and older devices, also --
996   //   but no promises on thoroughness!
997   function DetectMobileLong()
998   {
999      if ($this->DetectMobileQuick() == $this->true) 
1000         return $this->true; 
1001      if ($this->DetectGameConsole() == $this->true) 
1002         return $this->true; 
1003      if ($this->DetectSonyMylo() == $this->true) 
1004         return $this->true; 
1005
1006       //Detect older phones from certain manufacturers and operators.
1007       if (stripos($this->useragent, $this->uplink) > -1)
1008         return $this->true; 
1009       if (stripos($this->useragent, $this->manuSonyEricsson) > -1)
1010         return $this->true; 
1011       if (stripos($this->useragent, $this->manuericsson) > -1)
1012         return $this->true; 
1013       if (stripos($this->useragent, $this->manuSamsung1) > -1)
1014         return $this->true; 
1015
1016       if (stripos($this->useragent, $this->svcDocomo) > -1)
1017         return $this->true; 
1018       if (stripos($this->useragent, $this->svcKddi) > -1)
1019         return $this->true; 
1020       if (stripos($this->useragent, $this->svcVodafone) > -1)
1021         return $this->true; 
1022
1023      else
1024         return $this->false; 
1025   }
1026
1027
1028  //*****************************
1029  // For Mobile Web Site Design
1030  //*****************************
1031
1032   //**************************
1033   // The quick way to detect for a tier of devices.
1034   //   This method detects for the new generation of
1035   //   HTML 5 capable, larger screen tablets.
1036   //   Includes iPad, Android (e.g., Xoom), BB Playbook, WebOS, etc.
1037   function DetectTierTablet()
1038   {
1039      if ($this->initCompleted == $this->true ||
1040          $this->isTierTablet == $this->true)
1041         return $this->isTierTablet;
1042
1043      if (($this->DetectIpad() == $this->true) 
1044         || ($this->DetectAndroidTablet() == $this->true) 
1045         || ($this->DetectBlackBerryTablet() == $this->true) 
1046         || ($this->DetectWebOSTablet() == $this->true))
1047         return $this->true; 
1048      else
1049         return $this->false; 
1050   }
1051
1052
1053   //**************************
1054   // The quick way to detect for a tier of devices.
1055   //   This method detects for devices which can
1056   //   display iPhone-optimized web content.
1057   //   Includes iPhone, iPod Touch, Android, Windows Phone 7 and 8, BB10, WebOS, Playstation Vita, etc.
1058   function DetectTierIphone()
1059   {
1060      if ($this->initCompleted == $this->true ||
1061          $this->isTierIphone == $this->true)
1062         return $this->isTierIphone;
1063
1064      if (($this->DetectIphoneOrIpod() == $this->true)
1065                        || ($this->DetectAndroidPhone() == $this->true)
1066                        || ($this->DetectWindowsPhone() == $this->true)
1067                        || ($this->DetectBlackBerry10Phone() == $this->true)
1068                        || ($this->DetectPalmWebOS() == $this->true)
1069                        || ($this->DetectBada() == $this->true)
1070                        || ($this->DetectTizen() == $this->true)
1071                        || ($this->DetectGamingHandheld() == $this->true))
1072         return $this->true; 
1073     
1074      //Note: BB10 phone is in the previous paragraph
1075      if (($this->DetectBlackBerryWebKit() == $this->true) &&
1076                ($this->DetectBlackBerryTouch() == $this->true))
1077         return $this->true;
1078     
1079      else
1080         return $this->false; 
1081   }
1082   
1083   //**************************
1084   // The quick way to detect for a tier of devices.
1085   //   This method detects for devices which are likely to be capable
1086   //   of viewing CSS content optimized for the iPhone,
1087   //   but may not necessarily support JavaScript.
1088   //   Excludes all iPhone Tier devices.
1089   function DetectTierRichCss()
1090   {
1091      if ($this->initCompleted == $this->true ||
1092          $this->isTierRichCss == $this->true)
1093         return $this->isTierRichCss;
1094
1095      if ($this->DetectMobileQuick() == $this->true) 
1096      {
1097        //Exclude iPhone Tier and e-Ink Kindle devices
1098        if (($this->DetectTierIphone() == $this->true) ||
1099            ($this->DetectKindle() == $this->true))
1100           return $this->false;
1101           
1102        //The following devices are explicitly ok.
1103        if ($this->DetectWebkit() == $this->true) //Any WebKit
1104           return $this->true;
1105        if ($this->DetectS60OssBrowser() == $this->true)
1106           return $this->true;
1107           
1108        //Note: 'High' BlackBerry devices ONLY
1109        if ($this->DetectBlackBerryHigh() == $this->true)
1110           return $this->true;
1111       
1112        //Older Windows 'Mobile' isn't good enough for iPhone Tier.
1113        if ($this->DetectWindowsMobile() == $this->true)
1114           return $this->true;
1115        if (stripos($this->useragent, $this->engineTelecaQ) > -1)
1116           return $this->true;
1117         
1118        //default
1119        else
1120           return $this->false;
1121      }
1122      else
1123         return $this->false; 
1124   }
1125
1126   //**************************
1127   // The quick way to detect for a tier of devices.
1128   //   This method detects for all other types of phones,
1129   //   but excludes the iPhone and RichCSS Tier devices.
1130   function DetectTierOtherPhones()
1131   {
1132      if ($this->initCompleted == $this->true ||
1133          $this->isTierGenericMobile == $this->true)
1134         return $this->isTierGenericMobile;
1135
1136      //Exclude devices in the other 2 categories
1137      if (($this->DetectMobileLong() == $this->true)
1138                && ($this->DetectTierIphone() == $this->false)
1139                && ($this->DetectTierRichCss() == $this->false))
1140           return $this->true;
1141      else
1142         return $this->false; 
1143   }
1144     
1145
1146}
1147
1148
1149//Was informed by a MobileESP user that it's a best practice
1150//  to omit the closing ?&gt; marks here. They can sometimes
1151//  cause errors with HTML headers.
Note: See TracBrowser for help on using the repository browser.