forked from pkp/usageStats
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGeoLocationTool.inc.php
174 lines (144 loc) · 4.26 KB
/
GeoLocationTool.inc.php
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<?php
/**
* @file plugins/generic/usageStats/GeoLocationTool.php
*
* Copyright (c) 2013-2020 Simon Fraser University
* Copyright (c) 2003-2020 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class GeoLocationTool
* @ingroup plugins_generic_usageStats
*
* @brief Geo location by ip wrapper class.
*/
/** GeoIp tool for geo location based on ip */
include('lib' . DIRECTORY_SEPARATOR . 'geoIp' . DIRECTORY_SEPARATOR . 'geoipcity.inc');
use PKP\statistics\PKPStatisticsHelper;
class GeoLocationTool {
var $_geoLocationTool;
var $_regionName;
var $_isDbFilePresent;
/**
* Constructor.
* If we cannot find the database file, an empty object will be constructed.
* Use the method isPresent() to check if the database file is present before use.
*/
function __construct() {
$geoLocationDbFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . "GeoLiteCity.dat";
if (file_exists($geoLocationDbFile)) {
$isDbFilePresent = true;
$this->_geoLocationTool = geoip_open($geoLocationDbFile, GEOIP_STANDARD);
include('lib' . DIRECTORY_SEPARATOR . 'geoIp' . DIRECTORY_SEPARATOR . 'geoipregionvars.php');
$this->_regionName = $GEOIP_REGION_NAME;
} else {
$isDbFilePresent = false;
}
$this->_isDbFilePresent = $isDbFilePresent;
}
//
// Public methods.
//
/**
* Identify if the geolocation database tool is available for use.
* @return boolean
*/
function isPresent() {
return $this->_isDbFilePresent;
}
/**
* Return country code and city name for the passed
* ip address.
* @param $ip string
* @return array
*/
function getGeoLocation($ip) {
// If no geolocation tool, the geo database file is missing.
if (!$this->_geoLocationTool) return array(null, null, null);
$record = geoip_record_by_addr($this->_geoLocationTool, $ip);
if (!$record) {
return array(null, null, null);
}
$regionName = null;
if(isset($this->_regionName[$record->country_code][$record->region])) {
$regionName = $this->_regionName[$record->country_code][$record->region];
}
return array(
$record->country_code,
utf8_encode($record->city),
$record->region
);
}
/**
* Get all country codes.
* @return mixed array or null
*/
function getAllCountryCodes() {
if (!$this->_geoLocationTool) return null;
$tool = $this->_geoLocationTool;
$countryCodes = $tool->GEOIP_COUNTRY_CODES;
// Overwrite the first empty record with the code to
// unknow country.
$countryCodes[0] = PKPStatisticsHelper::STATISTICS_UNKNOWN_COUNTRY_ID;
return $countryCodes;
}
/**
* Return the 3 letters version of country codes
* based on the passed 2 letters version.
* @param $countryCode string
* @return mixed string or null
*/
function get3LettersCountryCode($countryCode) {
return $this->_getCountryCodeOnList($countryCode, 'GEOIP_COUNTRY_CODES3');
}
/**
* Return the 2 letter version of country codes
* based on the passed 3 letters version.
* @param $countryCode3 string
* @return mixed string or null
*/
function get2LettersCountryCode($countryCode3) {
return $this->_getCountryCodeOnList($countryCode3, 'GEOIP_COUNTRY_CODES');
}
/**
* Get regions by country.
* @param $countryId int
* @return array
*/
function getRegions($countryId) {
$regions = array();
$database = $this->_regionName;
if (isset($database[$countryId])) {
$regions = $database[$countryId];
}
return $regions;
}
/**
* Get the passed country code inside the passed
* list.
* @param $countryCode The 2 letters country code.
* @param $countryCodeList array Any geoip country
* code list.
* @return mixed String or null.
*/
function _getCountryCodeOnList($countryCode, $countryCodeListName) {
$returner = null;
if (!$this->_geoLocationTool) return $returner;
$tool = $this->_geoLocationTool;
if (isset($tool->$countryCodeListName)) {
$countryCodeList = $tool->$countryCodeListName;
} else {
return $returner;
}
$countryCodesIndex = $tool->GEOIP_COUNTRY_CODE_TO_NUMBER;
$countryCodeIndex = null;
if (isset($countryCodesIndex[$countryCode])) {
$countryCodeIndex = $countryCodesIndex[$countryCode];
}
if ($countryCodeIndex) {
if (isset($countryCodeList[$countryCodeIndex])) {
$returner = $countryCodeList[$countryCodeIndex];
}
}
return $returner;
}
}