class-wc-integration-maxmind-database-service.php
4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
<?php
/**
* The database service class file.
*
* @version 3.9.0
* @package WooCommerce\Integrations
*/
defined( 'ABSPATH' ) || exit;
/**
* The service class responsible for interacting with MaxMind databases.
*
* @since 3.9.0
*/
class WC_Integration_MaxMind_Database_Service {
/**
* The name of the MaxMind database to utilize.
*/
const DATABASE = 'GeoLite2-Country';
/**
* The extension for the MaxMind database.
*/
const DATABASE_EXTENSION = '.mmdb';
/**
* A prefix for the MaxMind database filename.
*
* @var string
*/
private $database_prefix;
/**
* WC_Integration_MaxMind_Database_Service constructor.
*
* @param string|null $database_prefix A prefix for the MaxMind database filename.
*/
public function __construct( $database_prefix ) {
$this->database_prefix = $database_prefix;
}
/**
* Fetches the path that the database should be stored.
*
* @return string The local database path.
*/
public function get_database_path() {
$uploads_dir = wp_upload_dir();
$database_path = trailingslashit( $uploads_dir['basedir'] ) . 'woocommerce_uploads/';
if ( ! empty( $this->database_prefix ) ) {
$database_path .= $this->database_prefix . '-';
}
$database_path .= self::DATABASE . self::DATABASE_EXTENSION;
/**
* Filter the geolocation database storage path.
*
* @param string $database_path The path to the database.
* @param int $version Deprecated since 3.4.0.
* @deprecated 3.9.0
*/
$database_path = apply_filters_deprecated(
'woocommerce_geolocation_local_database_path',
array( $database_path, 2 ),
'3.9.0',
'woocommerce_maxmind_geolocation_database_path'
);
/**
* Filter the geolocation database storage path.
*
* @since 3.9.0
* @param string $database_path The path to the database.
*/
return apply_filters( 'woocommerce_maxmind_geolocation_database_path', $database_path );
}
/**
* Fetches the database from the MaxMind service.
*
* @param string $license_key The license key to be used when downloading the database.
* @return string|WP_Error The path to the database file or an error if invalid.
*/
public function download_database( $license_key ) {
$download_uri = add_query_arg(
array(
'edition_id' => self::DATABASE,
'license_key' => urlencode( wc_clean( $license_key ) ),
'suffix' => 'tar.gz',
),
'https://download.maxmind.com/app/geoip_download'
);
// Needed for the download_url call right below.
require_once ABSPATH . 'wp-admin/includes/file.php';
$tmp_archive_path = download_url( esc_url_raw( $download_uri ) );
if ( is_wp_error( $tmp_archive_path ) ) {
// Transform the error into something more informative.
$error_data = $tmp_archive_path->get_error_data();
if ( isset( $error_data['code'] ) ) {
switch ( $error_data['code'] ) {
case 401:
return new WP_Error(
'woocommerce_maxmind_geolocation_database_license_key',
__( 'The MaxMind license key is invalid. If you have recently created this key, you may need to wait for it to become active.', 'woocommerce' )
);
}
}
return new WP_Error( 'woocommerce_maxmind_geolocation_database_download', __( 'Failed to download the MaxMind database.', 'woocommerce' ) );
}
// Extract the database from the archive.
try {
$file = new PharData( $tmp_archive_path );
$tmp_database_path = trailingslashit( dirname( $tmp_archive_path ) ) . trailingslashit( $file->current()->getFilename() ) . self::DATABASE . self::DATABASE_EXTENSION;
$file->extractTo(
dirname( $tmp_archive_path ),
trailingslashit( $file->current()->getFilename() ) . self::DATABASE . self::DATABASE_EXTENSION,
true
);
} catch ( Exception $exception ) {
return new WP_Error( 'woocommerce_maxmind_geolocation_database_archive', $exception->getMessage() );
} finally {
// Remove the archive since we only care about a single file in it.
unlink( $tmp_archive_path );
}
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 The country code for the IP address, or empty if not found.
*/
public function get_iso_country_code_for_ip( $ip_address ) {
$country_code = '';
if ( ! class_exists( 'MaxMind\Db\Reader' ) ) {
wc_get_logger()->notice( __( 'Missing MaxMind Reader library!', 'woocommerce' ), array( 'source' => 'maxmind-geolocation' ) );
return $country_code;
}
$database_path = $this->get_database_path();
if ( ! file_exists( $database_path ) ) {
return $country_code;
}
try {
$reader = new MaxMind\Db\Reader( $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;
}
}