File: /var/www/ojs/plugins/generic/usageStats/GeoLocationTool.inc.php
<?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');
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] = 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;
}
}