1 <?php
2 3 4 5 6 7
8 class Geoip {
9
10 public static $default_country_code = false;
11
12 13 14 15 16 17 18
19 protected static $iso_3166_countryCodes = array(
20 'A1' => "Anonymous Proxy",
21 'A2' => "Satellite Provider",
22 'A3' => "Internal Netwrok",
23 'AD' => "Andorra",
24 'AE' => "United Arab Emirates",
25 'AF' => "Afghanistan",
26 'AG' => "Antigua and Barbuda",
27 'AI' => "Anguilla",
28 'AL' => "Albania",
29 'AM' => "Armenia",
30 'AN' => "Netherlands Antilles",
31 'AO' => "Angola",
32 'AP' => "Asia/Pacific Region",
33 'AQ' => "Antarctica",
34 'AR' => "Argentina",
35 'AS' => "American Samoa",
36 'AT' => "Austria",
37 'AU' => "Australia",
38 'AW' => "Aruba",
39 'AZ' => "Azerbaijan",
40 'BA' => "Bosnia and Herzegovina",
41 'BB' => "Barbados",
42 'BD' => "Bangladesh",
43 'BE' => "Belgium",
44 'BF' => "Burkina Faso",
45 'BG' => "Bulgaria",
46 'BH' => "Bahrain",
47 'BI' => "Burundi",
48 'BJ' => "Benin",
49 'BM' => "Bermuda",
50 'BN' => "Brunei Darussalam",
51 'BO' => "Bolivia",
52 'BR' => "Brazil",
53 'BS' => "Bahamas",
54 'BT' => "Bhutan",
55 'BV' => "Bouvet Island",
56 'BW' => "Botswana",
57 'BY' => "Belarus",
58 'BZ' => "Belize",
59 'CA' => "Canada",
60 'CC' => "Cocos (Keeling) Islands",
61 'CF' => "Central African Republic",
62 'CG' => "Congo",
63 'CH' => "Switzerland",
64 'CI' => "Cote D'Ivoire",
65 'CK' => "Cook Islands",
66 'CL' => "Chile",
67 'CM' => "Cameroon",
68 'CN' => "China",
69 'CO' => "Colombia",
70 'CR' => "Costa Rica",
71 'CU' => "Cuba",
72 'CV' => "Cape Verde",
73 'CX' => "Christmas Island",
74 'CY' => "Cyprus",
75 'CZ' => "Czech Republic",
76 'DE' => "Germany",
77 'DJ' => "Djibouti",
78 'DK' => "Denmark",
79 'DM' => "Dominica",
80 'DO' => "Dominican Republic",
81 'DZ' => "Algeria",
82 'EC' => "Ecuador",
83 'EE' => "Estonia",
84 'EG' => "Egypt",
85 'EH' => "Western Sahara",
86 'ER' => "Eritrea",
87 'ES' => "Spain",
88 'ET' => "Ethiopia",
89 'EU' => "Europe",
90 'FI' => "Finland",
91 'FJ' => "Fiji",
92 'FK' => "Falkland Islands (Malvinas)",
93 'FM' => "Micronesia - Federated States of",
94 'FO' => "Faroe Islands",
95 'FR' => "France",
96 'FX' => "France (Metropolitan)",
97 'GA' => "Gabon",
98 'GB' => "United Kingdom",
99 'GD' => "Grenada",
100 'GE' => "Georgia",
101 'GF' => "French Guiana",
102 'GH' => "Ghana",
103 'GI' => "Gibraltar",
104 'GL' => "Greenland",
105 'GM' => "Gambia",
106 'GN' => "Guinea",
107 'GP' => "Guadeloupe",
108 'GQ' => "Equatorial Guinea",
109 'GR' => "Greece",
110 'GS' => "South Georgia and the South Sandwich Islands",
111 'GT' => "Guatemala",
112 'GU' => "Guam",
113 'GW' => "Guinea-Bissau",
114 'GY' => "Guyana",
115 'HK' => "Hong Kong",
116 'HM' => "Heard Island and McDonald Islands",
117 'HN' => "Honduras",
118 'HR' => "Croatia",
119 'HT' => "Haiti",
120 'HU' => "Hungary",
121 'ID' => "Indonesia",
122 'IE' => "Ireland",
123 'IL' => "Israel",
124 'IN' => "India",
125 'IO' => "British Indian Ocean Territory",
126 'IQ' => "Iraq",
127 'IR' => "Iran - Islamic Republic of",
128 'IS' => "Iceland",
129 'IT' => "Italy",
130 'JM' => "Jamaica",
131 'JO' => "Jordan",
132 'JP' => "Japan",
133 'KE' => "Kenya",
134 'KG' => "Kyrgyzstan",
135 'KH' => "Cambodia",
136 'KI' => "Kiribati",
137 'KM' => "Comoros",
138 'KN' => "Saint Kitts and Nevis",
139 'KP' => "Korea - Democratic People's Republic of",
140 'KR' => "Korea - Republic of",
141 'KW' => "Kuwait",
142 'KY' => "Cayman Islands",
143 'KZ' => "Kazakhstan",
144 'LA' => "Lao People's Democratic Republic",
145 'LB' => "Lebanon",
146 'LC' => "Saint Lucia",
147 'LI' => "Liechtenstein",
148 'LK' => "Sri Lanka",
149 'LR' => "Liberia",
150 'LS' => "Lesotho",
151 'LT' => "Lithuania",
152 'LU' => "Luxembourg",
153 'LV' => "Latvia",
154 'LY' => "Libyan Arab Jamahiriya",
155 'MA' => "Morocco",
156 'MC' => "Monaco",
157 'MD' => "Moldova - Republic of",
158 'MG' => "Madagascar",
159 'MH' => "Marshall Islands",
160 'MK' => "Macedonia - the Former Yugoslav Republic of",
161 'ML' => "Mali",
162 'MM' => "Myanmar",
163 'MN' => "Mongolia",
164 'MO' => "Macao",
165 'MP' => "Northern Mariana Islands",
166 'MQ' => "Martinique",
167 'MR' => "Mauritania",
168 'MS' => "Montserrat",
169 'MT' => "Malta",
170 'MU' => "Mauritius",
171 'MV' => "Maldives",
172 'MW' => "Malawi",
173 'MX' => "Mexico",
174 'MY' => "Malaysia",
175 'MZ' => "Mozambique",
176 'NA' => "Namibia",
177 'NC' => "New Caledonia",
178 'NE' => "Niger",
179 'NF' => "Norfolk Island",
180 'NG' => "Nigeria",
181 'NI' => "Nicaragua",
182 'NL' => "Netherlands",
183 'NO' => "Norway",
184 'NP' => "Nepal",
185 'NR' => "Nauru",
186 'NU' => "Niue",
187 'NZ' => "New Zealand",
188 'OM' => "Oman",
189 'PA' => "Panama",
190 'PE' => "Peru",
191 'PF' => "French Polynesia",
192 'PG' => "Papua New Guinea",
193 'PH' => "Philippines",
194 'PK' => "Pakistan",
195 'PL' => "Poland",
196 'PM' => "Saint Pierre and Miquelon",
197 'PN' => "Pitcairn",
198 'PR' => "Puerto Rico",
199 'PS' => "Palestinian Territory - Occupied",
200 'PT' => "Portugal",
201 'PW' => "Palau",
202 'PY' => "Paraguay",
203 'QA' => "Qatar",
204 'RE' => "Reunion",
205 'RO' => "Romania",
206 'RU' => "Russian Federation",
207 'RW' => "Rwanda",
208 'SA' => "Saudi Arabia",
209 'SB' => "Solomon Islands",
210 'SC' => "Seychelles",
211 'SD' => "Sudan",
212 'SE' => "Sweden",
213 'SG' => "Singapore",
214 'SH' => "Saint Helena",
215 'SI' => "Slovenia",
216 'SJ' => "Svalbard and Jan Mayen",
217 'SK' => "Slovakia",
218 'SL' => "Sierra Leone",
219 'SM' => "San Marino",
220 'SN' => "Senegal",
221 'SO' => "Somalia",
222 'SR' => "Suriname",
223 'ST' => "Sao Tome and Principe",
224 'SV' => "El Salvador",
225 'SY' => "Syrian Arab Republic",
226 'SZ' => "Swaziland",
227 'TC' => "Turks and Caicos Islands",
228 'TD' => "Chad",
229 'TF' => "French Southern Territories",
230 'TG' => "Togo",
231 'TH' => "Thailand",
232 'TJ' => "Tajikistan",
233 'TK' => "Tokelau",
234 'TL' => "East Timor",
235 'TM' => "Turkmenistan",
236 'TN' => "Tunisia",
237 'TO' => "Tonga",
238 'TR' => "Turkey",
239 'TT' => "Trinidad and Tobago",
240 'TV' => "Tuvalu",
241 'TW' => "Taiwan (Province of China)",
242 'TZ' => "Tanzania (United Republic of)",
243 'UA' => "Ukraine",
244 'UG' => "Uganda",
245 'UM' => "United States Minor Outlying Islands",
246 'US' => "United States",
247 'UY' => "Uruguay",
248 'UZ' => "Uzbekistan",
249 'VA' => "Holy See (Vatican City State)",
250 'VC' => "Saint Vincent and the Grenadines",
251 'VE' => "Venezuela",
252 'VG' => "Virgin Islands - British",
253 'VI' => "Virgin Islands - U.S.",
254 'VN' => "Vietnam",
255 'VU' => "Vanuatu",
256 'WF' => "Wallis and Futuna",
257 'WS' => "Samoa",
258 'YE' => "Yemen",
259 'YT' => "Mayotte",
260 'YU' => "Yugoslavia",
261 'ZA' => "South Africa",
262 'ZM' => "Zambia",
263 'ZR' => "Zaire",
264 'ZW' => "Zimbabwe"
265 );
266
267 268 269 270 271 272 273 274 275 276 277 278 279
280 static function ip2country($address, $codeOnly = false) {
281
282
283 if(Director::is_cli() || !function_exists('exec')) return false;
284
285 $cmd = 'geoiplookup ' . escapeshellarg($address);
286 exec($cmd, $result, $code);
287
288
289 if($code == 127) return false;
290 if($result == false) return false;
291
292
293
294
295 $country = $result[0];
296
297 $start = strpos($country, ':');
298 if($start) $start += 2;
299 $code = substr($country, $start, 2);
300
301 if($code == 'IP' || $code == '--') {
302 if(self::$default_country_code) {
303 $code = self::$default_country_code;
304 } else {
305 return false;
306 }
307 }
308
309 if(!$codeOnly) {
310 $name = substr($country, $start + 4);
311 if(!$name) $name = $this->countryCode2name($code);
312
313 return array('code' => $code, 'name' => $name);
314 } else {
315 return $code;
316 }
317 }
318
319 320 321
322 static function visitor_country() {
323 if( ereg('^dev(\\.|$)', $_SERVER['HTTP_HOST']) && isset($_GET['country'])) return $_GET['country'];
324 else if(isset($_SERVER['REMOTE_ADDR'])) return Geoip::ip2country($_SERVER['REMOTE_ADDR'], true);
325 }
326
327 328 329 330
331 static function ip2country_check() {
332 global $ss_disableFeatures;
333 if($ss_disableFeatures['geoip']) return;
334
335
336 $checks = array(
337 'www.paradise.net.nz' => array('code'=>'NZ','name'=>'New Zealand'),
338 'news.com.au' => array('code'=>'AU','name'=>'Australia'),
339 'www.google.com' => array('code'=>'US','name'=>'United States'),
340 'a.b.c.d.e.f.g' => false,
341 );
342
343 $status = true;
344
345 foreach ($checks as $url => $expectedResponse) {
346 $response = self::ip2country($url);
347
348 if(!$response && $expectedResponse) {
349 user_error("ip2country_check failed sanity check: ip2country($url) returned false. Expected code: '$expectedResponse'", E_USER_WARNING);
350 $status = false;
351 } elseif ($response != $expectedResponse) {
352 user_error("ip2country_check failed sanity check: ip2country($url) returned code: '$response[code]/$response[name]'. Expected code: '$expectedResponse[code]/$expectedResponse[name]'", E_USER_WARNING);
353 $status = false;
354 }
355 }
356
357 return $status;
358 }
359
360 361 362 363
364 static function countryCode2name($code) {
365 if (!isset(Geoip::$iso_3166_countryCodes[$code])) return null;
366 $name = Geoip::$iso_3166_countryCodes[$code];
367
368 return _t("Country.$code", $name);
369 }
370
371 372 373
374 static function getCountryDropDown() {
375 $dropdown = Geoip::$iso_3166_countryCodes;
376 unset($dropdown['A1']);
377 unset($dropdown['A2']);
378 unset($dropdown['A3']);
379 foreach ($dropdown as $code => $name) {
380 $dropdown[$code] = _t("Country.$code", $name);
381 }
382 asort($dropdown);
383 return $dropdown;
384 }
385 }
386 ?>
387
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-