|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* ****************************************************************************** |
|
5
|
|
|
* Copyright 2011-2017 DANTE Ltd. and GÉANT on behalf of the GN3, GN3+, GN4-1 |
|
6
|
|
|
* and GN4-2 consortia |
|
7
|
|
|
* |
|
8
|
|
|
* License: see the web/copyright.php file in the file structure |
|
9
|
|
|
* ****************************************************************************** |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
/* |
|
13
|
|
|
* This product includes GeoLite data created by MaxMind, available from |
|
14
|
|
|
* http://www.maxmind.com |
|
15
|
|
|
*/ |
|
16
|
|
|
|
|
17
|
|
|
namespace core; |
|
18
|
|
|
|
|
19
|
|
|
use GeoIp2\Database\Reader; |
|
20
|
|
|
use \Exception; |
|
21
|
|
|
|
|
22
|
|
|
class DeviceLocation { |
|
23
|
|
|
/** |
|
24
|
|
|
* find out where the user is currently located |
|
25
|
|
|
* set $location with the discovered value |
|
26
|
|
|
*/ |
|
27
|
|
|
|
|
28
|
|
|
public static function locateDevice() { |
|
29
|
|
|
$geoipVersion = CONFIG['GEOIP']['version'] ?? 0; |
|
30
|
|
|
switch ($geoipVersion) { |
|
31
|
|
|
case 0: |
|
32
|
|
|
return(['status' => 'error', 'error' => 'Geolocation not supported']); |
|
33
|
|
|
case 1: |
|
34
|
|
|
return(self::locateDevice1()); |
|
35
|
|
|
case 2: |
|
36
|
|
|
return(self::locateDevice2()); |
|
37
|
|
|
default: |
|
38
|
|
|
throw new Exception("This version of GeoIP is not known!"); |
|
39
|
|
|
} |
|
40
|
|
|
} |
|
41
|
|
|
|
|
42
|
|
|
private static function locateDevice1() { |
|
43
|
|
View Code Duplication |
if (CONFIG['GEOIP']['version'] != 1) { |
|
|
|
|
|
|
44
|
|
|
return ['status' => 'error', 'error' => 'Function for GEOIPv1 called, but config says this is not the version to use!']; |
|
45
|
|
|
} |
|
46
|
|
|
//$host = $_SERVER['REMOTE_ADDR']; |
|
|
|
|
|
|
47
|
|
|
$host = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP); |
|
48
|
|
|
$record = geoip_record_by_name($host); |
|
49
|
|
|
if ($record === FALSE) { |
|
50
|
|
|
return ['status' => 'error', 'error' => 'Problem getting the address']; |
|
51
|
|
|
} |
|
52
|
|
|
$result = ['status' => 'ok']; |
|
53
|
|
|
$result['country'] = $record['country_code']; |
|
54
|
|
|
// the two lines below are a dirty hack to take of the error in naming the UK federation |
|
55
|
|
|
if ($result['country'] == 'GB') { |
|
56
|
|
|
$result['country'] = 'UK'; |
|
57
|
|
|
} |
|
58
|
|
|
$result['region'] = $record['region']; |
|
59
|
|
|
$result['geo'] = ['lat' => (float) $record['latitude'], 'lon' => (float) $record['longitude']]; |
|
60
|
|
|
return($result); |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* find out where the user is currently located, using GeoIP2 |
|
65
|
|
|
* @return array |
|
66
|
|
|
*/ |
|
67
|
|
|
private static function locateDevice2() { |
|
68
|
|
View Code Duplication |
if (CONFIG['GEOIP']['version'] != 2) { |
|
|
|
|
|
|
69
|
|
|
return ['status' => 'error', 'error' => 'Function for GEOIPv2 called, but config says this is not the version to use!']; |
|
70
|
|
|
} |
|
71
|
|
|
require_once CONFIG['GEOIP']['geoip2-path-to-autoloader']; |
|
72
|
|
|
$reader = new Reader(CONFIG['GEOIP']['geoip2-path-to-db']); |
|
73
|
|
|
$host = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP); |
|
74
|
|
|
try { |
|
75
|
|
|
$record = $reader->city($host); |
|
76
|
|
|
} catch (\Exception $e) { |
|
77
|
|
|
$result = ['status' => 'error', 'error' => 'Problem getting the address']; |
|
78
|
|
|
return($result); |
|
79
|
|
|
} |
|
80
|
|
|
$result = ['status' => 'ok']; |
|
81
|
|
|
$result['country'] = $record->country->isoCode; |
|
82
|
|
|
// the two lines below are a dirty hack to take of the error in naming the UK federation |
|
83
|
|
|
if ($result['country'] == 'GB') { |
|
84
|
|
|
$result['country'] = 'UK'; |
|
85
|
|
|
} |
|
86
|
|
|
$result['region'] = $record->continent->name; |
|
87
|
|
|
|
|
88
|
|
|
$result['geo'] = ['lat' => (float) $record->location->latitude, 'lon' => (float) $record->location->longitude]; |
|
89
|
|
|
return($result); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
} |
|
93
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.