Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 41 additions & 72 deletions GeoLocationTool.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
* @brief Geo location by ip wrapper class.
*/

/** GeoIp tool for geo location based on ip */
include('lib' . DIRECTORY_SEPARATOR . 'geoIp' . DIRECTORY_SEPARATOR . 'geoipcity.inc');
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

class GeoLocationTool {

Expand All @@ -30,10 +30,10 @@ class GeoLocationTool {
* Use the method isPresent() to check if the database file is present before use.
*/
function __construct() {
$geoLocationDbFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . "GeoLiteCity.dat";
$geoLocationDbFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . "GeoLite2-City.mmdb";
if (file_exists($geoLocationDbFile)) {
$isDbFilePresent = true;
$this->_geoLocationTool = geoip_open($geoLocationDbFile, GEOIP_STANDARD);
$this->_geoLocationTool = new Reader($geoLocationDbFile);
include('lib' . DIRECTORY_SEPARATOR . 'geoIp' . DIRECTORY_SEPARATOR . 'geoipregionvars.php');
$this->_regionName = $GEOIP_REGION_NAME;
} else {
Expand Down Expand Up @@ -64,21 +64,19 @@ 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) {
try {
$record = $this->_geoLocationTool->city($ip);
} catch (GeoIp2\Exception\AddressNotFoundException $e) {
return array(null, null, null);
}

$regionName = null;
if(isset($this->_regionName[$record->country_code][$record->region])) {
$regionName = $this->_regionName[$record->country_code][$record->region];
}

$regionIsoCode = $record->mostSpecificSubdivision->isoCode;
if (strlen($regionIsoCode) > 2) $regionIsoCode = '';

return array(
$record->country_code,
utf8_encode($record->city),
$record->region
$record->country->isoCode,
utf8_encode($record->city->name),
$regionIsoCode
);
}

Expand All @@ -89,34 +87,41 @@ function getGeoLocation($ip) {
function getAllCountryCodes() {
if (!$this->_geoLocationTool) return null;

$tool = $this->_geoLocationTool;
$countryCodes = $tool->GEOIP_COUNTRY_CODES;
$countryCodes = array(
"","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW",
"AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
"BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
"BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
"CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
"CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
"DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
"FK","FM","FO","FR","SX","GA","GB","GD","GE","GF",
"GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
"GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
"IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
"JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
"KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
"LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
"MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
"MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
"NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
"PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
"PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
"SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
"SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
"TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
"TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
"VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
"ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE",
"BL","MF", "BQ"
);

// Overwrite the first empty record with the code to
// unknow country.
$countryCodes[0] = 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.
Expand All @@ -132,41 +137,5 @@ function getRegions($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;
}
}

46 changes: 32 additions & 14 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,41 @@ The only needed additional step depends on whether you want to have geo
location data in your statistics or not. If that's the case, follow these
steps:

Linux:
1 - open a shell prompt
2 - go into OJS i.e. OMP installation’s base directory
2 - wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
3 - gunzip GeoLiteCity.dat.gz
4 - mv GeoLiteCity.dat plugins/generic/usageStats

Windows
1 - download the file http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
2 - decompress it using any decompression tool into plugins/generic/usageStats directory
Signup for Geolite2 Free Geolocation Data

1 - You will need a free GeoLite2 account to download the GeoLite2 databases.
For signing up, follow the instructions at
https://dev.maxmind.com/geoip/geolite2-free-geolocation-data#accessing-geolite2-free-geolocation-data
2 - For Linux, it is recommended to generate a license key, which can be used to automate
Geolite2 binary database downloads with the geoipupdate program

Linux
1 - Let your Linux administrator install the geoipupdate program using package manager of
your Linux distribution. The geoipupdate program is usually stored in /usr/bin/geoipupdate
2 - open a shell prompt
3 - create a directory geoip outside of your OJS i.e. OMP installation’s base directory
4 - obtain the GeoIP.conf file with your license key according to
https://dev.maxmind.com/geoip/updating-databases/#2-obtain-geoipconf-with-account-information
and store it in your geoip directory created in step 4
5 - give {ojs_root}/plugins/generic/usageStats write access for the apache user, e.g.
chmod g+w {ojs_root}/plugins/generic/usageStats
6 - /usr/bin/geoipupdate -v -f {geoip_directory}/GeoIP.conf -d {ojs_root}/plugins/generic/usageStats
This downloads the GeoLite2-ASN.mmdb, GeoLite2-City.mmdb and GeoLite2-Country.mmdb databases
to your plugins/generic/usageStats directory
7 - You may automate monthly updates of your Geolite2 databases using a cronjob. Add an entry to the
cron table like this:
# Download GeoIP2 databases every month
30 7 1 * * /usr/bin/geoipupdate -v -f {geoip_directory}/GeoIP.conf -d {ojs_root}/plugins/generic/usageStats
In order that this works, give the apache user write permissions for the following files:
{ojs_root}/plugins/generic/usageStats/.geoipupdate.lock
{ojs_root}/plugins/generic/usageStats/GeoLite2-ASN.mmdb
{ojs_root}/plugins/generic/usageStats/GeoLite2-City.mmdb
{ojs_root}/plugins/generic/usageStats/GeoLite2-Country.mmdb

In both cases the complete path to the installed database file should be
plugins/generic/usageStats/GeoLiteCity.dat

Note, that a separate license agreement is required for this use of this database.
For details, see:
https://dev.maxmind.com/geoip/legacy/geolite/
Windows
(add steps here)


Management
Expand Down
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"require": {
"geoip2/geoip2": "~2.0"
}
}
Loading