From a8f10210a3789f57338e52e033c2398ba78a8652 Mon Sep 17 00:00:00 2001 From: IP2Location Date: Wed, 20 Dec 2023 07:42:06 +0800 Subject: [PATCH 1/2] Update geoip-detect.php Add ip2location.io data source --- geoip-detect.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/geoip-detect.php b/geoip-detect.php index 24756b36..8c01011e 100644 --- a/geoip-detect.php +++ b/geoip-detect.php @@ -94,6 +94,7 @@ include_once(GEOIP_PLUGIN_DIR . '/data-sources/header.php'); include_once(GEOIP_PLUGIN_DIR . '/data-sources/ipstack.php'); include_once(GEOIP_PLUGIN_DIR . '/data-sources/fastah.php'); +include_once(GEOIP_PLUGIN_DIR . '/data-sources/ip2locationio.php'); // You can define these constants in your theme/plugin if you like. @@ -121,13 +122,13 @@ //define('GEOIP_DETECT_READER_CACHE_TIME', 7 * DAY_IN_SECONDS); /** - * AJAX mode: + * AJAX mode: * If you want to reduce the filesize of the used JS file, consider using a JS file variant: - * + * * - full: All features (default) * - base: Only get_info, no shortcodes, no body_class, no overrides ... * - minimal: base, but without the Record class (get_info is returning raw json data instead) - * + * */ //define('GEOIP_DETECT_JS_VARIANT', 'full'); From 60a59c39897c300fa9b17c8517f5415c904984d7 Mon Sep 17 00:00:00 2001 From: IP2Location Date: Wed, 20 Dec 2023 07:42:47 +0800 Subject: [PATCH 2/2] Create ip2locationio.php Add ip2location.io data source --- data-sources/ip2locationio.php | 223 +++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 data-sources/ip2locationio.php diff --git a/data-sources/ip2locationio.php b/data-sources/ip2locationio.php new file mode 100644 index 00000000..be0eeacc --- /dev/null +++ b/data-sources/ip2locationio.php @@ -0,0 +1,223 @@ +params = $params; + $this->params['language'] = reset($locales); + if (empty($this->params['language'])) { + $this->params['language'] = 'en'; + } + + $default_options = [ + 'timeout' => 1, + ]; + $this->options = $options + $default_options; + } + + protected function locales($locale, $value) + { + $locales = ['en' => $value]; + if ($locale != 'en') { + $locales[$locale] = $value; + } + + return $locales; + } + + public function city($ip) + { + $data = $this->api_call($ip); + + if (!$data) { + return _geoip_detect2_get_new_empty_record(); + } + + $r = []; + + $r['extra']['original'] = $data; + + if (isset($data['error']['error_message'])) { + throw new \RuntimeException($data['error']['error_message']); + // Example error: + /* @see https://www.ip2location.io/ip2location-documentation + { + "error":{ + "error_code":10000, + "error_message":"Invalid API key or insufficient credit." + } + } + */ + } + + $locale = $this->params['language']; + + if (!empty($data['country_name'])) { + $r['country']['names'] = $this->locales($locale, $data['country_name']); + } + if (!empty($data['country_code'])) { + $r['country']['iso_code'] = strtoupper($data['country_code']); + } + if (!empty($data['region_name'])) { + $r['subdivisions'][0] = [ + 'iso_code' => '', + 'names' => $this->locales($locale, $data['region_name']), + ]; + } + if (!empty($data['city_name'])) { + $r['city']['names'] = $this->locales($locale, $data['city_name']); + } + if (!empty($data['latitude'])) { + $r['location']['latitude'] = $data['latitude']; + } + if (!empty($data['longitude'])) { + $r['location']['longitude'] = $data['longitude']; + } + if (isset($data['asn'])) { + $r['traits']['autonomous_system_number'] = $data['asn']; + } + if (isset($data['as'])) { + $r['traits']['isp'] = $data['as']; + } + if (!empty($data['is_proxy'])) { + $r['traits']['is_anonymous_vpn'] = $data['is_proxy']; + } + + $r['traits']['ip_address'] = $ip; + + $record = new \GeoIp2\Model\City($r, ['en']); + + return $record; + } + + public function country($ip) + { + return $this->city($ip); // too much info shouldn't hurt ... + } + + public function close() + { + } + + private function build_url($ip) + { + $url = 'https://' . self::URL . $ip; + + $params = [ + 'key' => $this->params['key'], + ]; + + return $url . '?' . \http_build_query($params); + } + + private function api_call($ip) + { + try { + // Setting timeout limit to speed up sites + $context = stream_context_create( + [ + 'http' => [ + 'timeout' => $this->options['timeout'], + ], + ] + ); + // Using @file... to supress errors + // Example output: {"country_name":"UNITED STATES","country_code":"US","city":"Aurora, TX","ip":"12.215.42.19"} + + $body = @file_get_contents($this->build_url($ip), false, $context); + $data = json_decode($body, true); + + return $data; + } catch (\Exception $e) { + // If the API isn't available, we have to do this + throw $e; + + return null; + } + } +} + +class Ip2LocationIoSource extends AbstractDataSource +{ + protected $params = []; + + public function __construct() + { + $this->params['key'] = get_option('geoip-detect-ip2locationio_key', ''); + } + + public function getId() + { + return 'ip2locationio'; + } + + public function getLabel() + { + return __('IP2Location.io Geolocation API Service', 'geoip-detect'); + } + + public function getDescriptionHTML() + { + return __('Free 30,000 queries per month. Register API key as IP2Location.io.', 'geoip-detect'); + } + + public function getStatusInformationHTML() + { + $html = ''; + + if (!$this->isWorking()) { + $html .= '
' . __('IP2Location.io only works with an API key.', 'geoip-detect') . '
'; + } + + return $html; + } + + public function getParameterHTML() + { + $label_key = __('API Key:', 'geoip-detect'); + $key = esc_attr($this->params['key']); + + $html = <<
+HTML; + + return $html; + } + + public function saveParameters($post) + { + $message = ''; + + if (isset($post['options_ip2locationio']['key'])) { + $key = sanitize_key($post['options_ip2locationio']['key']); + update_option('geoip-detect-ip2locationio_key', $key); + $this->params['key'] = $key; + } + + if (geoip_detect2_is_source_active('ip2locationio') && !$this->isWorking()) { + $message .= __('IP2Location.io only works with an API key.', 'geoip-detect'); + } + + return $message; + } + + public function getReader($locales = ['en'], $options = []) + { + return new Reader($this->params, $locales, $options); + } + + public function isWorking() + { + return !empty($this->params['key']); + } +} +geoip_detect2_register_source(new Ip2LocationIoSource());