plugin = $plugin_instance;
}
public function settings_page_content() {
if (!current_user_can('manage_options')) {
return;
}
nocache_headers(); // Prevent caching on this admin page
// 1. DEFINIR LA ESTRUCTURA COMPLETA DEL MENÚ
$menu_structure = [
'dashboard' => [ 'title' => __('Dashboard', 'advanced-ip-blocker'), 'icon' => 'dashicons-dashboard', 'sub_tabs' => [ 'main_dashboard' => __('Security Dashboard', 'advanced-ip-blocker'), 'status' => __('System Status', 'advanced-ip-blocker') ] ],
'security_headers' => [
'title' => __('Security Headers', 'advanced-ip-blocker'),
'icon' => 'dashicons-admin-network',
'sub_tabs' => [ 'headers_config' => __('HTTP Headers', 'advanced-ip-blocker') ]
],
'settings' => [
'title' => __('Settings', 'advanced-ip-blocker'),
'icon' => 'dashicons-admin-settings',
'sub_tabs' => [
'general_settings' => __('General', 'advanced-ip-blocker'),
'2fa_management' => __('2FA Management', 'advanced-ip-blocker'),
'import_export' => __('Import / Export', 'advanced-ip-blocker')
]
],
'rules' => [ 'title' => __('Blocking Rules', 'advanced-ip-blocker'), 'icon' => 'dashicons-shield-alt', 'sub_tabs' => [ 'waf' => __('Firewall (WAF)', 'advanced-ip-blocker'), 'user_agents' => __('User Agents', 'advanced-ip-blocker'), 'honeypot' => __('Honeypot URLs', 'advanced-ip-blocker'), 'asn_blocking' => __('ASN Blocking', 'advanced-ip-blocker'), 'advanced_rules' => __('Advanced Rules', 'advanced-ip-blocker') ] ],
'ip_management' => [
'title' => __('IP Management', 'advanced-ip-blocker'),
'icon' => 'dashicons-location',
'sub_tabs' => [
'blocked_ips' => __('Blocked IPs', 'advanced-ip-blocker'),
'blocked_signatures' => __('Blocked Signatures', 'advanced-ip-blocker'),
'blocked_endpoints' => __('Blocked Endpoints', 'advanced-ip-blocker'),
'whitelist' => __('Whitelist', 'advanced-ip-blocker')
]
],
'scanner' => [
'title' => __('Site Scanner', 'advanced-ip-blocker'),
'icon' => 'dashicons-search',
'sub_tabs' => [ 'scan_overview' => __('Health & Vulnerabilities', 'advanced-ip-blocker') ]
],
'logs' => [ 'title' => __('Logs & Sessions', 'advanced-ip-blocker'), 'icon' => 'dashicons-list-view', 'sub_tabs' => [ 'security_log' => __('Security Log', 'advanced-ip-blocker'), 'audit_log' => __('Activity Audit Log', 'advanced-ip-blocker'), 'general_log' => __('General Log', 'advanced-ip-blocker'), 'ip_trust_log' => __('IP Trust Log', 'advanced-ip-blocker'), 'user_sessions' => __('User Sessions', 'advanced-ip-blocker'), 'cron_logs' => __('WP-Cron Log', 'advanced-ip-blocker') ] ],
'about' => [ 'title' => __('About', 'advanced-ip-blocker'), 'icon' => 'dashicons-info', 'sub_tabs' => [ 'credits' => __('Credits & Support', 'advanced-ip-blocker') ] ]
];
// phpcs:disable WordPress.Security.NonceVerification.Recommended
// La verificación de Nonce no es necesaria aquí.
// Estas variables GET solo se usan para la navegación y visualización de pestañas,
// no para procesar datos ni realizar acciones. La entrada ya se sanea con sanitize_key().
$current_page_slug = isset($_GET['page']) ? sanitize_key($_GET['page']) : 'advaipbl_settings_page';
// Primero, verificamos si la navegación es interna (clic en una pestaña/sub-pestaña)
if (isset($_GET['tab'])) {
$active_main_tab = sanitize_key($_GET['tab']);
$active_sub_tab = isset($_GET['sub-tab']) ? sanitize_key($_GET['sub-tab']) : null;
// phpcs:enable
} else {
// Si no, es una navegación desde el menú de la izquierda.
// Mapeamos el slug de la página a la pestaña correcta.
$page_slug_to_tab_map = [
'advaipbl_settings_page' => ['dashboard', 'main_dashboard'],
'advaipbl_settings_page-settings' => ['settings', 'general_settings'],
'advaipbl_settings_page-security-headers' => ['security_headers', 'headers_config'],
'advaipbl_settings_page-rules' => ['rules', 'waf'],
'advaipbl_settings_page-ip-management' => ['ip_management', 'blocked_ips'],
'advaipbl_settings_page-scanner' => ['scanner', 'scan_overview'],
'advaipbl_settings_page-logs' => ['logs', 'security_log'],
'advaipbl_settings_page-about' => ['about', 'credits'],
];
if (isset($page_slug_to_tab_map[$current_page_slug])) {
list($active_main_tab, $active_sub_tab) = $page_slug_to_tab_map[$current_page_slug];
} else {
// Fallback por si acaso
$active_main_tab = 'dashboard';
$active_sub_tab = 'main_dashboard';
}
}
// Validación final para asegurarse de que las pestañas existen
if (!isset($menu_structure[$active_main_tab])) {
$active_main_tab = 'dashboard';
}
if (empty($active_sub_tab) || !isset($menu_structure[$active_main_tab]['sub_tabs'][$active_sub_tab])) {
// Asigna la primera sub-pestaña de la pestaña principal activa
$active_sub_tab = key($menu_structure[$active_main_tab]['sub_tabs']);
}
$blocked_count = $this->plugin->get_blocked_count();
?>
plugin->display_admin_notice();
?>
$main_tab_data) :
$is_active = ($main_tab_key === $active_main_tab);
$first_sub_tab = key($main_tab_data['sub_tabs']);
// La URL para los enlaces de las pestañas SÍ debe construirse con add_query_arg
$url = add_query_arg(
[
'page' => 'advaipbl_settings_page',
'tab' => $main_tab_key,
'sub-tab' => $first_sub_tab
],
'admin.php'
);
?>
0) : ?>
$sub_tab_title) :
$is_active = ($sub_tab_key === $active_sub_tab);
$url = add_query_arg(
[
'page' => 'advaipbl_settings_page',
'tab' => $active_main_tab,
'sub-tab' => $sub_tab_key
],
'admin.php'
);
?>
display_dashboard_tab(); break;
case 'status': $this->display_status_tab(); break;
case 'headers_config': $this->plugin->security_headers_manager->display_settings_tab(); break;
case 'general_settings': $this->display_general_settings_tab(); break;
case '2fa_management': $this->display_2fa_management_tab(); break;
case 'import_export': $this->render_import_export_controls_callback(); break;
case 'waf': $this->display_waf_tab(); break;
case 'user_agents': $this->display_user_agents_tab(); break;
case 'honeypot': $this->display_honeypot_tab(); break;
case 'asn_blocking': $this->display_asn_blocking_tab(); break;
case 'advanced_rules': $this->display_advanced_rules_tab(); break;
case 'blocked_ips': $this->display_blocked_ips_tab(); break;
case 'blocked_signatures': $this->display_blocked_signatures_tab(); break;
case 'blocked_endpoints': $this->display_blocked_endpoints_tab(); break;
case 'whitelist': $this->display_whitelist_tab(); break;
case 'scan_overview': $this->display_scanner_tab(); break;
case 'security_log': $this->display_security_log_tab(); break;
case 'audit_log': $this->display_audit_log_tab(); break;
case 'general_log': $this->display_general_log_tab(); break;
case 'ip_trust_log': $this->display_ip_trust_log_tab(); break;
case 'user_sessions': $this->plugin->session_manager->display_admin_page(); break;
case 'cron_logs': $this->display_cron_logs_tab(); break;
case 'credits': $this->display_credits_tab(); break;
default: echo '
Error: Content for this tab is not available.
'; break;
}
?>
';
esc_html_e( 'This log shows which IP addresses are triggering WP-Cron tasks on your site, and which scheduled tasks (hooks) were due to run at that moment.', 'advanced-ip-blocker' );
echo '
';
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$search_term = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
$orderby = isset($_GET['orderby']) && in_array($_GET['orderby'], ['timestamp', 'ip'], true) ? sanitize_key($_GET['orderby']) : 'timestamp';
$order = isset($_GET['order']) && in_array(strtolower($_GET['order']), ['asc', 'desc'], true) ? strtolower(sanitize_key($_GET['order'])) : 'desc';
$current_page = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
$per_page = isset($_GET['advaipbl_per_page']) ? absint($_GET['advaipbl_per_page']) : 25;
// phpcs:enable
global $wpdb;
$table_name = $wpdb->prefix . 'advaipbl_logs';
$where_clauses = [$wpdb->prepare("log_type = %s", 'wp_cron')];
if (!empty($search_term)) {
$search_like = '%' . $wpdb->esc_like($search_term) . '%';
$where_clauses[] = $wpdb->prepare("(ip LIKE %s OR details LIKE %s)", $search_like, $search_like);
}
$where_sql = implode(' AND ', $where_clauses);
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$total_items = $wpdb->get_var("SELECT COUNT(log_id) FROM $table_name WHERE $where_sql");
$total_pages = ceil($total_items / $per_page);
$offset = ($current_page - 1) * $per_page;
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$logs = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE $where_sql ORDER BY " . esc_sql($orderby) . " " . esc_sql($order) . " LIMIT %d OFFSET %d", $per_page, $offset), ARRAY_A);
?>
add_query_arg([
'paged' => '%#%',
's' => $search_term,
'advaipbl_per_page' => $per_page,
]),
'format' => '',
'total' => $total_pages,
'current' => $current_page
]);
if ($page_links) echo wp_kses_post($page_links);
?>
plugin->print_log_sortable_header(__('Date/Time', 'advanced-ip-blocker'), 'timestamp', $orderby, $order); ?>
plugin->print_log_sortable_header(__('IP Address', 'advanced-ip-blocker'), 'ip', $orderby, $order); ?>
';
foreach ( $details['due_hooks'] as $hook ) {
echo '' . esc_html( $hook ) . ' ';
}
echo '';
} else {
echo '–';
}
?>
plugin->options['geolocation_provider'] ?? '';
$is_compatible = in_array($provider, ['ip-api.com', 'ipinfo.io'], true);
$is_spamhaus_enabled = !empty($this->plugin->options['enable_spamhaus_asn']);
$is_manual_enabled = !empty($this->plugin->options['enable_manual_asn']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings');
$spamhaus_stats = $this->plugin->dashboard_manager->get_spamhaus_stats();
?>
Warning: Your current geolocation provider (%1$s ) does not support ASN lookups. This feature is fully supported by ip-api.com and ipinfo.io . Please change your provider to use ASN blocking.', 'advanced-ip-blocker'),
['strong' => [], 'a' => ['href' => []]]
),
esc_html($provider),
esc_url($settings_url)
); ?>
prefix . 'advaipbl_malicious_signatures';
$is_enabled = !empty($this->plugin->options['enable_signature_blocking']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings#section-signature_engine');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: 1: Status (Enabled/Disabled), 2: Link to settings page. */
__('The Attack Signature Blocking system is currently %1$s. You can change this in the Settings .', 'advanced-ip-blocker'),
[ 'span' => ['class' => true], 'a' => ['href' => []] ]
),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$status_tag,
esc_url($settings_url)
);
?>
get_var("SELECT COUNT(id) FROM {$table_name}");
$total_pages = ceil($total_items / $per_page);
$offset = ($current_page - 1) * $per_page;
$query = "SELECT * FROM {$table_name} ORDER BY " . esc_sql($orderby) . " " . esc_sql($order) . " LIMIT %d OFFSET %d";
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$items = $wpdb->get_results($wpdb->prepare($query, $per_page, $offset), ARRAY_A);
// phpcs:enable
?>
plugin->render_per_page_selector($per_page); ?>
add_query_arg('paged', '%#%'), 'format' => '', 'total' => $total_pages, 'current' => $current_page]); if ($page_links) echo wp_kses_post($page_links); ?>
plugin->print_log_sortable_header(__('Signature Hash', 'advanced-ip-blocker'), 'signature_hash', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Reason', 'advanced-ip-blocker'), 'reason', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Last Seen', 'advanced-ip-blocker'), 'last_seen', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Expires In', 'advanced-ip-blocker'), 'expires_at', $orderby, $order); ?>
prefix . 'advaipbl_endpoint_lockdowns';
// Array para definir los endpoints que soportan lockdown
$lockdown_endpoints = [
'xmlrpc' => [
'name' => 'XML-RPC',
'option' => 'enable_xmlrpc_lockdown',
'anchor' => '#sub-section-xmlrpc-lockdown'
],
'login' => [
'name' => 'Login Page (wp-login.php)',
'option' => 'enable_login_lockdown',
'anchor' => '#sub-section-login-lockdown'
],
'404' => [
'name' => '404 Errors',
'option' => 'enable_404_lockdown',
'anchor' => '#section-blocking_rules'
],
'403' => [
'name' => '403 Errors',
'option' => 'enable_403_lockdown',
'anchor' => '#section-blocking_rules'
],
];
$settings_base_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings');
$status_parts = [];
foreach ($lockdown_endpoints as $key => $details) {
$is_enabled = !empty($this->plugin->options[$details['option']]);
$status_tag = sprintf(
'%s ',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
$settings_link = sprintf(
'%s ',
esc_url($settings_base_url . $details['anchor']),
esc_html__('Configure', 'advanced-ip-blocker')
);
/* translators: 1: Endpoint name (e.g., XML-RPC), 2: Status tag (Active/Inactive), 3: Link to configure */
$status_parts[] = sprintf('%1$s: %2$s (%3$s)', esc_html($details['name']), $status_tag, $settings_link);
}
?>
[],
'span' => ['class' => true],
'a' => ['href' => true],
]); ?>
query($wpdb->prepare("DELETE FROM {$table_name} WHERE expires_at <= %d", time()));
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$items = $wpdb->get_results("SELECT * FROM {$table_name} ORDER BY created_at DESC", ARRAY_A);
?>
'advaipbl_delete_lockdown',
'lockdown_id' => $item['id']
]),
'advaipbl_delete_lockdown_' . $item['id']
);
?>
plugin->options['enable_waf']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings#sub-section-waf');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: 1: Status tag (Active/Inactive), 2: Link to settings page. */
__('Web Application Firewall (WAF) is currently %1$s. You can change this in the Settings .', 'advanced-ip-blocker'),
[
'span' => ['class' => true],
'a' => ['href' => []]
]
),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$status_tag,
esc_url($settings_url)
);
?>
plugin->options = get_option(ADVAIPBL_Main::OPTION_SETTINGS);
$sections = [
'general' => __('General', 'advanced-ip-blocker'),
'notifications' => __('Notifications', 'advanced-ip-blocker'),
'htaccess' => __('Server Firewall (.htaccess)', 'advanced-ip-blocker'),
'cloudflare' => __('Cloud Edge Defense', 'advanced-ip-blocker'),
'ip_detection' => __('IP Detection', 'advanced-ip-blocker'),
'geolocation' => __('Geolocation', 'advanced-ip-blocker'),
'threat_intelligence' => __('Threat Intelligence', 'advanced-ip-blocker'),
'protections' => __('Core Protections', 'advanced-ip-blocker'),
'blocking_rules' => __('Threshold Blocking', 'advanced-ip-blocker'),
'ip_trust' => __('IP Trust & Scoring', 'advanced-ip-blocker'),
'login_protection' => __('Login Protection', 'advanced-ip-blocker'),
'signature_engine' => __('Signature Engine', 'advanced-ip-blocker'),
'internal_security' => __('Internal Security', 'advanced-ip-blocker'),
'uninstall' => __('Uninstallation', 'advanced-ip-blocker'),
];
// Obtener estadísticas de la lista comunitaria
$community_stats = $this->plugin->community_manager->get_stats();
$list_count = $community_stats['count'] ?? 0;
$last_update = $community_stats['last_update'] ?? 0;
?>
';
echo '' . esc_html__('Compatibility Warning:', 'advanced-ip-blocker') . ' ';
echo esc_html__('Your server appears to be running Nginx independently. Nginx does NOT support .htaccess files. Enabling these options will write to the file, but the server will likely ignore them.', 'advanced-ip-blocker');
echo '
';
}
?>
plugin->htaccess_manager->is_writable()) : ?>
X-Forwarded-For if the request comes from one of these IPs, preventing IP spoofing.', 'advanced-ip-blocker'); ?>
free API key is required.', 'advanced-ip-blocker'),
['a' => ['href' => [], 'target' => []]]
),
'https://www.abuseipdb.com/pricing'
); ?>
plugin->options['allow_telemetry'])) :
$telemetry_setting_id = 'advaipbl_allow_telemetry';
?>
Enable anonymous usage tracking.', 'advanced-ip-blocker'), ['a' => ['href' => []]]), '#' . esc_attr($telemetry_setting_id)); ?>
plugin->options['enable_2fa']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings#sub-section-2FA');
$profile_url = admin_url('profile.php');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: %1$s: Status tag (Active/Inactive), %2$s: Link to Settings, %3$s: Link to Profile. */
__('Two-Factor Authentication (2FA) is currently %1$s. You can change this in the Settings . When enabled, users will see the 2FA setup section in their Profile .', 'advanced-ip-blocker'),
[
'span' => ['class' => true],
'a' => ['href' => true],
]
),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$status_tag,
esc_url($settings_url),
esc_url($profile_url)
);
?>
process_bulk_action();
$users_list_table->prepare_items();
?>
views(); ?>
search_box( __( 'Search Users', 'advanced-ip-blocker' ), 'user' );
$users_list_table->display();
?>
plugin->options['enable_user_agent_blocking']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings#sub-section-user-agent');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: 1: Status tag (Active/Inactive), 2: Link to settings page. */
__('User-Agent Protection is currently %1$s. You can change this in the Settings .', 'advanced-ip-blocker'),
[
'span' => ['class' => true],
'a' => ['href' => []]
]
),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$status_tag,
esc_url($settings_url)
);
?>
plugin->options['enable_honeypot_blocking']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings#sub-section-honeypot');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: 1: Status tag (Active/Inactive), 2: Link to settings page. */
__('Honeypot Protection is currently %1$s. You can change this in the Settings .', 'advanced-ip-blocker'),
[
'span' => ['class' => true],
'a' => ['href' => []]
]
),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$status_tag,
esc_url($settings_url)
);
?>
/blog/ or /contact/). Use attack-specific patterns.', 'advanced-ip-blocker') ); ?>
prefix . 'advaipbl_blocked_ips';
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$filter_type = isset($_GET['filter_type']) ? sanitize_key($_GET['filter_type']) : 'all';
$search_term = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
$orderby = isset($_GET['orderby']) && in_array($_GET['orderby'], ['ip_range', 'block_type', 'timestamp'], true) ? sanitize_key($_GET['orderby']) : 'timestamp';
$order = isset($_GET['order']) && in_array(strtolower($_GET['order']), ['asc', 'desc'], true) ? strtolower(sanitize_key($_GET['order'])) : 'desc';
$current_page = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
$per_page = isset($_GET['advaipbl_per_page']) ? absint($_GET['advaipbl_per_page']) : 20;
// phpcs:enable
$offset = ($current_page - 1) * $per_page;
$where_clauses = [];
if ('all' !== $filter_type) {
$where_clauses[] = $wpdb->prepare("block_type = %s", $filter_type);
}
// Add Search Clause
if (!empty($search_term)) {
$search_like = '%' . $wpdb->esc_like($search_term) . '%';
$where_clauses[] = $wpdb->prepare("ip_range LIKE %s", $search_like);
}
$where_sql = !empty($where_clauses) ? 'WHERE ' . implode(' AND ', $where_clauses) : '';
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$table_name} {$where_sql}");
$total_pages = ceil($total_items / $per_page);
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$items_for_page = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table_name} {$where_sql} ORDER BY " . esc_sql($orderby) . " " . esc_sql($order) . " LIMIT %d OFFSET %d", $per_page, $offset), ARRAY_A);
$ips_and_ranges_on_page = wp_list_pluck($items_for_page, 'ip_range');
$single_ips_on_page = array_filter($ips_and_ranges_on_page, function($entry) { return filter_var($entry, FILTER_VALIDATE_IP); });
$locations = !empty($single_ips_on_page) ? $this->plugin->session_manager->get_cached_locations($single_ips_on_page) : [];
$definitions = $this->plugin->get_all_block_type_definitions();
?>
plugin->print_sortable_header(__('IP', 'advanced-ip-blocker'), 'ip_range', $orderby, $order); ?>
plugin->print_sortable_header(__('Block Type', 'advanced-ip-blocker'), 'block_type', $orderby, $order); ?>
plugin->print_sortable_header(__('Since', 'advanced-ip-blocker'), 'timestamp', $orderby, $order); ?>
1 año, legacy permanent), lo mostramos como permanente.
if ($block['block_type'] === 'manual' || $duration_seconds <= 0 || $duration_seconds > 31536000) {
esc_html_e('Permanent', 'advanced-ip-blocker');
} else {
$duration_minutes = round($duration_seconds / 60);
printf( /* translators: %d: The number of minutes for a block duration. */
esc_html__('%d minutes', 'advanced-ip-blocker'),
(int) $duration_minutes
);
}
}
?>
' . esc_html__( 'View Map', 'advanced-ip-blocker' ) . ' ';
}
} else {
esc_html_e( 'Not available', 'advanced-ip-blocker' );
}
?>
'advaipbl_unblock_ip', 'ip' => $block['ip_range']]),
'advaipbl_unblock_ip'
);
?>
$data) {
if ( is_array($data) && isset($data['timestamp']) ) {
$table_data[] = [ 'ip' => $ip, 'timestamp' => $data['timestamp'], 'detail' => $data['detail'] ?? '' ];
} elseif ( is_numeric($data) ) {
$table_data[] = [ 'ip' => $ip, 'timestamp' => $data, 'detail' => __('Migrated from old format', 'advanced-ip-blocker') ];
}
}
}
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$sortable_columns = ['ip', 'timestamp', 'detail'];
$orderby = isset($_GET['orderby']) && in_array($_GET['orderby'], $sortable_columns, true) ? sanitize_key($_GET['orderby']) : 'timestamp';
$order = isset($_GET['order']) && in_array(strtolower($_GET['order']), ['asc', 'desc'], true) ? strtolower(sanitize_key($_GET['order'])) : 'desc';
// phpcs:enable
usort($table_data, function($a, $b) use ($orderby, $order) {
$a_val = $a[$orderby] ?? ''; $b_val = $b[$orderby] ?? '';
if ($a_val == $b_val) return 0;
return ($order === 'asc') ? strnatcasecmp((string)$a_val, (string)$b_val) : strnatcasecmp((string)$b_val, (string)$a_val);
});
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$current_page = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$per_page = isset($_GET['advaipbl_per_page']) ? absint($_GET['advaipbl_per_page']) : 20;
$total_items = count($table_data);
$total_pages = ceil($total_items / $per_page);
$items_for_page = array_slice($table_data, ($current_page - 1) * $per_page, $per_page);
$ips_on_page = wp_list_pluck($items_for_page, 'ip');
$locations = $this->plugin->session_manager->get_cached_locations($ips_on_page);
?>
plugin->render_per_page_selector($per_page); ?>
add_query_arg('paged', '%#%'), 'format' => '', 'total' => $total_pages, 'current' => $current_page]); if ($page_links) echo wp_kses_post($page_links); ?>
plugin->print_log_sortable_header(__('IP / Location', 'advanced-ip-blocker'), 'ip', $orderby, $order); ?>
plugin->print_log_sortable_header(__('User', 'advanced-ip-blocker'), 'user', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Details', 'advanced-ip-blocker'), 'detail', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Added Since', 'advanced-ip-blocker'), 'timestamp', $orderby, $order); ?>
' . esc_html(implode(', ', $location_parts)) . ' ';
}
?>
' . esc_html($matches[1]) . '';
echo '' . esc_html($matches[2]) . ' ';
}
?>
0 ? esc_html(ADVAIPBL_Main::get_formatted_datetime($item['timestamp'])) : '...'; ?>
display_log_table_generic($security_log_types, ['critical', 'warning']);
}
/**
* Muestra la pestaña de logs generales (auditoría), restaurada a su formato original.
*/
public function display_general_log_tab() {
if (empty($this->plugin->options['enable_logging'])) {
echo '' . esc_html__('General event logging is disabled in the "Settings" tab.', 'advanced-ip-blocker') . '
';
return;
}
// phpcs:disable WordPress.Security.NonceVerification.Recommended
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$search_term = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
$orderby = isset($_GET['orderby']) && in_array($_GET['orderby'], ['timestamp', 'level', 'ip', 'message'], true) ? sanitize_key($_GET['orderby']) : 'timestamp';
$order = isset($_GET['order']) && in_array(strtolower($_GET['order']), ['asc', 'desc'], true) ? strtolower(sanitize_key($_GET['order'])) : 'desc';
$current_page = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
$per_page = isset($_GET['advaipbl_per_page']) ? absint($_GET['advaipbl_per_page']) : 25;
// phpcs:enable
// phpcs:enable
global $wpdb;
$table_name = $wpdb->prefix . 'advaipbl_logs';
$where_clauses = [$wpdb->prepare("log_type = %s", 'general')];
if (!empty($search_term)) {
$search_like = '%' . $wpdb->esc_like($search_term) . '%';
$where_clauses[] = $wpdb->prepare("(ip LIKE %s OR message LIKE %s)", $search_like, $search_like);
}
$where_sql = implode(' AND ', $where_clauses);
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$total_items = $wpdb->get_var("SELECT COUNT(log_id) FROM $table_name WHERE $where_sql");
$total_pages = ceil($total_items / $per_page);
$offset = ($current_page - 1) * $per_page;
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$logs = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE $where_sql ORDER BY " . esc_sql($orderby) . " " . esc_sql($order) . " LIMIT %d OFFSET %d", $per_page, $offset), ARRAY_A);
?>
plugin->print_log_sortable_header(__('Date/Time', 'advanced-ip-blocker'), 'timestamp', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Level', 'advanced-ip-blocker'), 'level', $orderby, $order); ?>
plugin->print_log_sortable_header(__('IP', 'advanced-ip-blocker'), 'ip', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Message', 'advanced-ip-blocker'), 'message', $orderby, $order); ?>
prefix . 'advaipbl_ip_scores';
$is_enabled = !empty($this->plugin->options['enable_threat_scoring']);
$settings_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings#section-ip_trust');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: 1: Status tag (Active/Inactive), 2: Link to settings page. */
__('The Threat Scoring System is currently %1$s. You can change this in the Settings .', 'advanced-ip-blocker'),
[ 'span' => ['class' => true], 'a' => ['href' => []] ]
),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$status_tag,
esc_url($settings_url)
);
?>
0"];
if (!empty($search_term)) {
$where_clauses[] = $wpdb->prepare("ip LIKE %s", '%' . $wpdb->esc_like($search_term) . '%');
}
$where_sql = implode(' AND ', $where_clauses);
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$total_items = $wpdb->get_var("SELECT COUNT(id) FROM {$table_name} WHERE {$where_sql}");
$total_pages = ceil($total_items / $per_page);
$offset = ($current_page - 1) * $per_page;
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$items = $wpdb->get_results($wpdb->prepare(
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT * FROM {$table_name} WHERE {$where_sql} ORDER BY " . esc_sql($orderby) . " " . esc_sql($order) . " LIMIT %d OFFSET %d",
$per_page, $offset
), ARRAY_A);
$ips_on_page = wp_list_pluck($items, 'ip');
$locations = $this->plugin->session_manager->get_cached_locations($ips_on_page);
$threshold = (int) ($this->plugin->options['threat_score_threshold'] ?? 100);
?>
plugin->print_log_sortable_header(__('IP / Location', 'advanced-ip-blocker'), 'ip', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Current Score', 'advanced-ip-blocker'), 'score', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Last Activity', 'advanced-ip-blocker'), 'last_event_timestamp', $orderby, $order); ?>
' . esc_html(trim("$city, $country", ', ')) . ' ';
} ?>
0 ? min(100, ($item['score'] / $threshold) * 100) : 100;
$progress_color = $score_percentage > 80 ? '#dc3232' : ($score_percentage > 50 ? '#f59e0b' : '#0073aa');
?>
' . esc_html(ucfirst(str_replace('_', ' ', $last_event['event']))) . '';
echo ' (+ ' . esc_html($last_event['points']) . ' ' . esc_html__('points', 'advanced-ip-blocker') . ')';
}
?>
__('General System Event Log', 'advanced-ip-blocker'), 'wp_cron' => __('WP-Cron Execution Log', 'advanced-ip-blocker'), ];
$title = $titles[$log_types] ?? ucfirst($log_types) . ' Log';
$current_sub_tab = ($log_types === 'general') ? 'general_log' : $log_types . '_logs';
}
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$search_term = isset($_GET['s']) ? sanitize_text_field(wp_unslash($_GET['s'])) : '';
$orderby = isset($_GET['orderby']) && in_array($_GET['orderby'], ['timestamp', 'ip', 'log_type', 'message'], true) ? sanitize_key($_GET['orderby']) : 'timestamp';
$order = isset($_GET['order']) && in_array(strtolower($_GET['order']), ['asc', 'desc'], true) ? strtolower(sanitize_key($_GET['order'])) : 'desc';
$current_page = isset($_GET['paged']) ? absint($_GET['paged']) : 1;
$per_page = isset($_GET['advaipbl_per_page']) ? absint($_GET['advaipbl_per_page']) : 20;
$hide_community = isset($_GET['hide_community']) && $_GET['hide_community'] === '1';
// phpcs:enable
global $wpdb;
$table_name = $wpdb->prefix . 'advaipbl_logs';
$where_clauses = [];
$level_placeholders = implode(', ', array_fill(0, count($levels_to_show), '%s'));
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
$where_clauses[] = $wpdb->prepare("level IN ({$level_placeholders})", ...$levels_to_show);
if ($is_unified_log) {
$types_to_query = ($current_filter !== 'all' && in_array($current_filter, $log_types)) ? [$current_filter] : $log_types;
if (!empty($types_to_query)) {
$placeholders = implode(', ', array_fill(0, count($types_to_query), '%s'));
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
$where_clauses[] = $wpdb->prepare("log_type IN ({$placeholders})", ...$types_to_query);
}
} else {
$where_clauses[] = $wpdb->prepare("log_type = %s", $log_types);
}
if (!empty($search_term)) {
$search_like = '%' . $wpdb->esc_like($search_term) . '%';
$where_clauses[] = $wpdb->prepare("(ip LIKE %s OR details LIKE %s OR message LIKE %s)", $search_like, $search_like, $search_like);
}
if ($is_unified_log && $hide_community && $current_filter !== 'aib_network') {
$where_clauses[] = "log_type != 'aib_network'";
}
$where_sql = implode(' AND ', $where_clauses);
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$total_items = $wpdb->get_var("SELECT COUNT(log_id) FROM $table_name WHERE $where_sql");
$total_pages = ceil($total_items / $per_page);
$offset = ($current_page - 1) * $per_page;
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$logs = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE $where_sql ORDER BY " . esc_sql($orderby) . " " . esc_sql($order) . " LIMIT %d OFFSET %d", $per_page, $offset), ARRAY_A);
?>
plugin->print_log_sortable_header(__('Date/Time', 'advanced-ip-blocker'), 'timestamp', $orderby, $order); ?>
plugin->print_log_sortable_header(__('IP', 'advanced-ip-blocker'), 'ip', $orderby, $order); ?>
plugin->print_log_sortable_header(__('Type', 'advanced-ip-blocker'), 'log_type', $orderby, $order); ?>
plugin->options['duration_' . $log_type])) {
$duration_minutes = (int) $this->plugin->options['duration_' . $log_type];
}
$duration_text = '';
if ($duration_minutes <= 0) {
$duration_text = __('Permanent', 'advanced-ip-blocker');
} else {
/* translators: %d: The number of minutes for a block duration. */
$duration_text = sprintf(esc_html__('%d min', 'advanced-ip-blocker'), $duration_minutes);
}
echo '' . esc_html__('Blocked:', 'advanced-ip-blocker') . ' ' . esc_html($duration_text);
}
?>
' . implode(', ', $location_parts) . ' ';
}
?>
plugin->get_all_block_type_definitions()[$log_type]['label'] ?? ucwords(str_replace('_', ' ', $log_type))); ?>
' . esc_html__('User:', 'advanced-ip-blocker') . ' ' . esc_html($details['username'] ?? 'N/A');
break;
case 'waf':
$detail_display = '' . esc_html__('Rule:', 'advanced-ip-blocker') . ' ' . esc_html($details['rule'] ?? 'N/A');
if (!empty($uri)) { $detail_display .= '' . $uri . ' '; }
break;
case 'asn':
$detail_display = esc_html($details['asn_number'] ?? 'N/A') . ' (' . esc_html($details['asn_name'] ?? '') . ')';
if (!empty($details['source'])) { $detail_display .= ' - ' . __('Source:', 'advanced-ip-blocker') . ' ' . esc_html($details['source']); }
if (!empty($uri)) { $detail_display .= '' . $uri . ' '; }
break;
case 'threat_score':
$detail_display = esc_html($entry['message']);
if (!empty($uri)) { $detail_display .= '' . $uri . ' '; }
break;
case 'advanced_rule':
$level = $entry['level'];
$rule_name_html = '' . esc_html__('Rule:', 'advanced-ip-blocker') . ' ' . esc_html($details['rule_name'] ?? 'N/A');
if ($level === 'critical') { // Block
$detail_display = $rule_name_html;
} elseif ($level === 'warning') { // Challenge
$detail_display = $rule_name_html;
} else { // Score (info)
$points = $details['points_added'] ?? 0;
$detail_display = $rule_name_html . ' (+ ' . esc_html($points) . ' ' . esc_html__('points', 'advanced-ip-blocker') . ')';
}
if (!empty($uri)) {
$detail_display .= '' . $uri . ' ';
}
break;
case 'geo_challenge':
$country_name = esc_html($details['country'] ?? 'N/A');
$detail_display = '' . esc_html__('Country:', 'advanced-ip-blocker') . ' ' . $country_name;
if (!empty($uri)) {
$detail_display .= '' . $uri . ' ';
}
break;
case 'signature_challenge':
$detail_display = esc_html($entry['message']);
if (!empty($uri)) { $detail_display .= '' . $uri . ' '; }
break;
case 'signature_flagged':
$hash = $details['signature_hash'] ?? 'N/A';
$short_hash = substr($hash, 0, 12) . '...';
$detail_display = '' . esc_html__('Signature:', 'advanced-ip-blocker') . ' ' . esc_html($short_hash) . '';
$detail_display .= '' . esc_html($entry['message']) . ' ';
break;
case 'endpoint_challenge':
$reason = $details['reason'] ?? $entry['message'];
$detail_display = '' . esc_html($reason) . ' ';
if (!empty($uri)) {
$detail_display .= '' . $uri . ' ';
}
break;
case 'login_geoblock':
$detail_display = '' . esc_html($entry['message']) . ' ';
if (!empty($uri)) {
$detail_display .= '' . $uri . ' ';
}
break;
case '404':
case '403':
case 'honeypot':
default:
$detail_display = !empty($uri) ? $uri : esc_html($entry['message']);
break;
}
echo wp_kses_post($detail_display);
?>
Stripe
bc1qxfsmpqk0q7an82ckm7380pzpsea2sa294824lg
0xAF8CC1B71EAbF5dffDa2aF58AEF43b2559163284
# General Help
wp help advaipbl
# IP Management
wp advaipbl block <ip> [--reason=<reason>]
wp advaipbl unblock <ip>
wp advaipbl whitelist <add|remove|list> [<ip>]
# Threat Scoring & Signatures
wp advaipbl score <list|get|reset|decay-run> [--ip=<ip>]
wp advaipbl signature <list|delete|whitelist> [--hash=<hash>]
wp advaipbl signature-analyze
# Geolocation, ASN & WAF
wp advaipbl geoblock <add|remove|list> <country_code>
wp advaipbl asn <add|remove|list> <asn>
wp advaipbl asn-whitelist <add|remove|list> <asn>
wp advaipbl waf <add|remove|list> [<rule>] [--from-file=<file>]
# User & Session Management
wp advaipbl session <list|terminate> [--user-id=<id>]
wp advaipbl 2fa <status|reset> <user>
# System & Config
wp advaipbl log <list|clear> [--type=<type>] [--count=<number>]
wp advaipbl config <get|set> [<key>] [<value>]
wp advaipbl provider <list|set|set_key|remove_key>
wp advaipbl spamhaus-update
plugin->get_ip_intelligence();
$server_ip = $this->plugin->get_server_ip();
$client_ip = $ip_data['visitor_ip'] ?? 'N/A';
?>
plugin->get_remote_addr();
$client_ip = $this->plugin->get_client_ip();
if ( $remote_addr && $client_ip !== $remote_addr && filter_var( $remote_addr, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) {
echo '
';
/* translators: %1$s: Client's real IP. %2$s: Proxy/CDN IP. */
echo '' . esc_html__( 'Info:', 'advanced-ip-blocker' ) . ' ' . sprintf( esc_html__( 'It seems your site is behind a reverse proxy or CDN. Your IP is correctly detected as %1$s, while your server connects through %2$s. This is a normal and correct configuration.', 'advanced-ip-blocker' ), '' . esc_html( $client_ip ) . '', '' . esc_html( $remote_addr ) . '' );
echo '
';
$has_recommendations = true;
}
// Comprobación de la IP del servidor
if ( ! $this->plugin->get_server_ip() ) {
echo '
';
echo '' . esc_html__( 'Warning:', 'advanced-ip-blocker' ) . ' ' . esc_html__( 'The plugin could not automatically determine your server\'s public IP. The feature that adds the server IP to the whitelist on activation will not work. Please add your server IP to the whitelist manually to prevent any issues with geoblocking or other functionalities.', 'advanced-ip-blocker' );
echo '
';
$has_recommendations = true;
}
$xmlrpc_plugins = $this->plugin->get_xmlrpc_dependent_plugins();
if ( ! empty( $xmlrpc_plugins ) ) :
?>
';
echo '' . esc_html__( 'All Clear!', 'advanced-ip-blocker' ) . ' ' . esc_html__( 'No potential configuration issues were detected.', 'advanced-ip-blocker' );
echo '
';
}
?>
plugin->get_client_ip();
$server_ip = $this->plugin->get_server_ip();
$is_cloudflare = isset($_SERVER['HTTP_CF_CONNECTING_IP']);
?>
plugin->options['enable_threat_scoring']);
$is_geolocation_ready = !empty($this->plugin->options['geolocation_provider']);
$settings_base_url = admin_url('admin.php?page=advaipbl_settings_page-settings&sub-tab=general_settings');
$status_parts = [];
$status_parts[] = sprintf(
'%1$s: %3$s (%5$s )',
esc_html__('Threat Scoring', 'advanced-ip-blocker'),
$is_threat_scoring_enabled ? 'enabled' : 'disabled',
$is_threat_scoring_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker'),
esc_url($settings_base_url . '#section-ip_trust'),
esc_html__('configure', 'advanced-ip-blocker')
);
$status_parts[] = sprintf(
'%1$s: %3$s (%5$s )',
esc_html__('Geolocation', 'advanced-ip-blocker'),
$is_geolocation_ready ? 'enabled' : 'disabled',
$is_geolocation_ready ? esc_html__('Ready', 'advanced-ip-blocker') : esc_html__('Not Configured', 'advanced-ip-blocker'),
esc_url($settings_base_url . '#section-geolocation'),
esc_html__('configure', 'advanced-ip-blocker')
);
?>
', $status_parts), [
'strong' => [],
'span' => ['class' => true],
'a' => ['href' => []],
'br' => []
]);
?>
plugin->site_scanner->run_local_scan();
$get_icon = function($status) {
switch($status) {
case 'good': return ' ';
case 'warning': return ' ';
case 'critical': return ' ';
default: return ' ';
}
};
?>
' . esc_html__('You do not have permission to view this log.', 'advanced-ip-blocker') . '';
return;
}
$is_enabled = !empty($this->plugin->options['enable_audit_log']) && '1' === $this->plugin->options['enable_audit_log'];
$settings_url = admin_url('admin.php?page=advaipbl_settings_page&tab=settings&sub-tab=general_settings#section-internal_security');
?>
%s',
$is_enabled ? 'enabled' : 'disabled',
$is_enabled ? esc_html__('Active', 'advanced-ip-blocker') : esc_html__('Inactive', 'advanced-ip-blocker')
);
printf(
wp_kses(
/* translators: 1: Status tag (Active/Inactive), 2: Link to settings page. */
__('Activity Logging is currently %1$s. You can configure this feature in the Settings tab .', 'advanced-ip-blocker'),
['a' => ['href' => []], 'span' => ['class' => []]]
),
wp_kses_post($status_tag),
esc_url($settings_url)
);
?>
prefix . 'advaipbl_activity_log';
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
$logs = [];
$total_items = 0;
$total_pages = 0;
} else {
// Fetch logs
$logs = $this->plugin->audit_logger->get_logs($per_page, $offset);
// Count total for pagination (Simple implementation)
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter
$total_items = $wpdb->get_var("SELECT COUNT(id) FROM $table_name");
$total_pages = ceil($total_items / $per_page);
}
?>
add_query_arg('paged', '%#%'),
'format' => '',
'total' => $total_pages,
'current' => $current_page
]);
if ($page_links) echo wp_kses_post($page_links);
?>
user_login : __('System/Guest', 'advanced-ip-blocker');
$details = json_decode($log['details'], true);
$formatted_details = $details ? '' . esc_html(json_encode($details, JSON_PRETTY_PRINT)) . ' ' : '';
?>
(ID: )