to admin-post.php, * nonced, one case_id and (where relevant) one more field. None of them uses * a native JS confirm or alert dialog — the scope and consequence of the * action is printed as plain text in the form itself (a
* right above the button), so the operator reads it before the click reaches * the server, not in a dialog JavaScript could skip. Only the decisions * GUARDFORGE_Case_Model::can_transition actually allows from a case's * current status are rendered — an operator is never shown a button the * handler would refuse. */ if ( ! defined( 'ABSPATH' ) ) { exit; } $guardforge_cases_repo = GUARDFORGE_Cases::instance(); $guardforge_status = isset( $_GET['status'] ) ? sanitize_key( wp_unslash( $_GET['status'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only: this screen's own filter or pager; it narrows what is listed and changes nothing. $guardforge_type = isset( $_GET['type'] ) ? sanitize_key( wp_unslash( $_GET['type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only: this screen's own filter or pager; it narrows what is listed and changes nothing. $guardforge_filters = array_filter( [ 'status' => $guardforge_status, 'type' => $guardforge_type ] ); // §6.4 review round 1, m2: an unbounded SELECT * here degrades linearly as // cases accumulate. limit/offset are opt-in on GUARDFORGE_Cases::list_cases // precisely so this screen can bound itself without touching // recheck_open_cases's own unfiltered sweep of every open case. $guardforge_per_page = 50; $guardforge_paged = max( 1, ( isset( $_GET['gf_paged'] ) ? absint( wp_unslash( $_GET['gf_paged'] ) ) : 1 ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only: this screen's own filter or pager; it narrows what is listed and changes nothing. $guardforge_total = $guardforge_cases_repo->count_cases( $guardforge_filters ); $guardforge_pages = max( 1, (int) ceil( $guardforge_total / $guardforge_per_page ) ); $guardforge_cases = $guardforge_cases_repo->list_cases( array_merge( $guardforge_filters, [ 'limit' => $guardforge_per_page, 'offset' => ( $guardforge_paged - 1 ) * $guardforge_per_page, ] ) ); $guardforge_type_labels = [ 'file_change' => __( 'File change', 'guardforge' ), 'vuln_match' => __( 'Vulnerability', 'guardforge' ), 'login_series' => __( 'Login series', 'guardforge' ), ]; $guardforge_status_labels = [ 'open' => __( 'Open', 'guardforge' ), 'acknowledged' => __( 'Acknowledged', 'guardforge' ), 'assigned' => __( 'Assigned', 'guardforge' ), 'needs_verification' => __( 'Needs verification', 'guardforge' ), 'mitigated' => __( 'Mitigated', 'guardforge' ), 'fix_applied' => __( 'Fix applied', 'guardforge' ), 'explained' => __( 'Explained', 'guardforge' ), 'unverified' => __( 'Unverified', 'guardforge' ), 'fixed' => __( 'Fixed', 'guardforge' ), ]; $guardforge_post_url = admin_url( 'admin-post.php' ); $guardforge_case_error = isset( $_GET['gf_case_error'] ) ? sanitize_key( wp_unslash( $_GET['gf_case_error'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only: a result our own redirect carries back from a nonce-checked action; it is only printed, escaped. $guardforge_case_status = isset( $_GET['gf_case_status'] ) ? sanitize_key( wp_unslash( $_GET['gf_case_status'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only: a result our own redirect carries back from a nonce-checked action; it is only printed, escaped. $guardforge_error_labels = [ 'not_found' => __( 'That case could not be found.', 'guardforge' ), 'transition_not_allowed' => __( "That case is not in a state that accepts this decision — someone may have already acted on it.", 'guardforge' ), 'assign_no_user' => __( 'Enter a WordPress user ID to assign this case to.', 'guardforge' ), 'reason_required' => __( 'A reason is required to record an expected change.', 'guardforge' ), 'wrong_case_type' => __( 'That decision only applies to file-change cases.', 'guardforge' ), 'remedy_unavailable' => __( 'That remedy does not apply to this case type.', 'guardforge' ), 'pro_not_installed' => __( 'That action needs GuardForge Pro, which is not installed on this site.', 'guardforge' ), 'no_evidence' => __( 'This case has no evidence of the kind that action needs.', 'guardforge' ), 'patch_failed' => __( 'The update could not be applied — see the Vulnerabilities screen\'s action log for the error.', 'guardforge' ), 'bf_protection_disabled' => __( 'Brute-force protection is switched off for this site — turn it on under Settings before blocking an IP from here.', 'guardforge' ), 'ip_whitelisted' => __( 'This IP is on the brute-force whitelist, so GuardForge will not block it.', 'guardforge' ), 'staging_mode' => __( 'This site is in staging mode, so IP blocks are not applied here.', 'guardforge' ), ]; ?>
|