1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
| <?php
/**
* Extends RequestHandler component by adding some useful geolocation information.
*
* Requires MaxMind WebService license key to work properly
*
* @copyright 2009 Erhan Abay
* @package app
* @subpackage app.controllers.components
* @version $Revision$
* @lastmodified $Date$
*/
App::import('Component', 'RequestHandler');
class RequestHandlerExtComponent extends RequestHandlerComponent
{
/**
* Required to query MaxMind WebService
*
* Provide your own key by replacing XXXXX.
*/
const MM_LICENSE_KEY = 'XXXXXX';
public function startup(&$controller)
{
parent::startup(&$controller);
$this->controller =& $controller;
}
/**
* Searches key value in array returned by function getGeoLocation()
*
* @param string $name Name of the method
* @param unknown_type $arguments Not used, required not to give error
* @return string if key found
* null else
*/
public function __call($name, $raw = false)
{
$var = Inflector::underscore(preg_replace('/getClient/i', '', $name));
$geo_location = (array)$this->getGeoLocation($raw);
return array_key_exists($var, $geo_location) ? $geo_location[$var] : null;
}
/**
* Queries to the MaxMind WebService and returns an array of information
*
* @param bool $raw
* @return null if IP address is local
* bool false if webservice returns error code
* string if $raw is set true
* array else
*/
public function getGeoLocation($raw = false)
{
if ($this->isLocalIP()) {
return null;
}
if ($this->controller->Session->check('User.GeoLocation')) {
return $raw ? $this->controller->Session->read('User.GeoLocation.raw') : $this->controller->Session->read('User.GeoLocation');
}
App::import('HttpSocket');
$http = new HttpSocket();
/*
* Returns in order:
*
* 0 ISO 3166 Two-letter Country Code,
* 1 Region Code,
* 2 City,
* 3 Postal Code,
* 4 Latitude,
* 5 Longitude,
* 6 Metropolitan Code,
* 7 Area Code,
* 8 ISP,
* 9 Organization,
* 10 Error code
*/
$result = $http->get('http://geoip1.maxmind.com/f', array(
'l' => self::MM_LICENSE_KEY,
'i' => $this->getClientIP()
));
$values = explode(',', $result);
if (isset($values[10])) {
return false;
}
if ($raw) {
return $result;
}
$keys = array('country_code', 'region_code', 'city', 'postal_code', 'latitude', 'longitude', 'metropolitan_code', 'area_code', 'isp', 'organization');
$data = array_combine($keys, $values);
$data['coords'] = $values[4].','.$values[5];
$data['raw'] = $result;
$this->controller->Session->write('User.GeoLocation', $data);
return $data;
}
/**
* Detects whether IP address is local or not
*
* @param string $ip IP address to check
* @return bool
*/
public function isLocalIP($ip = null) {
$ip = is_null($ip) ? $this->getClientIP() : $ip;
$regex = '/(192\.168\.[0-9]{1,3}\.[0-9]{1,3})';
$regex .= '|(10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})';
$regex .= '|(172\.0?([1][6-9])¦([2][0-9])¦([3][0-1])\.[0-9]{1,3}\.[0-9]{1,3})';
$regex .= '|(127\.0\.0\.1)/';
return (bool)preg_match($regex, $ip);
}
}
|