' . __( '(comma separated)', 'ip-geo-block' ) . '', '' . __( '(comma or RET separated)', 'ip-geo-block' ) . '', '', '', __( 'Help', 'ip-geo-block' ), __( 'Before adding as “Exception”, please click on “” button (if exists) attached to the following list to confirm that the blocked request is not malicious.', 'ip-geo-block' ), __( 'Open CIDR calculator for IPv4 / IPv6.', 'ip-geo-block' ), ); /** * Register a setting and its sanitization callback. * @link https://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 = IP_Geo_Block::PLUGIN_NAME, // 'ip-geo-block' $option_name = IP_Geo_Block::OPTION_NAME, // 'ip_geo_block_settings' array( $context, 'validate_settings' ) ); /** * Add new section to a new page inside the existing page. * @link https://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 rules and behavior *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-validation-rule', array( __( 'Validation rules and behavior', 'ip-geo-block' ), '' . $common[4] . '' ), NULL, $option_slug ); /** * Register a settings field to the settings page and section. * @link https://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. */ // Get the country code of client $key = IP_Geo_Block::get_geolocation( $val = IP_Geo_Block::get_ip_address( $options ) ); add_settings_field( $option_name.'_ip_client', __( 'Your IP address / Country', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'html', 'option' => $option_name, 'field' => 'ip_client', 'value' => '' . esc_html( $key['ip'] . ' / ' . ( $key['code'] && isset( $key['provider'] ) ? $key['code'] . ' (' . $key['provider'] . ')' : __( 'n/a', 'ip-geo-block' ) ) ) . '', 'after' => ' ' . __( 'Scan country code', 'ip-geo-block' ) . '
', ) ); if ( $key = IP_Geo_Block_Util::get_server_ip() && $key !== $val && ! IP_Geo_Block_Util::is_private_ip( $key ) ): // Get the country code of server $key = IP_Geo_Block::get_geolocation( $_SERVER['SERVER_ADDR'] ); add_settings_field( $option_name.'_ip_server', __( 'Server IP address / Country', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'html', 'option' => $option_name, 'field' => 'ip_server', 'value' => '' . esc_html( $key['ip'] . ' / ' . ( $key['code'] && isset( $key['provider'] ) ? $key['code'] . ' (' . $key['provider'] . ')' : __( 'n/a', 'ip-geo-block' ) ) ) . '', 'after' => ' ' . __( 'Scan country code', 'ip-geo-block' ) . '
', ) ); endif; // If the matching rule is not initialized, then add a caution $rule = array( -1 => NULL, 0 => __( 'Whitelist', 'ip-geo-block' ), 1 => __( 'Blacklist', 'ip-geo-block' ), ); $rule_desc = array( __( 'Please select either “Whitelist” or “Blacklist”.', 'ip-geo-block' ), __( 'Whitelist of country code', 'ip-geo-block' ) . '
(ISO 3166-1 alpha-2)', __( 'Blacklist of country code', 'ip-geo-block' ) . '
(ISO 3166-1 alpha-2)', ); // Matching rule add_settings_field( $option_name.'_matching_rule', '' . __( 'Matching rule', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'matching_rule', 'value' => $options['matching_rule'], 'list' => $rule, 'desc' => array( -1 => $rule_desc[0], 0 => __( 'A request from which the country code or IP address is NOT in the whitelist will be blocked.', 'ip-geo-block' ), 1 => __( 'A request from which the country code or IP address is in the blacklist will be blocked.', 'ip-geo-block' ), ), 'before' => '', ) ); // Country code for matching rule (ISO 3166-1 alpha-2) add_settings_field( $option_name.'_white_list', $rule_desc[1], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'white_list', 'value' => $options['white_list'], 'after' => $common[0], 'class' => $options['matching_rule'] == 0 ? '' : 'ip-geo-block-hide', ) ); add_settings_field( $option_name.'_black_list', $rule_desc[2], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'black_list', 'value' => $options['black_list'], 'after' => $common[0], 'class' => $options['matching_rule'] == 1 ? '' : 'ip-geo-block-hide', ) ); // Use AS number add_settings_field( $option_name.'_Maxmind_use_asn', __( 'Use Autonomous System Number', 'ip-geo-block' ) . ' (ASN)', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'Maxmind', 'sub-field' => 'use_asn', 'value' => 1 === (int)$options['Maxmind']['use_asn'], 'after' => '

