✓ ' . sprintf( esc_html__( 'IP %s unblocked.', 'guardforge' ), '' . esc_html( $guardforge_ip ) . '' ) . '';
}
$guardforge_prefix = '_transient_' . GUARDFORGE_Bruteforce::ATTEMPTS_TRANSIENT_PREFIX;
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- lists this plugin's own lockout transients by their full-slug prefix; WordPress has no API that enumerates transients, and the pattern goes through prepare and esc_like.
$guardforge_locked = $wpdb->get_results( $wpdb->prepare(
"SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE %s",
$wpdb->esc_like( $guardforge_prefix ) . '%'
) );
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
$guardforge_log_table = $wpdb->prefix . 'guardforge_login_log';
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $guardforge_log_table is a prefixed table name, not user input.
// One row per IP, so locks in the same second tie on last_time, and LIMIT cuts
// the tie wherever the engine puts it. The IP is the group's own column.
$guardforge_recent = $wpdb->get_results(
"SELECT ip, COUNT(*) as cnt, MAX(event_time) as last_time
FROM {$guardforge_log_table}
WHERE result = 'locked'
GROUP BY ip
ORDER BY last_time DESC, ip ASC
LIMIT 20"
);
// phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
?>
| | |
option_name );
?>
|
option_value; ?> |
|
| | | |
| ip ); ?> |
cnt ); ?> |
last_time ); ?> |
|