PluginProbe ʕ •ᴥ•ʔ
Hustle – Email Marketing, Lead Generation, Optins, Popups / 7.3.7
Hustle – Email Marketing, Lead Generation, Optins, Popups v7.3.7
7.8.13 7.8.13.1 trunk 3.0 3.1 3.1.1 3.1.2 3.1.3 3.1.4 4.3.2 4.4.4 4.4.5 4.4.5.1 4.4.5.4 4.6 4.6.1.1 4.6.1.4 4.7.0.2 4.7.0.3 4.7.0.7 4.7.0.9 4.7.1.0 4.7.1.1 4.8.0.0 5.0.0 5.0.1 5.0.1.1 5.0.1.2 5.1 5.1.1 5.1.2 5.1.3 5.1.3.1 5.1.3.2 5.1.4 5.1.5 6.0 6.0.1 6.0.2 6.0.3 6.0.4.2 6.0.5 6.0.6.1 6.0.7 6.0.8.1 6.0.9 7.0.0.1 7.0.2 7.0.3 7.0.4 7.1.0 7.1.1 7.2.0 7.2.1 7.3.0 7.3.1 7.3.3 7.3.5 7.3.6 7.3.7 7.4.0 7.4.1 7.4.11 7.4.13 7.4.13.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.5.1 7.4.5.2 7.4.6 7.4.7 7.5.0 7.6.0 7.6.1 7.6.3 7.6.4 7.6.6 7.7.0 7.7.1 7.8.0 7.8.1 7.8.10 7.8.10.1 7.8.10.2 7.8.11 7.8.12 7.8.12.1 7.8.2 7.8.3 7.8.4 7.8.5 7.8.6 7.8.7 7.8.8 7.8.9 7.8.9.1 7.8.9.2 7.8.9.3
wordpress-popup / inc / opt-in-geo.php
wordpress-popup / inc Last commit date
display-conditions 5 years ago front 5 years ago helpers 5 years ago metas 5 years ago palettes 5 years ago provider 5 years ago providers 5 years ago templates 5 years ago update 5 years ago class-hustle-admin-page-abstract.php 5 years ago class-hustle-condition-factory.php 6 years ago class-hustle-dashboard-admin.php 5 years ago class-hustle-data.php 5 years ago class-hustle-db.php 6 years ago class-hustle-module-admin.php 5 years ago class-hustle-module-collection.php 5 years ago class-hustle-module-decorator.php 5 years ago class-hustle-module-page-abstract.php 5 years ago class-hustle-notifications.php 5 years ago class-hustle-settings-admin.php 5 years ago class-hustle-upsell-page.php 5 years ago class-hustle-wp-dashboard-page.php 5 years ago hustle-collection.php 6 years ago hustle-deletion.php 5 years ago hustle-embedded-admin.php 6 years ago hustle-entries-admin.php 5 years ago hustle-entry-model.php 5 years ago hustle-general-data-protection.php 6 years ago hustle-init.php 5 years ago hustle-mail.php 5 years ago hustle-meta.php 5 years ago hustle-migration.php 5 years ago hustle-model.php 5 years ago hustle-module-model.php 5 years ago hustle-module-widget-legacy.php 5 years ago hustle-module-widget.php 5 years ago hustle-modules-common-admin-ajax.php 5 years ago hustle-popup-admin.php 6 years ago hustle-providers-admin.php 5 years ago hustle-providers.php 6 years ago hustle-settings-admin-ajax.php 5 years ago hustle-settings-page.php 5 years ago hustle-slidein-admin.php 6 years ago hustle-sshare-admin.php 5 years ago hustle-sshare-model.php 5 years ago hustle-tracking-model.php 5 years ago opt-in-geo.php 5 years ago opt-in-utils.php 5 years ago opt-in-wpmudev-api.php 6 years ago
opt-in-geo.php
364 lines
1 <?php
2
3 /**
4 * Geolocation utility functions
5 *
6 * Most of the methods are courtesy Philipp Stracker
7 *
8 * Class Opt_In_Geo
9 */
10 class Opt_In_Geo {
11 /**
12 * Site option key
13 *
14 * @var COUNTRY_IP_MAP
15 */
16 const COUNTRY_IP_MAP = 'wpoi-county-id-map';
17
18 /**
19 * Default GeoIP provider key
20 *
21 * @var DEFAULT_GEOIP_PROVIDER
22 */
23 const DEFAULT_GEOIP_PROVIDER = 'geoplugin';
24
25 /**
26 * Tries to get the public IP address of the current user.
27 *
28 * @return string The IP Address
29 */
30 public static function get_user_ip() {
31 // check for bot
32 if ( self::_is_crawler() ) {
33 return false;
34 }
35
36 $result = (object) array(
37 'ip' => $_SERVER['REMOTE_ADDR'],
38 'proxy' => false,
39 'proxy_ip' => '',
40 );
41
42 /*
43 * This code tries to bypass a proxy and get the actual IP address of
44 * the visitor behind the proxy.
45 * Warning: These values might be spoofed!
46 */
47 $ip_fields = array(
48 'HTTP_CLIENT_IP',
49 'HTTP_X_FORWARDED_FOR',
50 'HTTP_X_FORWARDED',
51 'HTTP_X_CLUSTER_CLIENT_IP',
52 'HTTP_FORWARDED_FOR',
53 'HTTP_FORWARDED',
54 'REMOTE_ADDR',
55 );
56 $forwarded = false;
57 foreach ( $ip_fields as $key ) {
58 if ( true === array_key_exists( $key, $_SERVER ) ) {
59 foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) {
60 $ip = trim( $ip );
61
62 if ( false !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
63 $forwarded = $ip;
64 break 2;
65 }
66 }
67 }
68 }
69
70 // If we found a different IP address than REMOTE_ADDR then it's a proxy!
71 if ( ! empty( $forwarded ) && $forwarded !== $result->ip ) {
72 $result->proxy = true;
73 $result->proxy_ip = $result->ip;
74 $result->ip = $forwarded;
75 }
76
77 if ( $result->ip ) {
78 $user_ip = $result->ip;
79 } else {
80 $user_ip = 'UNKNOWN';
81 }
82
83 return apply_filters( 'hustle_user_ip', $user_ip );
84 }
85
86 /**
87 * Checks if the users IP address belongs to a certain country.
88 *
89 * @return bool
90 */
91 public function get_user_country() {
92
93 // check for bot
94 if ( self::_is_crawler() ) {
95 return false;
96 }
97
98 // Grab the users IP address
99 $ip = self::get_user_ip();
100
101 // See if an add-on provides the country for us.
102 $country = apply_filters( 'wpoi-get-user-country', '', $ip );
103
104 if ( empty( $country ) ) {
105 $country = $this->get_country_from_ip( $ip );
106 }
107
108 if ( empty( $country ) ) {
109 $country = 'XX';
110 }
111
112 return $country;
113 }
114
115 /**
116 * Returns a list of available ip-resolution services.
117 *
118 * @return array List of available webservices.
119 */
120 private function _get_geo_services() {
121 static $geo_service = null;
122 if ( null === $geo_service ) {
123 $geo_service = array();
124
125 $geo_service['hostip'] = (object) array(
126 'label' => 'Host IP',
127 'url' => 'http://api.hostip.info/country.php?ip=%ip%',
128 'type' => 'text',
129 );
130
131 $geo_service['geoplugin'] = (object) array(
132 'label' => 'GeoPlugin',
133 'url' => 'http://www.geoplugin.net/json.gp?ip=%ip%',
134 'type' => 'json',
135 'field' => array( 'geoplugin_countryCode' ),
136 );
137
138 /**
139 * Allow other modules/plugins to register a geo service.
140 */
141 $geo_service = apply_filters( 'wpoi-geo-services', $geo_service );
142 }
143
144 return $geo_service;
145 }
146
147 /**
148 * Returns a list of deprecated geo ip-resolution services.
149 *
150 * @since 4.2.1
151 * @return array List of deprecated webservices.
152 */
153 private function get_deprecated_geo_services() {
154 $geo_service = array(
155 'telize',
156 'nekudo',
157 );
158
159 /**
160 * Hook to filter the list of depracated geo ip-resolution services.
161 *
162 * @since 4.2.1
163 *
164 * @param array
165 */
166 $geo_service = apply_filters( 'hustle_depracated_geo_services', $geo_service );
167
168 return $geo_service;
169 }
170
171
172 /**
173 * Returns the lookup-service details
174 *
175 * @return object Service object for geo lookup
176 */
177 private function _get_service( $type = null ) {
178 $service = false;
179 if ( null === $type ) {
180 $remote_ip_url = apply_filters( 'wpoi-remote-ip-url', '' );
181 if ( ! empty( $remote_ip_url ) ) {
182 $type = '';
183 } else {
184 $type = self::DEFAULT_GEOIP_PROVIDER;
185 }
186
187 /**
188 * Allow to choose a geo service.
189 */
190 $type = apply_filters( 'wpoi-geo-type-service', $type );
191 }
192
193 if ( empty( $type ) ) {
194 $service = (object) array(
195 'url' => $remote_ip_url,
196 'label' => 'wp-config.php',
197 'type' => 'text',
198 );
199 } elseif ( 'geo_db' === $type ) {
200 $service = (object) array(
201 'url' => 'db',
202 'label' => __( 'Local IP Lookup Table', 'hustle' ),
203 'type' => 'text',
204 );
205 } else {
206 $geo_service = $this->_get_geo_services();
207 $deprecated_geo_service = $this->get_deprecated_geo_services();
208
209 if ( in_array( $type, $deprecated_geo_service, true ) ) {
210 $message = sprintf(
211 /* translators: %s: geoip provider name. */
212 __( 'GeoIP provider %s is no longer available. Switching to default.', 'hustle' ),
213 $type
214 );
215 _deprecated_argument( __FUNCTION__, '4.2.1', $message );
216
217 $service = $geo_service[ self::DEFAULT_GEOIP_PROVIDER ];
218 } else {
219 if ( isset( $geo_service[ $type ] ) ) {
220 $service = $geo_service[ $type ];
221 } else {
222 if ( WP_DEBUG ) {
223 $message = sprintf(
224 /* translators: %s: geoip provider name. */
225 __( 'GeoIP provider %s does not exist. Switching to default.', 'hustle' ),
226 $type
227 );
228 trigger_error( $message, E_USER_NOTICE );
229 }
230 $service = $geo_service[ self::DEFAULT_GEOIP_PROVIDER ];
231 }
232 }
233 }
234
235 return $service;
236 }
237
238 /**
239 * Queries an external geo-API to find the country of the specified IP.
240 *
241 * @param string $ip The IP Address.
242 * @param object $service Lookup-Service details.
243 * @return string The country code.
244 */
245 private function _country_from_api( $ip, $service ) {
246 $country = false;
247
248 if ( is_object( $service ) && ! empty( $service->url ) ) {
249 $url = str_replace( '%ip%', $ip, $service->url );
250 $response = wp_remote_get( $url );
251
252 if ( ! is_wp_error( $response ) ) {
253
254 $body = isset( $response['body'] ) ? $response['body'] : '';
255
256 if ( ! is_wp_error( $response )
257 && 200 === (int) $response['response']['code']
258 && 'XX' !== $response['body']
259 || false !== ( $body = file_get_contents( $url ) ) // phpcs:ignore
260 ) {
261 if ( 'text' === $service->type ) {
262 $country = trim( $body );
263 } elseif ( 'json' === $service->type ) {
264 $data = (array) json_decode( $body );
265 if ( isset( $service->field ) ) {
266 if ( is_array( $service->field ) ) {
267 $keys = $service->field;
268 $value = $data;
269 while ( $a = array_shift( $keys ) ) { // phpcs:ignore
270 if ( is_array( $value ) ) {
271 if ( isset( $value[ $a ] ) ) {
272 $value = $value[ $a ];
273 }
274 } elseif ( is_object( $value ) ) {
275 if ( isset( $value->$a ) ) {
276 $value = $value->$a;
277 }
278 }
279 if ( is_string( $value ) ) {
280 $country = $value;
281 }
282 }
283 } else {
284 $country = isset( $data[ $service->field ] ) ? $data[ $service->field ] : null;
285 }
286 }
287 }
288 }
289 }
290 }
291
292 return $country;
293 }
294
295 /**
296 * Updates ip-country map and stores in options ( sitemeta ) table
297 *
298 * @param $ip
299 * @param $country
300 * @return mixed
301 */
302 private function _update_ip_county_map( $ip, $country ) {
303 $country_ip_map[ $ip ] = $country;
304 update_option( self::COUNTRY_IP_MAP, $country_ip_map );
305 return $country;
306 }
307
308 /**
309 * Retrieves ip-country map from options ( sitemeta ) table
310 *
311 * @return array
312 */
313 private function _get_ip_county_map() {
314 return get_option( self::COUNTRY_IP_MAP, array() );
315 }
316
317 /**
318 * Checks if the user is a crawler/bot.
319 *
320 * @return bool
321 */
322 private static function _is_crawler() {
323
324 if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/bot|crawler|ia_archiver|mediapartners-google|80legs|wget|voyager|baiduspider|curl|yahoo!|slurp/i', $_SERVER['HTTP_USER_AGENT'] ) ) {
325 return true;
326 }
327
328 return false;
329 }
330
331 /**
332 * Returns country string using ip address
333 *
334 * @param $ip
335 * @return string
336 */
337 public function get_country_from_ip( $ip ) {
338 // check for bot
339 if ( self::_is_crawler() ) {
340 return false;
341 }
342
343 $ip = (string) $ip;
344
345 if ( '127.0.0.1' === $ip ) {
346 return $this->_update_ip_county_map( $ip, 'localhost' ); }
347
348 $country_ip_map = $this->_get_ip_county_map();
349 if ( isset( $country_ip_map[ $ip ] ) ) {
350 if ( ! empty( $country_ip_map[ $ip ] ) ) {
351 return $country_ip_map[ $ip ];
352 }
353 }
354 $service = $this->_get_service();
355 $country = $this->_country_from_api( $ip, $service );
356
357 if ( ! empty( $country ) ) {
358 return $this->_update_ip_county_map( $ip, $country );
359 }
360
361 return 'XX';
362 }
363 }
364