function ip_geo_block_tab_geolocation($context)
{
    $plugin_slug = IP_Geo_Block::PLUGIN_SLUG;
    $option_slug = $context->option_slug['settings'];
    $option_name = $context->option_name['settings'];
    $options = IP_Geo_Block::get_option('settings');
    register_setting($option_slug, $option_name);
    /*----------------------------------------*
     * Geolocation
     *----------------------------------------*/
    $section = "{$plugin_slug}-search";
    add_settings_section($section, __('Search IP address geolocation', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    // make providers list
    $list = array();
    $providers = IP_Geo_Block_Provider::get_providers('key');
    foreach ($providers as $provider => $key) {
        if (!is_string($key) || !empty($options['providers'][$provider])) {
            $list += array($provider => $provider);
        }
    }
    $field = 'service';
    $provider = array_keys($providers);
    add_settings_field($option_name . "_{$field}", __('Geolocation service', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'value' => $provider[0], 'list' => $list));
    $field = 'ip_address';
    add_settings_field($option_name . "_{$field}", __('IP address', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'value' => ''));
    $field = 'get_location';
    add_settings_field($option_name . "_{$field}", __('Find geolocation', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Search now', IP_Geo_Block::TEXT_DOMAIN), 'after' => "<div id=\"{$plugin_slug}-loading\"></div>"));
}
 /**
  * Limit the number of rows to send to the user agent
  *
  */
 public static function limit_rows($time)
 {
     $time = intval($time);
     $options = IP_Geo_Block::get_option('settings');
     if ($time < 100) {
         return (int) $options['validation']['maxlogs'];
     } elseif ($time < 200) {
         return (int) ($options['validation']['maxlogs'] / 2);
     }
     return (int) ($options['validation']['maxlogs'] / 5);
 }
 /**
  * Post process (never return)
  *
  */
 private static function abort($validate, $settings, $exist)
 {
     $context = IP_Geo_Block::get_instance();
     // mark as malicious
     $validate['result'] = 'blocked';
     //'malice';
     // (1) blocked, unknown, (3) unauthenticated, (5) all
     if ((int) $settings['validation']['reclogs'] & 1) {
         require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
         IP_Geo_Block_Logs::record_log('admin', $validate, $settings);
     }
     // update statistics
     if ($settings['save_statistics']) {
         $context->update_statistics('admin', $validate);
     }
     // send response code to refuse
     $context->send_response('admin', $exist ? $settings['response_code'] : 404);
 }
function ip_geo_block_tab_accesslog($context)
{
    $plugin_slug = IP_Geo_Block::PLUGIN_SLUG;
    $option_slug = $context->option_slug['settings'];
    $option_name = $context->option_name['settings'];
    $settings = IP_Geo_Block::get_option('settings');
    register_setting($option_slug, $option_name);
    if ($settings['validation']['reclogs']) {
        /*----------------------------------------*
         * Validation logs
         *----------------------------------------*/
        $section = "{$plugin_slug}-accesslog";
        add_settings_section($section, __('Validation logs', IP_Geo_Block::TEXT_DOMAIN), 'ip_geo_block_list_accesslog', $option_slug);
        $field = 'clear_logs';
        add_settings_field($option_name . "_{$field}", __('Clear logs', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Clear now', IP_Geo_Block::TEXT_DOMAIN), 'after' => "<div id=\"{$plugin_slug}-logs\"></div>"));
    } else {
        /*----------------------------------------*
         * Warning
         *----------------------------------------*/
        $section = "{$plugin_slug}-accesslog";
        add_settings_section($section, __('Validation logs', IP_Geo_Block::TEXT_DOMAIN), 'ip_geo_block_warn_accesslog', $option_slug);
    }
}
 /**
  * Check status of provider selection
  *
  */
 public static function diag_providers($settings = NULL)
 {
     if (!$settings) {
         $settings = IP_Geo_Block::get_option('settings');
         $settings = $settings['providers'];
     }
     $field = 0;
     foreach (self::get_providers('key') as $key => $val) {
         if (NULL === $val && !isset($settings[$key]) || FALSE === $val && !empty($settings[$key]) || is_string($val) && !empty($settings[$key])) {
             $field++;
         }
     }
     if (0 === $field) {
         return __('You need to select at least one IP geolocation service. Otherwise <strong>you\'ll be blocked</strong> after the cache expires.', IP_Geo_Block::TEXT_DOMAIN);
     }
     return NULL;
 }
 /**
  * Example 17: Usage of 'IP_Geo_Block::get_geolocation()'
  * Use case: Get geolocation of visitor's ip address with latitude and longitude
  *
  */
 function my_geolocation()
 {
     /**
      * IP_Geo_Block::get_geolocation(
      *    $ip = NULL, $providers = array(), $callback = 'get_country'
      * );
      *
      * @param string $ip IP address / default: $_SERVER['REMOTE_ADDR']
      * @param array  $providers list of providers / ex: array( 'ipinfo.io' )
      * @param string $callback geolocation function / ex: 'get_location'
      * @return array country code and so on
      */
     $geolocation = IP_Geo_Block::get_geolocation();
     /**
      * 'ip'       => validated ip address
      * 'auth'     => authenticated or not
      * 'time'     => processing time
      * 'code'     => country code
      * 'provider' => IP geolocation service provider
      */
     var_dump($geolocation);
     if (isset($geolocation['errorMessage'])) {
         echo 'error at getting geolocation';
         // error handling
     }
 }
function ip_geo_block_tab_statistics($context)
{
    $plugin_slug = IP_Geo_Block::PLUGIN_SLUG;
    $option_slug = $context->option_slug['statistics'];
    $option_name = $context->option_name['statistics'];
    $options = IP_Geo_Block::get_option('statistics');
    $setting = IP_Geo_Block::get_option('settings');
    register_setting($option_slug, $option_name);
    if ($setting['save_statistics']) {
        /*----------------------------------------*
         * Statistics of comment post
         *----------------------------------------*/
        $section = "{$plugin_slug}-statistics";
        add_settings_section($section, __('Statistics of validation', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
        $field = 'blocked';
        add_settings_field($option_name . "_{$field}", __('Blocked', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'html', 'option' => $option_name, 'field' => $field, 'value' => esc_html($options[$field])));
        $field = 'countries';
        $html = "<div id=\"{$plugin_slug}-chart-countries\"></div>";
        $html .= "<ul id=\"{$plugin_slug}-countries\" class=\"{$option_slug}-{$field}\">";
        arsort($options['countries']);
        foreach ($options['countries'] as $key => $val) {
            $html .= sprintf("<li>%2s:%5d</li>", esc_html($key), (int) $val);
        }
        $html .= "</ul>";
        add_settings_field($option_name . "_{$field}", __('Blocked by countries', IP_Geo_Block::TEXT_DOMAIN) . '<br>(<a id="show-hide-details" href="javascript:void(0)" title="Show/Hide details">' . __('Show/Hide details', IP_Geo_Block::TEXT_DOMAIN) . '</a>)', array($context, 'callback_field'), $option_slug, $section, array('type' => 'html', 'option' => $option_name, 'field' => $field, 'value' => $html));
        $field = 'type';
        add_settings_field($option_name . "_{$field}", __('Blocked by type of IP address', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'html', 'option' => $option_name, 'field' => $field, 'value' => "<table class=\"{$option_slug}-{$field}\">" . "<thead><tr><th>IPv4</th><th>IPv6</th></tr></thead><tbody><tr>" . "<td>" . esc_html($options['IPv4']) . "</td>" . "<td>" . esc_html($options['IPv6']) . "</td>" . "</tr></tbody></table>"));
        $field = 'service';
        $html = "<table class=\"{$option_slug}-{$field}\"><thead><tr>";
        $html .= "<th>" . __('Name of API', IP_Geo_Block::TEXT_DOMAIN) . "</th>";
        $html .= "<th>" . __('Calls', IP_Geo_Block::TEXT_DOMAIN) . "</th>";
        $html .= "<th>" . __('Response [msec]', IP_Geo_Block::TEXT_DOMAIN) . "</th>";
        $html .= "</tr></thead><tbody>";
        foreach ($options['providers'] as $key => $val) {
            $html .= "<tr><td>" . esc_html($key) . "</td>";
            $html .= "<td>" . sprintf("%5d", (int) $val['count']) . "</td><td>";
            $html .= sprintf("%5d", (int) (1000.0 * $val['time'] / $val['count']));
            $html .= "</td></tr>";
        }
        $html .= "</tbody></table>";
        add_settings_field($option_name . "_{$field}", __('Average response time of each API', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'html', 'option' => $option_name, 'field' => $field, 'value' => $html));
        $field = 'clear_statistics';
        add_settings_field($option_name . "_{$field}", __('Clear statistics', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Clear now', IP_Geo_Block::TEXT_DOMAIN), 'after' => "<div id=\"{$plugin_slug}-statistics\"></div>"));
    } else {
        /*----------------------------------------*
         * Warning
         *----------------------------------------*/
        $section = "{$plugin_slug}-statistics";
        add_settings_section($section, __('Statistics of validation', IP_Geo_Block::TEXT_DOMAIN), 'ip_geo_block_warn_statistics', $option_slug);
    }
    /*----------------------------------------*
     * Statistics of cache
     *----------------------------------------*/
    $section = "{$plugin_slug}-cache";
    add_settings_section($section, __('Statistics of cache', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    $field = 'cache';
    $html = "<table class=\"{$option_slug}-{$field}\"><thead><tr>";
    $html .= "<th>" . __('IP address', IP_Geo_Block::TEXT_DOMAIN) . "</th>";
    $html .= "<th>" . __('Country code / Access', IP_Geo_Block::TEXT_DOMAIN) . "</th>";
    $html .= "<th>" . __('Elapsed [sec] / Calls', IP_Geo_Block::TEXT_DOMAIN) . "</th>";
    $html .= "</tr></thead><tbody>";
    if ($transient = get_transient(IP_Geo_Block::CACHE_KEY)) {
        $time = time();
        $debug = defined('IP_GEO_BLOCK_DEBUG') && IP_GEO_BLOCK_DEBUG;
        foreach ($transient as $key => $val) {
            if ($setting['anonymize']) {
                $key = preg_replace('/\\d{1,3}$/', '***', $key);
            }
            if (empty($val['auth']) || $debug) {
                // hide authenticated user
                $html .= "<tr><td>" . esc_html($key) . "</td>";
                $html .= "<td>" . esc_html($val['code']) . " / ";
                $html .= "<small>" . esc_html($val['hook']) . "</small></td>";
                $html .= "<td>" . ($time - (int) $val['time']) . " / ";
                $html .= $setting['save_statistics'] ? (int) $val['call'] : "-";
                if ($debug) {
                    $user = get_user_by('id', intval($val['auth']));
                    $html .= " " . esc_html($user ? $user->get('user_login') : "");
                    $html .= " / fail:" . intval($val['fail']);
                }
                $html .= "</td></tr>";
            }
        }
    }
    $html .= "</tbody></table>";
    add_settings_field($option_name . "_{$field}", __('IP address in cache', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'html', 'option' => $option_name, 'field' => $field, 'value' => $html));
    $field = 'clear_cache';
    add_settings_field($option_name . "_{$field}", __('Clear cache', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Clear now', IP_Geo_Block::TEXT_DOMAIN), 'after' => "<div id=\"{$plugin_slug}-cache\"></div>"));
}
 /**
  * Ajax callback function
  *
  * @link http://codex.wordpress.org/AJAX_in_Plugins
  * @link http://codex.wordpress.org/Function_Reference/check_ajax_referer
  * @link http://core.trac.wordpress.org/browser/trunk/wp-admin/admin-ajax.php
  */
 public function admin_ajax_callback()
 {
     // Check request origin, nonce, capability.
     if (!check_admin_referer($this->get_ajax_action(), 'nonce') || !current_user_can('manage_options') || empty($_POST)) {
         // @since 2.0
         status_header(403);
         // Forbidden @since 2.0.0
     }
     $which = isset($_POST['which']) ? $_POST['which'] : NULL;
     switch (isset($_POST['cmd']) ? $_POST['cmd'] : NULL) {
         case 'download':
             $res = IP_Geo_Block::download_database();
             break;
         case 'search':
             require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php';
             // check format
             if (filter_var($ip = $_POST['ip'], FILTER_VALIDATE_IP)) {
                 // get option settings and compose request headers
                 $options = IP_Geo_Block::get_option('settings');
                 $args = IP_Geo_Block::get_request_headers($options);
                 // create object for provider and get location
                 if ($geo = IP_Geo_Block_API::get_instance($which, $options)) {
                     $res = $geo->get_location($ip, $args);
                 } else {
                     $res = array('errorMessage' => 'Unknown service.');
                 }
             } else {
                 $res = array('errorMessage' => 'Invalid IP address.');
             }
             break;
         case 'scan-code':
             require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-apis.php';
             // scan all the country code using selected APIs
             $ip = IP_Geo_Block::get_ip_address();
             $options = IP_Geo_Block::get_option('settings');
             $args = IP_Geo_Block::get_request_headers($options);
             $type = IP_Geo_Block_Provider::get_providers('type', FALSE, FALSE);
             $providers = IP_Geo_Block_Provider::get_valid_providers($options['providers'], FALSE, FALSE);
             $res['IP address'] = esc_html($ip);
             foreach ($providers as $provider) {
                 if ($geo = IP_Geo_Block_API::get_instance($provider, $options)) {
                     $ret = $geo->get_location($ip, $args);
                     $res[$provider] = array('type' => $type[$provider], 'code' => esc_html(FALSE === $ret ? __('n/a', IP_Geo_Block::TEXT_DOMAIN) : (!empty($ret['errorMessage']) ? $ret['errorMessage'] : (!empty($ret['countryCode']) ? $ret['countryCode'] : __('UNKNOWN', IP_Geo_Block::TEXT_DOMAIN)))));
                 }
             }
             break;
         case 'clear-statistics':
             // set default values
             update_option($this->option_name['statistics'], IP_Geo_Block::get_default('statistics'));
             $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG, 'tab' => 'tab=1');
             break;
         case 'clear-cache':
             // delete cache of IP address
             delete_transient(IP_Geo_Block::CACHE_KEY);
             // @since 2.8
             $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG, 'tab' => 'tab=1');
             break;
         case 'clear-logs':
             require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
             $hook = array('comment', 'login', 'admin', 'xmlrpc');
             $which = in_array($which, $hook) ? $which : NULL;
             IP_Geo_Block_Logs::clean_log($which);
             $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG, 'tab' => 'tab=4');
             break;
         case 'restore':
             require_once IP_GEO_BLOCK_PATH . 'includes/localdate.php';
             require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
             // if js is slow then limit the number of rows
             $limit = IP_Geo_Block_Logs::limit_rows(@$_POST['time']);
             // compose html with sanitization
             $which = IP_Geo_Block_Logs::restore_log($which);
             foreach ($which as $hook => $rows) {
                 $html = '';
                 $n = 0;
                 foreach ($rows as $logs) {
                     $log = (int) array_shift($logs);
                     $html .= "<tr><td data-value={$log}>";
                     $html .= ip_geo_block_localdate($log, 'Y-m-d H:i:s') . "</td>";
                     foreach ($logs as $log) {
                         $log = esc_html($log);
                         $html .= "<td>{$log}</td>";
                     }
                     $html .= "</tr>";
                     if (++$n >= $limit) {
                         break;
                     }
                 }
                 $res[$hook] = $html;
             }
             break;
         case 'create_table':
         case 'delete_table':
             require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
             if ('create_table' === $_POST['cmd']) {
                 IP_Geo_Block_Logs::create_log();
             } else {
                 IP_Geo_Block_Logs::delete_log();
             }
             $res = array('page' => 'options-general.php?page=' . IP_Geo_Block::PLUGIN_SLUG);
     }
     if (isset($res)) {
         // wp_send_json_{success,error}() @since 3.5.0
         wp_send_json($res);
     }
     // @since 3.5.0
     die;
     // End of ajax
 }
 /**
  * Return an instance of this class.
  *
  */
 public static function get_instance()
 {
     if (null == self::$instance) {
         self::$instance = new self();
     }
     return self::$instance;
 }
function ip_geo_block_tab_settings($context)
{
    $plugin_slug = IP_Geo_Block::PLUGIN_SLUG;
    $option_slug = $context->option_slug['settings'];
    $option_name = $context->option_name['settings'];
    $options = IP_Geo_Block::get_option('settings');
    // Get the country code
    $key = IP_Geo_Block::get_geolocation();
    /**
     * Register a setting and its sanitization callback.
     * @link http://codex.wordpress.org/Function_Reference/register_setting
     *
     * register_setting( $option_group, $option_name, $sanitize_callback );
     * @param string $option_group A settings group name.
     * @param string $option_name The name of an option to sanitize and save.
     * @param string $sanitize_callback A callback function that sanitizes option values.
     * @since 2.7.0
     */
    register_setting($option_slug, $option_name, array($context, 'validate_settings'));
    /**
     * Add new section to a new page inside the existing page.
     * @link http://codex.wordpress.org/Function_Reference/add_settings_section
     *
     * add_settings_section( $id, $title, $callback, $page );
     * @param string $id String for use in the 'id' attribute of tags.
     * @param string $title Title of the section.
     * @param string $callback Function that fills the section with the desired content.
     * @param string $page The menu page on which to display this section.
     * @since 2.7.0
     */
    /*----------------------------------------*
     * Validation rule settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-validation-rule";
    add_settings_section($section, __('Validation rule settings', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    /**
     * Register a settings field to the settings page and section.
     * @link http://codex.wordpress.org/Function_Reference/add_settings_field
     *
     * add_settings_field( $id, $title, $callback, $page, $section, $args );
     * @param string $id String for use in the 'id' attribute of tags.
     * @param string $title Title of the field.
     * @param string $callback Function that fills the field with the desired inputs.
     * @param string $page The menu page on which to display this field.
     * @param string $section The section of the settings page in which to show the box.
     * @param array $args Additional arguments that are passed to the $callback function.
     */
    $field = 'ip_country';
    add_settings_field($option_name . "_{$field}", __('<dfn title="You can confirm the appropriate Geolocation APIs and country code by referring &#8220;Scan your country code&#8221;.">Your IP address / Country</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'html', 'option' => $option_name, 'field' => $field, 'value' => esc_html($key['ip'] . ' / ' . ($key['code'] ? $key['code'] . ' (' . $key['provider'] . ')' : __('UNKNOWN', IP_Geo_Block::TEXT_DOMAIN))), 'after' => "&nbsp;<a id=\"{$plugin_slug}-scan-code\" class=\"button button-secondary\" href=\"javascript:void(0)\" title=\"" . __('Scan all the APIs you selected at Geolocation API settings', IP_Geo_Block::TEXT_DOMAIN) . '">' . __('Scan your country code', IP_Geo_Block::TEXT_DOMAIN) . "</a><div id=\"{$plugin_slug}-scanning\"></div>"));
    // If the matching rule is not initialized, then add a caution
    $list = 0 <= $options['matching_rule'] ? array() : array(-1 => __('Disable', IP_Geo_Block::TEXT_DOMAIN));
    $list += array(0 => __('White list', IP_Geo_Block::TEXT_DOMAIN), 1 => __('Black list', IP_Geo_Block::TEXT_DOMAIN));
    $comma = '<span style="margin-left: 0.2em">' . __('(comma separated)', IP_Geo_Block::TEXT_DOMAIN) . '</span>';
    $dfn = sprintf(__('<dfn title="&#8220;Block by country&#8221; will be bypassed in case of empty. Please consider to include &#8220;ZZ&#8221; which means UNKNOWN especially in case of black list.">Country code for matching rule</dfn>%s', IP_Geo_Block::TEXT_DOMAIN), ' (<a class="ip-geo-block-link" href="http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements" title="ISO 3166-1 alpha-2 - Wikipedia, the free encyclopedia" target=_blank>ISO 3166-1 alpha-2</a>)');
    $field = 'matching_rule';
    add_settings_field($option_name . "_{$field}", __('<dfn title="Please select either &#8220;White list&#8221; or &#8220;Black list&#8221;.">Matching rule</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'value' => $options[$field], 'list' => $list));
    $field = 'white_list';
    add_settings_field($option_name . "_{$field}", $dfn, array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'value' => $options[$field], 'display' => $options['matching_rule'] !== 1, 'after' => $comma));
    $field = 'black_list';
    add_settings_field($option_name . "_{$field}", $dfn, array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'value' => $options[$field], 'display' => $options['matching_rule'] !== 0, 'after' => $comma));
    $field = 'extra_ips';
    $key = 'white_list';
    add_settings_field($option_name . "_{$field}_{$key}", __('<dfn title="e.g. &#8220;192.0.64.0/18&#8221; for Jetpack server, &#8220;69.46.36.0/27&#8221; for WordFence server">White list of extra IP addresses prior to country code</dfn>', IP_Geo_Block::TEXT_DOMAIN) . ' (<a class="ip-geo-block-link" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia" target=_blank>CIDR</a>)', array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'after' => $comma));
    $key = 'black_list';
    add_settings_field($option_name . "_{$field}_{$key}", __('<dfn title="Server level access control (e.g. .htaccess) is recommended.">Black list of extra IP addresses prior to country code</dfn>', IP_Geo_Block::TEXT_DOMAIN) . ' (<a class="ip-geo-block-link" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" title="Classless Inter-Domain Routing - Wikipedia, the free encyclopedia" target=_blank>CIDR</a>)', array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'after' => $comma));
    $field = 'validation';
    $key = 'proxy';
    add_settings_field($option_name . "_{$field}_{$key}", __('<dfn title="e.g. HTTP_X_FORWARDED_FOR">$_SERVER keys to retrieve extra IP addresses</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'after' => $comma));
    $field = 'response_code';
    add_settings_field($option_name . "_{$field}", sprintf(__('Response code %s', IP_Geo_Block::TEXT_DOMAIN), "(<a class=\"{$plugin_slug}-link\" href=\"http://tools.ietf.org/html/rfc2616#section-10\" title=\"RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1\" target=_blank>RFC 2616</a>)"), array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'value' => $options[$field], 'list' => array(200 => '200 OK', 205 => '205 Reset Content', 301 => '301 Moved Permanently', 302 => '302 Found', 307 => '307 Temporary Redirect', 400 => '400 Bad Request', 403 => '403 Forbidden', 404 => '404 Not Found', 406 => '406 Not Acceptable', 410 => '410 Gone', 500 => '500 Internal Server Error', 503 => '503 Service Unavailable')));
    /*----------------------------------------*
     * Validation target settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-validation-target";
    add_settings_section($section, __('Validation target settings', IP_Geo_Block::TEXT_DOMAIN), 'ip_geo_block_note_target', $option_slug);
    // same as in tab-accesslog.php
    $dfn = __('<dfn title="Validate access to %s.">%s</dfn>', IP_Geo_Block::TEXT_DOMAIN);
    $list = array('comment' => sprintf($dfn, 'wp-comments-post.php', __('Comment post', IP_Geo_Block::TEXT_DOMAIN)), 'xmlrpc' => sprintf($dfn, 'xmlrpc.php', __('XML-RPC', IP_Geo_Block::TEXT_DOMAIN)), 'login' => sprintf($dfn, 'wp-login.php', __('Login form', IP_Geo_Block::TEXT_DOMAIN)), 'admin' => sprintf($dfn, 'wp-admin/*.php', __('Admin area', IP_Geo_Block::TEXT_DOMAIN)));
    $admin = array_pop($list);
    $login = array_pop($list);
    $field = 'validation';
    foreach ($list as $key => $val) {
        add_settings_field($option_name . "_{$field}_{$key}", $list[$key], array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkbox', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'text' => __('Block by country', IP_Geo_Block::TEXT_DOMAIN)));
    }
    $key = 'login';
    add_settings_field($option_name . "_{$field}_{$key}", $login, array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'list' => array(0 => __('Disable', IP_Geo_Block::TEXT_DOMAIN), 2 => __('Block by country (register, lost password)', IP_Geo_Block::TEXT_DOMAIN), 1 => __('Block by country', IP_Geo_Block::TEXT_DOMAIN)), 'desc' => array(2 => __('Registered users can login as membership from anywhere, but the request for new user registration and lost password is blocked by the country code.', IP_Geo_Block::TEXT_DOMAIN)), 'after' => '<div class="ip_geo_block_settings_desc"></div>'));
    $list = array(1 => __('Block by country', IP_Geo_Block::TEXT_DOMAIN), 2 => __('Prevent Zero-day Exploit', IP_Geo_Block::TEXT_DOMAIN));
    $login = array(1 => __('It will block a request related to the services for both public facing pages and the dashboard.', IP_Geo_Block::TEXT_DOMAIN), 2 => __('Regardless of the country code, it will block a malicious request related to the services only for the dashboard.', IP_Geo_Block::TEXT_DOMAIN));
    $key = 'admin';
    add_settings_field($option_name . "_{$field}_{$key}", $admin, array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkboxes', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'list' => $list, 'desc' => $login));
    $key = 'ajax';
    $val = esc_html(substr(IP_Geo_Block::$content_dir['admin'], 1));
    add_settings_field($option_name . "_{$field}_{$key}", sprintf($dfn, "{$val}admin-(ajax|post).php", __('Admin ajax/post', IP_Geo_Block::TEXT_DOMAIN)), array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkboxes', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'list' => $list, 'desc' => $login));
    array_unshift($list, __('Disable', IP_Geo_Block::TEXT_DOMAIN));
    $admin = __('Regardless of the country code, it will block a malicious request to <code>%s&hellip;/*.php</code>.', IP_Geo_Block::TEXT_DOMAIN);
    $key = 'plugins';
    $val = esc_html(substr(IP_Geo_Block::$content_dir['plugins'], 1));
    add_settings_field($option_name . "_{$field}_{$key}", sprintf($dfn, "{$val}&hellip;/*.php", __('Plugins area', IP_Geo_Block::TEXT_DOMAIN)), array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'list' => $list, 'desc' => array(2 => sprintf($admin, $val)), 'after' => '<div class="ip_geo_block_settings_desc"></div>'));
    $key = 'themes';
    $val = esc_html(substr(IP_Geo_Block::$content_dir['themes'], 1));
    add_settings_field($option_name . "_{$field}_{$key}", sprintf($dfn, "{$val}&hellip;/*.php", __('Themes area', IP_Geo_Block::TEXT_DOMAIN)), array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'sub-field' => $key, 'value' => $options[$field][$key], 'list' => $list, 'desc' => array(2 => sprintf($admin, $val)), 'after' => '<div class="ip_geo_block_settings_desc"></div>'));
    $field = 'signature';
    add_settings_field($option_name . "_{$field}", __('<dfn title="This works independently of &#8220;Block by country&#8221; and &#8220;Prevent Zero-day Exploit&#8221;, and validates malicious signature to prevent disclosing the important files via vulnerable plugins or themes.">Important files</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'value' => $options[$field], 'after' => $comma));
    /*----------------------------------------*
     * Geolocation service settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-provider";
    add_settings_section($section, __('Geolocation API settings', IP_Geo_Block::TEXT_DOMAIN), 'ip_geo_block_note_services', $option_slug);
    $field = 'providers';
    add_settings_field($option_name . "_{$field}", __('<dfn title="Cache and local database are scaned at the top priority.">API selection and key settings</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'check-provider', 'option' => $option_name, 'field' => $field, 'value' => $options[$field], 'providers' => IP_Geo_Block_Provider::get_providers('key'), 'titles' => IP_Geo_Block_Provider::get_providers('type')));
    /*----------------------------------------*
     * Local database settings
     *----------------------------------------*/
    // higher priority order
    $providers = IP_Geo_Block_Provider::get_addons();
    $section = "{$plugin_slug}-database";
    add_settings_section($section, __('Local database settings', IP_Geo_Block::TEXT_DOMAIN), empty($providers) ? 'ip_geo_block_note_database' : NULL, $option_slug);
    foreach ($providers as $provider) {
        if ($geo = IP_Geo_Block_API::get_instance($provider, NULL)) {
            $geo->add_settings_field($provider, $section, $option_slug, $option_name, $options, array($context, 'callback_field'), __('database', IP_Geo_Block::TEXT_DOMAIN), __('Last update: %s', IP_Geo_Block::TEXT_DOMAIN));
        }
    }
    $field = 'update';
    add_settings_field($option_name . "_{$field}_auto", __('Auto updating (once a month)', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkbox', 'option' => $option_name, 'field' => $field, 'sub-field' => 'auto', 'value' => $options[$field]['auto'], 'disabled' => empty($providers)));
    add_settings_field($option_name . "_{$field}_download", __('Download database', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Download now', IP_Geo_Block::TEXT_DOMAIN), 'disabled' => empty($providers), 'after' => "<div id=\"{$plugin_slug}-download\"></div>"));
    /*----------------------------------------*
     * Record settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-recording";
    add_settings_section($section, __('Record settings', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    $field = 'save_statistics';
    add_settings_field($option_name . "_{$field}", __('Record validation statistics', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkbox', 'option' => $option_name, 'field' => $field, 'value' => $options[$field]));
    $field = 'validation';
    add_settings_field($option_name . "_{$field}_reclogs", __('Record validation logs', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'select', 'option' => $option_name, 'field' => $field, 'sub-field' => 'reclogs', 'value' => $options[$field]['reclogs'], 'list' => array(0 => __('Disable', IP_Geo_Block::TEXT_DOMAIN), 1 => __('Only when blocked', IP_Geo_Block::TEXT_DOMAIN), 2 => __('Only when passed', IP_Geo_Block::TEXT_DOMAIN), 3 => __('Unauthenticated user', IP_Geo_Block::TEXT_DOMAIN), 4 => __('Authenticated user', IP_Geo_Block::TEXT_DOMAIN), 5 => __('All of validation', IP_Geo_Block::TEXT_DOMAIN))));
    add_settings_field($option_name . "_{$field}_postkey", __('<dfn title="e.g. action, comment, log, pwd">$_POST keys to be recorded with their values in logs</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'sub-field' => 'postkey', 'value' => $options[$field]['postkey'], 'after' => $comma));
    $field = 'anonymize';
    add_settings_field($option_name . "_{$field}", __('<dfn title="e.g. 123.456.789.***">Anonymize IP address</dfn>', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkbox', 'option' => $option_name, 'field' => $field, 'value' => !empty($options[$field]) ? TRUE : FALSE));
    /*----------------------------------------*
     * Cache settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-cache";
    add_settings_section($section, __('Cache settings', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    $field = 'cache_hold';
    add_settings_field($option_name . "_{$field}", __('Number of entries', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'value' => $options[$field]));
    $field = 'cache_time';
    add_settings_field($option_name . "_{$field}", sprintf(__('<dfn title="If user authentication fails consecutively %d times, subsequent login will also be prohibited for this period.">Expiration time [sec]</dfn>', IP_Geo_Block::TEXT_DOMAIN), (int) $options['login_fails']), array($context, 'callback_field'), $option_slug, $section, array('type' => 'text', 'option' => $option_name, 'field' => $field, 'value' => $options[$field]));
    /*----------------------------------------*
     * Submission settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-submission";
    add_settings_section($section, __('Submission settings', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    $val = $GLOBALS['allowedtags'];
    unset($val['blockquote']);
    $field = 'comment';
    add_settings_field($option_name . "_{$field}", '<dfn title="' . __('The whole will be wrapped by &lt;p&gt; tag. Allowed tags: ', IP_Geo_Block::TEXT_DOMAIN) . implode(', ', array_keys($val)) . '">' . __('Message on comment form', IP_Geo_Block::TEXT_DOMAIN) . '</dfn>', array($context, 'callback_field'), $option_slug, $section, array('type' => 'select-text', 'option' => $option_name, 'field' => $field, 'sub-field' => 'pos', 'txt-field' => 'msg', 'value' => $options[$field]['pos'], 'list' => array(0 => __('None', IP_Geo_Block::TEXT_DOMAIN), 1 => __('Top', IP_Geo_Block::TEXT_DOMAIN), 2 => __('Bottom', IP_Geo_Block::TEXT_DOMAIN)), 'text' => $options[$field]['msg']));
    /*----------------------------------------*
     * Plugin settings
     *----------------------------------------*/
    $section = "{$plugin_slug}-others";
    add_settings_section($section, __('Plugin settings', IP_Geo_Block::TEXT_DOMAIN), NULL, $option_slug);
    $field = 'clean_uninstall';
    add_settings_field($option_name . "_{$field}", __('Remove all settings at uninstallation', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'checkbox', 'option' => $option_name, 'field' => $field, 'value' => $options[$field]));
    if (defined('IP_GEO_BLOCK_DEBUG') && IP_GEO_BLOCK_DEBUG) {
        // Manipulate DB table for validation logs
        $field = 'delete_table';
        add_settings_field($option_name . "_{$field}", __('Delete DB table for validation logs', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Delete now', IP_Geo_Block::TEXT_DOMAIN), 'after' => "<div id=\"{$plugin_slug}-delete_table\"></div>"));
        $field = 'create_table';
        add_settings_field($option_name . "_{$field}", __('Create DB table for validation logs', IP_Geo_Block::TEXT_DOMAIN), array($context, 'callback_field'), $option_slug, $section, array('type' => 'button', 'option' => $option_name, 'field' => $field, 'value' => __('Create now', IP_Geo_Block::TEXT_DOMAIN), 'after' => "<div id=\"{$plugin_slug}-create_table\"></div>"));
    }
}
<?php

/**
 * Fired when the plugin is uninstalled.
 *
 * @package   IP_Geo_Block
 * @author    tokkonopapa <*****@*****.**>
 * @license   GPL-2.0+
 * @link      https://github.com/tokkonopapa
 * @copyright 2013-2015 tokkonopapa
 */
// If uninstall not called from WordPress, then exit
if (!defined('WP_UNINSTALL_PLUGIN')) {
    exit;
}
// Define uninstall functionality here
if (!defined('IP_GEO_BLOCK_PATH')) {
    define('IP_GEO_BLOCK_PATH', plugin_dir_path(__FILE__));
}
// @since 2.8
include IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block.php';
IP_Geo_Block::uninstall();