Project

General

Profile

1
<?php
2
/**
3
* @package   Warp Theme Framework
4
* @author    YOOtheme http://www.yootheme.com
5
* @copyright Copyright (C) YOOtheme GmbH
6
* @license   http://www.gnu.org/licenses/gpl.html GNU/GPL
7
*/
8

    
9
/*
10
	Class: UseragentWarpHelper
11
		User agent helper class, detect browser, version and operating system
12
		Based on Simple PHP User agent (http://github.com/ornicar/php-user-agent, Thibault Duplessis <thibault.duplessis@gmail.com>, MIT License)
13
*/
14
class UseragentWarpHelper extends WarpHelper {
15

    
16
	/* user agent info */
17
	protected $_info;
18
	
19
	/*
20
		Function: browser
21
			Retrieve browser name
22

    
23
		Returns:
24
			String
25
	*/
26
	public function browser() {
27
		
28
		if (empty($this->_info)) {
29
			$this->_info = $this->parse();
30
		}
31
		
32
		return $this->_info['browser_name'];
33
	}
34

    
35
	/*
36
		Function: version
37
			Retrieve browser version
38

    
39
		Returns:
40
			String
41
	*/
42
	public function version() {
43
		
44
		if (empty($this->_info)) {
45
			$this->_info = $this->parse();
46
		}
47
		
48
		return $this->_info['browser_version'];
49
	}
50

    
51
	/*
52
		Function: os
53
			Retrieve operating system
54

    
55
		Returns:
56
			String
57
	*/
58
	public function os() {
59
		
60
		if (empty($this->_info)) {
61
			$this->_info = $this->parse();
62
		}
63
		
64
		return $this->_info['operating_system'];
65
	}
66

    
67
	/**
68
	 * Parse a user agent string.
69
	 *
70
	 * @param   string  $userAgentString  defaults to $_SERVER['HTTP_USER_AGENT'] if empty
71
	 * @return  array   (                 the user agent informations
72
	 *            'browser_name'      => 'firefox',
73
	 *            'browser_version'   => '3.6',
74
	 *            'operating_system'  => 'linux'
75
	 *          )
76
	 */
77
	public function parse($userAgentString = null) {
78
		
79
		// use current user agent string as default
80
		if (!$userAgentString) {
81
			$userAgentString = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
82
		}
83
		
84
		// parse quickly (with medium accuracy)
85
		$informations = $this->doParse($userAgentString);
86
		
87
		// run some filters to increase accuracy
88
		foreach ($this->getFilters() as $filter) {
89
			$this->$filter($informations);
90
		}
91
		
92
		return $informations;
93
	}
94
	
95
	/**
96
	 * Detect quickly informations from the user agent string
97
	 *
98
	 * @param   string $userAgentString   user agent string
99
	 * @return  array                     user agent informations array
100
	 */
101
	public function doParse($userAgentString) {
102
		
103
		$userAgent = array(
104
			'string' => $this->cleanUserAgentString($userAgentString) ,
105
			'browser_name' => null,
106
			'browser_version' => null,
107
			'operating_system' => null
108
		);
109

    
110
		if (empty($userAgent['string'])) {
111
			return $userAgent;
112
		}
113

    
114
		// build regex that matches phrases for known browsers
115
		// (e.g. "Firefox/2.0" or "MSIE 6.0" (This only matches the major and minor
116
		// version numbers.  E.g. "2.0.0.6" is parsed as simply "2.0"
117
		$pattern = '#(' . join('|', $this->getKnownBrowsers()) . ')[/ ]+([0-9]+(?:\.[0-9]+)?)#';
118

    
119
		// Find all phrases (or return empty array if none found)
120
		if (preg_match_all($pattern, $userAgent['string'], $matches)) {
121

    
122
			// Since some UAs have more than one phrase (e.g Firefox has a Gecko phrase,
123
			// Opera 7,8 have a MSIE phrase), use the last one found (the right-most one
124
			// in the UA).  That's usually the most correct.
125
			$i = count($matches[1]) - 1;
126

    
127
			if (isset($matches[1][$i])) {
128
				$userAgent['browser_name'] = $matches[1][$i];
129
			}
130

    
131
			if (isset($matches[2][$i])) {
132
				$userAgent['browser_version'] = $matches[2][$i];
133
			}
134
		}
135

    
136
		// Find operating system
137
		$pattern = '#' . join('|', $this->getKnownOperatingSystems()) . '#';
138

    
139
		if (preg_match($pattern, $userAgent['string'], $match)) {
140
			if (isset($match[0])) {
141
				$userAgent['operating_system'] = $match[0];
142
			}
143
		}
144

    
145
		return $userAgent;
146
	}
147

    
148
	/**
149
	 * Make user agent string lowercase, and replace browser aliases
150
	 *
151
	 * @param   string $userAgentString the dirty user agent string
152
	 * @return  string                  the clean user agent string
153
	 */
154
	public function cleanUserAgentString($userAgentString) {
155
		
156
		// clean up the string
157
		$userAgentString = trim(strtolower($userAgentString));
158

    
159
		// replace browser names with their aliases
160
		$userAgentString = strtr($userAgentString, $this->getKnownBrowserAliases());
161

    
162
		// replace operating system names with their aliases
163
		$userAgentString = strtr($userAgentString, $this->getKnownOperatingSystemAliases());
164

    
165
		return $userAgentString;
166
	}
167

    
168
	/**
169
	 * Get the list of filters that get called when parsing a user agent
170
	 *
171
	 * @return  array list of valid callables
172
	 */
173
	public function getFilters() {
174
		return array(
175
			'filterGoogleAndroid',
176
			'filterGoogleChrome',
177
			'filterSafariVersion',
178
			'filterOperaVersion',
179
			'filterYahoo'
180
		);
181
	}
182

    
183
	/**
184
	 * Add a filter to be called when parsing a user agent
185
	 *
186
	 * @param   string $filter name of the filter method
187
	 */
188
	public function addFilter($filter) {
189
		$this->filters+= $filter;
190
	}
191
	
192
	/**
193
	 * Get known browsers
194
	 *
195
	 * @return  array the browsers
196
	 */
197
	public function getKnownBrowsers() {
198
		return array(
199
			'msie',
200
			'firefox',
201
			'safari',
202
			'webkit',
203
			'opera',
204
			'netscape',
205
			'konqueror',
206
			'gecko',
207
			'chrome',
208
			'googlebot',
209
			'iphone',
210
			'msnbot',
211
			'applewebkit'
212
		);
213
	}
214

    
215
	/**
216
	 * Get known browser aliases
217
	 *
218
	 * @return  array the browser aliases
219
	 */
220
	public function getKnownBrowserAliases() {
221
		return array(
222
			'shiretoko' => 'firefox',
223
			'namoroka' => 'firefox',
224
			'shredder' => 'firefox',
225
			'minefield' => 'firefox',
226
			'granparadiso' => 'firefox'
227
		);
228
	}
229
	
230
	/**
231
	 * Get known operating system
232
	 *
233
	 * @return  array the operating systems
234
	 */
235
	public function getKnownOperatingSystems() {
236
		return array(
237
			'windows',
238
			'macintosh',
239
			'linux',
240
			'freebsd',
241
			'unix',
242
			'iphone',
243
			'ipod',
244
			'ipad',
245
			'android',
246
		);
247
	}
248
	
249
	/**
250
	 * Get known operating system aliases
251
	 *
252
	 * @return  array the operating system aliases
253
	 */
254
	public function getKnownOperatingSystemAliases() {
255
		return array();
256
	}
257
	
258
	/**
259
	 * Filters
260
	 */
261

    
262
	/**
263
	 * Google android os
264
	 */
265
	public function filterGoogleAndroid(&$userAgent) {
266
		if ('safari' === $userAgent['browser_name'] && strpos($userAgent['string'], 'android')) {
267
			$userAgent['operating_system'] = strpos($userAgent['string'], 'mobile') ? 'android' : 'android.tablet';
268
		}
269
	}
270
	
271
	/**
272
	 * Google chrome has a safari like signature
273
	 */
274
	public function filterGoogleChrome(&$userAgent) {
275
		if ('safari' === $userAgent['browser_name'] && strpos($userAgent['string'], 'chrome/')) {
276
			$userAgent['browser_name'] = 'chrome';
277
			$userAgent['browser_version'] = preg_replace('|.+chrome/([0-9]+(?:\.[0-9]+)?).+|', '$1', $userAgent['string']);
278
		}
279
	}
280
	
281
	/**
282
	 * Safari version is not encoded "normally"
283
	 */
284
	public function filterSafariVersion(&$userAgent) {
285
		if ('safari' === $userAgent['browser_name'] && strpos($userAgent['string'], ' version/')) {
286
			$userAgent['browser_version'] = preg_replace('|.+\sversion/([0-9]+(?:\.[0-9]+)?).+|', '$1', $userAgent['string']);
287
		}
288
	}
289
	
290
	/**
291
	 * Opera 10.00 (and higher) version number is located at the end
292
	 */
293
	public function filterOperaVersion(&$userAgent) {
294
		if ('opera' === $userAgent['browser_name'] && strpos($userAgent['string'], ' version/')) {
295
			$userAgent['browser_version'] = preg_replace('|.+\sversion/([0-9]+\.[0-9]+)\s*.*|', '$1', $userAgent['string']);
296
		}
297
	}
298
	
299
	/**
300
	 * Yahoo bot has a special user agent string
301
	 */
302
	public function filterYahoo(&$userAgent) {
303
		if (null === $userAgent['browser_name'] && strpos($userAgent['string'], 'yahoo! slurp')) {
304
			$userAgent['browser_name'] = 'yahoobot';
305
		}
306
	}
307

    
308
}
(14-14/14)