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); ?> |
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
]);
?>
$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);
}
}