diff --git a/README.md b/README.md index 03c16e2c..4df452ca 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ Provides geographic information detected by an IP adress. This can be used in th * Commercial Web-API: [Maxmind GeoIP2 Precision](https://www.maxmind.com/en/geoip2-precision-services) (City, Country or Insights) * Hosting-Provider dependent: [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/200168236-What-does-CloudFlare-IP-Geolocation-do-) or [Amazon AWS CloudFront](https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/) (Country) * Free or Commercial Web-API: [Ipstack](https://ipstack.com) + * Commercial Web-API via AWS Marketplace: [Fastah](https://aws.amazon.com/marketplace/pp/prodview-k5gjowexrefl2) + * Provides these 5 functions (see [API Documentation](https://github.com/yellowtree/geoip-detect/wiki/API:-PHP)): * `geoip_detect2_get_info_from_ip($ip, $locales = array('en'), $options = array())`: Lookup Geo-Information of the specified IP * `geoip_detect2_get_info_from_current_ip($locales = array('en'), $options = array())`: Lookup Geo-Information of the current website user diff --git a/data-sources/fastah.php b/data-sources/fastah.php new file mode 100644 index 00000000..35e20213 --- /dev/null +++ b/data-sources/fastah.php @@ -0,0 +1,225 @@ +params= $params; + $this->params['language'] = reset($locales); + // TODO: Fastah API responses only support 'en' at this time + //if (empty($this->params['language'])) { + $this->params['language'] = 'en'; + //} + + $default_options = array( + 'timeout' => 1, + ); + $this->options = $options + $default_options; + } + + protected function locales($locale, $value) { + $locales = array('en' => $value); + if ($locale != 'en') { + $locales[$locale] = $value; + } + return $locales; + } + + public function city($ip) { + try { + $requestArgs = array( + 'method' => 'GET', + 'httpversion' => ($this->params['http2'] === 1) ? 2.0 : 1.1, + 'timeout' => $this->options['timeout'], + 'headers' => array( + 'Fastah-Key' => $this->params['key'] + ) + ); + $response = wp_remote_get($this->build_url($ip), $requestArgs); + $respCode = wp_remote_retrieve_response_code( $response ); + if (is_wp_error($response)) { + return _geoip_detect2_get_new_empty_record($ip, $response->get_error_message()); + } + $body = wp_remote_retrieve_body( $response ); + $data = json_decode( $body, true ); + if ($respCode !== 200) { + if ($data && isset($data['error']) && isset($data['error']['message'])) { + return _geoip_detect2_get_new_empty_record($ip, $data['error']['message']); + } + if ($data && isset($data['message'])) { + return _geoip_detect2_get_new_empty_record($ip, $data['message']); + } + } + } catch (\Exception $e) { + return _geoip_detect2_get_new_empty_record($ip, $e->getMessage()); + } + + $r = array(); + $r['extra']['original'] = $data; + + $locale = 'en'; // The REST API only support English at this time + + if (!empty($data['locationData'])) { + // Continent + $r['continent']['code'] = strtoupper($data['locationData']['continentCode']); + // Country + $r['country']['names'] = $this->locales($locale, $data['locationData']['countryName']); + $r['country']['iso_code'] = strtoupper($data['locationData']['countryCode']); + // City + $r['city']['names'] = $this->locales($locale, $data['locationData']['cityName']); + $r['city']['geoname_id'] = $data['locationData']['cityGeonamesId']; + // Lat, Lng + $r['location']['latitude'] = $data['locationData']['lat']; + $r['location']['longitude'] = $data['locationData']['lng']; + // TZ + $r['location']['time_zone'] = $data['locationData']['tz']; + } + + // EU flag + $r['country']['isInEuropeanUnion'] = $data['isEuropeanUnion']; + + $r['traits']['ip_address'] = $data['ip']; + + $record = new \GeoIp2\Model\City($r, array('en')); + + return $record; + } + + public function country($ip) { + return $this->city($ip); + } + + public function close() { + + } + + private function build_url($ip) { + $url = 'https'; + $url .= '://' . self::URL . $ip; + return $url . '?' . \http_build_query($params); + } + +} + + +class FastahSource extends AbstractDataSource { + protected $params = array(); + // PHP-Curl with functional TLS 1.2 (secure ciphers) and HTTP 1.1 are minimum requirements + protected $bestAvailHTTP = CURL_HTTP_VERSION_1_1; + + public function __construct() { + $this->params['key'] = get_option('geoip-detect-fastah_key', ''); + + // Set default by probing PHP/Curl capabilities - minimum is HTTP 1.1 over TLSv1.2 + // HTTP/2 ought to be available in PHP-Curl > v7.47.0 @see https://curl.se/docs/http2.html + if (curl_version()["features"] & CURL_HTTP_VERSION_2_0 !== 0) { + $this->bestAvailHTTP = CURL_HTTP_VERSION_2_0; + if (curl_version()["features"] & CURL_HTTP_VERSION_2TLS !== 0) { + $this->bestAvailHTTP = CURL_HTTP_VERSION_2TLS; + } + } + if ($this->bestAvailHTTP < CURL_HTTP_VERSION_2_0) { + $this->params['http2'] = get_option('geoip-detect-fastah_http2', 0); + } else { + $this->params['http2'] = get_option('geoip-detect-fastah_http2', 1); + } + } + + public function getId() { return 'fastah'; } + public function getLabel() { return __('Fastah Web API beta', 'geoip-detect'); } + + public function getDescriptionHTML() { return __('Commercial, with enterprise-friendly support and billing. Sign-up on AWS Marketplace. API Documentation', 'geoip-detect'); } + public function getStatusInformationHTML() { + $html = ''; + + $html .= \sprintf(__('HTTP2: %s', 'geoip-detect'), $this->params['http2'] ? __('Enabled', 'geoip-detect') : __('Disabled', 'geoip-detect')) . '
'; + + if (!$this->isWorking()) { + if (!is_callable('curl_init')) { + $html .= '
' . __('Fastah requires PHP-Curl for secure HTTPS requests.', 'geoip-detect') . '
'; + } else { + $html .= '
' . __('Fastah only works with an API key.', 'geoip-detect') . '
'; + } + } + + return $html; + } + + public function getParameterHTML() { + $label_key = __('API Access Key :', 'geoip-detect'); + $label_http2 = __('Use HTTP/2 :', 'geoip-detect'); + + $key = esc_attr($this->params['key']); + + $html = <<
+Sign-up for a 30-day trial key, API usage dashboard

+$label_http2 '; + + return $html; + } + + public function saveParameters($post) { + $message = ''; + + if (isset($post['options_fastah']['key'])) { + $key = sanitize_key($post['options_fastah']['key']); + update_option('geoip-detect-fastah_key', $key); + $this->params['key']= $key; + } + + if (isset($post['options_fastah']['http2'])) { + $http2 = (int) $post['options_fastah']['http2']; + update_option('geoip-detect-fastah_http2', $http2); + // Show warning if HTTP/2 requested but actually not available via PHP-Curl + if ($http2 == 1 and $this->bestAvailHTTP < CURL_HTTP_VERSION_2_0) { + $message .= __('Fastah requires PHP-Curl with HTTP/2 support.
', 'geoip-detect'); + $http2 = 0; // Turn it OFF forcefully + } + $this->params['http2'] = $http2; + } + + if (geoip_detect2_is_source_active('fastah') && !$this->isWorking()) + $message .= __('Fastah only works with an API key.', 'geoip-detect'); + + return $message; + } + + public function getReader($locales = array('en'), $options = array()) { + return new Reader($this->params, $locales, $options); + } + + public function isWorking() { + return (!empty($this->params['key']) and is_callable('curl_init')); + } + +} +geoip_detect2_register_source(new FastahSource()); diff --git a/geoip-detect.php b/geoip-detect.php index d438ed09..2090187f 100644 --- a/geoip-detect.php +++ b/geoip-detect.php @@ -92,6 +92,7 @@ include_once(GEOIP_PLUGIN_DIR . '/data-sources/precision.php'); 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'); // You can define these constants in your theme/plugin if you like. diff --git a/readme.txt b/readme.txt index 685456ba..723cd76d 100644 --- a/readme.txt +++ b/readme.txt @@ -22,6 +22,7 @@ Provides geographic information detected by an IP adress. This can be used in th * Commercial Web-API: [Maxmind GeoIP2 Precision](https://www.maxmind.com/en/geoip2-precision-services) (City, Country or Insights) * Hosting-Provider dependent: [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/200168236-What-does-CloudFlare-IP-Geolocation-do-) or [Amazon AWS CloudFront](https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/) (Country) * Free or Commercial Web-API: [Ipstack](https://ipstack.com) + * Commercial Web-API via AWS Marketplace: [Fastah](https://aws.amazon.com/marketplace/pp/prodview-k5gjowexrefl2) * Provides these 5 functions (see [API Documentation](https://github.com/yellowtree/geoip-detect/wiki/API:-PHP)): * `geoip_detect2_get_info_from_ip($ip, $locales = array('en'), $options = array())`: Lookup Geo-Information of the specified IP * `geoip_detect2_get_info_from_current_ip($locales = array('en'), $options = array())`: Lookup Geo-Information of the current website user diff --git a/tests/test-datasources.php b/tests/test-datasources.php index dcc1405c..97462907 100644 --- a/tests/test-datasources.php +++ b/tests/test-datasources.php @@ -34,7 +34,7 @@ public function testPresenceOfAllDataSources() { $source_ids = array_keys($sources); sort($source_ids); - $this->assertSame(array('auto', 'header', 'hostinfo', 'ipstack', 'manual', 'precision'), $source_ids); + $this->assertSame(array('auto', 'fastah', 'header','hostinfo', 'ipstack', 'manual', 'precision'), $source_ids); } public function testInvalidDatasources() { diff --git a/views/options.php b/views/options.php index 1f8fd99b..0c0c6a19 100644 --- a/views/options.php +++ b/views/options.php @@ -85,6 +85,9 @@ documentation for more infos). You should use a different data source or disable AJAX.', 'geoip-detect'), 'https://github.com/yellowtree/geoip-detect/wiki/JS-API-Documentation'); ?> + + documentation for more infos).', 'geoip-detect'), 'https://github.com/yellowtree/geoip-detect/wiki/JS-API-Documentation'); ?> +