Moved the MaxMind geolocation lookup into the integration class

This commit is contained in:
Christopher Allford 2020-01-09 23:46:25 -08:00
parent 02ee3f695e
commit bbbfc3bfab
5 changed files with 48 additions and 66 deletions

View File

@ -8,6 +8,7 @@
*
* @package WooCommerce\Classes
* @since 3.4.0
* @deprecated 3.9.0
*/
defined( 'ABSPATH' ) || exit;

View File

@ -151,11 +151,8 @@ class WC_Geolocation {
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) ); // WPCS: input var ok, CSRF ok.
} else {
$ip_address = $ip_address ? $ip_address : self::get_ip_address();
$database = WC_Integration_MaxMind_Geolocation_Database::get_database_path();
if ( file_exists( $database ) ) {
$country_code = self::geolocate_via_db( $ip_address, $database );
} elseif ( $api_fallback ) {
if ( $api_fallback ) {
$country_code = self::geolocate_via_api( $ip_address );
} else {
$country_code = '';
@ -197,23 +194,6 @@ class WC_Geolocation {
WC_Integration_MaxMind_Geolocation::update_database();
}
/**
* Use MAXMIND GeoLite database to geolocation the user.
*
* @param string $ip_address IP address.
* @param string $database Database path.
* @return string
*/
private static function geolocate_via_db( $ip_address, $database ) {
if ( ! class_exists( 'WC_Geolite_Integration', false ) ) {
require_once WC_ABSPATH . 'includes/class-wc-geolite-integration.php';
}
$geolite = new WC_Geolite_Integration( $database );
return $geolite->get_country_iso( $ip_address );
}
/**
* Use APIs to Geolocate the user.
*

View File

@ -11,7 +11,7 @@ defined( 'ABSPATH' ) || exit;
/**
* WC Integration MaxMind Geolocation Database
*
* @version 3.9.0
* @since 3.9.0
*/
class WC_Integration_MaxMind_Geolocation_Database {
@ -112,4 +112,29 @@ class WC_Integration_MaxMind_Geolocation_Database {
return $tmp_database_path;
}
/**
* Fetches the ISO country code associated with an IP address.
*
* @param string $ip_address The IP address to find the country code for.
* @return string|null The country code for the IP address, or null if none was found.
*/
public static function get_iso_country_code_for_ip( $ip_address ) {
$country_code = null;
try {
$reader = new MaxMind\Db\Reader( self::get_database_path() );
$data = $reader->get( $ip_address );
if ( isset( $data['country']['iso_code'] ) ) {
$country_code = $data['country']['iso_code'];
}
$reader->close();
} catch ( Exception $e ) {
wc_get_logger()->notice( $e->getMessage(), array( 'source' => 'maxmind-geolocation' ) );
}
return $country_code;
}
}

View File

@ -13,7 +13,7 @@ require_once 'class-wc-integration-maxmind-geolocation-database.php';
/**
* WC Integration MaxMind Geolocation
*
* @version 3.9.0
* @since 3.9.0
*/
class WC_Integration_MaxMind_Geolocation extends WC_Integration {
@ -49,6 +49,9 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
if ( $bind_updater ) {
add_action( 'woocommerce_geoip_updater', array( __CLASS__, 'update_database' ) );
}
// Bind to the geolocation filter for MaxMind database lookups.
add_filter( 'woocommerce_geolocate_ip', array( $this, 'geolocate_ip' ), 10, 2 );
}
/**
@ -110,8 +113,6 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
* @param string|null $new_database_path The path to the new database file. Null will fetch a new archive.
*/
public static function update_database( $new_database_path = null ) {
$logger = wc_get_logger();
// Allow us to easily interact with the filesystem.
require_once ABSPATH . 'wp-admin/includes/file.php';
WP_Filesystem();
@ -134,7 +135,7 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
$tmp_database_path = WC_Integration_MaxMind_Geolocation_Database::download_database( $license_key );
if ( is_wp_error( $tmp_database_path ) ) {
$logger->notice( $tmp_database_path->get_error_message(), array( 'source' => 'geolocation' ) );
wc_get_logger()->notice( $tmp_database_path->get_error_message(), array( 'source' => 'maxmind-geolocation' ) );
return;
}
}
@ -143,4 +144,19 @@ class WC_Integration_MaxMind_Geolocation extends WC_Integration {
$wp_filesystem->move( $tmp_database_path, $target_database_path, true );
$wp_filesystem->delete( dirname( $tmp_database_path ) );
}
/**
* Performs a geolocation lookup against the MaxMind database for the given IP address.
*
* @param string $country_code The country code for the IP address.
* @param string $ip_address The IP address to geolocate.
* @return string The country code for the IP address.
*/
public function geolocate_ip( $country_code, $ip_address ) {
if ( false !== $country_code ) {
return $country_code;
}
return WC_Integration_MaxMind_Geolocation_Database::get_iso_country_code_for_ip( $ip_address );
}
}

View File

@ -1,40 +0,0 @@
<?php
/**
* Class Functions.
*
* @package WooCommerce\Tests\Geolocation
*/
/**
* Class WC_Tests_Integrations
*/
class WC_Tests_Geolite_Integration extends WC_Unit_Test_Case {
/**
* Test get country ISO.
*
* @requires PHP 5.4
*/
public function test_get_country_iso() {
require_once dirname( WC_PLUGIN_FILE ) . '/includes/class-wc-geolite-integration.php';
// Download GeoLite2 database.
WC_Geolocation::update_database();
// OpenDNS IP address.
$ipv4 = '208.67.220.220';
$ipv6 = '2620:0:ccc::2';
// Init GeoLite.
$geolite = new WC_Geolite_Integration( WC_Geolocation::get_local_database_path() );
// Check for IPv4.
$this->assertEquals( 'US', $geolite->get_country_iso( $ipv4 ) );
// Check for IPv6.
$this->assertEquals( 'US', $geolite->get_country_iso( $ipv6 ) );
// Check for non-valid IP.
$this->assertEquals( '', $geolite->get_country_iso( 'foobar' ) );
}
}