1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12: class Visitor
13: {
14: 15: 16:
17: protected static $languages;
18:
19:
20: 21: 22:
23: protected static $encodings;
24:
25:
26: 27: 28:
29: protected static $browser_info;
30:
31:
32: 33: 34:
35: protected static $fingerprint;
36:
37:
38: 39: 40:
41: protected static $request;
42:
43:
44: 45: 46: 47: 48: 49:
50: public static function get_browser_info($type = NULL)
51: {
52: self::get_request();
53:
54: if (self::$browser_info === NULL) {
55: self::fill_browser_info(self::$browser_info, $type);
56: }
57:
58: if ($type === NULL) {
59: return self::$browser_info;
60: }
61:
62: return self::$browser_info[$type];
63: }
64:
65:
66: 67: 68: 69: 70:
71: private static function fill_browser_info()
72: {
73: $browser_info = array(
74: 'name' => 'unknown',
75: 'version' => 'unknown',
76: 'os' => 'unknown',
77: 'user_agent' => 'unknown',
78: 'version_full' => 'unknown',
79: 'mobile' => 'unknown',
80: 'core' => 'unknown',
81: );
82:
83: self::$browser_info = $browser_info;
84:
85: $user_agent = self::$request->server['HTTP_USER_AGENT'];
86:
87: if ($user_agent === NULL) {
88: return;
89: }
90:
91: self::$browser_info['user_agent'] = $user_agent;
92: $user_agent = strtolower($user_agent);
93:
94: $pattern = '/(bot|crawler|holmes|seek|dig|spider|curl|index|slurp|search)/';
95:
96: if (preg_match($pattern, $user_agent, $matches) !== 0) {
97: return;
98: }
99:
100: $pattern = '/(win|mac|linux|os\/2|beos|openbsd|freebsd|netbsd|sunos|darwin|android|symbos|symbian|blackberry)/';
101: if (preg_match($pattern, $user_agent, $matches) !== 0) {
102: $browser_info['os'] = $matches[0];
103: }
104:
105: $patterns = array(
106: '/.*(dillo){1}\/([0-9\.\-inmsc]+)/',
107: '/.*(netpositive){1}\/([0-9\.ab\+]+)/',
108: '/.*(seamonkey){1}\/([0-9\.ab\+]+)/',
109: '/^(lynx){1}\/([0-9\.devrl]+)/',
110: '/^(w3m){1}\/([0-9\.]+)/',
111: '/^(links){1}[\( ]*([0-9\.pre]+)/',
112: '/^(elinks){1}[\(\/ ]*([0-9\.pre]+)/',
113: '/.*(opera){1}.*(\d{2}\.\d{2})$/',
114: '/.*(opera){1}\/(\d+\.\d{2})/',
115: '/(chrom[eium]){1}\/([abpre\.\d]+) ?/',
116: '/(firefox){1}\/([abpre\.\d]+) ?/',
117: '/(msie){1} (\d+\.\d+);/',
118: );
119:
120: foreach ($patterns as $pattern) {
121: if (preg_match($pattern, $user_agent, $matches) !== 0) {
122: $browser_info['name'] = $matches[1];
123: $browser_info['version_full'] = $matches[2];
124: $browser_info['version'] = (float) $browser_info['version_full'];
125: break;
126: }
127: }
128:
129: $patterns = array(
130: '/(applewebkit)/',
131: '/(webkit)/',
132: '/(khtml)/',
133: '/(gecko)/',
134: '/(presto)/',
135: '/(trident)/',
136: );
137:
138: foreach ($patterns as $pattern) {
139: if (preg_match($pattern, $user_agent, $matches) !== 0) {
140: $browser_info['core'] = $matches[0];
141: break;
142: }
143: }
144:
145: $pattern = '/(mobile|phone|fennec|opera mini|skyfire)/';
146: if (preg_match($pattern, $user_agent, $matches) !== 0) {
147: $browser_info['mobile'] = TRUE;
148:
149: } else {
150: $browser_info['mobile'] = FALSE;
151: }
152:
153: self::$browser_info = $browser_info;
154: }
155:
156:
157:
158: 159: 160: 161: 162:
163: public static function get_ip()
164: {
165: self::get_request();
166:
167: $ip = self::$request->server['HTTP_CLIENT_IP'];
168: if ($ip !== NULL
169: AND Validate::ip($ip) !== FALSE) {
170:
171: return $ip;
172: }
173:
174: $ip_tmp = self::$request->server['HTTP_X_FORWARDED_FOR'];
175: if ($ip_tmp !== NULL) {
176: foreach (explode(',', $ip_tmp) as $ip) {
177: if (Validate::ip(trim($ip)) == TRUE) {
178: return $ip;
179: }
180: }
181: }
182:
183: $keys = array(
184: 'HTTP_X_FORWARDED',
185: 'HTTP_FORWARDED_FOR',
186: 'HTTP_FORWARDED',
187: 'HTTP_X_FORWARDED',
188: );
189:
190: foreach ($keys as $key) {
191: $ip = self::$request->server[$key];
192: if ($ip !== NULL
193: AND Validate::ip($ip) !== FALSE) {
194:
195: return $ip;
196: }
197: }
198:
199: return self::$request->server['REMOTE_ADDR'];
200: }
201:
202:
203: 204: 205: 206: 207:
208: public static function get_languages()
209: {
210: self::get_request();
211:
212: if (self::$languages !== NULL) {
213: return self::$languages;
214: }
215:
216: $accepted_languages = self::$request->server['HTTP_ACCEPT_LANGUAGE'];
217:
218: self::$languages = array();
219:
220: if ($accepted_languages === NULL) {
221: $accepted_languages = explode(',', $accepted_languages);
222: foreach ($accepted_languages as $key => $language) {
223: if (strpos($language, ';') == TRUE) {
224: list($accepted_languages[$key]) = explode(';', $language);
225: }
226:
227: if (strpos($language, '-') == TRUE) {
228: list($accepted_languages[$key]) = explode('-', $language);
229: }
230: }
231:
232: self::$languages = array_unique($accepted_languages);
233: }
234:
235: return self::$languages;
236: }
237:
238:
239: 240: 241: 242: 243: 244:
245: public static function get_language($languages = array())
246: {
247: $accepted_languages = self::get_languages();
248:
249: if (empty($languages) === TRUE
250: AND empty($accepted_languages) === TRUE) {
251:
252: return TRUE;
253: }
254:
255: if (empty($languages) === TRUE
256: AND empty($accepted_languages) === FALSE) {
257:
258: return reset($accepted_languages);
259: }
260:
261: foreach($accepted_languages as $language) {
262: if (in_array($language, $languages) === TRUE) {
263: return $language;
264: }
265: }
266:
267: return reset($languages);
268: }
269:
270:
271: 272: 273:
274: public static function get_fingerprint()
275: {
276: self::get_request();
277:
278: if (self::$fingerprint !== NULL) {
279: return self::$fingerprint;
280: }
281:
282: $items = array(
283: 'HTTP_USER_AGENT'
284: ,'HTTP_ACCEPT'
285: ,'HTTP_ACCEPT_ENCODING'
286: ,'HTTP_ACCEPT_LANGUAGE'
287: ,'HTTP_ACCEPT_CHARSET'
288: );
289:
290: $fingerprint = '';
291: foreach ($items as $item) {
292: $fingerprint .= self::$request->server[$item];
293: }
294:
295: $fingerprint .= self::get_ip();
296:
297: self::$fingerprint = md5($fingerprint);
298:
299: return self::$fingerprint;
300: }
301:
302:
303: 304: 305:
306: public static function get_encodings()
307: {
308: self::get_request();
309:
310: if (self::$encodings === NULL) {
311: if (Arrays::get_value(self::$request->server, 'HTTP_ACCEPT_ENCODING') === NULL) {
312: self::$encodings = array();
313:
314: } else {
315: self::$encodings = explode(',', self::$request->server['HTTP_ACCEPT_ENCODING']);
316:
317: }
318: }
319:
320: return self::$encodings;
321: }
322:
323:
324: 325: 326: 327: 328: 329:
330: public static function accept_encoding($encoding)
331: {
332: $encodings = self::get_encodings();
333: return Arrays::in_array($encoding, $encodings);
334: }
335:
336:
337: private static function get_request()
338: {
339: if (empty(self::$request) === FALSE) {
340: return;
341: }
342:
343: self::$request = new Request();
344: }
345: }
346: