1<?php
2	/**
3	 * File: Browser.php
4	 * Author: Chris Schuld (http://chrisschuld.com/)
5	 * Last Modified: August 20th, 2010
6	 * @version 1.9
7	 * @package PegasusPHP
8	 *
9	 * Copyright (C) 2008-2010 Chris Schuld  (chris@chrisschuld.com)
10	 *
11	 * This program is free software; you can redistribute it and/or
12	 * modify it under the terms of the GNU General Public License as
13	 * published by the Free Software Foundation; either version 2 of
14	 * the License, or (at your option) any later version.
15	 *
16	 * This program is distributed in the hope that it will be useful,
17	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19	 * GNU General Public License for more details at:
20	 * http://www.gnu.org/copyleft/gpl.html
21	 *
22	 *
23	 * Typical Usage:
24	 *
25	 *   $browser = new Browser();
26	 *   if( $browser->getBrowser() == Browser::BROWSER_FIREFOX && $browser->getVersion() >= 2 ) {
27	 *   	echo 'You have FireFox version 2 or greater';
28	 *   }
29	 *
30	 * User Agents Sampled from: http://www.useragentstring.com/
31	 *
32	 * This implementation is based on the original work from Gary White
33	 * http://apptools.com/phptools/browser/
34	 *
35	 * UPDATES:
36	 *
37	 * 2010-08-20 (v1.9):
38	 *  + Added MSN Explorer Browser (legacy)
39	 *  + Added Bing/MSN Robot (Thanks Rob MacDonald)
40	 *  + Added the Android Platform (PLATFORM_ANDROID)
41	 *  + Fixed issue with Android 1.6/2.2 (Thanks Tom Hirashima)
42	 *
43	 * 2010-04-27 (v1.8):
44	 *  + Added iPad Support
45	 *
46	 * 2010-03-07 (v1.7):
47	 *  + *MAJOR* Rebuild (preg_match and other "slow" routine removal(s))
48	 *  + Almost allof Gary's original code has been replaced
49	 *  + Large PHPUNIT testing environment created to validate new releases and additions
50	 *  + Added FreeBSD Platform
51	 *  + Added OpenBSD Platform
52	 *  + Added NetBSD Platform
53	 *  + Added SunOS Platform
54	 *  + Added OpenSolaris Platform
55	 *  + Added support of the Iceweazel Browser
56	 *  + Added isChromeFrame() call to check if chromeframe is in use
57	 *  + Moved the Opera check in front of the Firefox check due to legacy Opera User Agents
58	 *  + Added the __toString() method (Thanks Deano)
59	 *
60	 * 2009-11-15:
61	 *  + Updated the checkes for Firefox
62	 *  + Added the NOKIA platform
63	 *  + Added Checks for the NOKIA brower(s)
64	 *
65	 * 2009-11-08:
66	 *  + PHP 5.3 Support
67	 *  + Added support for BlackBerry OS and BlackBerry browser
68	 *  + Added support for the Opera Mini browser
69	 *  + Added additional documenation
70	 *  + Added support for isRobot() and isMobile()
71	 *  + Added support for Opera version 10
72	 *  + Added support for deprecated Netscape Navigator version 9
73	 *  + Added support for IceCat
74	 *  + Added support for Shiretoko
75	 *
76	 * 2010-04-27 (v1.8):
77	 *  + Added iPad Support
78	 *
79	 * 2009-08-18:
80	 *  + Updated to support PHP 5.3 - removed all deprecated function calls
81	 *  + Updated to remove all double quotes (") -- converted to single quotes (')
82	 *
83	 * 2009-04-27:
84	 *  + Updated the IE check to remove a typo and bug (thanks John)
85	 *
86	 * 2009-04-22:
87	 *  + Added detection for GoogleBot
88	 *  + Added detection for the W3C Validator.
89	 *  + Added detection for Yahoo! Slurp
90	 *
91	 * 2009-03-14:
92	 *  + Added detection for iPods.
93	 *  + Added Platform detection for iPhones
94	 *  + Added Platform detection for iPods
95	 *
96	 * 2009-02-16: (Rick Hale)
97	 *  + Added version detection for Android phones.
98	 *
99	 * 2008-12-09:
100	 *  + Removed unused constant
101	 *
102	 * 2008-11-07:
103	 *  + Added Google's Chrome to the detection list
104	 *  + Added isBrowser(string) to the list of functions special thanks to
105	 *    Daniel 'mavrick' Lang for the function concept (http://mavrick.id.au)
106	 *
107	 *
108	 * Gary White noted: "Since browser detection is so unreliable, I am
109	 * no longer maintaining this script. You are free to use and or
110	 * modify/update it as you want, however the author assumes no
111	 * responsibility for the accuracy of the detected values."
112	 *
113	 * Anyone experienced with Gary's script might be interested in these notes:
114	 *
115	 *   Added class constants
116	 *   Added detection and version detection for Google's Chrome
117	 *   Updated the version detection for Amaya
118	 *   Updated the version detection for Firefox
119	 *   Updated the version detection for Lynx
120	 *   Updated the version detection for WebTV
121	 *   Updated the version detection for NetPositive
122	 *   Updated the version detection for IE
123	 *   Updated the version detection for OmniWeb
124	 *   Updated the version detection for iCab
125	 *   Updated the version detection for Safari
126	 *   Updated Safari to remove mobile devices (iPhone)
127	 *   Added detection for iPhone
128	 *   Added detection for robots
129	 *   Added detection for mobile devices
130	 *   Added detection for BlackBerry
131	 *   Removed Netscape checks (matches heavily with firefox & mozilla)
132	 *
133	 */
134
135	class Browser {
136		private $_agent = '';
137		private $_browser_name = '';
138		private $_version = '';
139		private $_platform = '';
140		private $_os = '';
141		private $_is_aol = false;
142		private $_is_mobile = false;
143		private $_is_robot = false;
144		private $_aol_version = '';
145
146		const BROWSER_UNKNOWN = 'unknown';
147		const VERSION_UNKNOWN = 'unknown';
148
149		const BROWSER_OPERA = 'Opera';                            // http://www.opera.com/
150		const BROWSER_OPERA_MINI = 'Opera Mini';                  // http://www.opera.com/mini/
151		const BROWSER_WEBTV = 'WebTV';                            // http://www.webtv.net/pc/
152		const BROWSER_IE = 'Internet Explorer';                   // http://www.microsoft.com/ie/
153		const BROWSER_POCKET_IE = 'Pocket Internet Explorer';     // http://en.wikipedia.org/wiki/Internet_Explorer_Mobile
154		const BROWSER_KONQUEROR = 'Konqueror';                    // http://www.konqueror.org/
155		const BROWSER_ICAB = 'iCab';                              // http://www.icab.de/
156		const BROWSER_OMNIWEB = 'OmniWeb';                        // http://www.omnigroup.com/applications/omniweb/
157		const BROWSER_FIREBIRD = 'Firebird';                      // http://www.ibphoenix.com/
158		const BROWSER_FIREFOX = 'Firefox';                        // http://www.mozilla.com/en-US/firefox/firefox.html
159		const BROWSER_ICEWEASEL = 'Iceweasel';                    // http://www.geticeweasel.org/
160		const BROWSER_SHIRETOKO = 'Shiretoko';                    // http://wiki.mozilla.org/Projects/shiretoko
161		const BROWSER_MOZILLA = 'Mozilla';                        // http://www.mozilla.com/en-US/
162		const BROWSER_AMAYA = 'Amaya';                            // http://www.w3.org/Amaya/
163		const BROWSER_LYNX = 'Lynx';                              // http://en.wikipedia.org/wiki/Lynx
164		const BROWSER_SAFARI = 'Safari';                          // http://apple.com
165		const BROWSER_IPHONE = 'iPhone';                          // http://apple.com
166		const BROWSER_IPOD = 'iPod';                              // http://apple.com
167		const BROWSER_IPAD = 'iPad';                              // http://apple.com
168		const BROWSER_CHROME = 'Chrome';                          // http://www.google.com/chrome
169		const BROWSER_ANDROID = 'Android';                        // http://www.android.com/
170		const BROWSER_GOOGLEBOT = 'GoogleBot';                    // http://en.wikipedia.org/wiki/Googlebot
171		const BROWSER_SLURP = 'Yahoo! Slurp';                     // http://en.wikipedia.org/wiki/Yahoo!_Slurp
172		const BROWSER_W3CVALIDATOR = 'W3C Validator';             // http://validator.w3.org/
173		const BROWSER_BLACKBERRY = 'BlackBerry';                  // http://www.blackberry.com/
174		const BROWSER_ICECAT = 'IceCat';                          // http://en.wikipedia.org/wiki/GNU_IceCat
175		const BROWSER_NOKIA_S60 = 'Nokia S60 OSS Browser';        // http://en.wikipedia.org/wiki/Web_Browser_for_S60
176		const BROWSER_NOKIA = 'Nokia Browser';                    // * all other WAP-based browsers on the Nokia Platform
177		const BROWSER_MSN = 'MSN Browser';                        // http://explorer.msn.com/
178		const BROWSER_MSNBOT = 'MSN Bot';                         // http://search.msn.com/msnbot.htm
179		                                                          // http://en.wikipedia.org/wiki/Msnbot  (used for Bing as well)
180
181		const BROWSER_NETSCAPE_NAVIGATOR = 'Netscape Navigator';  // http://browser.netscape.com/ (DEPRECATED)
182		const BROWSER_GALEON = 'Galeon';                          // http://galeon.sourceforge.net/ (DEPRECATED)
183		const BROWSER_NETPOSITIVE = 'NetPositive';                // http://en.wikipedia.org/wiki/NetPositive (DEPRECATED)
184		const BROWSER_PHOENIX = 'Phoenix';                        // http://en.wikipedia.org/wiki/History_of_Mozilla_Firefox (DEPRECATED)
185
186		const PLATFORM_UNKNOWN = 'unknown';
187		const PLATFORM_WINDOWS = 'Windows';
188		const PLATFORM_WINDOWS_CE = 'Windows CE';
189		const PLATFORM_APPLE = 'Apple';
190		const PLATFORM_LINUX = 'Linux';
191		const PLATFORM_OS2 = 'OS/2';
192		const PLATFORM_BEOS = 'BeOS';
193		const PLATFORM_IPHONE = 'iPhone';
194		const PLATFORM_IPOD = 'iPod';
195		const PLATFORM_IPAD = 'iPad';
196		const PLATFORM_BLACKBERRY = 'BlackBerry';
197		const PLATFORM_NOKIA = 'Nokia';
198		const PLATFORM_FREEBSD = 'FreeBSD';
199		const PLATFORM_OPENBSD = 'OpenBSD';
200		const PLATFORM_NETBSD = 'NetBSD';
201		const PLATFORM_SUNOS = 'SunOS';
202		const PLATFORM_OPENSOLARIS = 'OpenSolaris';
203		const PLATFORM_ANDROID = 'Android';
204
205		const OPERATING_SYSTEM_UNKNOWN = 'unknown';
206
207		public function Browser($useragent="") {
208			$this->reset();
209			if( $useragent != "" ) {
210				$this->setUserAgent($useragent);
211			}
212			else {
213				$this->determine();
214			}
215		}
216
217		/**
218		* Reset all properties
219		*/
220		public function reset() {
221			$this->_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "";
222			$this->_browser_name = self::BROWSER_UNKNOWN;
223			$this->_version = self::VERSION_UNKNOWN;
224			$this->_platform = self::PLATFORM_UNKNOWN;
225			$this->_os = self::OPERATING_SYSTEM_UNKNOWN;
226			$this->_is_aol = false;
227			$this->_is_mobile = false;
228			$this->_is_robot = false;
229			$this->_aol_version = self::VERSION_UNKNOWN;
230		}
231
232		/**
233		* Check to see if the specific browser is valid
234		* @param string $browserName
235		* @return True if the browser is the specified browser
236		*/
237		function isBrowser($browserName) { return( 0 == strcasecmp($this->_browser_name, trim($browserName))); }
238
239		/**
240		* The name of the browser.  All return types are from the class contants
241		* @return string Name of the browser
242		*/
243		public function getBrowser() { return $this->_browser_name; }
244		/**
245		* Set the name of the browser
246		* @param $browser The name of the Browser
247		*/
248		public function setBrowser($browser) { return $this->_browser_name = $browser; }
249		/**
250		* The name of the platform.  All return types are from the class contants
251		* @return string Name of the browser
252		*/
253		public function getPlatform() { return $this->_platform; }
254		/**
255		* Set the name of the platform
256		* @param $platform The name of the Platform
257		*/
258		public function setPlatform($platform) { return $this->_platform = $platform; }
259		/**
260		* The version of the browser.
261		* @return string Version of the browser (will only contain alpha-numeric characters and a period)
262		*/
263		public function getVersion() { return $this->_version; }
264		/**
265		* Set the version of the browser
266		* @param $version The version of the Browser
267		*/
268		public function setVersion($version) { $this->_version = preg_replace('/[^0-9,.,a-z,A-Z-]/','',$version); }
269		/**
270		* The version of AOL.
271		* @return string Version of AOL (will only contain alpha-numeric characters and a period)
272		*/
273		public function getAolVersion() { return $this->_aol_version; }
274		/**
275		* Set the version of AOL
276		* @param $version The version of AOL
277		*/
278		public function setAolVersion($version) { $this->_aol_version = preg_replace('/[^0-9,.,a-z,A-Z]/','',$version); }
279		/**
280		* Is the browser from AOL?
281		* @return boolean True if the browser is from AOL otherwise false
282		*/
283		public function isAol() { return $this->_is_aol; }
284		/**
285		* Is the browser from a mobile device?
286		* @return boolean True if the browser is from a mobile device otherwise false
287		*/
288		public function isMobile() { return $this->_is_mobile; }
289		/**
290		* Is the browser from a robot (ex Slurp,GoogleBot)?
291		* @return boolean True if the browser is from a robot otherwise false
292		*/
293		public function isRobot() { return $this->_is_robot; }
294		/**
295		* Set the browser to be from AOL
296		* @param $isAol
297		*/
298		public function setAol($isAol) { $this->_is_aol = $isAol; }
299		/**
300		 * Set the Browser to be mobile
301		 * @param boolean $value is the browser a mobile brower or not
302		 */
303		protected function setMobile($value=true) { $this->_is_mobile = $value; }
304		/**
305		 * Set the Browser to be a robot
306		 * @param boolean $value is the browser a robot or not
307		 */
308		protected function setRobot($value=true) { $this->_is_robot = $value; }
309		/**
310		* Get the user agent value in use to determine the browser
311		* @return string The user agent from the HTTP header
312		*/
313		public function getUserAgent() { return $this->_agent; }
314		/**
315		* Set the user agent value (the construction will use the HTTP header value - this will overwrite it)
316		* @param $agent_string The value for the User Agent
317		*/
318		public function setUserAgent($agent_string) {
319			$this->reset();
320			$this->_agent = $agent_string;
321			$this->determine();
322		}
323		/**
324		 * Used to determine if the browser is actually "chromeframe"
325		 * @since 1.7
326		 * @return boolean True if the browser is using chromeframe
327		 */
328		public function isChromeFrame() {
329			return( strpos($this->_agent,"chromeframe") !== false );
330		}
331		/**
332		* Returns a formatted string with a summary of the details of the browser.
333		* @return string formatted string with a summary of the browser
334		*/
335		public function __toString() {
336			return "<strong>Browser Name:</strong>{$this->getBrowser()}<br/>\n" .
337			       "<strong>Browser Version:</strong>{$this->getVersion()}<br/>\n" .
338			       "<strong>Browser User Agent String:</strong>{$this->getUserAgent()}<br/>\n" .
339			       "<strong>Platform:</strong>{$this->getPlatform()}<br/>";
340		}
341		/**
342		 * Protected routine to calculate and determine what the browser is in use (including platform)
343		 */
344		protected function determine() {
345			$this->checkPlatform();
346			$this->checkBrowsers();
347			$this->checkForAol();
348		}
349		/**
350		 * Protected routine to determine the browser type
351		 * @return boolean True if the browser was detected otherwise false
352		 */
353		 protected function checkBrowsers() {
354			return (
355				// well-known, well-used
356				// Special Notes:
357				// (1) Opera must be checked before FireFox due to the odd
358				//     user agents used in some older versions of Opera
359				// (2) WebTV is strapped onto Internet Explorer so we must
360				//     check for WebTV before IE
361				// (3) (deprecated) Galeon is based on Firefox and needs to be
362				//     tested before Firefox is tested
363				// (4) OmniWeb is based on Safari so OmniWeb check must occur
364				//     before Safari
365				// (5) Netscape 9+ is based on Firefox so Netscape checks
366				//     before FireFox are necessary
367				$this->checkBrowserWebTv() ||
368				$this->checkBrowserInternetExplorer() ||
369				$this->checkBrowserOpera() ||
370				$this->checkBrowserGaleon() ||
371				$this->checkBrowserNetscapeNavigator9Plus() ||
372				$this->checkBrowserFirefox() ||
373				$this->checkBrowserChrome() ||
374				$this->checkBrowserOmniWeb() ||
375
376				// common mobile
377				$this->checkBrowserAndroid() ||
378				$this->checkBrowseriPad() ||
379				$this->checkBrowseriPod() ||
380				$this->checkBrowseriPhone() ||
381				$this->checkBrowserBlackBerry() ||
382				$this->checkBrowserNokia() ||
383
384				// common bots
385				$this->checkBrowserGoogleBot() ||
386				$this->checkBrowserMSNBot() ||
387				$this->checkBrowserSlurp() ||
388
389				// WebKit base check (post mobile and others)
390				$this->checkBrowserSafari() ||
391
392				// everyone else
393				$this->checkBrowserNetPositive() ||
394				$this->checkBrowserFirebird() ||
395				$this->checkBrowserKonqueror() ||
396				$this->checkBrowserIcab() ||
397				$this->checkBrowserPhoenix() ||
398				$this->checkBrowserAmaya() ||
399				$this->checkBrowserLynx() ||
400				$this->checkBrowserShiretoko() ||
401				$this->checkBrowserIceCat() ||
402				$this->checkBrowserW3CValidator() ||
403				$this->checkBrowserMozilla() /* Mozilla is such an open standard that you must check it last */
404			);
405	    }
406
407	    /**
408	     * Determine if the user is using a BlackBerry (last updated 1.7)
409	     * @return boolean True if the browser is the BlackBerry browser otherwise false
410	     */
411	    protected function checkBrowserBlackBerry() {
412		    if( stripos($this->_agent,'blackberry') !== false ) {
413			    $aresult = explode("/",stristr($this->_agent,"BlackBerry"));
414			    $aversion = explode(' ',$aresult[1]);
415			    $this->setVersion($aversion[0]);
416			    $this->_browser_name = self::BROWSER_BLACKBERRY;
417			    $this->setMobile(true);
418			    return true;
419		    }
420		    return false;
421	    }
422
423	    /**
424	     * Determine if the user is using an AOL User Agent (last updated 1.7)
425	     * @return boolean True if the browser is from AOL otherwise false
426	     */
427	    protected function checkForAol() {
428			$this->setAol(false);
429			$this->setAolVersion(self::VERSION_UNKNOWN);
430
431			if( stripos($this->_agent,'aol') !== false ) {
432			    $aversion = explode(' ',stristr($this->_agent, 'AOL'));
433			    $this->setAol(true);
434			    $this->setAolVersion(preg_replace('/[^0-9\.a-z]/i', '', $aversion[1]));
435			    return true;
436		    }
437		    return false;
438	    }
439
440	    /**
441	     * Determine if the browser is the GoogleBot or not (last updated 1.7)
442	     * @return boolean True if the browser is the GoogletBot otherwise false
443	     */
444	    protected function checkBrowserGoogleBot() {
445		    if( stripos($this->_agent,'googlebot') !== false ) {
446				$aresult = explode('/',stristr($this->_agent,'googlebot'));
447				$aversion = explode(' ',$aresult[1]);
448				$this->setVersion(str_replace(';','',$aversion[0]));
449				$this->_browser_name = self::BROWSER_GOOGLEBOT;
450				$this->setRobot(true);
451				return true;
452		    }
453		    return false;
454	    }
455
456		/**
457	     * Determine if the browser is the MSNBot or not (last updated 1.9)
458	     * @return boolean True if the browser is the MSNBot otherwise false
459	     */
460		protected function checkBrowserMSNBot() {
461			if( stripos($this->_agent,"msnbot") !== false ) {
462				$aresult = explode("/",stristr($this->_agent,"msnbot"));
463				$aversion = explode(" ",$aresult[1]);
464				$this->setVersion(str_replace(";","",$aversion[0]));
465				$this->_browser_name = self::BROWSER_MSNBOT;
466				$this->setRobot(true);
467				return true;
468			}
469			return false;
470		}
471
472	    /**
473	     * Determine if the browser is the W3C Validator or not (last updated 1.7)
474	     * @return boolean True if the browser is the W3C Validator otherwise false
475	     */
476	    protected function checkBrowserW3CValidator() {
477		    if( stripos($this->_agent,'W3C-checklink') !== false ) {
478			    $aresult = explode('/',stristr($this->_agent,'W3C-checklink'));
479			    $aversion = explode(' ',$aresult[1]);
480			    $this->setVersion($aversion[0]);
481			    $this->_browser_name = self::BROWSER_W3CVALIDATOR;
482			    return true;
483		    }
484		    else if( stripos($this->_agent,'W3C_Validator') !== false ) {
485				// Some of the Validator versions do not delineate w/ a slash - add it back in
486				$ua = str_replace("W3C_Validator ", "W3C_Validator/", $this->_agent);
487			    $aresult = explode('/',stristr($ua,'W3C_Validator'));
488			    $aversion = explode(' ',$aresult[1]);
489			    $this->setVersion($aversion[0]);
490			    $this->_browser_name = self::BROWSER_W3CVALIDATOR;
491			    return true;
492		    }
493		    return false;
494	    }
495
496	    /**
497	     * Determine if the browser is the Yahoo! Slurp Robot or not (last updated 1.7)
498	     * @return boolean True if the browser is the Yahoo! Slurp Robot otherwise false
499	     */
500	    protected function checkBrowserSlurp() {
501		    if( stripos($this->_agent,'slurp') !== false ) {
502			    $aresult = explode('/',stristr($this->_agent,'Slurp'));
503			    $aversion = explode(' ',$aresult[1]);
504			    $this->setVersion($aversion[0]);
505			    $this->_browser_name = self::BROWSER_SLURP;
506				$this->setRobot(true);
507				$this->setMobile(false);
508			    return true;
509		    }
510		    return false;
511	    }
512
513	    /**
514	     * Determine if the browser is Internet Explorer or not (last updated 1.7)
515	     * @return boolean True if the browser is Internet Explorer otherwise false
516	     */
517	    protected function checkBrowserInternetExplorer() {
518
519		    // Test for v1 - v1.5 IE
520		    if( stripos($this->_agent,'microsoft internet explorer') !== false ) {
521			    $this->setBrowser(self::BROWSER_IE);
522			    $this->setVersion('1.0');
523			    $aresult = stristr($this->_agent, '/');
524			    if( preg_match('/308|425|426|474|0b1/i', $aresult) ) {
525				    $this->setVersion('1.5');
526			    }
527				return true;
528		    }
529		    // Test for versions > 1.5
530		    else if( stripos($this->_agent,'msie') !== false && stripos($this->_agent,'opera') === false ) {
531		    	// See if the browser is the odd MSN Explorer
532		    	if( stripos($this->_agent,'msnb') !== false ) {
533			    	$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'MSN'));
534				    $this->setBrowser( self::BROWSER_MSN );
535				    $this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
536				    return true;
537		    	}
538		    	$aresult = explode(' ',stristr(str_replace(';','; ',$this->_agent),'msie'));
539		    	$this->setBrowser( self::BROWSER_IE );
540		    	$this->setVersion(str_replace(array('(',')',';'),'',$aresult[1]));
541		    	return true;
542		    }
543		    // Test for Pocket IE
544		    else if( stripos($this->_agent,'mspie') !== false || stripos($this->_agent,'pocket') !== false ) {
545			    $aresult = explode(' ',stristr($this->_agent,'mspie'));
546			    $this->setPlatform( self::PLATFORM_WINDOWS_CE );
547			    $this->setBrowser( self::BROWSER_POCKET_IE );
548			    $this->setMobile(true);
549
550			    if( stripos($this->_agent,'mspie') !== false ) {
551				    $this->setVersion($aresult[1]);
552			    }
553			    else {
554				    $aversion = explode('/',$this->_agent);
555				    $this->setVersion($aversion[1]);
556			    }
557			    return true;
558		    }
559			return false;
560	    }
561
562	    /**
563	     * Determine if the browser is Opera or not (last updated 1.7)
564	     * @return boolean True if the browser is Opera otherwise false
565	     */
566	    protected function checkBrowserOpera() {
567		    if( stripos($this->_agent,'opera mini') !== false ) {
568			    $resultant = stristr($this->_agent, 'opera mini');
569			    if( preg_match('/\//',$resultant) ) {
570				    $aresult = explode('/',$resultant);
571				    $aversion = explode(' ',$aresult[1]);
572				    $this->setVersion($aversion[0]);
573				}
574			    else {
575				    $aversion = explode(' ',stristr($resultant,'opera mini'));
576				    $this->setVersion($aversion[1]);
577			    }
578			    $this->_browser_name = self::BROWSER_OPERA_MINI;
579				$this->setMobile(true);
580				return true;
581		    }
582		    else if( stripos($this->_agent,'opera') !== false ) {
583			    $resultant = stristr($this->_agent, 'opera');
584			    if( preg_match('/Version\/(10.*)$/',$resultant,$matches) ) {
585				    $this->setVersion($matches[1]);
586			    }
587			    else if( preg_match('/\//',$resultant) ) {
588				    $aresult = explode('/',str_replace("("," ",$resultant));
589				    $aversion = explode(' ',$aresult[1]);
590				    $this->setVersion($aversion[0]);
591			    }
592			    else {
593				    $aversion = explode(' ',stristr($resultant,'opera'));
594				    $this->setVersion(isset($aversion[1])?$aversion[1]:"");
595			    }
596			    $this->_browser_name = self::BROWSER_OPERA;
597			    return true;
598		    }
599			return false;
600	    }
601
602	    /**
603	     * Determine if the browser is Chrome or not (last updated 1.7)
604	     * @return boolean True if the browser is Chrome otherwise false
605	     */
606	    protected function checkBrowserChrome() {
607		    if( stripos($this->_agent,'Chrome') !== false ) {
608			    $aresult = explode('/',stristr($this->_agent,'Chrome'));
609			    $aversion = explode(' ',$aresult[1]);
610			    $this->setVersion($aversion[0]);
611			    $this->setBrowser(self::BROWSER_CHROME);
612			    return true;
613		    }
614		    return false;
615	    }
616
617
618	    /**
619	     * Determine if the browser is WebTv or not (last updated 1.7)
620	     * @return boolean True if the browser is WebTv otherwise false
621	     */
622	    protected function checkBrowserWebTv() {
623		    if( stripos($this->_agent,'webtv') !== false ) {
624			    $aresult = explode('/',stristr($this->_agent,'webtv'));
625			    $aversion = explode(' ',$aresult[1]);
626			    $this->setVersion($aversion[0]);
627			    $this->setBrowser(self::BROWSER_WEBTV);
628			    return true;
629		    }
630		    return false;
631	    }
632
633	    /**
634	     * Determine if the browser is NetPositive or not (last updated 1.7)
635	     * @return boolean True if the browser is NetPositive otherwise false
636	     */
637	    protected function checkBrowserNetPositive() {
638		    if( stripos($this->_agent,'NetPositive') !== false ) {
639			    $aresult = explode('/',stristr($this->_agent,'NetPositive'));
640			    $aversion = explode(' ',$aresult[1]);
641			    $this->setVersion(str_replace(array('(',')',';'),'',$aversion[0]));
642			    $this->setBrowser(self::BROWSER_NETPOSITIVE);
643			    return true;
644		    }
645		    return false;
646	    }
647
648	    /**
649	     * Determine if the browser is Galeon or not (last updated 1.7)
650	     * @return boolean True if the browser is Galeon otherwise false
651	     */
652	    protected function checkBrowserGaleon() {
653		    if( stripos($this->_agent,'galeon') !== false ) {
654			    $aresult = explode(' ',stristr($this->_agent,'galeon'));
655			    $aversion = explode('/',$aresult[0]);
656			    $this->setVersion($aversion[1]);
657			    $this->setBrowser(self::BROWSER_GALEON);
658			    return true;
659		    }
660		    return false;
661	    }
662
663	    /**
664	     * Determine if the browser is Konqueror or not (last updated 1.7)
665	     * @return boolean True if the browser is Konqueror otherwise false
666	     */
667	    protected function checkBrowserKonqueror() {
668		    if( stripos($this->_agent,'Konqueror') !== false ) {
669			    $aresult = explode(' ',stristr($this->_agent,'Konqueror'));
670			    $aversion = explode('/',$aresult[0]);
671			    $this->setVersion($aversion[1]);
672			    $this->setBrowser(self::BROWSER_KONQUEROR);
673			    return true;
674		    }
675		    return false;
676	    }
677
678	    /**
679	     * Determine if the browser is iCab or not (last updated 1.7)
680	     * @return boolean True if the browser is iCab otherwise false
681	     */
682	    protected function checkBrowserIcab() {
683		    if( stripos($this->_agent,'icab') !== false ) {
684			    $aversion = explode(' ',stristr(str_replace('/',' ',$this->_agent),'icab'));
685			    $this->setVersion($aversion[1]);
686			    $this->setBrowser(self::BROWSER_ICAB);
687			    return true;
688		    }
689		    return false;
690	    }
691
692	    /**
693	     * Determine if the browser is OmniWeb or not (last updated 1.7)
694	     * @return boolean True if the browser is OmniWeb otherwise false
695	     */
696	    protected function checkBrowserOmniWeb() {
697		    if( stripos($this->_agent,'omniweb') !== false ) {
698			    $aresult = explode('/',stristr($this->_agent,'omniweb'));
699			    $aversion = explode(' ',isset($aresult[1])?$aresult[1]:"");
700			    $this->setVersion($aversion[0]);
701			    $this->setBrowser(self::BROWSER_OMNIWEB);
702			    return true;
703		    }
704		    return false;
705	    }
706
707	    /**
708	     * Determine if the browser is Phoenix or not (last updated 1.7)
709	     * @return boolean True if the browser is Phoenix otherwise false
710	     */
711	    protected function checkBrowserPhoenix() {
712		    if( stripos($this->_agent,'Phoenix') !== false ) {
713			    $aversion = explode('/',stristr($this->_agent,'Phoenix'));
714			    $this->setVersion($aversion[1]);
715			    $this->setBrowser(self::BROWSER_PHOENIX);
716			    return true;
717		    }
718		    return false;
719	    }
720
721	    /**
722	     * Determine if the browser is Firebird or not (last updated 1.7)
723	     * @return boolean True if the browser is Firebird otherwise false
724	     */
725	    protected function checkBrowserFirebird() {
726		    if( stripos($this->_agent,'Firebird') !== false ) {
727			    $aversion = explode('/',stristr($this->_agent,'Firebird'));
728			    $this->setVersion($aversion[1]);
729			    $this->setBrowser(self::BROWSER_FIREBIRD);
730				return true;
731		    }
732		    return false;
733	    }
734
735	    /**
736	     * Determine if the browser is Netscape Navigator 9+ or not (last updated 1.7)
737		 * NOTE: (http://browser.netscape.com/ - Official support ended on March 1st, 2008)
738	     * @return boolean True if the browser is Netscape Navigator 9+ otherwise false
739	     */
740	    protected function checkBrowserNetscapeNavigator9Plus() {
741		    if( stripos($this->_agent,'Firefox') !== false && preg_match('/Navigator\/([^ ]*)/i',$this->_agent,$matches) ) {
742			    $this->setVersion($matches[1]);
743			    $this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
744			    return true;
745		    }
746		    else if( stripos($this->_agent,'Firefox') === false && preg_match('/Netscape6?\/([^ ]*)/i',$this->_agent,$matches) ) {
747			    $this->setVersion($matches[1]);
748			    $this->setBrowser(self::BROWSER_NETSCAPE_NAVIGATOR);
749			    return true;
750		    }
751		    return false;
752	    }
753
754	    /**
755	     * Determine if the browser is Shiretoko or not (https://wiki.mozilla.org/Projects/shiretoko) (last updated 1.7)
756	     * @return boolean True if the browser is Shiretoko otherwise false
757	     */
758	    protected function checkBrowserShiretoko() {
759		    if( stripos($this->_agent,'Mozilla') !== false && preg_match('/Shiretoko\/([^ ]*)/i',$this->_agent,$matches) ) {
760			    $this->setVersion($matches[1]);
761			    $this->setBrowser(self::BROWSER_SHIRETOKO);
762			    return true;
763		    }
764		    return false;
765	    }
766
767	    /**
768	     * Determine if the browser is Ice Cat or not (http://en.wikipedia.org/wiki/GNU_IceCat) (last updated 1.7)
769	     * @return boolean True if the browser is Ice Cat otherwise false
770	     */
771	    protected function checkBrowserIceCat() {
772		    if( stripos($this->_agent,'Mozilla') !== false && preg_match('/IceCat\/([^ ]*)/i',$this->_agent,$matches) ) {
773			    $this->setVersion($matches[1]);
774			    $this->setBrowser(self::BROWSER_ICECAT);
775			    return true;
776		    }
777		    return false;
778	    }
779
780	    /**
781	     * Determine if the browser is Nokia or not (last updated 1.7)
782	     * @return boolean True if the browser is Nokia otherwise false
783	     */
784	    protected function checkBrowserNokia() {
785		    if( preg_match("/Nokia([^\/]+)\/([^ SP]+)/i",$this->_agent,$matches) ) {
786			    $this->setVersion($matches[2]);
787				if( stripos($this->_agent,'Series60') !== false || strpos($this->_agent,'S60') !== false ) {
788					$this->setBrowser(self::BROWSER_NOKIA_S60);
789				}
790				else {
791					$this->setBrowser( self::BROWSER_NOKIA );
792				}
793			    $this->setMobile(true);
794			    return true;
795		    }
796			return false;
797	    }
798
799	    /**
800	     * Determine if the browser is Firefox or not (last updated 1.7)
801	     * @return boolean True if the browser is Firefox otherwise false
802	     */
803	    protected function checkBrowserFirefox() {
804		    if( stripos($this->_agent,'safari') === false ) {
805				if( preg_match("/Firefox[\/ \(]([^ ;\)]+)/i",$this->_agent,$matches) ) {
806					$this->setVersion($matches[1]);
807					$this->setBrowser(self::BROWSER_FIREFOX);
808					return true;
809				}
810				else if( preg_match("/Firefox$/i",$this->_agent,$matches) ) {
811					$this->setVersion("");
812					$this->setBrowser(self::BROWSER_FIREFOX);
813					return true;
814				}
815			}
816		    return false;
817	    }
818
819		/**
820	     * Determine if the browser is Firefox or not (last updated 1.7)
821	     * @return boolean True if the browser is Firefox otherwise false
822	     */
823	    protected function checkBrowserIceweasel() {
824			if( stripos($this->_agent,'Iceweasel') !== false ) {
825				$aresult = explode('/',stristr($this->_agent,'Iceweasel'));
826				$aversion = explode(' ',$aresult[1]);
827				$this->setVersion($aversion[0]);
828				$this->setBrowser(self::BROWSER_ICEWEASEL);
829				return true;
830			}
831			return false;
832		}
833	    /**
834	     * Determine if the browser is Mozilla or not (last updated 1.7)
835	     * @return boolean True if the browser is Mozilla otherwise false
836	     */
837	    protected function checkBrowserMozilla() {
838		    if( stripos($this->_agent,'mozilla') !== false  && preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent) && stripos($this->_agent,'netscape') === false) {
839			    $aversion = explode(' ',stristr($this->_agent,'rv:'));
840			    preg_match('/rv:[0-9].[0-9][a-b]?/i',$this->_agent,$aversion);
841			    $this->setVersion(str_replace('rv:','',$aversion[0]));
842			    $this->setBrowser(self::BROWSER_MOZILLA);
843			    return true;
844		    }
845		    else if( stripos($this->_agent,'mozilla') !== false && preg_match('/rv:[0-9]\.[0-9]/i',$this->_agent) && stripos($this->_agent,'netscape') === false ) {
846			    $aversion = explode('',stristr($this->_agent,'rv:'));
847			    $this->setVersion(str_replace('rv:','',$aversion[0]));
848			    $this->setBrowser(self::BROWSER_MOZILLA);
849			    return true;
850		    }
851		    else if( stripos($this->_agent,'mozilla') !== false  && preg_match('/mozilla\/([^ ]*)/i',$this->_agent,$matches) && stripos($this->_agent,'netscape') === false ) {
852			    $this->setVersion($matches[1]);
853			    $this->setBrowser(self::BROWSER_MOZILLA);
854			    return true;
855		    }
856			return false;
857	    }
858
859	    /**
860	     * Determine if the browser is Lynx or not (last updated 1.7)
861	     * @return boolean True if the browser is Lynx otherwise false
862	     */
863	    protected function checkBrowserLynx() {
864		    if( stripos($this->_agent,'lynx') !== false ) {
865			    $aresult = explode('/',stristr($this->_agent,'Lynx'));
866			    $aversion = explode(' ',(isset($aresult[1])?$aresult[1]:""));
867			    $this->setVersion($aversion[0]);
868			    $this->setBrowser(self::BROWSER_LYNX);
869			    return true;
870		    }
871		    return false;
872	    }
873
874	    /**
875	     * Determine if the browser is Amaya or not (last updated 1.7)
876	     * @return boolean True if the browser is Amaya otherwise false
877	     */
878	    protected function checkBrowserAmaya() {
879		    if( stripos($this->_agent,'amaya') !== false ) {
880			    $aresult = explode('/',stristr($this->_agent,'Amaya'));
881			    $aversion = explode(' ',$aresult[1]);
882			    $this->setVersion($aversion[0]);
883			    $this->setBrowser(self::BROWSER_AMAYA);
884			    return true;
885		    }
886		    return false;
887	    }
888
889	    /**
890	     * Determine if the browser is Safari or not (last updated 1.7)
891	     * @return boolean True if the browser is Safari otherwise false
892	     */
893	    protected function checkBrowserSafari() {
894		    if( stripos($this->_agent,'Safari') !== false && stripos($this->_agent,'iPhone') === false && stripos($this->_agent,'iPod') === false ) {
895			    $aresult = explode('/',stristr($this->_agent,'Version'));
896			    if( isset($aresult[1]) ) {
897				    $aversion = explode(' ',$aresult[1]);
898				    $this->setVersion($aversion[0]);
899			    }
900			    else {
901				    $this->setVersion(self::VERSION_UNKNOWN);
902			    }
903			    $this->setBrowser(self::BROWSER_SAFARI);
904			    return true;
905		    }
906		    return false;
907	    }
908
909	    /**
910	     * Determine if the browser is iPhone or not (last updated 1.7)
911	     * @return boolean True if the browser is iPhone otherwise false
912	     */
913	    protected function checkBrowseriPhone() {
914		    if( stripos($this->_agent,'iPhone') !== false ) {
915			    $aresult = explode('/',stristr($this->_agent,'Version'));
916			    if( isset($aresult[1]) ) {
917				    $aversion = explode(' ',$aresult[1]);
918				    $this->setVersion($aversion[0]);
919			    }
920			    else {
921				    $this->setVersion(self::VERSION_UNKNOWN);
922			    }
923			    $this->setMobile(true);
924			    $this->setBrowser(self::BROWSER_IPHONE);
925			    return true;
926		    }
927		    return false;
928	    }
929
930	    /**
931	     * Determine if the browser is iPod or not (last updated 1.7)
932	     * @return boolean True if the browser is iPod otherwise false
933	     */
934	    protected function checkBrowseriPad() {
935		    if( stripos($this->_agent,'iPad') !== false ) {
936			    $aresult = explode('/',stristr($this->_agent,'Version'));
937			    if( isset($aresult[1]) ) {
938				    $aversion = explode(' ',$aresult[1]);
939				    $this->setVersion($aversion[0]);
940			    }
941			    else {
942				    $this->setVersion(self::VERSION_UNKNOWN);
943			    }
944			    $this->setMobile(true);
945			    $this->setBrowser(self::BROWSER_IPAD);
946			    return true;
947		    }
948		    return false;
949	    }
950
951	    /**
952	     * Determine if the browser is iPod or not (last updated 1.7)
953	     * @return boolean True if the browser is iPod otherwise false
954	     */
955	    protected function checkBrowseriPod() {
956		    if( stripos($this->_agent,'iPod') !== false ) {
957			    $aresult = explode('/',stristr($this->_agent,'Version'));
958			    if( isset($aresult[1]) ) {
959				    $aversion = explode(' ',$aresult[1]);
960				    $this->setVersion($aversion[0]);
961			    }
962			    else {
963				    $this->setVersion(self::VERSION_UNKNOWN);
964			    }
965			    $this->setMobile(true);
966			    $this->setBrowser(self::BROWSER_IPOD);
967			    return true;
968		    }
969		    return false;
970	    }
971
972	    /**
973	     * Determine if the browser is Android or not (last updated 1.7)
974	     * @return boolean True if the browser is Android otherwise false
975	     */
976	    protected function checkBrowserAndroid() {
977		    if( stripos($this->_agent,'Android') !== false ) {
978			    $aresult = explode(' ',stristr($this->_agent,'Android'));
979			    if( isset($aresult[1]) ) {
980				    $aversion = explode(' ',$aresult[1]);
981				    $this->setVersion($aversion[0]);
982			    }
983			    else {
984				    $this->setVersion(self::VERSION_UNKNOWN);
985			    }
986			    $this->setMobile(true);
987			    $this->setBrowser(self::BROWSER_ANDROID);
988			    return true;
989		    }
990		    return false;
991	    }
992
993	    /**
994	     * Determine the user's platform (last updated 1.7)
995	     */
996	    protected function checkPlatform() {
997		    if( stripos($this->_agent, 'windows') !== false ) {
998			    $this->_platform = self::PLATFORM_WINDOWS;
999		    }
1000		    else if( stripos($this->_agent, 'iPad') !== false ) {
1001			    $this->_platform = self::PLATFORM_IPAD;
1002		    }
1003		    else if( stripos($this->_agent, 'iPod') !== false ) {
1004			    $this->_platform = self::PLATFORM_IPOD;
1005		    }
1006		    else if( stripos($this->_agent, 'iPhone') !== false ) {
1007			    $this->_platform = self::PLATFORM_IPHONE;
1008		    }
1009		    elseif( stripos($this->_agent, 'mac') !== false ) {
1010			    $this->_platform = self::PLATFORM_APPLE;
1011		    }
1012		    elseif( stripos($this->_agent, 'android') !== false ) {
1013			    $this->_platform = self::PLATFORM_ANDROID;
1014		    }
1015		    elseif( stripos($this->_agent, 'linux') !== false ) {
1016			    $this->_platform = self::PLATFORM_LINUX;
1017		    }
1018		    else if( stripos($this->_agent, 'Nokia') !== false ) {
1019			    $this->_platform = self::PLATFORM_NOKIA;
1020		    }
1021		    else if( stripos($this->_agent, 'BlackBerry') !== false ) {
1022			    $this->_platform = self::PLATFORM_BLACKBERRY;
1023		    }
1024		    elseif( stripos($this->_agent,'FreeBSD') !== false ) {
1025			    $this->_platform = self::PLATFORM_FREEBSD;
1026		    }
1027		    elseif( stripos($this->_agent,'OpenBSD') !== false ) {
1028			    $this->_platform = self::PLATFORM_OPENBSD;
1029		    }
1030		    elseif( stripos($this->_agent,'NetBSD') !== false ) {
1031			    $this->_platform = self::PLATFORM_NETBSD;
1032		    }
1033		    elseif( stripos($this->_agent, 'OpenSolaris') !== false ) {
1034			    $this->_platform = self::PLATFORM_OPENSOLARIS;
1035		    }
1036		    elseif( stripos($this->_agent, 'SunOS') !== false ) {
1037			    $this->_platform = self::PLATFORM_SUNOS;
1038		    }
1039		    elseif( stripos($this->_agent, 'OS\/2') !== false ) {
1040			    $this->_platform = self::PLATFORM_OS2;
1041		    }
1042		    elseif( stripos($this->_agent, 'BeOS') !== false ) {
1043			    $this->_platform = self::PLATFORM_BEOS;
1044		    }
1045		    elseif( stripos($this->_agent, 'win') !== false ) {
1046			    $this->_platform = self::PLATFORM_WINDOWS;
1047		    }
1048
1049	    }
1050    }
1051?>