security = $GLOBALS['wpban_security']; add_action('admin_menu', [$this, 'add_menu']); add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']); // AJAX handlers add_action('wp_ajax_wpban_save_settings', [$this, 'ajax_save_settings']); add_action('wp_ajax_wpban_apply_template', [$this, 'ajax_apply_template']); add_action('wp_ajax_wpban_get_logs', [$this, 'ajax_get_logs']); add_action('wp_ajax_wpban_export_logs', [$this, 'ajax_export_logs']); add_action('wp_ajax_wpban_clear_logs', [$this, 'ajax_clear_logs']); add_action('wp_ajax_wpban_test_email', [$this, 'ajax_test_email']); add_action('wp_ajax_wpban_get_country_stats', [$this, 'ajax_get_country_stats']); } public function add_menu() { add_menu_page( __('WPBan Security', 'wpban'), __('WPBan Security', 'wpban'), 'manage_options', 'wpban', [$this, 'render_dashboard'], 'dashicons-shield', 30 ); add_submenu_page( 'wpban', __('Settings', 'wpban'), __('Settings', 'wpban'), 'manage_options', 'wpban-settings', [$this, 'render_settings'] ); add_submenu_page( 'wpban', __('Security Logs', 'wpban'), __('Logs', 'wpban'), 'manage_options', 'wpban-logs', [$this, 'render_logs'] ); add_submenu_page( 'wpban', __('Tools', 'wpban'), __('Tools', 'wpban'), 'manage_options', 'wpban-tools', [$this, 'render_tools'] ); } public function enqueue_scripts($hook) { if (strpos($hook, 'wpban') === false) { return; } wp_enqueue_style('wpban-admin', WPBAN_URL . 'assets/admin.css', [], WPBAN_VERSION); wp_enqueue_script('wpban-admin', WPBAN_URL . 'assets/admin.js', ['jquery'], WPBAN_VERSION); wp_localize_script('wpban-admin', 'wpban', [ 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('wpban_admin'), 'i18n' => [ 'confirm_clear' => __('Are you sure you want to clear all logs?', 'wpban'), 'confirm_template' => __('This will replace your current settings. Continue?', 'wpban'), 'email_sent' => __('Test email sent!', 'wpban'), 'error' => __('An error occurred', 'wpban') ] ]); // Add Chart.js for statistics wp_enqueue_script('chartjs', 'https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js', [], '3.9.1'); } public function render_dashboard() { $stats = $this->security->get_stats(); $bypass_url = home_url('/?wpban_bypass=' . get_option('wpban_bypass_path')); ?>

0 ? round(($stats['today_blocks'] / $yesterday - 1) * 100) : 0; ?> 0 ? '↑' : '↓'; ?> %

security->get_templates() as $id => $template): ?>

timestamp)); ?> ago ip); ?> country_code ?: '-'); ?> action); ?> reason); ?>

Access Denied

Your access has been restricted.

', 'ban_message', [ 'textarea_name' => 'settings[ban_message]', 'textarea_rows' => 10, 'media_buttons' => false ] ); ?>


$info): ?>

$info): ?>
__('Rate limit exceeded', 'wpban'), 'geo_block' => __('Geographic block', 'wpban'), 'brute_force' => __('Brute force attempt', 'wpban'), 'crawler_block' => __('Crawler blocked', 'wpban') ]; $selected_events = $settings['email_notifications']['events'] ?? ['rate_limit', 'brute_force']; foreach ($events as $event => $label): ?>

sanitize_text_field($_GET['date_from'] ?? ''), 'date_to' => sanitize_text_field($_GET['date_to'] ?? ''), 'action' => sanitize_text_field($_GET['action_filter'] ?? ''), 'ip' => sanitize_text_field($_GET['ip_filter'] ?? ''), 'country' => sanitize_text_field($_GET['country_filter'] ?? '') ]; $result = $this->security->get_logs($filters, $current_page, $per_page); ?>

timestamp); ?> ip); ?> country_code ?: '-'); ?> action); ?> reason); ?> user_agent, 0, 50)); ?> uri); ?>
1): ?>
add_query_arg('paged', '%#%'), 'format' => '', 'prev_text' => '«', 'next_text' => '»', 'total' => $result['pages'], 'current' => $current_page ]); ?>

