diff --git 1.0/index.php 1.0/index.php
index acc1871..416dfd6 100644
|
|
function get_prepare_placeholders( $number, $format ) { |
361 | 361 | * NOTE: The location that is found here cannot be returned to the client. |
362 | 362 | * See `rebuild_location_from_geonames()`. |
363 | 363 | * |
364 | | * @todo - Add support for IPv6 addresses. Otherwise, this will quickly lose effectiveness. As of March 2017, IPv6 |
365 | | * adoption is at 16% globally and rising relatively fast. Some countries are as high as 30%. |
366 | | * See https://www.google.com/intl/en/ipv6/statistics.html#tab=ipv6-adoption for current stats. |
367 | | * |
368 | | * @todo - Core sends anonymized IPs like `2a03:2880:2110:df07::`, so make sure those work when implementing IPv6 |
369 | | * |
370 | 364 | * @param string $dotted_ip |
371 | 365 | * |
372 | 366 | * @return null|object `null` on failure; an object on success |
… |
… |
function get_prepare_placeholders( $number, $format ) { |
374 | 368 | function guess_location_from_ip( $dotted_ip ) { |
375 | 369 | global $wpdb; |
376 | 370 | |
377 | | $long_ip = ip2long( $dotted_ip ); |
378 | | if ( $long_ip === false ) |
| 371 | $long_ip = false; |
| 372 | |
| 373 | if ( filter_var( $dotted_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) { |
| 374 | $long_ip = ip2long( $dotted_ip ); |
| 375 | $from = 'ip2location'; |
| 376 | $where = 'ip_to >= %d'; |
| 377 | } else if ( filter_var( $dotted_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { |
| 378 | $long_ip = _ip2long_v6( $dotted_ip ); |
| 379 | $from = 'ip2location_v6'; |
| 380 | $where = "ip_to >= CAST('%s' AS decimal(39,0))"; |
| 381 | } |
| 382 | |
| 383 | if ( false === $long_ip || ! isset( $from, $where ) ) { |
379 | 384 | return; |
| 385 | } |
380 | 386 | |
381 | 387 | $row = $wpdb->get_row( $wpdb->prepare( " |
382 | 388 | SELECT ip_city, ip_latitude, ip_longitude, country_short |
383 | | FROM ip2location |
384 | | WHERE ip_to >= %d |
| 389 | FROM $from |
| 390 | WHERE $where |
385 | 391 | ORDER BY ip_to ASC |
386 | 392 | LIMIT 1", |
387 | 393 | $long_ip |
… |
… |
function guess_location_from_ip( $dotted_ip ) { |
396 | 402 | } |
397 | 403 | |
398 | 404 | /** |
| 405 | * Convert an IPv6 address to an IP number than can be queried in the ip2location database. |
| 406 | * |
| 407 | * PHP doesn't handle integers large enough to accommodate IPv6 numbers (128 bit), so the number needs |
| 408 | * to be cast as a string. |
| 409 | * |
| 410 | * @link https://en.wikipedia.org/wiki/IPv6 |
| 411 | * @link http://php.net/manual/en/language.types.integer.php |
| 412 | * |
| 413 | * The code in this function is based on an answer here: http://lite.ip2location.com/faqs |
| 414 | * |
| 415 | * Uses `inet_pton()` which correctly parses truncated IPv6 addresses such as `2a03:2880:2110:df07::` |
| 416 | * |
| 417 | * @access private |
| 418 | * |
| 419 | * @param string $address The IPv6 address to convert. |
| 420 | * |
| 421 | * @return string|bool `false` if invalid address. Otherwise an IP number cast as a string. |
| 422 | */ |
| 423 | function _ip2long_v6( $address ) { |
| 424 | $int = inet_pton( $address ); |
| 425 | |
| 426 | if ( false === $int ) { |
| 427 | return false; |
| 428 | } |
| 429 | |
| 430 | $bits = 15; |
| 431 | $ipv6long = 0; |
| 432 | |
| 433 | while ( $bits >= 0 ) { |
| 434 | $bin = sprintf( "%08b", ( ord( $int[ $bits ] ) ) ); |
| 435 | |
| 436 | if ( $ipv6long ) { |
| 437 | $ipv6long = $bin . $ipv6long; |
| 438 | } else { |
| 439 | $ipv6long = $bin; |
| 440 | } |
| 441 | |
| 442 | $bits--; |
| 443 | } |
| 444 | |
| 445 | $ipv6long = gmp_strval( gmp_init( $ipv6long, 2 ), 10 ); |
| 446 | |
| 447 | return $ipv6long; |
| 448 | } |
| 449 | |
| 450 | /** |
399 | 451 | * Rebuild the location given to the client from the event source data |
400 | 452 | * |
401 | 453 | * We cannot publicly expose location data that we retrieve from the `ip2location` database, because that would |