* @license GPL-3.0 * @link https://www.ipgeoblock.com/ * @copyright 2013-2019 tokkonopapa */ class IP_Geo_Block_Admin { /** * Constants for admin class * */ const INTERVAL_LIVE_UPDATE = 5; // interval for live update [sec] const TIMEOUT_LIVE_UPDATE = 60; // timeout of pausing live update [sec] /** * Globals in this class * */ private static $instance = NULL; private $is_network_admin = FALSE; private $admin_tab = 0; /** * Initialize the plugin by loading admin scripts & styles * and adding a settings page and menu. */ private function __construct() { // Setup the tab number. $this->admin_tab = isset( $_GET['tab'] ) ? (int)$_GET['tab'] : 0; $this->admin_tab = min( 5, max( 0, $this->admin_tab ) ); // Load plugin text domain and add body class add_action( 'init', array( $this, 'admin_init' ) ); // Add suggest text for inclusion in the site's privacy policy. @since 4.9.6 // add_action( 'admin_init', array( $this, 'add_privacy_policy' ) ); // Setup a nonce to validate authentication. add_filter( 'wp_redirect', array( $this, 'add_redirect_nonce' ), 10, 2 ); // @since 2.1.0 } /** * Return an instance of this class. * */ public static function get_instance() { return self::$instance ? self::$instance : ( self::$instance = new self ); } /** * Load the plugin text domain for translation and add body class. * */ public function admin_init() { // include drop in for admin if it exists $settings = IP_Geo_Block::get_option(); file_exists( $file = IP_Geo_Block_Util::unslashit( $settings['api_dir'] ) . '/drop-in-admin.php' ) and include( $file ); // Add the options page and menu item. add_action( 'admin_menu', array( $this, 'setup_admin_page' ) ); // @since: 2.5.0 add_action( 'admin_post_ip_geo_block', array( $this, 'admin_ajax_callback' ) ); // @since: 2.6.0 add_action( 'wp_ajax_ip_geo_block', array( $this, 'admin_ajax_callback' ) ); // @since: 2.1.0 add_filter( 'wp_prepare_revision_for_js', array( $this, 'add_revision_nonce' ), 10, 3 ); if ( IP_Geo_Block_Util::is_user_logged_in() ) add_filter( IP_Geo_Block::PLUGIN_NAME . '-bypass-admins', array( $this, 'verify_request' ), 10, 2 ); if ( is_multisite() && is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) { // @since: 3.0.0 $this->is_network_admin = current_user_can( 'manage_network_options' ); add_action( 'network_admin_menu', array( $this, 'setup_admin_page' ) ); // @since: 2.5 add_action( 'wpmu_new_blog', array( $this, 'create_blog' ), 10, 6 ); // on creating a new blog @since MU add_action( 'delete_blog', array( $this, 'delete_blog' ), 10, 2 ); // on deleting an old blog @since 3.0.0 } // loads a plugin’s translated strings. load_plugin_textdomain( IP_Geo_Block::PLUGIN_NAME, FALSE, dirname( IP_GEO_BLOCK_BASE ) . '/languages/' ); // add webview class into body tag. // https://stackoverflow.com/questions/37591279/detect-if-user-is-using-webview-for-android-ios-or-a-regular-browser if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Mobile/' ) !== FALSE ) && ( strpos( $_SERVER['HTTP_USER_AGENT'], 'Safari/' ) === FALSE ) ) { add_filter( 'admin_body_class', array( $this, 'add_webview_class' ) ); } // for Android elseif ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && $_SERVER['HTTP_X_REQUESTED_WITH'] === "com.company.app" ) { add_filter( 'admin_body_class', array( $this, 'add_webview_class' ) ); } } /** * Whether this plugin activated by network or not. * */ public function is_network_admin() { return $this->is_network_admin; } /** * Add webview class into the body. * */ public function add_webview_class( $classes ) { return $classes . ($classes ? ' ' : '') . 'webview'; } /** * Add nonce when redirect into wp-admin area. * */ public function add_redirect_nonce( $location, $status ) { $status = TRUE; // default is `retrieve` a nonce $urls = array( wp_login_url() ); // avoid multiple redirection caused by WP hide 1.4.9.1 if ( is_plugin_active( 'wp-hide-security-enhancer/wp-hide.php' ) ) $urls[] = 'options-permalink.php'; foreach ( $urls as $url ) { if ( FALSE !== strpos( $location, $url ) ) { $status = FALSE; // do not `retieve` a nonce break; } } return IP_Geo_Block_Util::rebuild_nonce( $location, $status ); } /** * Add nonce to revision @since 4.4.0 * */ public function add_revision_nonce( $revisions_data, $revision, $post ) { $revisions_data['restoreUrl'] = add_query_arg( $nonce = IP_Geo_Block::get_auth_key(), IP_Geo_Block_Util::create_nonce( $nonce ), $revisions_data['restoreUrl'] ); return $revisions_data; } /** * Verify admin screen without action instead of validating nonce. * */ public function verify_request( $queries, $settings ) { // the request that is intended to show the page without any action follows authentication of core. if ( 'GET' === $_SERVER['REQUEST_METHOD'] && isset( $_GET['page'] ) ) { foreach ( array( 'action', 'task') as $key ) { if ( ! empty( $_GET[ $key ] ) ) return $queries; } $queries[] = $_GET['page']; } return $queries; } /** * Do some procedures when a blog is created or deleted. * */ public function create_blog( $blog_id, $user_id, $domain, $path, $site_id, $meta ) { defined( 'IP_GEO_BLOCK_DEBUG' ) and IP_GEO_BLOCK_DEBUG and assert( is_main_site(), 'Not main blog.' ); require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-actv.php'; // get options on main blog $settings = IP_Geo_Block::get_option(); // Switch to the new blog and initialize. switch_to_blog( $blog_id ); IP_Geo_Block_Activate::activate_blog(); // Copy option from main blog. if ( $this->is_network_admin && $settings['network_wide'] ) IP_Geo_Block::update_option( $settings, FALSE ); // Restore the main blog. restore_current_blog(); } public function delete_blog( $blog_id, $drop ) { // blog is already switched to the target in wpmu_delete_blog() $drop and IP_Geo_Block_Logs::delete_tables(); } /** * Get the action name of ajax for nonce * */ private function get_ajax_action() { return IP_Geo_Block::PLUGIN_NAME . '-ajax-action'; } /** * Register and enqueue plugin-specific style sheet and JavaScript. * * @see https://developers.google.com/maps/faq#china_ws_access */ public function enqueue_admin_assets() { $release = ( ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ); $footer = TRUE; $dependency = array( 'jquery' ); $version = $release ? IP_Geo_Block::VERSION : max( filemtime( plugin_dir_path( __FILE__ ) . 'css/admin.css' ), filemtime( plugin_dir_path( __FILE__ ) . 'js/admin.js' ) ); switch ( $this->admin_tab ) { case 1: /* Statistics */ case 4: /* Logs */ // css and js for DataTables wp_enqueue_style( IP_Geo_Block::PLUGIN_NAME . '-datatables-css', plugins_url( 'datatables/css/datatables-all.min.css', __FILE__ ), array(), IP_Geo_Block::VERSION ); wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-datatables-js', plugins_url( 'datatables/js/datatables-all.min.js', __FILE__ ), $dependency, IP_Geo_Block::VERSION, $footer ); if ( 4 === $this->admin_tab ) break; case 5: /* Sites list */ // js for google charts wp_register_script( $addon = IP_Geo_Block::PLUGIN_NAME . '-google-chart', apply_filters( 'google-charts', 'https://www.gstatic.com/charts/loader.js' ), array(), NULL, $footer ); wp_enqueue_script( $addon ); break; case 2: /* Search */ // Google Map in China $geo = IP_Geo_Block::get_geolocation(); if ( isset( $geo['code'] ) && 'CN' === $geo['code'] ) { add_filter( 'google-charts', array( $this, 'google_charts_cn' ) ); add_filter( 'google-maps', array( $this, 'google_maps_cn' ) ); add_filter( 'google-maps-nokey', array( $this, 'google_maps_nokey_cn' ) ); } // js for google map $settings = IP_Geo_Block::get_option(); if ( $key = $settings['api_key']['GoogleMap'] ) { wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-gmap-js', plugins_url( $release ? 'js/gmap.min.js' : 'js/gmap.js', __FILE__ ), $dependency, IP_Geo_Block::VERSION, $footer ); wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-google-map', apply_filters( 'google-maps', '//maps.googleapis.com/maps/api/js' ) . ( 'default' !== $key ? "?key=$key" : '' ), $dependency, IP_Geo_Block::VERSION, $footer ); } wp_enqueue_script( IP_Geo_Block::PLUGIN_NAME . '-whois-js', plugins_url( $release ? 'js/whois.min.js' : 'js/whois.js', __FILE__ ), $dependency, IP_Geo_Block::VERSION, $footer ); break; } // css for option page wp_enqueue_style( IP_Geo_Block::PLUGIN_NAME . '-admin-icons', plugins_url( $release ? 'css/admin-icons.min.css' : 'css/admin-icons.css', __FILE__ ), array(), IP_Geo_Block::VERSION ); wp_enqueue_style( IP_Geo_Block::PLUGIN_NAME . '-admin-styles', plugins_url( $release ? 'css/admin.min.css' : 'css/admin.css', __FILE__ ), array(), $version ); // js for IP Geo Block admin page wp_register_script( $handle = IP_Geo_Block::PLUGIN_NAME . '-admin-script', plugins_url( $release ? 'js/admin.min.js' : 'js/admin.js', __FILE__ ), $dependency + ( isset( $addon ) ? array( $addon ) : array() ), $version, $footer ); wp_localize_script( $handle, 'IP_GEO_BLOCK', array( 'action' => 'ip_geo_block', 'tab' => $this->admin_tab, 'url' => admin_url( 'admin-ajax.php' ), 'nonce' => IP_Geo_Block_Util::create_nonce( $this->get_ajax_action() ), 'msg' => array( /* [ 0] */ __( 'Are you sure ?', 'ip-geo-block' ), /* [ 1] */ __( 'Open a new window', 'ip-geo-block' ), /* [ 2] */ __( 'Generate new link', 'ip-geo-block' ), /* [ 3] */ __( 'Delete current link', 'ip-geo-block' ), /* [ 4] */ __( 'Please add the following link to favorites / bookmarks in your browser : ', 'ip-geo-block' ), /* [ 5] */ __( 'ajax for logged-in user', 'ip-geo-block' ), /* [ 6] */ __( 'ajax for non logged-in user', 'ip-geo-block' ), /* [ 7] */ __( '[Found: %d]', 'ip-geo-block' ), /* [ 8] */ __( 'Find and verify `%s` on “Logs” tab.', 'ip-geo-block' ), /* [ 9] */ __( 'This feature is available with HTML5 compliant browsers.', 'ip-geo-block' ), /* [10] */ __( 'The selected row cannot be found in the table.', 'ip-geo-block' ), /* [11] */ __( 'An error occurred while executing the ajax command `%s`.', 'ip-geo-block' ), ), 'i18n' => array( /* [ 0] */ '
', /* [ 1] */ __( 'No data available in table', 'ip-geo-block' ), /* [ 2] */ __( 'No matching records found', 'ip-geo-block' ), /* [ 3] */ __( 'IP address', 'ip-geo-block' ), /* [ 4] */ __( 'Code', 'ip-geo-block' ), /* [ 5] */ __( 'ASN', 'ip-geo-block' ), /* [ 6] */ __( 'Host name', 'ip-geo-block' ), /* [ 7] */ __( 'Target', 'ip-geo-block' ), /* [ 8] */ __( 'Failure / Total', 'ip-geo-block' ), /* [ 9] */ __( 'Elapsed[sec]', 'ip-geo-block' ), /* [10] */ __( 'Time', 'ip-geo-block' ), /* [11] */ __( 'Result', 'ip-geo-block' ), /* [12] */ __( 'Request', 'ip-geo-block' ), /* [13] */ __( 'User agent', 'ip-geo-block' ), /* [14] */ __( 'HTTP headers', 'ip-geo-block' ), /* [15] */ __( '$_POST data', 'ip-geo-block' ), ), 'interval' => self::INTERVAL_LIVE_UPDATE, // interval for live update [sec] 'timeout' => self::TIMEOUT_LIVE_UPDATE, // timeout of pausing live update [sec] 'altgmap' => apply_filters( 'google-maps-nokey', 'https://www.google.com/maps/embed' ), ) ); wp_enqueue_script( $handle ); } /** * Google Map in China * */ public function google_charts_cn ( $url ) { return 'https://www.gstatic.cn/charts/loader.js'; } public function google_maps_cn ( $url ) { return '//maps.google.cn/maps/api/js'; } public function google_maps_nokey_cn( $url ) { return '//maps.google.cn/maps'; } /** * Add plugin meta links * */ public function add_plugin_meta_links( $links, $file ) { if ( $file === IP_GEO_BLOCK_BASE ) { array_push( $links, '' . __( 'Contribute on GitHub', 'ip-geo-block' ) . '' ); } return $links; } /** * Add settings action link to the plugins page. * */ public function add_action_links( $links ) { $settings = IP_Geo_Block::get_option(); return array_merge( array( 'settings' => '' . __( 'Settings' ) . '' ), $links ); } /** * Add suggest text for inclusion in the site's privacy policy. @since 4.9.6 * * /wp-admin/tools.php?wp-privacy-policy-guide * https://developer.wordpress.org/plugins/privacy/privacy-related-options-hooks-and-capabilities/ */ public function add_privacy_policy() { if ( function_exists( 'wp_add_privacy_policy_content' ) ) wp_add_privacy_policy_content( 'IP Geo Block', __( 'suggested text.', 'ip-geo-block' ) ); } /** * Show global notice. * */ public function show_admin_notices() { $key = IP_Geo_Block::PLUGIN_NAME . '-notice'; if ( FALSE !== ( $notices = get_transient( $key ) ) ) { foreach ( $notices as $msg => $type ) { echo "\n", '