get_var("SELECT COUNT(*) FROM {$wpdb->prefix}wpban_logs"); $logs_size = $wpdb->get_var("SELECT ROUND(((data_length + index_length) / 1024 / 1024), 2) FROM information_schema.TABLES WHERE table_schema = '" . DB_NAME . "' AND table_name = '{$wpdb->prefix}wpban_logs'"); ?>
MB

$value) { $settings['rate_limits'][$key] = max(1, intval($value)); } } update_option('wpban_settings', $settings); $this->security->clear_cache(); wp_send_json_success(['message' => __('Settings saved successfully!', 'wpban')]); } public function ajax_apply_template() { check_ajax_referer('wpban_admin', '_ajax_nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $template_id = sanitize_key($_POST['template']); $templates = $this->security->get_templates(); if (!isset($templates[$template_id])) { wp_send_json_error(__('Invalid template', 'wpban')); } $current = get_option('wpban_settings', []); $new_settings = array_merge($current, $templates[$template_id]['settings']); update_option('wpban_settings', $new_settings); $this->security->clear_cache(); wp_send_json_success(['message' => __('Template applied successfully!', 'wpban')]); } public function ajax_get_logs() { check_ajax_referer('wpban_admin', '_ajax_nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $page = intval($_POST['page'] ?? 1); $filters = [ 'date_from' => sanitize_text_field($_POST['date_from'] ?? ''), 'date_to' => sanitize_text_field($_POST['date_to'] ?? ''), 'action' => sanitize_text_field($_POST['action'] ?? ''), 'ip' => sanitize_text_field($_POST['ip'] ?? '') ]; $result = $this->security->get_logs($filters, $page); ob_start(); // Render log rows foreach ($result['logs'] as $log) { // ... render table rows ... } $html = ob_get_clean(); wp_send_json_success([ 'html' => $html, 'pagination' => paginate_links([ 'total' => $result['pages'], 'current' => $page ]) ]); } public function ajax_export_logs() { check_ajax_referer('wpban_admin', '_ajax_nonce'); if (!current_user_can('manage_options')) { wp_die('Permission denied'); } $logs = $this->security->get_logs([], 1, 10000); header('Content-Type: text/csv'); header('Content-Disposition: attachment; filename="wpban-logs-' . date('Y-m-d') . '.csv"'); $output = fopen('php://output', 'w'); fputcsv($output, ['Time', 'IP', 'Country', 'Action', 'Reason', 'User Agent', 'Referer', 'URI']); foreach ($logs['logs'] as $log) { fputcsv($output, [ $log->timestamp, $log->ip, $log->country_code, $log->action, $log->reason, $log->user_agent, $log->referer, $log->uri ]); } fclose($output); exit; } public function ajax_clear_logs() { check_ajax_referer('wpban_admin', '_ajax_nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } global $wpdb; $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}wpban_logs"); wp_send_json_success(['message' => __('Logs cleared successfully!', 'wpban')]); } public function ajax_test_email() { check_ajax_referer('wpban_admin', '_ajax_nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } $settings = get_option('wpban_settings', []); $to = $settings['email_notifications']['recipient'] ?? get_option('admin_email'); $subject = sprintf('[%s] WPBan Test Email', get_bloginfo('name')); $message = "This is a test email from WPBan Security.\n\n"; $message .= "If you received this email, your notifications are working correctly!"; $sent = wp_mail($to, $subject, $message); if ($sent) { wp_send_json_success(['message' => __('Test email sent successfully!', 'wpban')]); } else { wp_send_json_error(__('Failed to send test email. Please check your email settings.', 'wpban')); } } public function ajax_get_country_stats() { check_ajax_referer('wpban_admin', '_ajax_nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Permission denied'); } global $wpdb; $stats = $wpdb->get_results( "SELECT country_code, COUNT(*) as count FROM {$wpdb->prefix}wpban_logs WHERE country_code IS NOT NULL GROUP BY country_code ORDER BY count DESC LIMIT 20" ); wp_send_json_success($stats); } }