public function city($ip)
 {
     if (!geoip_detect_is_ip($ip, true)) {
         throw new \Exception('The Hostip.info-Database only contains IPv4 adresses.');
     }
     $data = $this->api_call($ip);
     if (!$data) {
         return null;
     }
     $r = array();
     if ($data['country_name']) {
         $r['country']['names'] = array('en' => $data['country_name']);
     }
     if ($data['country_code']) {
         $r['country']['iso_code'] = strtoupper($data['country_code']);
     }
     if ($data['city']) {
         $r['city']['names'] = array('en' => $data['city']);
     }
     $r['traits']['ip_address'] = $ip;
     $record = new \GeoIp2\Model\City($r, array('en'));
     return $record;
 }
/**
 * Sometimes we can only see an local IP adress (local development environment.)
 * In this case we need to ask an internet server which IP adress our internet connection has.
 * (This function is not cached. Some providers may throttle our requests, that's why caching is enabled by default.)
 * 
 * @return string The detected IPv4 Adress. If none is found, '0.0.0.0' is returned instead.
 */
function _geoip_detect_get_external_ip_adress_without_cache()
{
    $ipservices = array('http://ipv4.icanhazip.com', 'http://ipecho.net/plain', 'http://v4.ident.me', 'http://bot.whatismyipaddress.com', 'http://ip.appspot.com');
    // Randomizing to avoid querying the same service each time
    shuffle($ipservices);
    $ipservices = apply_filters('geiop_detect_ipservices', $ipservices);
    $ipservices = array_slice($ipservices, 0, 3);
    foreach ($ipservices as $url) {
        $ret = wp_remote_get($url, array('timeout' => defined('WP_TESTS_TITLE') ? 3 : 1));
        if (is_wp_error($ret)) {
            if (WP_DEBUG || defined('WP_TESTS_TITLE')) {
                trigger_error('_geoip_detect_get_external_ip_adress_without_cache(): Curl error (' . $url . '): ' . $ret->get_error_message(), E_USER_NOTICE);
            }
        } else {
            if (isset($ret['response']['code']) && $ret['response']['code'] != 200) {
                if (WP_DEBUG || defined('WP_TESTS_TITLE')) {
                    trigger_error('_geoip_detect_get_external_ip_adress_without_cache(): HTTP error (' . $url . '): Returned code ' . $ret['response']['code'], E_USER_NOTICE);
                }
            } else {
                if (isset($ret['body'])) {
                    $ip = trim($ret['body']);
                    if (geoip_detect_is_ip($ip)) {
                        return $ip;
                    }
                }
            }
        }
    }
    return '0.0.0.0';
}
function geoip_detect_option_page()
{
    if (!current_user_can('manage_options')) {
        return;
    }
    $registry = DataSourceRegistry::getInstance();
    $sources = $registry->getAllSources();
    $currentSource = $registry->getCurrentSource();
    $message = '';
    $numeric_options = array('set_css_country', 'has_reverse_proxy', 'disable_pagecache');
    $text_options = array('external_ip');
    $option_names = array_merge($numeric_options, $text_options);
    if (geoip_detect_verify_nonce()) {
        switch (@$_POST['action']) {
            case 'update':
                $registry->setCurrentSource('auto');
                $s = new \YellowTree\GeoipDetect\DataSources\Auto\AutoDataSource();
                $ret = $s->maxmindUpdate();
                if ($ret === true) {
                    $message .= __('Updated successfully.', 'geoip-detect');
                } else {
                    $message .= __('Update failed.', 'geoip-detect') . ' ' . $ret;
                }
                break;
            case 'choose':
                $registry->setCurrentSource($_POST['options']['source']);
                $currentSource = $registry->getCurrentSource();
                break;
            case 'options-source':
                $messages = array();
                foreach ($sources as $s) {
                    $ret = $s->saveParameters($_POST);
                    if (is_string($ret) && $ret) {
                        $messages[] = $ret;
                    }
                }
                if ($messages) {
                    $message .= implode('<br />', $messages);
                }
                break;
            case 'options':
                // Empty IP Cache
                delete_transient('geoip_detect_external_ip');
                if (!empty($_POST['options']['external_ip'])) {
                    if (!geoip_detect_is_ip($_POST['options']['external_ip'])) {
                        $message .= 'The external IP "' . esc_html($_POST['options']['external_ip']) . '" is not a valid IP.';
                        unset($_POST['options']['external_ip']);
                    } else {
                        if (!geoip_detect_is_public_ip($_POST['options']['external_ip'])) {
                            $message .= 'Warning: The external IP "' . esc_html($_POST['options']['external_ip']) . '" is not a public internet IP, so it will probably not work.';
                        }
                    }
                }
                foreach ($option_names as $opt_name) {
                    if (in_array($opt_name, $numeric_options)) {
                        $opt_value = isset($_POST['options'][$opt_name]) ? (int) $_POST['options'][$opt_name] : 0;
                    } else {
                        $opt_value = isset($_POST['options'][$opt_name]) ? $_POST['options'][$opt_name] : '';
                    }
                    update_option('geoip-detect-' . $opt_name, $opt_value);
                }
                break;
        }
    }
    $wp_options = array();
    foreach ($option_names as $opt_name) {
        $wp_options[$opt_name] = get_option('geoip-detect-' . $opt_name);
    }
    $ipv6_supported = GEOIP_DETECT_IPV6_SUPPORTED;
    include_once GEOIP_PLUGIN_DIR . '/views/options.php';
}
 function testExternalIpShortcode()
 {
     $ip = do_shortcode('[geoip_detect2_get_external_ip_adress]');
     $this->assertTrue(geoip_detect_is_ip($ip), 'The return of the shortcode was not an ip adress: "' . $ip . '"');
 }