'; if ( 'updated' === $type ) echo '', IP_Geo_Block_Util::kses( $msg ), ''; else echo 'IP Geo Block: ', IP_Geo_Block_Util::kses( $msg ); echo '

', "\n"; } // delete all admin noties delete_transient( $key ); } } /** * Add global notice. * */ public static function add_admin_notice( $type, $msg ) { $key = IP_Geo_Block::PLUGIN_NAME . '-notice'; if ( FALSE === ( $notices = get_transient( $key ) ) ) $notices = array(); // can't overwrite the existent notice if ( ! isset( $notices[ $msg ] ) ) { $notices[ $msg ] = $type; set_transient( $key, $notices, MINUTE_IN_SECONDS ); } } /** * Get the admin url that depends on network multisite. * */ public function dashboard_url( $network_wide = FALSE ) { return ( $network_wide ? $this->is_network_admin : $network_wide ) ? network_admin_url( 'admin.php' /*'settings.php'*/ ) : admin_url( 'options-general.php' ); } /** * Register the administration menu into the WordPress Dashboard menu. * */ private function add_plugin_admin_menu( $settings ) { // Control tab number if ( $admin_menu = ( 'admin_menu' === current_filter() ) ) { if ( $this->is_network_admin && $settings['network_wide'] ) $this->admin_tab = min( 4, max( 1, $this->admin_tab ) ); else $this->admin_tab = min( 4, max( 0, $this->admin_tab ) ); } else { if ( $this->is_network_admin && $settings['network_wide'] ) $this->admin_tab = in_array( $this->admin_tab, array( 0, 5 ), TRUE ) ? $this->admin_tab : 0; else $this->admin_tab = 5; } if ( $admin_menu ) { // `options-general.php` ==> `options.php` ==> `settings-updated` is added as query just after settings updated. if ( ! empty( $_REQUEST['page'] ) && IP_Geo_Block::PLUGIN_NAME === $_REQUEST['page'] && ! empty( $_REQUEST['settings-updated'] ) && $this->is_network_admin && $settings['network_wide'] ) { $this->update_multisite_settings( $settings ); wp_safe_redirect( esc_url_raw( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $this->dashboard_url( TRUE ) ) ) ); exit; } // Add a settings page for this plugin to the Settings menu. $hook = add_options_page( __( 'IP Geo Block', 'ip-geo-block' ), __( 'IP Geo Block', 'ip-geo-block' ), 'manage_options', IP_Geo_Block::PLUGIN_NAME, array( $this, 'display_plugin_admin_page' ) ); } elseif ( $this->is_network_admin ) { // Add a settings page for this plugin to the Settings menu. $hook = add_menu_page( __( 'IP Geo Block', 'ip-geo-block' ), __( 'IP Geo Block', 'ip-geo-block' ), 'manage_network_options', IP_Geo_Block::PLUGIN_NAME, array( $this, 'display_plugin_admin_page' ) //, 'dashicons-admin-site' // or 'data:image/svg+xml;base64...' ); add_submenu_page( IP_Geo_Block::PLUGIN_NAME, __( 'IP Geo Block', 'ip-geo-block' ), __( 'Sites list', 'ip-geo-block' ), 'manage_network_options', IP_Geo_Block::PLUGIN_NAME . '&tab=5', array( $this, 'display_plugin_admin_page' ) ); if ( $settings['network_wide'] ) { add_submenu_page( IP_Geo_Block::PLUGIN_NAME, __( 'IP Geo Block', 'ip-geo-block' ), __( 'Settings', 'ip-geo-block' ), 'manage_network_options', IP_Geo_Block::PLUGIN_NAME, array( $this, 'display_plugin_admin_page' ) ); } wp_enqueue_style( IP_Geo_Block::PLUGIN_NAME . '-admin-icons', plugins_url( ! defined( 'IP_GEO_BLOCK_DEBUG' ) || ! IP_GEO_BLOCK_DEBUG ? 'css/admin-icons.min.css' : 'css/admin-icons.css', __FILE__ ), array(), IP_Geo_Block::VERSION ); } // If successful, load admin assets only on this page. if ( ! empty( $hook ) ) // 'admin_enqueue_scripts' add_action( "load-$hook", array( $this, 'enqueue_admin_assets' ) ); } /** * Diagnosis of admin settings. * */ private function diagnose_admin_screen( $settings ) { $updating = get_transient( IP_Geo_Block::CRON_NAME ); $adminurl = $this->dashboard_url( FALSE ); $network = $this->dashboard_url( $settings['network_wide'] ); // Check version and compatibility if ( version_compare( get_bloginfo( 'version' ), '3.7.0' ) < 0 ) self::add_admin_notice( 'error', __( 'You need WordPress 3.7+.', 'ip-geo-block' ) ); if ( ! $settings['api_dir'] || ! file_exists( $settings['api_dir'] ) ) { $this->add_admin_notice( 'error', sprintf( __( 'Can not load Geolocation API libraries from %s. It seems to have failed downloading ZIP file from WordPress-IP-Geo-API. Try to deactivate IP Geo Block once and activate it again, or install ip-geo-api with write permission according to this instruction.', 'ip-geo-block' ), apply_filters( 'ip-geo-block-api-dir', $settings['api_dir'] ? $settings['api_dir'] : basename( WP_CONTENT_DIR ) ) ) ); } else { $providers = IP_Geo_Block_Provider::get_valid_providers( $settings, FALSE, FALSE, TRUE ); if ( empty( $providers ) ) { $this->add_admin_notice( 'error', sprintf( __( 'You should select at least one API at Geolocation API settings. Otherwise you\'ll be blocked after the cache expires.', 'ip-geo-block' ), esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME, 'tab' => 0, 'sec' => 4 ), $network ) ) . '#' . IP_Geo_Block::PLUGIN_NAME . '-section-4' ) ); } else { $providers = IP_Geo_Block_Provider::get_addons( $settings['providers'] ); if ( empty( $providers ) ) { $this->add_admin_notice( 'error', sprintf( __( 'You should select at least one API for local database at Geolocation API settings. Otherwise access to the external API may slow down the site.', 'ip-geo-block' ), esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME, 'tab' => 0, 'sec' => 4 ), $network ) ) . '#' . IP_Geo_Block::PLUGIN_NAME . '-section-4' ) ); } } } // Check consistency of matching rule if ( -1 === (int)$settings['matching_rule'] ) { if ( FALSE !== $updating ) { self::add_admin_notice( 'notice-warning', sprintf( __( 'Now downloading geolocation databases in background. After a little while, please check your country code and “Matching rule” at Validation rules and behavior.', 'ip-geo-block' ), esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $network ) ) ) ); } else { self::add_admin_notice( 'error', sprintf( __( 'The “Matching rule” is not set properly. Please confirm it at Validation rules and behavior.', 'ip-geo-block' ), esc_url( add_query_arg( array( 'page' => IP_Geo_Block::PLUGIN_NAME ), $network ) ) ) ); } } // Check to finish updating matching rule elseif ( 'done' === $updating ) { delete_transient( IP_Geo_Block::CRON_NAME ); self::add_admin_notice( 'updated ', __( 'Local database and matching rule have been updated.', 'ip-geo-block' ) ); } // Check self blocking (skip during updating) if ( FALSE === $updating && 1 === (int)$settings['validation']['login'] ) { $instance = IP_Geo_Block::get_instance(); $validate = $instance->validate_ip( 'login', $settings, TRUE, FALSE ); // skip authentication check switch( $validate['result'] ) { case 'limited': self::add_admin_notice( 'error', __( 'Once you logout, you will be unable to login again because the number of login attempts reaches the limit.', 'ip-geo-block' ) . ' ' . sprintf( __( 'Please remove your IP address in “%1$sStatistics in IP address cache%2$s” on “%3$sStatistics%4$s” tab to prevent locking yourself out.', 'ip-geo-block' ), '', '', '', '' ) ); break; case 'blocked': case 'extra': self::add_admin_notice( 'error', ( $settings['matching_rule'] ? __( 'Once you logout, you will be unable to login again because your country code or IP address is in the blacklist.', 'ip-geo-block' ) : __( 'Once you logout, you will be unable to login again because your country code or IP address is not in the whitelist.', 'ip-geo-block' ) ) . ' ' . ( 'ZZ' !== $validate['code'] ? sprintf( __( 'Please check your “%sValidation rules and behavior%s”.', 'ip-geo-block' ), '', '' ) : sprintf( __( 'Please confirm your local geolocation database files exist at “%sLocal database settings%s” section, or remove your IP address in cache at “%sStatistics in cache%s” section.', 'ip-geo-block' ), '', '', '', '' ) ) ); break; } } // Check consistency of emergency login link if ( isset( $settings['login_link'] ) && $settings['login_link']['link'] && ! IP_Geo_Block_Util::verify_link( $settings['login_link']['link'], $settings['login_link']['hash'] ) ) { self::add_admin_notice( 'error', sprintf( __( 'Emergency login link is outdated. Please delete it once and generate again at “%sPlugin settings%s” section. Also do not forget to update favorites / bookmarks in your browser.', 'ip-geo-block' ), '', '' ) ); } // Check activation of IP Geo Allow if ( $settings['validation']['timing'] && is_plugin_active( 'ip-geo-allow/index.php' ) ) { self::add_admin_notice( 'error', __( '“mu-plugins” (ip-geo-block-mu.php) at “Validation timing” is imcompatible with IP Geo Allow. Please select “init” action hook.', 'ip-geo-block' ) ); } } /** * Setup menu and option page for this plugin * */ public function setup_admin_page() { $settings = IP_Geo_Block::get_option(); // Register the administration menu. $this->add_plugin_admin_menu( $settings ); // Avoid multiple validation. if ( 'GET' === $_SERVER['REQUEST_METHOD'] ) $this->diagnose_admin_screen( $settings ); // Register settings page only if it is needed. if ( ( isset( $_GET ['page' ] ) && IP_Geo_Block::PLUGIN_NAME === $_GET ['page' ] ) || ( isset( $_POST['option_page'] ) && IP_Geo_Block::PLUGIN_NAME === $_POST['option_page'] ) ) { $this->register_settings_tab(); } // Add an action link pointing to the options page. @since 2.7 else { add_filter( 'plugin_row_meta', array( $this, 'add_plugin_meta_links' ), 10, 2 ); add_filter( 'plugin_action_links_' . IP_GEO_BLOCK_BASE, array( $this, 'add_action_links' ), 10, 1 ); } // Register scripts for admin. add_action( 'admin_enqueue_scripts', array( 'IP_Geo_Block', 'enqueue_nonce' ), 0 ); // Show admin notices at the place where it should be. @since 2.5.0 add_action( 'admin_notices', array( $this, 'show_admin_notices' ) ); add_action( 'network_admin_notices', array( $this, 'show_admin_notices' ) ); } /** * Get cookie that indicates open/close section * */ public function get_cookie() { static $cookie = array(); if ( empty( $cookie ) && ! empty( $_COOKIE[ IP_Geo_Block::PLUGIN_NAME ] ) ) { foreach ( explode( '&', $_COOKIE[ IP_Geo_Block::PLUGIN_NAME ] ) as $i => $v ) { list( $i, $v ) = explode( '=', $v ); $cookie[ $i ] = str_split( $v ); } } return $cookie; } /** * Prints out all settings sections added to a particular settings page * * wp-admin/includes/template.php @since 2.7.0 */ private function do_settings_sections( $page, $tab ) { global $wp_settings_sections, $wp_settings_fields; // target section to be opened $target = isset( $_GET['sec'] ) ? (int)$_GET['sec'] : -1; if ( isset( $wp_settings_sections[ $page ] ) ) { $index = 0; // index of fieldset $cookie = $this->get_cookie(); foreach ( (array) $wp_settings_sections[ $page ] as $section ) { // TRUE if open ('o') or FALSE if close ('x') $stat = empty( $cookie[ $tab ][ $index ] ) || 'x' !== $cookie[ $tab ][ $index ] || $index === $target; echo "\n", '
', "\n", '

', is_array( $section['title'] ) ? $section['title'][0] . '[ ' . $section['title'][1] . ' ]' : $section['title'], '

', "\n", '
' : ' style="display:none">'), "\n"; if ( $section['callback'] ) call_user_func( $section['callback'], $section ); if ( isset( $wp_settings_fields, $wp_settings_fields[ $page ], $wp_settings_fields[ $page ][ $section['id'] ] ) ) { echo ''; do_settings_fields( $page, $section['id'] ); echo "
\n"; } echo "
\n
\n"; ++$index; } } } /** * Render the settings page for this plugin. * */ public function display_plugin_admin_page() { $tab = $this->admin_tab; $tabs = array( 5 => __( 'Sites list', 'ip-geo-block' ), 0 => __( 'Settings', 'ip-geo-block' ), 1 => __( 'Statistics', 'ip-geo-block' ), 4 => __( 'Logs', 'ip-geo-block' ), 2 => __( 'Search', 'ip-geo-block' ), 3 => __( 'Attribution', 'ip-geo-block' ), ); $settings = IP_Geo_Block::get_option(); $cookie = $this->get_cookie(); $title = esc_html( get_admin_page_title() ); // Target page that depends on the network multisite or not. if ( 'options-general.php' === $GLOBALS['pagenow'] ) { $action = 'options.php'; unset( $tabs[5] ); // Sites list if ( $this->is_network_admin ) { $title .= ' [ '; $title .= '' . __( 'Sites list', 'ip-geo-block' ) . ''; if ( $settings['network_wide'] ) { unset( $tabs[0] ); // Settings $title .= ' / ' . __( 'Settings', 'ip-geo-block' ) . ''; } $title .= ' ]'; } } // '/wp-admin/network/admin.php' else { // `edit.php` is an action handler for Multisite administration dashboard. // `edit.php` ==> do action `network_admin_edit_ip-geo-block` ==> `validate_network_settings()` $action = 'edit.php?action=' . IP_Geo_Block::PLUGIN_NAME; if ( $this->is_network_admin ) { unset( $tabs[1], $tabs[4], $tabs[2], $tabs[3] ); // Statistics, Logs, Search, Attribution $title .= ' [ '; $title .= __( 'Sites list', 'ip-geo-block' ); if ( $settings['network_wide'] ) { $title .= ' / ' . __( 'Settings', 'ip-geo-block' ); } else { unset( $tabs[0] ); // Settings } $title .= ' ]'; } } ?>

> do_settings_sections( IP_Geo_Block::PLUGIN_NAME, $tab ); if ( 0 === $tab ) submit_button(); // @since 3.1 ?>
get_attribution(); } } echo '