' . sprintf( __( 'Some useful tools to find ASN are introduced in “%s”.', 'ip-geo-block' ), 'Utilizing AS number' ) . '

', ) ); // $_SERVER keys to retrieve extra IP addresses add_settings_field( $option_name.'_validation_proxy', __( '$_SERVER keys to retrieve extra IP addresses', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'proxy', 'value' => $options['validation']['proxy'], 'placeholder' => IP_Geo_Block_Util::get_proxy_var(), 'after' => $common[0], ) ); // White list of extra IP addresses prior to country code (CIDR, ASN) add_settings_field( $option_name.'_extra_ips_white_list', __( 'Whitelist of extra IP addresses prior to country code', 'ip-geo-block' ) . ' (CIDR' . ', ASN)' . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'textarea', 'option' => $option_name, 'field' => 'extra_ips', 'sub-field' => 'white_list', 'value' => $options['extra_ips']['white_list'], 'placeholder' => '192.168.0.0/16,2001:db8::/96,AS1234', 'after' => $common[1], ) ); // Black list of extra IP addresses prior to country code (CIDR, ASN) add_settings_field( $option_name.'_extra_ips_black_list', __( 'Blacklist of extra IP addresses prior to country code', 'ip-geo-block' ) . ' (CIDR' . ', ASN)' . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'textarea', 'option' => $option_name, 'field' => 'extra_ips', 'sub-field' => 'black_list', 'value' => $options['extra_ips']['black_list'], 'placeholder' => '192.168.0.0/16,2001:db8::/96,AS1234', 'after' => $common[1], ) ); // Bad signatures add_settings_field( $option_name.'_signature', __( 'Bad signatures in query ()', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'textarea', 'option' => $option_name, 'field' => 'signature', 'value' => $options['signature'], 'after' => $common[1], ) ); // Prevent malicious upload - white list of file extention and MIME type $list = '\n"; $list .= '\n"; // Verify capability $list .= ''; // Prevent malicious file uploading add_settings_field( $option_name.'_validation_mimetype', __( 'Prevent malicious file uploading', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'mimetype', 'value' => $options['validation']['mimetype'], 'list' => array( 0 => __( 'Disable', 'ip-geo-block' ), 1 => __( 'Verify file extension and MIME type', 'ip-geo-block' ), 2 => __( 'Verify file extension only', 'ip-geo-block' ), ), 'after' => $list, ) ); // Metadata Exploit Protection add_settings_field( $option_name.'_validation_metadata', __( 'Metadata Exploit Protection', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'metadata', 'value' => $options['validation']['metadata'], ) ); if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ): // Prevent metadata alteration $list = '' . "\n"; $list .= '' . "\n"; add_settings_field( $option_name.'_metadata', __( 'Prevent metadata alteration', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'html', 'option' => $option_name, 'field' => 'metadata', 'value' => $list, ) ); endif; // Response code (RFC 2616) add_settings_field( $option_name.'_response_code', sprintf( __( 'Response code %s', 'ip-geo-block' ), '(RFC 2616)' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'response_code', 'value' => $options['response_code'], 'list' => array( 200 => '200 OK', 301 => '301 Moved Permanently', 302 => '302 Found', 303 => '303 See Other', 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', ), ) ); // Redirect URI add_settings_field( $option_name.'_redirect_uri', __( 'Redirect URL', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'redirect_uri', 'value' => $options['redirect_uri'], 'class' => $options['response_code'] < 400 ? '' : 'ip-geo-block-hide', 'placeholder' => '/about/', ) ); // Response message add_settings_field( $option_name.'_response_msg', __( 'Response message', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'response_msg', 'value' => $options['response_msg'], 'class' => $options['response_code'] >= 400 ? '' : 'ip-geo-block-hide', ) ); // Validation timing $options['validation']['timing'] = IP_Geo_Block_Opts::get_validation_timing(); add_settings_field( $option_name.'_validation_timing', '' . __( 'Validation timing', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'timing', 'value' => $options['validation']['timing'], 'list' => array( 0 => __( '“init” action hook', 'ip-geo-block' ), 1 => __( '“mu-plugins” (ip-geo-block-mu.php)', 'ip-geo-block' ), ), 'desc' => array( 0 => __( 'Validate at “init” action hook in the same manner as typical plugins.', 'ip-geo-block' ), 1 => __( 'Validate at an earlier phase than other typical plugins. It can reduce load on server but has some restrictions.', 'ip-geo-block' ), ), ) ); // Simulation mode add_settings_field( $option_name.'_simulate', '' . __( 'Simulation mode', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'simulate', 'value' => isset( $options['simulate'] ) ? $options['simulate'] : FALSE, ) ); /*----------------------------------------* * Back-end target settings *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-validation-target', array( __( 'Back-end target settings', 'ip-geo-block' ), '' . $common[4] . '' ), array( __CLASS__, 'note_target' ), $option_slug ); // same as in tab-accesslog.php $dfn = __( '%s', 'ip-geo-block' ); $target = array( 'comment' => sprintf( $dfn, 'wp-comments-post.php', __( 'Comment post', 'ip-geo-block' ) ), 'xmlrpc' => sprintf( $dfn, 'xmlrpc.php', __( 'XML-RPC', 'ip-geo-block' ) ), 'login' => sprintf( $dfn, 'wp-login.php, wp-signup.php', __( 'Login form', 'ip-geo-block' ) ), 'admin' => sprintf( $dfn, '/wp-admin/*.php', __( 'Admin area', 'ip-geo-block' ) ), 'others' => sprintf( $dfn, 'executable files', __( 'Other areas', 'ip-geo-block' ) ), 'public' => sprintf( $dfn, __( 'public facing pages', 'ip-geo-block' ), __( 'Public facing pages', 'ip-geo-block' ) ), ); // Comment post add_settings_field( $option_name.'_validation_comment', $target['comment'], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'comment', 'value' => $options['validation']['comment'], 'text' => __( 'Block by country', 'ip-geo-block' ), ) ); $val = $GLOBALS['allowedtags']; unset( $val['blockquote'] ); // Message on comment form add_settings_field( $option_name.'_comment', '
' . __( 'Message on comment form', 'ip-geo-block' ) . '
', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select-text', 'option' => $option_name, 'field' => 'comment', 'sub-field' => 'pos', 'txt-field' => 'msg', 'value' => $options['comment']['pos'], 'class' => 'ip-geo-block-subitem-parent', 'list' => array( 0 => __( 'None', 'ip-geo-block' ), 1 => __( 'Top', 'ip-geo-block' ), 2 => __( 'Bottom', 'ip-geo-block' ), ), 'text' => $options['comment']['msg'], // escaped by esc_attr() at 'text' ) ); // XML-RPC add_settings_field( $option_name.'_validation_xmlrpc', $target['xmlrpc'], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'xmlrpc', 'value' => $options['validation']['xmlrpc'], 'list' => array( 0 => __( 'Disable', 'ip-geo-block' ), 1 => __( 'Block by country', 'ip-geo-block' ), 2 => __( 'Completely close', 'ip-geo-block' ), ), ) ); $desc = array( 'login' => '' . __( 'Log in' ) . '', 'register' => '' . __( 'Register' ) . '', 'resetpass' => '' . __( 'Password Reset' ) . '', 'lostpassword' => '' . __( 'Lost Password' ) . '', 'postpass' => '' . __( 'Password protected' ) . '', ); $list = ''; foreach ( $desc as $key => $val ) { $list .= '
  • \n"; } // Login form add_settings_field( $option_name.'_validation_login', $target['login'], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'login', 'value' => $options['validation']['login'], 'text' => __( 'Block by country', 'ip-geo-block' ), 'after' => '\n", ) ); $list = array( 1 => __( 'Block by country', 'ip-geo-block' ), 2 => __( 'Prevent Zero-day Exploit', 'ip-geo-block' ), ); $desc = array( 1 => __( 'It will block a request related to the services for both “non-logged in user” and “logged-in user”.', 'ip-geo-block' ), 2 => __( 'Regardless of the country code, it will block a malicious request related to the services only for “logged-in user”.', 'ip-geo-block' ), ); // Max failed login attempts per IP address add_settings_field( $option_name.'_login_fails', '
    ' . __( 'Max failed login attempts per IP address', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'login_fails', 'value' => $options['login_fails'], 'class' => 'ip-geo-block-subitem-parent', 'list' => array( -1 => 'Disable', 0 => 0, 1 => 1, 3 => 3, 5 => 5, 7 => 7, 10 => 10, ), ) ); // Admin area add_settings_field( $option_name.'_validation_admin', $target['admin'], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkboxes', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'admin', 'value' => $options['validation']['admin'], 'list' => $list, 'desc' => $desc, ) ); $tmp = array( __( 'admin post for logged-in user', 'ip-geo-block' ), __( 'admin post for non logged-in user', 'ip-geo-block' ), ); // Get all the admin-post actions $exception = ''; $installed = IP_Geo_Block_Util::get_registered_actions( FALSE ); foreach ( $installed as $key => $val ) { $val = ''; $val .= $installed[ $key ] & 1 ? '*' : ''; $val .= $installed[ $key ] & 2 ? '*' : ''; $key = esc_attr( $key ); $exception .= '
  • ' . '' . '' . $val . '
  • ' . "\n"; } // Admin ajax/post $path = IP_Geo_Block::get_wp_path(); $val = esc_html( $path['admin'] ); add_settings_field( $option_name.'_validation_ajax', sprintf( $dfn, $val.'admin-(ajax|post).php', __( 'Admin ajax/post', 'ip-geo-block' ) ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkboxes', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'ajax', 'value' => $options['validation']['ajax'], 'list' => $list, 'desc' => $desc, 'after' => '' ) ); array_unshift( $list, __( 'Disable', 'ip-geo-block' ) ); $desc = array( __( 'Regardless of the country code, it will block a malicious request to %s⋯/*.php.', 'ip-geo-block' ), __( 'Select the item which causes unintended blocking in order to exclude from the validation target. Grayed item indicates “INACTIVE”.', 'ip-geo-block' ), __( 'It configures “%s” to validate a direct request to the PHP file which does not load WordPress core. Make sure to deny direct access to the hidden files beginning with a dot by the server\'s configuration.', 'ip-geo-block' ), __( 'Sorry, but your server type is not supported.', 'ip-geo-block' ), __( 'You need to click “Save Changes” button for imported settings to take effect.', 'ip-geo-block' ), ); // Set rewrite condition $config = IP_Geo_Block_Admin_Rewrite::get_config_file(); $options['rewrite'] = IP_Geo_Block_Admin_Rewrite::check_rewrite_all(); // Get all the plugins $exception = ''; $installed = get_plugins(); // @since 1.5.0 $activated = get_site_option( 'active_sitewide_plugins' ); // @since 2.8.0 ! is_array( $activated ) and $activated = array(); $activated = array_merge( $activated, array_fill_keys( get_option( 'active_plugins' ), TRUE ) ); // Make a list of installed plugins foreach ( $installed as $key => $val ) { $active = isset( $activated[ $key ] ); $key = explode( '/', $key, 2 ); $key = esc_attr( $key[0] ); $exception .= '
  • \n"; } // Plugins area $val = esc_html( $path['plugins'] ); $tmp = '' . '
    '; add_settings_field( $option_name.'_validation_plugins', sprintf( $dfn, $val.'…/*.php', __( 'Plugins area', 'ip-geo-block' ) ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'plugins', 'value' => $options['validation']['plugins'], 'list' => $list, 'desc' => array( 2 => sprintf( $desc[0], $val ), ), 'after' => $tmp . '' ) ); // Get all the themes $exception = ''; $installed = wp_get_themes(); // @since 3.4.0 $activated = wp_get_theme(); // @since 3.4.0 $activated = $activated->get( 'Name' ); // List of installed themes foreach ( $installed as $key => $val ) { $key = esc_attr( $key ); $active = ( ( $val = $val->get( 'Name' ) ) === $activated ); $exception .= '
  • \n"; } // Themes area $val = esc_html( $path['themes'] ); $tmp = '' . '
    '; add_settings_field( $option_name.'_validation_themes', sprintf( $dfn, $val.'…/*.php', __( 'Themes area', 'ip-geo-block' ) ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'themes', 'value' => $options['validation']['themes'], 'list' => $list, 'desc' => array( 2 => sprintf( $desc[0], $val ), ), 'after' => $tmp . '' ) ); /*----------------------------------------* * Front-end target settings *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-public', array( __( 'Front-end target settings', 'ip-geo-block' ), '' . $common[4] . '' ), array( __CLASS__, 'note_public' ), $option_slug ); // Public facing pages add_settings_field( $option_name.'_validation_public', $target['public'], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'public', 'value' => $options['validation']['public'], 'text' => __( 'Block by country', 'ip-geo-block' ), ) ); // Matching rule add_settings_field( $option_name.'_public_matching_rule', '' . __( 'Matching rule', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'matching_rule', 'value' => $options['public']['matching_rule'], 'list' => array( -1 => __( 'Follow “Validation rules and behavior”', 'ip-geo-block' ) ) + $rule, ) ); // Country code for matching rule (ISO 3166-1 alpha-2) add_settings_field( $option_name.'_public_white_list', $rule_desc[1], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'white_list', 'value' => $options['public']['white_list'], 'after' => $common[0], 'class' => $options['public']['matching_rule'] == 0 ? '' : 'ip-geo-block-hide', ) ); add_settings_field( $option_name.'_public_black_list', $rule_desc[2], array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'black_list', 'value' => $options['public']['black_list'], 'after' => $common[0], 'class' => $options['public']['matching_rule'] == 1 ? '' : 'ip-geo-block-hide', ) ); // Response code (RFC 2616) add_settings_field( $option_name.'_public_response_code', sprintf( __( 'Response code %s', 'ip-geo-block' ), '(RFC 2616)' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'response_code', 'value' => $options['public']['response_code'], 'list' => array( 200 => '200 OK', 301 => '301 Moved Permanently', 302 => '302 Found', 303 => '303 See Other', 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', ), 'class' => $options['public']['matching_rule'] == -1 ? 'ip-geo-block-hide' :'', ) ); // Redirect URI add_settings_field( $option_name.'_public_redirect_uri', __( 'Redirect URL', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'redirect_uri', 'value' => $options['public']['redirect_uri' ], 'class' => $options['public']['matching_rule'] != -1 && $options['public']['response_code'] < 400 ? '' : 'ip-geo-block-hide', 'placeholder' => '/about/', ) ); // Response message add_settings_field( $option_name.'_public_response_msg', __( 'Response message', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'response_msg', 'value' => $options['public']['response_msg' ], 'class' => $options['public']['matching_rule'] != -1 && $options['public']['response_code'] >= 400 ? '' : 'ip-geo-block-hide', ) ); // List of page $exception = '' . "\n"; // List of post type $exception .= '' . "\n"; // List of category $exception .= '' . "\n"; // List of tag $exception .= '' . "\n"; // Validation target add_settings_field( $option_name.'_public_target_rule', '' . __( 'Validation target', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'target_rule', 'value' => $options['public']['target_rule'], 'list' => array( 0 => __( 'All requests', 'ip-geo-block' ), 1 => __( 'Specify the targets', 'ip-geo-block' ), ), 'desc' => array( 1 => __( "Notice that “Validation timing” is deferred till “wp” action hook. It means that this feature would not be compatible with any page caching.", 'ip-geo-block' ), ), 'after' => $exception, ) ); if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ): // Excluded action add_settings_field( $option_name.'_exception_public', '' . __( 'Excluded actions', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'exception', 'sub-field' => 'public', 'value' => implode( ',', $options['exception']['public'] ), 'after' => $common[0], ) ); endif; // Badly-behaved bots and crawlers $exception = '\n"; add_settings_field( $option_name.'_public_behavior', __( 'Block badly-behaved bots and crawlers', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'behavior', 'value' => $options['public']['behavior'], 'after' => $exception, ) ); // UA string and qualification add_settings_field( $option_name.'_public_ua_list', '' . __( 'UA string and qualification', 'ip-geo-block' ) . '', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'textarea', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'ua_list', 'value' => $options['public']['ua_list'], 'after' => $common[1], ) ); // Reverse DNS lookup add_settings_field( $option_name.'_public_dnslkup', '
    ' . __( 'Reverse DNS lookup', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'public', 'sub-field' => 'dnslkup', 'value' => $options['public']['dnslkup'], 'class' => 'ip-geo-block-subitem-parent', ) ); /*----------------------------------------* * Privacy and record settings *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-recording', array( __( 'Privacy and record settings', 'ip-geo-block' ), '' . $common[4] . '' ), array( __CLASS__, 'note_privacy' ), $option_slug ); // Anonymize IP address add_settings_field( $option_name.'_anonymize', __( 'Anonymize IP address', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'anonymize', 'value' => ! empty( $options['anonymize'] ), ) ); // Do not send IP address to external APIs add_settings_field( $option_name.'_restrict_api', __( 'Do not send IP address to external APIs', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'restrict_api', 'value' => ! empty( $options['restrict_api'] ), ) ); // Record IP address cache add_settings_field( $option_name.'_cache_hold', __( 'Record “IP address cache”', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'cache_hold', 'value' => $options['cache_hold'], ) ); // Expiration time [sec] for each entry add_settings_field( $option_name.'_cache_time', '
    ' . __( 'Expiration time [sec] for each entry', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'cache_time', 'value' => $options['cache_time'], 'class' => 'ip-geo-block-subitem-parent', ) ); // Record Validation logs add_settings_field( $option_name.'_validation_reclogs', __( 'Record “Validation logs”', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'reclogs', 'value' => $options['validation']['reclogs'], 'list' => array( 0 => __( 'Disable', 'ip-geo-block' ), 1 => __( 'When blocked', 'ip-geo-block' ), 2 => __( 'When passed', 'ip-geo-block' ), 6 => __( 'When “blocked” or “passed (not in whitelist)”', 'ip-geo-block' ), 3 => __( 'Unauthenticated visitor', 'ip-geo-block' ), 4 => __( 'Authenticated user', 'ip-geo-block' ), 5 => __( 'All the validation', 'ip-geo-block' ), ), ) ); // Expiration time [days] for each entry add_settings_field( $option_name.'_validation_explogs', '
    ' . sprintf( __( 'Expiration time [days] for each entry', 'ip-geo-block' ), $options['validation']['maxlogs'] ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'explogs', 'value' => $options['validation']['explogs'], 'class' => 'ip-geo-block-subitem-parent', ) ); // $_POST key to record with value add_settings_field( $option_name.'_validation_postkey', '
    ' . __( '$_POST key to record with value', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'postkey', 'value' => $options['validation']['postkey'], 'after' => $common[0], 'class' => 'ip-geo-block-subitem-parent', ) ); if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ): // Maximum entries in Logs add_settings_field( $option_name.'_validation_maxlogs', '
    ' . __( 'Maximum entries in “Logs”', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'maxlogs', 'value' => $options['validation']['maxlogs'], 'class' => 'ip-geo-block-subitem-parent', ) ); // Live update add_settings_field( $option_name.'_live_update', '
    ' . __( 'Database source of SQLite for “Live update”', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'select', 'option' => $option_name, 'field' => 'live_update', 'sub-field' => 'in_memory', 'value' => extension_loaded( 'pdo_sqlite' ) ? $options['live_update']['in_memory'] : -1, 'class' => 'ip-geo-block-subitem-parent', 'list' => array( -1 => NULL, 0 => __( 'Ordinary file', 'ip-geo-block' ), 1 => __( 'In-Memory', 'ip-geo-block' ), ), 'desc' => array( -1 => __( 'PDO_SQLITE driver not available','ip-geo-block' ), 0 => __( 'It takes a few tens of milliseconds as overhead. It can be safely used without conflict with other plugins.', 'ip-geo-block' ), 1 => __( 'It takes a few milliseconds as overhead. There is a possibility of conflict with other plugins using this method.', 'ip-geo-block' ), ), ) ); // Reset data source of live log add_settings_field( $option_name.'_reset_live', '
    ' . __( 'Reset database source of “Live update”', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'button', 'option' => $option_name, 'field' => 'reset_live', 'value' => __( 'Reset now', 'ip-geo-block' ), 'after' => '
    ', 'class' => 'ip-geo-block-subitem-parent', ) ); endif; // Get the next schedule of cron $tmp = wp_next_scheduled( IP_Geo_Block::CACHE_NAME ); $tmp = $tmp ? IP_Geo_Block_Util::localdate( $tmp ) : '' . __( 'Task could not be found in WP-Cron. Please try to deactivate this plugin once and activate again.', 'ip-geo-block' ). ''; // Interval [sec] to cleanup expired entries of IP address add_settings_field( $option_name.'_cache_time_gc', __( 'Interval [sec] to cleanup expired entries of IP address', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'cache_time_gc', 'value' => $options['cache_time_gc'], 'after' => '

    ' . sprintf( __( 'Next schedule: %s', 'ip-geo-block'), $tmp ) . '

    ', ) ); // Record Statistics of validation add_settings_field( $option_name.'_save_statistics', __( 'Record “Statistics of validation”', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'save_statistics', 'value' => $options['save_statistics'], ) ); if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ): add_settings_field( $option_name.'_validation_recdays', '
    ' . __( 'Maximum period for “Statistics” [days]', 'ip-geo-block' ) . '
    ', array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'validation', 'sub-field' => 'recdays', 'value' => $options['validation']['recdays'], 'class' => 'ip-geo-block-subitem-parent', ) ); endif; // Remove all settings and records at uninstallation add_settings_field( $option_name.'_clean_uninstall', __( 'Remove all settings and records at uninstallation', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'clean_uninstall', 'value' => $options['clean_uninstall'], ) ); /*----------------------------------------* * Geolocation API settings *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-provider', array( __( 'Geolocation API settings', 'ip-geo-block' ), '' . $common[4] . '' ), array( __CLASS__, 'note_services' ), $option_slug ); // Local DBs and APIs $provider = IP_Geo_Block_Provider::get_providers( 'key' ); // all available providers $providers = IP_Geo_Block_Provider::get_addons( $options['providers'], TRUE ); // only local // Disable 3rd parties API if ( ! empty( $options['restrict_api'] ) ) { foreach ( array_keys( $provider ) as $key ) { if ( ! in_array( $key, $providers, TRUE ) ) { $provider[ $key ] = is_string( $provider[ $key ] ) ? '-1' : -1; } } } // API selection and key settings add_settings_field( $option_name.'_providers', __( 'API selection and key settings', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'check-provider', 'option' => $option_name, 'field' => 'providers', 'value' => $options['providers'], 'local' => $providers, 'providers' => $provider, 'titles' => IP_Geo_Block_Provider::get_providers( 'type' ), ) ); if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ): // Timeout for network API add_settings_field( $option_name.'_timeout', __( 'Timeout for network API [sec]', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'timeout', 'value' => $options['timeout'], ) ); endif; /*----------------------------------------* * Local database settings *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-database', array( __( 'Local database settings', 'ip-geo-block' ), '' . $common[4] . '' ), array( __CLASS__, 'note_database' ), $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' ), __( 'Last update: %s', 'ip-geo-block' ) ); } } // Get the next schedule of cron if ( ! ( $tmp = wp_next_scheduled( IP_Geo_Block::CRON_NAME, array( FALSE ) ) ) ) { if ( is_multisite() ) { global $wpdb; $blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `$wpdb->blogs` ORDER BY `blog_id` ASC" ); switch_to_blog( $blog_ids[0] ); // main blog $tmp = wp_next_scheduled( IP_Geo_Block::CRON_NAME, array( FALSE ) ); restore_current_blog(); } else { $tmp = wp_next_scheduled( IP_Geo_Block::CRON_NAME, array( FALSE ) ); } } $tmp = $tmp ? IP_Geo_Block_Util::localdate( $tmp ) : '' . __( 'Task could not be found in WP-Cron. Please try to deactivate this plugin once and activate again.', 'ip-geo-block' ). ''; // Auto updating (once a month) add_settings_field( $option_name.'_update_auto', __( 'Auto updating (once a month)', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'update', 'sub-field' => 'auto', 'value' => $options['update']['auto'], 'disabled' => empty( $providers ), 'after' => $options['update']['auto'] ? '

    ' . sprintf( __( 'Next schedule: %s', 'ip-geo-block'), $tmp ) . '

    ' : '', ) ); // Download database add_settings_field( $option_name.'_update_download', __( 'Download database', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'button', 'option' => $option_name, 'field' => 'update', 'value' => __( 'Download now', 'ip-geo-block' ), 'disabled' => empty( $providers ), 'after' => '
    ', ) ); /*----------------------------------------* * Plugin settings *----------------------------------------*/ add_settings_section( $section = $plugin_slug . '-others', array( __( 'Plugin settings', 'ip-geo-block' ), '' . $common[4] . '' ), NULL, $option_slug ); // @see https://vedovini.net/2015/10/using-the-wordpress-settings-api-with-network-admin-pages/ if ( $context->is_network_admin() ) { add_action( 'network_admin_edit_' . IP_Geo_Block::PLUGIN_NAME, array( $context, 'validate_network_settings' ) ); // Network wide configuration add_settings_field( $option_name.'_network_wide', __( 'Network wide settings', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'checkbox', 'option' => $option_name, 'field' => 'network_wide', 'value' => $options['network_wide'], 'disabled' => ! is_main_site(), ) ); } // Emergency login link $key = IP_Geo_Block_Util::get_link(); add_settings_field( $option_name.'_login_link', __( 'Emergency login link', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'none', 'before' => empty( $key ) ? ''. __( 'Generate new link', 'ip-geo-block' ) . ' ' : ''. __( 'Delete current link', 'ip-geo-block' ) . ' ', 'after' => '
    ', ) ); // Google Maps API key add_settings_field( $option_name.'_api_key', __( 'Google Maps API key', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'text', 'option' => $option_name, 'field' => 'api_key', 'sub-field' => 'GoogleMap', 'value' => $options['api_key']['GoogleMap'], ) ); // Export / Import settings add_settings_field( $option_name.'_export-import', sprintf( '' . __( 'Export / Import settings', 'ip-geo-block' ) . '', $desc[4] ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'none', 'before' => ''. __( 'Export settings', 'ip-geo-block' ) . ' ' . ''. __( 'Import settings', 'ip-geo-block' ) . '', 'after' => '
    ', ) ); // Pre-defined settings add_settings_field( $option_name.'_pre-defined', sprintf( '' . __( 'Import pre-defined settings', 'ip-geo-block' ) . '', $desc[4] ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'none', 'before' => '' . __( 'Default settings', 'ip-geo-block' ) . ' ' . '' . __( 'Best for Back-end', 'ip-geo-block' ) . '', 'after' => '
    ', ) ); if ( defined( 'IP_GEO_BLOCK_DEBUG' ) && IP_GEO_BLOCK_DEBUG ): // DB tables for this plugin add_settings_field( $option_name.'_diag_tables', __( 'Diagnose all DB tables', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'button', 'option' => $option_name, 'field' => 'diag_tables', 'value' => __( 'Diagnose now', 'ip-geo-block' ), 'after' => '
    ', ) ); endif; // Diagnostic information add_settings_field( $option_name.'_show-info', __( 'Diagnostic information
    [ support forum ]', 'ip-geo-block' ), array( $context, 'callback_field' ), $option_slug, $section, array( 'type' => 'none', 'before' => '' . __( 'Show information', 'ip-geo-block' ) . ' ', 'after' => '
    ', ) ); } /** * Subsidiary note for the sections * */ public static function note_target() { } public static function note_services() { echo '', "\n"; } public static function note_database() { // https://pecl.php.net/package/phar if ( ! version_compare( PHP_VERSION, '5.4.0', '>=' ) || ! class_exists( 'PharData', FALSE ) ) { echo '', "\n"; } } public static function note_public() { echo '', "\n"; } public static function note_privacy() { } }