PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.4
WooCommerce v10.9.4
10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / class-wc-geo-ip.php
woocommerce / includes Last commit date
abstracts 1 month ago admin 6 days ago blocks 11 months ago cli 1 month ago customizer 4 months ago data-stores 1 month ago emails 5 days ago export 1 year ago gateways 1 month ago import 3 months ago integrations 2 months ago interfaces 4 months ago legacy 4 months ago libraries 1 month ago log-handlers 1 year ago payment-tokens 5 years ago product-usage 1 year ago queue 4 months ago react-admin 1 month ago rest-api 1 month ago shipping 3 months ago shortcodes 1 month ago theme-support 2 years ago tracks 1 month ago traits 5 years ago walkers 5 years ago wccom-site 1 month ago widgets 2 months ago class-wc-ajax.php 1 month ago class-wc-auth.php 1 year ago class-wc-autoloader.php 9 months ago class-wc-background-emailer.php 2 months ago class-wc-background-updater.php 5 years ago class-wc-brands-brand-settings-manager.php 1 year ago class-wc-brands-coupons.php 1 year ago class-wc-brands.php 1 month ago class-wc-breadcrumb.php 4 months ago class-wc-cache-helper.php 1 month ago class-wc-cart-fees.php 2 years ago class-wc-cart-session.php 3 months ago class-wc-cart-totals.php 11 months ago class-wc-cart.php 1 month ago class-wc-checkout.php 1 month ago class-wc-cli.php 10 months ago class-wc-comments.php 4 months ago class-wc-countries.php 2 months ago class-wc-coupon.php 2 months ago class-wc-customer-download-log.php 5 years ago class-wc-customer-download.php 1 year ago class-wc-customer.php 1 day ago class-wc-data-exception.php 8 years ago class-wc-data-store.php 3 years ago class-wc-datetime.php 4 years ago class-wc-deprecated-action-hooks.php 2 years ago class-wc-deprecated-filter-hooks.php 3 months ago class-wc-discounts.php 11 months ago class-wc-download-handler.php 1 month ago class-wc-emails.php 1 month ago class-wc-embed.php 1 year ago class-wc-form-handler.php 3 months ago class-wc-frontend-scripts.php 2 months ago class-wc-geo-ip.php 9 months ago class-wc-geolite-integration.php 6 years ago class-wc-geolocation.php 2 months ago class-wc-https.php 3 years ago class-wc-install.php 6 days ago class-wc-integrations.php 5 years ago class-wc-log-levels.php 2 years ago class-wc-logger.php 4 months ago class-wc-meta-data.php 1 month ago class-wc-order-factory.php 2 months ago class-wc-order-item-coupon.php 4 years ago class-wc-order-item-fee.php 5 months ago class-wc-order-item-meta.php 4 years ago class-wc-order-item-product.php 1 month ago class-wc-order-item-shipping.php 5 months ago class-wc-order-item-tax.php 1 month ago class-wc-order-item.php 1 month ago class-wc-order-query.php 1 month ago class-wc-order-refund.php 1 year ago class-wc-order.php 1 month ago class-wc-payment-gateways.php 1 month ago class-wc-payment-tokens.php 3 years ago class-wc-post-data.php 2 months ago class-wc-post-types.php 1 month ago class-wc-privacy-background-process.php 1 year ago class-wc-privacy-erasers.php 10 months ago class-wc-privacy-exporters.php 4 years ago class-wc-privacy.php 1 year ago class-wc-product-attribute.php 4 months ago class-wc-product-download.php 4 months ago class-wc-product-external.php 1 year ago class-wc-product-factory.php 3 months ago class-wc-product-grouped.php 3 months ago class-wc-product-query.php 4 months ago class-wc-product-simple.php 11 months ago class-wc-product-variable.php 1 month ago class-wc-product-variation.php 1 month ago class-wc-query.php 1 month ago class-wc-rate-limiter.php 4 years ago class-wc-regenerate-images-request.php 3 years ago class-wc-regenerate-images.php 2 years ago class-wc-register-wp-admin-settings.php 5 years ago class-wc-rest-authentication.php 2 years ago class-wc-rest-exception.php 5 years ago class-wc-session-handler.php 3 months ago class-wc-shipping-rate.php 1 year ago class-wc-shipping-zone.php 5 years ago class-wc-shipping-zones.php 7 months ago class-wc-shipping.php 2 months ago class-wc-shortcodes.php 1 year ago class-wc-structured-data.php 1 month ago class-wc-tax.php 2 months ago class-wc-template-loader.php 7 months ago class-wc-tracker.php 1 month ago class-wc-validation.php 2 years ago class-wc-webhook.php 1 month ago class-woocommerce.php 1 day ago wc-account-functions.php 1 month ago wc-attribute-functions.php 1 month ago wc-brands-functions.php 1 year ago wc-cart-functions.php 1 month ago wc-conditional-functions.php 11 months ago wc-core-functions.php 2 months ago wc-coupon-functions.php 5 months ago wc-deprecated-functions.php 1 month ago wc-formatting-functions.php 1 month ago wc-interactivity-api-functions.php 2 months ago wc-notice-functions.php 5 months ago wc-order-functions.php 1 month ago wc-order-item-functions.php 3 years ago wc-order-step-logger-functions.php 4 months ago wc-page-functions.php 1 month ago wc-product-functions.php 2 months ago wc-rest-functions.php 7 months ago wc-stock-functions.php 7 months ago wc-template-functions.php 1 month ago wc-template-hooks.php 10 months ago wc-term-functions.php 2 months ago wc-update-functions.php 6 days ago wc-user-functions.php 1 month ago wc-webhook-functions.php 1 month ago wc-widget-functions.php 5 years ago
class-wc-geo-ip.php
1817 lines
1 <?php
2 /**
3 * Geo IP class
4 *
5 * This class is a fork of GeoIP class from MaxMind LLC.
6 *
7 * @package WooCommerce\Classes
8 * @version 2.4.0
9 * @deprecated 3.4.0
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 /**
17 * WC_Geo_IP Class.
18 *
19 * @deprecated 3.4.0
20 */
21 class WC_Geo_IP {
22
23 const GEOIP_COUNTRY_BEGIN = 16776960;
24 const GEOIP_STATE_BEGIN_REV0 = 16700000;
25 const GEOIP_STATE_BEGIN_REV1 = 16000000;
26 const GEOIP_MEMORY_CACHE = 1;
27 const GEOIP_SHARED_MEMORY = 2;
28 const STRUCTURE_INFO_MAX_SIZE = 20;
29 const GEOIP_COUNTRY_EDITION = 1;
30 const GEOIP_PROXY_EDITION = 8;
31 const GEOIP_ASNUM_EDITION = 9;
32 const GEOIP_NETSPEED_EDITION = 10;
33 const GEOIP_REGION_EDITION_REV0 = 7;
34 const GEOIP_REGION_EDITION_REV1 = 3;
35 const GEOIP_CITY_EDITION_REV0 = 6;
36 const GEOIP_CITY_EDITION_REV1 = 2;
37 const GEOIP_ORG_EDITION = 5;
38 const GEOIP_ISP_EDITION = 4;
39 const SEGMENT_RECORD_LENGTH = 3;
40 const STANDARD_RECORD_LENGTH = 3;
41 const ORG_RECORD_LENGTH = 4;
42 const GEOIP_SHM_KEY = 0x4f415401;
43 const GEOIP_DOMAIN_EDITION = 11;
44 const GEOIP_COUNTRY_EDITION_V6 = 12;
45 const GEOIP_LOCATIONA_EDITION = 13;
46 const GEOIP_ACCURACYRADIUS_EDITION = 14;
47 const GEOIP_CITY_EDITION_REV1_V6 = 30;
48 const GEOIP_CITY_EDITION_REV0_V6 = 31;
49 const GEOIP_NETSPEED_EDITION_REV1 = 32;
50 const GEOIP_NETSPEED_EDITION_REV1_V6 = 33;
51 const GEOIP_USERTYPE_EDITION = 28;
52 const GEOIP_USERTYPE_EDITION_V6 = 29;
53 const GEOIP_ASNUM_EDITION_V6 = 21;
54 const GEOIP_ISP_EDITION_V6 = 22;
55 const GEOIP_ORG_EDITION_V6 = 23;
56 const GEOIP_DOMAIN_EDITION_V6 = 24;
57
58 /**
59 * Flags.
60 *
61 * @var int
62 */
63 public $flags;
64
65 /**
66 * File handler.
67 *
68 * @var resource
69 */
70 public $filehandle;
71
72 /**
73 * Memory buffer.
74 *
75 * @var string
76 */
77 public $memory_buffer;
78
79 /**
80 * Database type.
81 *
82 * @var int
83 */
84 public $databaseType;
85
86 /**
87 * Database segments.
88 *
89 * @var int
90 */
91 public $databaseSegments;
92
93 /**
94 * Record length.
95 *
96 * @var int
97 */
98 public $record_length;
99
100 /**
101 * Shmid.
102 *
103 * @var string
104 */
105 public $shmid;
106
107 /**
108 * Two letters country codes.
109 *
110 * @var array
111 */
112 public $GEOIP_COUNTRY_CODES = array(
113 '',
114 'AP',
115 'EU',
116 'AD',
117 'AE',
118 'AF',
119 'AG',
120 'AI',
121 'AL',
122 'AM',
123 'CW',
124 'AO',
125 'AQ',
126 'AR',
127 'AS',
128 'AT',
129 'AU',
130 'AW',
131 'AZ',
132 'BA',
133 'BB',
134 'BD',
135 'BE',
136 'BF',
137 'BG',
138 'BH',
139 'BI',
140 'BJ',
141 'BM',
142 'BN',
143 'BO',
144 'BR',
145 'BS',
146 'BT',
147 'BV',
148 'BW',
149 'BY',
150 'BZ',
151 'CA',
152 'CC',
153 'CD',
154 'CF',
155 'CG',
156 'CH',
157 'CI',
158 'CK',
159 'CL',
160 'CM',
161 'CN',
162 'CO',
163 'CR',
164 'CU',
165 'CV',
166 'CX',
167 'CY',
168 'CZ',
169 'DE',
170 'DJ',
171 'DK',
172 'DM',
173 'DO',
174 'DZ',
175 'EC',
176 'EE',
177 'EG',
178 'EH',
179 'ER',
180 'ES',
181 'ET',
182 'FI',
183 'FJ',
184 'FK',
185 'FM',
186 'FO',
187 'FR',
188 'SX',
189 'GA',
190 'GB',
191 'GD',
192 'GE',
193 'GF',
194 'GH',
195 'GI',
196 'GL',
197 'GM',
198 'GN',
199 'GP',
200 'GQ',
201 'GR',
202 'GS',
203 'GT',
204 'GU',
205 'GW',
206 'GY',
207 'HK',
208 'HM',
209 'HN',
210 'HR',
211 'HT',
212 'HU',
213 'ID',
214 'IE',
215 'IL',
216 'IN',
217 'IO',
218 'IQ',
219 'IR',
220 'IS',
221 'IT',
222 'JM',
223 'JO',
224 'JP',
225 'KE',
226 'KG',
227 'KH',
228 'KI',
229 'KM',
230 'KN',
231 'KP',
232 'KR',
233 'KW',
234 'KY',
235 'KZ',
236 'LA',
237 'LB',
238 'LC',
239 'LI',
240 'LK',
241 'LR',
242 'LS',
243 'LT',
244 'LU',
245 'LV',
246 'LY',
247 'MA',
248 'MC',
249 'MD',
250 'MG',
251 'MH',
252 'MK',
253 'ML',
254 'MM',
255 'MN',
256 'MO',
257 'MP',
258 'MQ',
259 'MR',
260 'MS',
261 'MT',
262 'MU',
263 'MV',
264 'MW',
265 'MX',
266 'MY',
267 'MZ',
268 'NA',
269 'NC',
270 'NE',
271 'NF',
272 'NG',
273 'NI',
274 'NL',
275 'NO',
276 'NP',
277 'NR',
278 'NU',
279 'NZ',
280 'OM',
281 'PA',
282 'PE',
283 'PF',
284 'PG',
285 'PH',
286 'PK',
287 'PL',
288 'PM',
289 'PN',
290 'PR',
291 'PS',
292 'PT',
293 'PW',
294 'PY',
295 'QA',
296 'RE',
297 'RO',
298 'RU',
299 'RW',
300 'SA',
301 'SB',
302 'SC',
303 'SD',
304 'SE',
305 'SG',
306 'SH',
307 'SI',
308 'SJ',
309 'SK',
310 'SL',
311 'SM',
312 'SN',
313 'SO',
314 'SR',
315 'ST',
316 'SV',
317 'SY',
318 'SZ',
319 'TC',
320 'TD',
321 'TF',
322 'TG',
323 'TH',
324 'TJ',
325 'TK',
326 'TM',
327 'TN',
328 'TO',
329 'TL',
330 'TR',
331 'TT',
332 'TV',
333 'TW',
334 'TZ',
335 'UA',
336 'UG',
337 'UM',
338 'US',
339 'UY',
340 'UZ',
341 'VA',
342 'VC',
343 'VE',
344 'VG',
345 'VI',
346 'VN',
347 'VU',
348 'WF',
349 'WS',
350 'YE',
351 'YT',
352 'RS',
353 'ZA',
354 'ZM',
355 'ME',
356 'ZW',
357 'A1',
358 'A2',
359 'O1',
360 'AX',
361 'GG',
362 'IM',
363 'JE',
364 'BL',
365 'MF',
366 'BQ',
367 'SS',
368 'XK',
369 'O1',
370 );
371
372 /**
373 * 3 letters country codes.
374 *
375 * @var array
376 */
377 public $GEOIP_COUNTRY_CODES3 = array(
378 '',
379 'AP',
380 'EU',
381 'AND',
382 'ARE',
383 'AFG',
384 'ATG',
385 'AIA',
386 'ALB',
387 'ARM',
388 'CUW',
389 'AGO',
390 'ATA',
391 'ARG',
392 'ASM',
393 'AUT',
394 'AUS',
395 'ABW',
396 'AZE',
397 'BIH',
398 'BRB',
399 'BGD',
400 'BEL',
401 'BFA',
402 'BGR',
403 'BHR',
404 'BDI',
405 'BEN',
406 'BMU',
407 'BRN',
408 'BOL',
409 'BRA',
410 'BHS',
411 'BTN',
412 'BVT',
413 'BWA',
414 'BLR',
415 'BLZ',
416 'CAN',
417 'CCK',
418 'COD',
419 'CAF',
420 'COG',
421 'CHE',
422 'CIV',
423 'COK',
424 'CHL',
425 'CMR',
426 'CHN',
427 'COL',
428 'CRI',
429 'CUB',
430 'CPV',
431 'CXR',
432 'CYP',
433 'CZE',
434 'DEU',
435 'DJI',
436 'DNK',
437 'DMA',
438 'DOM',
439 'DZA',
440 'ECU',
441 'EST',
442 'EGY',
443 'ESH',
444 'ERI',
445 'ESP',
446 'ETH',
447 'FIN',
448 'FJI',
449 'FLK',
450 'FSM',
451 'FRO',
452 'FRA',
453 'SXM',
454 'GAB',
455 'GBR',
456 'GRD',
457 'GEO',
458 'GUF',
459 'GHA',
460 'GIB',
461 'GRL',
462 'GMB',
463 'GIN',
464 'GLP',
465 'GNQ',
466 'GRC',
467 'SGS',
468 'GTM',
469 'GUM',
470 'GNB',
471 'GUY',
472 'HKG',
473 'HMD',
474 'HND',
475 'HRV',
476 'HTI',
477 'HUN',
478 'IDN',
479 'IRL',
480 'ISR',
481 'IND',
482 'IOT',
483 'IRQ',
484 'IRN',
485 'ISL',
486 'ITA',
487 'JAM',
488 'JOR',
489 'JPN',
490 'KEN',
491 'KGZ',
492 'KHM',
493 'KIR',
494 'COM',
495 'KNA',
496 'PRK',
497 'KOR',
498 'KWT',
499 'CYM',
500 'KAZ',
501 'LAO',
502 'LBN',
503 'LCA',
504 'LIE',
505 'LKA',
506 'LBR',
507 'LSO',
508 'LTU',
509 'LUX',
510 'LVA',
511 'LBY',
512 'MAR',
513 'MCO',
514 'MDA',
515 'MDG',
516 'MHL',
517 'MKD',
518 'MLI',
519 'MMR',
520 'MNG',
521 'MAC',
522 'MNP',
523 'MTQ',
524 'MRT',
525 'MSR',
526 'MLT',
527 'MUS',
528 'MDV',
529 'MWI',
530 'MEX',
531 'MYS',
532 'MOZ',
533 'NAM',
534 'NCL',
535 'NER',
536 'NFK',
537 'NGA',
538 'NIC',
539 'NLD',
540 'NOR',
541 'NPL',
542 'NRU',
543 'NIU',
544 'NZL',
545 'OMN',
546 'PAN',
547 'PER',
548 'PYF',
549 'PNG',
550 'PHL',
551 'PAK',
552 'POL',
553 'SPM',
554 'PCN',
555 'PRI',
556 'PSE',
557 'PRT',
558 'PLW',
559 'PRY',
560 'QAT',
561 'REU',
562 'ROU',
563 'RUS',
564 'RWA',
565 'SAU',
566 'SLB',
567 'SYC',
568 'SDN',
569 'SWE',
570 'SGP',
571 'SHN',
572 'SVN',
573 'SJM',
574 'SVK',
575 'SLE',
576 'SMR',
577 'SEN',
578 'SOM',
579 'SUR',
580 'STP',
581 'SLV',
582 'SYR',
583 'SWZ',
584 'TCA',
585 'TCD',
586 'ATF',
587 'TGO',
588 'THA',
589 'TJK',
590 'TKL',
591 'TKM',
592 'TUN',
593 'TON',
594 'TLS',
595 'TUR',
596 'TTO',
597 'TUV',
598 'TWN',
599 'TZA',
600 'UKR',
601 'UGA',
602 'UMI',
603 'USA',
604 'URY',
605 'UZB',
606 'VAT',
607 'VCT',
608 'VEN',
609 'VGB',
610 'VIR',
611 'VNM',
612 'VUT',
613 'WLF',
614 'WSM',
615 'YEM',
616 'MYT',
617 'SRB',
618 'ZAF',
619 'ZMB',
620 'MNE',
621 'ZWE',
622 'A1',
623 'A2',
624 'O1',
625 'ALA',
626 'GGY',
627 'IMN',
628 'JEY',
629 'BLM',
630 'MAF',
631 'BES',
632 'SSD',
633 'O1',
634 );
635
636 /**
637 * Country names.
638 *
639 * @var array
640 */
641 public $GEOIP_COUNTRY_NAMES = array(
642 '',
643 'Asia/Pacific Region',
644 'Europe',
645 'Andorra',
646 'United Arab Emirates',
647 'Afghanistan',
648 'Antigua and Barbuda',
649 'Anguilla',
650 'Albania',
651 'Armenia',
652 'Curacao',
653 'Angola',
654 'Antarctica',
655 'Argentina',
656 'American Samoa',
657 'Austria',
658 'Australia',
659 'Aruba',
660 'Azerbaijan',
661 'Bosnia and Herzegovina',
662 'Barbados',
663 'Bangladesh',
664 'Belgium',
665 'Burkina Faso',
666 'Bulgaria',
667 'Bahrain',
668 'Burundi',
669 'Benin',
670 'Bermuda',
671 'Brunei Darussalam',
672 'Bolivia',
673 'Brazil',
674 'Bahamas',
675 'Bhutan',
676 'Bouvet Island',
677 'Botswana',
678 'Belarus',
679 'Belize',
680 'Canada',
681 'Cocos (Keeling) Islands',
682 'Congo, The Democratic Republic of the',
683 'Central African Republic',
684 'Congo',
685 'Switzerland',
686 "Cote D'Ivoire",
687 'Cook Islands',
688 'Chile',
689 'Cameroon',
690 'China',
691 'Colombia',
692 'Costa Rica',
693 'Cuba',
694 'Cape Verde',
695 'Christmas Island',
696 'Cyprus',
697 'Czech Republic',
698 'Germany',
699 'Djibouti',
700 'Denmark',
701 'Dominica',
702 'Dominican Republic',
703 'Algeria',
704 'Ecuador',
705 'Estonia',
706 'Egypt',
707 'Western Sahara',
708 'Eritrea',
709 'Spain',
710 'Ethiopia',
711 'Finland',
712 'Fiji',
713 'Falkland Islands (Malvinas)',
714 'Micronesia, Federated States of',
715 'Faroe Islands',
716 'France',
717 'Sint Maarten (Dutch part)',
718 'Gabon',
719 'United Kingdom',
720 'Grenada',
721 'Georgia',
722 'French Guiana',
723 'Ghana',
724 'Gibraltar',
725 'Greenland',
726 'Gambia',
727 'Guinea',
728 'Guadeloupe',
729 'Equatorial Guinea',
730 'Greece',
731 'South Georgia and the South Sandwich Islands',
732 'Guatemala',
733 'Guam',
734 'Guinea-Bissau',
735 'Guyana',
736 'Hong Kong',
737 'Heard Island and McDonald Islands',
738 'Honduras',
739 'Croatia',
740 'Haiti',
741 'Hungary',
742 'Indonesia',
743 'Ireland',
744 'Israel',
745 'India',
746 'British Indian Ocean Territory',
747 'Iraq',
748 'Iran, Islamic Republic of',
749 'Iceland',
750 'Italy',
751 'Jamaica',
752 'Jordan',
753 'Japan',
754 'Kenya',
755 'Kyrgyzstan',
756 'Cambodia',
757 'Kiribati',
758 'Comoros',
759 'Saint Kitts and Nevis',
760 "Korea, Democratic People's Republic of",
761 'Korea, Republic of',
762 'Kuwait',
763 'Cayman Islands',
764 'Kazakhstan',
765 "Lao People's Democratic Republic",
766 'Lebanon',
767 'Saint Lucia',
768 'Liechtenstein',
769 'Sri Lanka',
770 'Liberia',
771 'Lesotho',
772 'Lithuania',
773 'Luxembourg',
774 'Latvia',
775 'Libya',
776 'Morocco',
777 'Monaco',
778 'Moldova, Republic of',
779 'Madagascar',
780 'Marshall Islands',
781 'Macedonia',
782 'Mali',
783 'Myanmar',
784 'Mongolia',
785 'Macau',
786 'Northern Mariana Islands',
787 'Martinique',
788 'Mauritania',
789 'Montserrat',
790 'Malta',
791 'Mauritius',
792 'Maldives',
793 'Malawi',
794 'Mexico',
795 'Malaysia',
796 'Mozambique',
797 'Namibia',
798 'New Caledonia',
799 'Niger',
800 'Norfolk Island',
801 'Nigeria',
802 'Nicaragua',
803 'Netherlands',
804 'Norway',
805 'Nepal',
806 'Nauru',
807 'Niue',
808 'New Zealand',
809 'Oman',
810 'Panama',
811 'Peru',
812 'French Polynesia',
813 'Papua New Guinea',
814 'Philippines',
815 'Pakistan',
816 'Poland',
817 'Saint Pierre and Miquelon',
818 'Pitcairn Islands',
819 'Puerto Rico',
820 'Palestinian Territory',
821 'Portugal',
822 'Palau',
823 'Paraguay',
824 'Qatar',
825 'Reunion',
826 'Romania',
827 'Russian Federation',
828 'Rwanda',
829 'Saudi Arabia',
830 'Solomon Islands',
831 'Seychelles',
832 'Sudan',
833 'Sweden',
834 'Singapore',
835 'Saint Helena',
836 'Slovenia',
837 'Svalbard and Jan Mayen',
838 'Slovakia',
839 'Sierra Leone',
840 'San Marino',
841 'Senegal',
842 'Somalia',
843 'Suriname',
844 'Sao Tome and Principe',
845 'El Salvador',
846 'Syrian Arab Republic',
847 'Eswatini',
848 'Turks and Caicos Islands',
849 'Chad',
850 'French Southern Territories',
851 'Togo',
852 'Thailand',
853 'Tajikistan',
854 'Tokelau',
855 'Turkmenistan',
856 'Tunisia',
857 'Tonga',
858 'Timor-Leste',
859 'Türkiye',
860 'Trinidad and Tobago',
861 'Tuvalu',
862 'Taiwan',
863 'Tanzania, United Republic of',
864 'Ukraine',
865 'Uganda',
866 'United States Minor Outlying Islands',
867 'United States',
868 'Uruguay',
869 'Uzbekistan',
870 'Holy See (Vatican City State)',
871 'Saint Vincent and the Grenadines',
872 'Venezuela',
873 'Virgin Islands, British',
874 'Virgin Islands, U.S.',
875 'Vietnam',
876 'Vanuatu',
877 'Wallis and Futuna',
878 'Samoa',
879 'Yemen',
880 'Mayotte',
881 'Serbia',
882 'South Africa',
883 'Zambia',
884 'Montenegro',
885 'Zimbabwe',
886 'Anonymous Proxy',
887 'Satellite Provider',
888 'Other',
889 'Aland Islands',
890 'Guernsey',
891 'Isle of Man',
892 'Jersey',
893 'Saint Barthelemy',
894 'Saint Martin',
895 'Bonaire, Saint Eustatius and Saba',
896 'South Sudan',
897 'Kosovo',
898 'Other',
899 );
900
901 /**
902 * 2 letters continent codes.
903 *
904 * @var array
905 */
906 public $GEOIP_CONTINENT_CODES = array(
907 '--',
908 'AS',
909 'EU',
910 'EU',
911 'AS',
912 'AS',
913 'NA',
914 'NA',
915 'EU',
916 'AS',
917 'NA',
918 'AF',
919 'AN',
920 'SA',
921 'OC',
922 'EU',
923 'OC',
924 'NA',
925 'AS',
926 'EU',
927 'NA',
928 'AS',
929 'EU',
930 'AF',
931 'EU',
932 'AS',
933 'AF',
934 'AF',
935 'NA',
936 'AS',
937 'SA',
938 'SA',
939 'NA',
940 'AS',
941 'AN',
942 'AF',
943 'EU',
944 'NA',
945 'NA',
946 'AS',
947 'AF',
948 'AF',
949 'AF',
950 'EU',
951 'AF',
952 'OC',
953 'SA',
954 'AF',
955 'AS',
956 'SA',
957 'NA',
958 'NA',
959 'AF',
960 'AS',
961 'AS',
962 'EU',
963 'EU',
964 'AF',
965 'EU',
966 'NA',
967 'NA',
968 'AF',
969 'SA',
970 'EU',
971 'AF',
972 'AF',
973 'AF',
974 'EU',
975 'AF',
976 'EU',
977 'OC',
978 'SA',
979 'OC',
980 'EU',
981 'EU',
982 'NA',
983 'AF',
984 'EU',
985 'NA',
986 'AS',
987 'SA',
988 'AF',
989 'EU',
990 'NA',
991 'AF',
992 'AF',
993 'NA',
994 'AF',
995 'EU',
996 'AN',
997 'NA',
998 'OC',
999 'AF',
1000 'SA',
1001 'AS',
1002 'AN',
1003 'NA',
1004 'EU',
1005 'NA',
1006 'EU',
1007 'AS',
1008 'EU',
1009 'AS',
1010 'AS',
1011 'AS',
1012 'AS',
1013 'AS',
1014 'EU',
1015 'EU',
1016 'NA',
1017 'AS',
1018 'AS',
1019 'AF',
1020 'AS',
1021 'AS',
1022 'OC',
1023 'AF',
1024 'NA',
1025 'AS',
1026 'AS',
1027 'AS',
1028 'NA',
1029 'AS',
1030 'AS',
1031 'AS',
1032 'NA',
1033 'EU',
1034 'AS',
1035 'AF',
1036 'AF',
1037 'EU',
1038 'EU',
1039 'EU',
1040 'AF',
1041 'AF',
1042 'EU',
1043 'EU',
1044 'AF',
1045 'OC',
1046 'EU',
1047 'AF',
1048 'AS',
1049 'AS',
1050 'AS',
1051 'OC',
1052 'NA',
1053 'AF',
1054 'NA',
1055 'EU',
1056 'AF',
1057 'AS',
1058 'AF',
1059 'NA',
1060 'AS',
1061 'AF',
1062 'AF',
1063 'OC',
1064 'AF',
1065 'OC',
1066 'AF',
1067 'NA',
1068 'EU',
1069 'EU',
1070 'AS',
1071 'OC',
1072 'OC',
1073 'OC',
1074 'AS',
1075 'NA',
1076 'SA',
1077 'OC',
1078 'OC',
1079 'AS',
1080 'AS',
1081 'EU',
1082 'NA',
1083 'OC',
1084 'NA',
1085 'AS',
1086 'EU',
1087 'OC',
1088 'SA',
1089 'AS',
1090 'AF',
1091 'EU',
1092 'EU',
1093 'AF',
1094 'AS',
1095 'OC',
1096 'AF',
1097 'AF',
1098 'EU',
1099 'AS',
1100 'AF',
1101 'EU',
1102 'EU',
1103 'EU',
1104 'AF',
1105 'EU',
1106 'AF',
1107 'AF',
1108 'SA',
1109 'AF',
1110 'NA',
1111 'AS',
1112 'AF',
1113 'NA',
1114 'AF',
1115 'AN',
1116 'AF',
1117 'AS',
1118 'AS',
1119 'OC',
1120 'AS',
1121 'AF',
1122 'OC',
1123 'AS',
1124 'EU',
1125 'NA',
1126 'OC',
1127 'AS',
1128 'AF',
1129 'EU',
1130 'AF',
1131 'OC',
1132 'NA',
1133 'SA',
1134 'AS',
1135 'EU',
1136 'NA',
1137 'SA',
1138 'NA',
1139 'NA',
1140 'AS',
1141 'OC',
1142 'OC',
1143 'OC',
1144 'AS',
1145 'AF',
1146 'EU',
1147 'AF',
1148 'AF',
1149 'EU',
1150 'AF',
1151 '--',
1152 '--',
1153 '--',
1154 'EU',
1155 'EU',
1156 'EU',
1157 'EU',
1158 'NA',
1159 'NA',
1160 'NA',
1161 'AF',
1162 '--',
1163 );
1164
1165 /** @var WC_Logger Logger instance */
1166 public static $log = false;
1167
1168 /**
1169 * Logging method.
1170 *
1171 * @param string $message Log message.
1172 * @param string $level Optional. Default 'info'.
1173 * emergency|alert|critical|error|warning|notice|info|debug
1174 */
1175 public static function log( $message, $level = 'info' ) {
1176 if ( empty( self::$log ) ) {
1177 self::$log = wc_get_logger();
1178 }
1179 self::$log->log( $level, $message, array( 'source' => 'geoip' ) );
1180 }
1181
1182 /**
1183 * Open geoip file.
1184 *
1185 * @param string $filename
1186 * @param int $flags
1187 */
1188 public function geoip_open( $filename, $flags ) {
1189 $this->flags = $flags;
1190 if ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1191 $this->shmid = @shmop_open( self::GEOIP_SHM_KEY, 'a', 0, 0 );
1192 } else {
1193 if ( $this->filehandle = fopen( $filename, 'rb' ) ) {
1194 if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
1195 $s_array = fstat( $this->filehandle );
1196 $this->memory_buffer = fread( $this->filehandle, $s_array['size'] );
1197 }
1198 } else {
1199 self::log( 'GeoIP API: Can not open ' . $filename, 'error' );
1200 }
1201 }
1202
1203 $this->_setup_segments();
1204 }
1205
1206 /**
1207 * Setup segments.
1208 *
1209 * @return WC_Geo_IP instance
1210 */
1211 private function _setup_segments() {
1212 $this->databaseType = self::GEOIP_COUNTRY_EDITION;
1213 $this->record_length = self::STANDARD_RECORD_LENGTH;
1214
1215 if ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1216 $offset = @shmop_size( $this->shmid ) - 3;
1217
1218 for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) {
1219 $delim = @shmop_read( $this->shmid, $offset, 3 );
1220 $offset += 3;
1221
1222 if ( ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) == $delim ) {
1223 $this->databaseType = ord( @shmop_read( $this->shmid, $offset, 1 ) );
1224
1225 if ( $this->databaseType >= 106 ) {
1226 $this->databaseType -= 105;
1227 }
1228
1229 $offset++;
1230
1231 if ( self::GEOIP_REGION_EDITION_REV0 == $this->databaseType ) {
1232 $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0;
1233 } elseif ( self::GEOIP_REGION_EDITION_REV1 == $this->databaseType ) {
1234 $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1;
1235 } elseif ( ( self::GEOIP_CITY_EDITION_REV0 == $this->databaseType )
1236 || ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType )
1237 || ( self::GEOIP_ORG_EDITION == $this->databaseType )
1238 || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType )
1239 || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType )
1240 || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType )
1241 || ( self::GEOIP_ISP_EDITION == $this->databaseType )
1242 || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType )
1243 || ( self::GEOIP_USERTYPE_EDITION == $this->databaseType )
1244 || ( self::GEOIP_USERTYPE_EDITION_V6 == $this->databaseType )
1245 || ( self::GEOIP_LOCATIONA_EDITION == $this->databaseType )
1246 || ( self::GEOIP_ACCURACYRADIUS_EDITION == $this->databaseType )
1247 || ( self::GEOIP_CITY_EDITION_REV0_V6 == $this->databaseType )
1248 || ( self::GEOIP_CITY_EDITION_REV1_V6 == $this->databaseType )
1249 || ( self::GEOIP_NETSPEED_EDITION_REV1 == $this->databaseType )
1250 || ( self::GEOIP_NETSPEED_EDITION_REV1_V6 == $this->databaseType )
1251 || ( self::GEOIP_ASNUM_EDITION == $this->databaseType )
1252 || ( self::GEOIP_ASNUM_EDITION_V6 == $this->databaseType )
1253 ) {
1254 $this->databaseSegments = 0;
1255 $buf = @shmop_read( $this->shmid, $offset, self::SEGMENT_RECORD_LENGTH );
1256
1257 for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) {
1258 $this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) );
1259 }
1260
1261 if ( ( self::GEOIP_ORG_EDITION == $this->databaseType )
1262 || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType )
1263 || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType )
1264 || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType )
1265 || ( self::GEOIP_ISP_EDITION == $this->databaseType )
1266 || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType )
1267 ) {
1268 $this->record_length = self::ORG_RECORD_LENGTH;
1269 }
1270 }
1271
1272 break;
1273 } else {
1274 $offset -= 4;
1275 }
1276 }
1277 if ( ( self::GEOIP_COUNTRY_EDITION == $this->databaseType )
1278 || ( self::GEOIP_COUNTRY_EDITION_V6 == $this->databaseType )
1279 || ( self::GEOIP_PROXY_EDITION == $this->databaseType )
1280 || ( self::GEOIP_NETSPEED_EDITION == $this->databaseType )
1281 ) {
1282 $this->databaseSegments = self::GEOIP_COUNTRY_BEGIN;
1283 }
1284 } else {
1285 $filepos = ftell( $this->filehandle );
1286 fseek( $this->filehandle, -3, SEEK_END );
1287
1288 for ( $i = 0; $i < self::STRUCTURE_INFO_MAX_SIZE; $i++ ) {
1289
1290 $delim = fread( $this->filehandle, 3 );
1291 if ( ( chr( 255 ) . chr( 255 ) . chr( 255 ) ) == $delim ) {
1292
1293 $this->databaseType = ord( fread( $this->filehandle, 1 ) );
1294 if ( $this->databaseType >= 106 ) {
1295 $this->databaseType -= 105;
1296 }
1297
1298 if ( self::GEOIP_REGION_EDITION_REV0 == $this->databaseType ) {
1299 $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV0;
1300 } elseif ( self::GEOIP_REGION_EDITION_REV1 == $this->databaseType ) {
1301 $this->databaseSegments = self::GEOIP_STATE_BEGIN_REV1;
1302 } elseif ( ( self::GEOIP_CITY_EDITION_REV0 == $this->databaseType )
1303 || ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType )
1304 || ( self::GEOIP_CITY_EDITION_REV0_V6 == $this->databaseType )
1305 || ( self::GEOIP_CITY_EDITION_REV1_V6 == $this->databaseType )
1306 || ( self::GEOIP_ORG_EDITION == $this->databaseType )
1307 || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType )
1308 || ( self::GEOIP_ISP_EDITION == $this->databaseType )
1309 || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType )
1310 || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType )
1311 || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType )
1312 || ( self::GEOIP_LOCATIONA_EDITION == $this->databaseType )
1313 || ( self::GEOIP_ACCURACYRADIUS_EDITION == $this->databaseType )
1314 || ( self::GEOIP_NETSPEED_EDITION_REV1 == $this->databaseType )
1315 || ( self::GEOIP_NETSPEED_EDITION_REV1_V6 == $this->databaseType )
1316 || ( self::GEOIP_USERTYPE_EDITION == $this->databaseType )
1317 || ( self::GEOIP_USERTYPE_EDITION_V6 == $this->databaseType )
1318 || ( self::GEOIP_ASNUM_EDITION == $this->databaseType )
1319 || ( self::GEOIP_ASNUM_EDITION_V6 == $this->databaseType )
1320 ) {
1321 $this->databaseSegments = 0;
1322 $buf = fread( $this->filehandle, self::SEGMENT_RECORD_LENGTH );
1323
1324 for ( $j = 0; $j < self::SEGMENT_RECORD_LENGTH; $j++ ) {
1325 $this->databaseSegments += ( ord( $buf[ $j ] ) << ( $j * 8 ) );
1326 }
1327
1328 if ( ( self::GEOIP_ORG_EDITION == $this->databaseType )
1329 || ( self::GEOIP_DOMAIN_EDITION == $this->databaseType )
1330 || ( self::GEOIP_ISP_EDITION == $this->databaseType )
1331 || ( self::GEOIP_ORG_EDITION_V6 == $this->databaseType )
1332 || ( self::GEOIP_DOMAIN_EDITION_V6 == $this->databaseType )
1333 || ( self::GEOIP_ISP_EDITION_V6 == $this->databaseType )
1334 ) {
1335 $this->record_length = self::ORG_RECORD_LENGTH;
1336 }
1337 }
1338
1339 break;
1340 } else {
1341 fseek( $this->filehandle, -4, SEEK_CUR );
1342 }
1343 }
1344
1345 if ( ( self::GEOIP_COUNTRY_EDITION == $this->databaseType )
1346 || ( self::GEOIP_COUNTRY_EDITION_V6 == $this->databaseType )
1347 || ( self::GEOIP_PROXY_EDITION == $this->databaseType )
1348 || ( self::GEOIP_NETSPEED_EDITION == $this->databaseType )
1349 ) {
1350 $this->databaseSegments = self::GEOIP_COUNTRY_BEGIN;
1351 }
1352
1353 fseek( $this->filehandle, $filepos, SEEK_SET );
1354 }
1355
1356 return $this;
1357 }
1358
1359 /**
1360 * Close geoip file.
1361 *
1362 * @return bool
1363 */
1364 public function geoip_close() {
1365 if ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1366 return true;
1367 }
1368
1369 return fclose( $this->filehandle );
1370 }
1371
1372 /**
1373 * Common get record.
1374 *
1375 * @param string $seek_country
1376 * @return WC_Geo_IP_Record instance
1377 */
1378 private function _common_get_record( $seek_country ) {
1379 // workaround php's broken substr, strpos, etc handling with
1380 // mbstring.func_overload and mbstring.internal_encoding
1381 $mbExists = extension_loaded( 'mbstring' );
1382 if ( $mbExists ) {
1383 $enc = mb_internal_encoding();
1384 mb_internal_encoding( 'ISO-8859-1' );
1385 }
1386
1387 $record_pointer = $seek_country + ( 2 * $this->record_length - 1 ) * $this->databaseSegments;
1388
1389 if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
1390 $record_buf = substr( $this->memory_buffer, $record_pointer, FULL_RECORD_LENGTH );
1391 } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1392 $record_buf = @shmop_read( $this->shmid, $record_pointer, FULL_RECORD_LENGTH );
1393 } else {
1394 fseek( $this->filehandle, $record_pointer, SEEK_SET );
1395 $record_buf = fread( $this->filehandle, FULL_RECORD_LENGTH );
1396 }
1397
1398 $record = new WC_Geo_IP_Record();
1399 $record_buf_pos = 0;
1400 $char = ord( substr( $record_buf, $record_buf_pos, 1 ) );
1401 $record->country_code = $this->GEOIP_COUNTRY_CODES[ $char ];
1402 $record->country_code3 = $this->GEOIP_COUNTRY_CODES3[ $char ];
1403 $record->country_name = $this->GEOIP_COUNTRY_NAMES[ $char ];
1404 $record->continent_code = $this->GEOIP_CONTINENT_CODES[ $char ];
1405 $str_length = 0;
1406
1407 $record_buf_pos++;
1408
1409 // Get region
1410 $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1411 while ( 0 != $char ) {
1412 $str_length++;
1413 $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1414 }
1415
1416 if ( $str_length > 0 ) {
1417 $record->region = substr( $record_buf, $record_buf_pos, $str_length );
1418 }
1419
1420 $record_buf_pos += $str_length + 1;
1421 $str_length = 0;
1422
1423 // Get city
1424 $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1425 while ( 0 != $char ) {
1426 $str_length++;
1427 $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1428 }
1429
1430 if ( $str_length > 0 ) {
1431 $record->city = substr( $record_buf, $record_buf_pos, $str_length );
1432 }
1433
1434 $record_buf_pos += $str_length + 1;
1435 $str_length = 0;
1436
1437 // Get postal code
1438 $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1439 while ( 0 != $char ) {
1440 $str_length++;
1441 $char = ord( substr( $record_buf, $record_buf_pos + $str_length, 1 ) );
1442 }
1443
1444 if ( $str_length > 0 ) {
1445 $record->postal_code = substr( $record_buf, $record_buf_pos, $str_length );
1446 }
1447
1448 $record_buf_pos += $str_length + 1;
1449
1450 // Get latitude and longitude
1451 $latitude = 0;
1452 $longitude = 0;
1453 for ( $j = 0; $j < 3; ++$j ) {
1454 $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) );
1455 $latitude += ( $char << ( $j * 8 ) );
1456 }
1457
1458 $record->latitude = ( $latitude / 10000 ) - 180;
1459
1460 for ( $j = 0; $j < 3; ++$j ) {
1461 $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) );
1462 $longitude += ( $char << ( $j * 8 ) );
1463 }
1464
1465 $record->longitude = ( $longitude / 10000 ) - 180;
1466
1467 if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) {
1468 $metroarea_combo = 0;
1469 if ( 'US' === $record->country_code ) {
1470 for ( $j = 0; $j < 3; ++$j ) {
1471 $char = ord( substr( $record_buf, $record_buf_pos++, 1 ) );
1472 $metroarea_combo += ( $char << ( $j * 8 ) );
1473 }
1474
1475 $record->metro_code = $record->dma_code = floor( $metroarea_combo / 1000 );
1476 $record->area_code = $metroarea_combo % 1000;
1477 }
1478 }
1479
1480 if ( $mbExists ) {
1481 mb_internal_encoding( $enc );
1482 }
1483
1484 return $record;
1485 }
1486
1487 /**
1488 * Get record.
1489 *
1490 * @param int $ipnum
1491 * @return WC_Geo_IP_Record instance
1492 */
1493 private function _get_record( $ipnum ) {
1494 $seek_country = $this->_geoip_seek_country( $ipnum );
1495 if ( $seek_country == $this->databaseSegments ) {
1496 return null;
1497 }
1498
1499 return $this->_common_get_record( $seek_country );
1500 }
1501
1502 /**
1503 * Seek country IPv6.
1504 *
1505 * @param int $ipnum
1506 * @return string
1507 */
1508 public function _geoip_seek_country_v6( $ipnum ) {
1509 // arrays from unpack start with offset 1
1510 // yet another php mystery. array_merge work around
1511 // this broken behaviour
1512 $v6vec = array_merge( unpack( 'C16', $ipnum ) );
1513
1514 $offset = 0;
1515 for ( $depth = 127; $depth >= 0; --$depth ) {
1516 if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
1517 $buf = $this->_safe_substr(
1518 $this->memory_buffer,
1519 2 * $this->record_length * $offset,
1520 2 * $this->record_length
1521 );
1522 } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1523 $buf = @shmop_read(
1524 $this->shmid,
1525 2 * $this->record_length * $offset,
1526 2 * $this->record_length
1527 );
1528 } else {
1529 if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) {
1530 break;
1531 }
1532
1533 $buf = fread( $this->filehandle, 2 * $this->record_length );
1534 }
1535 $x = array( 0, 0 );
1536 for ( $i = 0; $i < 2; ++$i ) {
1537 for ( $j = 0; $j < $this->record_length; ++$j ) {
1538 $x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 );
1539 }
1540 }
1541
1542 $bnum = 127 - $depth;
1543 $idx = $bnum >> 3;
1544 $b_mask = 1 << ( $bnum & 7 ^ 7 );
1545 if ( ( $v6vec[ $idx ] & $b_mask ) > 0 ) {
1546 if ( $x[1] >= $this->databaseSegments ) {
1547 return $x[1];
1548 }
1549 $offset = $x[1];
1550 } else {
1551 if ( $x[0] >= $this->databaseSegments ) {
1552 return $x[0];
1553 }
1554 $offset = $x[0];
1555 }
1556 }
1557
1558 self::log( 'GeoIP API: Error traversing database - perhaps it is corrupt?', 'error' );
1559
1560 return false;
1561 }
1562
1563 /**
1564 * Seek country.
1565 *
1566 * @param int $ipnum
1567 * @return string
1568 */
1569 private function _geoip_seek_country( $ipnum ) {
1570 $offset = 0;
1571 for ( $depth = 31; $depth >= 0; --$depth ) {
1572 if ( $this->flags & self::GEOIP_MEMORY_CACHE ) {
1573 $buf = $this->_safe_substr(
1574 $this->memory_buffer,
1575 2 * $this->record_length * $offset,
1576 2 * $this->record_length
1577 );
1578 } elseif ( $this->flags & self::GEOIP_SHARED_MEMORY ) {
1579 $buf = @shmop_read(
1580 $this->shmid,
1581 2 * $this->record_length * $offset,
1582 2 * $this->record_length
1583 );
1584 } else {
1585 if ( 0 != fseek( $this->filehandle, 2 * $this->record_length * $offset, SEEK_SET ) ) {
1586 break;
1587 }
1588
1589 $buf = fread( $this->filehandle, 2 * $this->record_length );
1590 }
1591
1592 $x = array( 0, 0 );
1593 for ( $i = 0; $i < 2; ++$i ) {
1594 for ( $j = 0; $j < $this->record_length; ++$j ) {
1595 $x[ $i ] += ord( $buf[ $this->record_length * $i + $j ] ) << ( $j * 8 );
1596 }
1597 }
1598 if ( $ipnum & ( 1 << $depth ) ) {
1599 if ( $x[1] >= $this->databaseSegments ) {
1600 return $x[1];
1601 }
1602
1603 $offset = $x[1];
1604 } else {
1605 if ( $x[0] >= $this->databaseSegments ) {
1606 return $x[0];
1607 }
1608
1609 $offset = $x[0];
1610 }
1611 }
1612
1613 self::log( 'GeoIP API: Error traversing database - perhaps it is corrupt?', 'error' );
1614
1615 return false;
1616 }
1617
1618 /**
1619 * Record by addr.
1620 *
1621 * @param string $addr
1622 *
1623 * @return WC_Geo_IP_Record
1624 */
1625 public function geoip_record_by_addr( $addr ) {
1626 if ( null == $addr ) {
1627 return 0;
1628 }
1629
1630 $ipnum = ip2long( $addr );
1631 return $this->_get_record( $ipnum );
1632 }
1633
1634 /**
1635 * Country ID by addr IPv6.
1636 *
1637 * @param string $addr
1638 * @return int|bool
1639 */
1640 public function geoip_country_id_by_addr_v6( $addr ) {
1641 if ( ! defined( 'AF_INET6' ) ) {
1642 self::log( 'GEOIP (geoip_country_id_by_addr_v6): PHP was compiled with --disable-ipv6 option' );
1643 return false;
1644 }
1645 $ipnum = inet_pton( $addr );
1646 return $this->_geoip_seek_country_v6( $ipnum ) - self::GEOIP_COUNTRY_BEGIN;
1647 }
1648
1649 /**
1650 * Country ID by addr.
1651 *
1652 * @param string $addr
1653 * @return int
1654 */
1655 public function geoip_country_id_by_addr( $addr ) {
1656 $ipnum = ip2long( $addr );
1657 return $this->_geoip_seek_country( $ipnum ) - self::GEOIP_COUNTRY_BEGIN;
1658 }
1659
1660 /**
1661 * Country code by addr IPv6.
1662 *
1663 * @param string $addr
1664 * @return string
1665 */
1666 public function geoip_country_code_by_addr_v6( $addr ) {
1667 $country_id = $this->geoip_country_id_by_addr_v6( $addr );
1668 if ( false !== $country_id && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) {
1669 return $this->GEOIP_COUNTRY_CODES[ $country_id ];
1670 }
1671
1672 return false;
1673 }
1674
1675 /**
1676 * Country code by addr.
1677 *
1678 * @param string $addr
1679 * @return string
1680 */
1681 public function geoip_country_code_by_addr( $addr ) {
1682 if ( self::GEOIP_CITY_EDITION_REV1 == $this->databaseType ) {
1683 $record = $this->geoip_record_by_addr( $addr );
1684 if ( false !== $record ) {
1685 return $record->country_code;
1686 }
1687 } else {
1688 $country_id = $this->geoip_country_id_by_addr( $addr );
1689 if ( false !== $country_id && isset( $this->GEOIP_COUNTRY_CODES[ $country_id ] ) ) {
1690 return $this->GEOIP_COUNTRY_CODES[ $country_id ];
1691 }
1692 }
1693
1694 return false;
1695 }
1696
1697 /**
1698 * Encode string.
1699 *
1700 * @param string $string
1701 * @param int $start
1702 * @param int $length
1703 * @return string
1704 */
1705 private function _safe_substr( $string, $start, $length ) {
1706 // workaround php's broken substr, strpos, etc handling with
1707 // mbstring.func_overload and mbstring.internal_encoding
1708 $mb_exists = extension_loaded( 'mbstring' );
1709
1710 if ( $mb_exists ) {
1711 $enc = mb_internal_encoding();
1712 mb_internal_encoding( 'ISO-8859-1' );
1713 }
1714
1715 $buf = substr( $string, $start, $length );
1716
1717 if ( $mb_exists ) {
1718 mb_internal_encoding( $enc );
1719 }
1720
1721 return $buf;
1722 }
1723 }
1724
1725 /**
1726 * Geo IP Record class.
1727 */
1728 class WC_Geo_IP_Record {
1729
1730 /**
1731 * Country code.
1732 *
1733 * @var string
1734 */
1735 public $country_code;
1736
1737 /**
1738 * 3 letters country code.
1739 *
1740 * @var string
1741 */
1742 public $country_code3;
1743
1744 /**
1745 * Country name.
1746 *
1747 * @var string
1748 */
1749 public $country_name;
1750
1751 /**
1752 * Region.
1753 *
1754 * @var string
1755 */
1756 public $region;
1757
1758 /**
1759 * City.
1760 *
1761 * @var string
1762 */
1763 public $city;
1764
1765 /**
1766 * Postal code.
1767 *
1768 * @var string
1769 */
1770 public $postal_code;
1771
1772 /**
1773 * Latitude
1774 *
1775 * @var int
1776 */
1777 public $latitude;
1778
1779 /**
1780 * Longitude.
1781 *
1782 * @var int
1783 */
1784 public $longitude;
1785
1786 /**
1787 * Area code.
1788 *
1789 * @var int
1790 */
1791 public $area_code;
1792
1793 /**
1794 * DMA Code.
1795 *
1796 * Metro and DMA code are the same.
1797 * Use metro code instead.
1798 *
1799 * @var float
1800 */
1801 public $dma_code;
1802
1803 /**
1804 * Metro code.
1805 *
1806 * @var float
1807 */
1808 public $metro_code;
1809
1810 /**
1811 * Continent code.
1812 *
1813 * @var string
1814 */
1815 public $continent_code;
1816 }
1817