', implode( '
', $tab ), "

\n"; echo '

', __( 'Thanks for providing these great services for free.', 'ip-geo-block' ), "
\n"; echo __( '(Most browsers will redirect you to each site without referrer when you click the link.)', 'ip-geo-block' ), "

\n"; } ?> ', get_num_queries(), ' queries. ', timer_stop(0), ' seconds. ', memory_get_usage(), " bytes.

\n"; } ?>

[ ]

'admin/includes/tab-settings.php', 1 => 'admin/includes/tab-statistics.php', 4 => 'admin/includes/tab-accesslog.php', 2 => 'admin/includes/tab-geolocation.php', 3 => 'admin/includes/tab-attribution.php', 5 => 'admin/includes/tab-network.php', ); require_once IP_GEO_BLOCK_PATH . $files[ $this->admin_tab ]; IP_Geo_Block_Admin_Tab::tab_setup( $this, $this->admin_tab ); } /** * Function that fills the field with the desired inputs as part of the larger form. * The 'id' and 'name' should match the $id given in the add_settings_field(). * * @param array $args['value'] must be sanitized because it comes from external. */ public function callback_field( $args ) { if ( ! empty( $args['before'] ) ) echo $args['before'], "\n"; // must be sanitized at caller // field $id = $name = ''; if ( ! empty( $args['field'] ) ) { $id = "${args['option']}_${args['field']}"; $name = "${args['option']}[${args['field']}]"; } // sub field $sub_id = $sub_name = ''; if ( ! empty( $args['sub-field'] ) ) { $sub_id = "_${args['sub-field']}"; $sub_name = "[${args['sub-field']}]"; } switch ( $args['type'] ) { case 'check-provider': echo "\n