list( 'scan', null, 1 )[0] ?? null; $scanStatus = $scan['_status'] ?? 'not_started'; $scanComplete = 'completed' === $scanStatus && 'scan_incomplete' !== ( $scan['result_state'] ?? '' ); $open = $store->count( 'finding', 'open' ); $items = array(); if ( $open > 0 ) { $items[] = array( 'title' => 'Review open findings', 'state' => 'Action needed', 'copy' => sprintf( '%d open findings need a decision. Review their severity, evidence and coverage before approving any change.', $open ), 'url' => Admin::url( 'findings' ), 'action' => 'Review findings', 'priority' => 100 ); } $items[] = array( 'title' => 'Establish scan coverage', 'state' => $scanComplete ? 'Completed checks recorded' : ( in_array( $scanStatus, array( 'queued', 'running' ), true ) ? 'In progress' : 'Action needed' ), 'copy' => $scanComplete ? 'Review the completed scan’s scope and unassessed items. A completed scan does not establish that every part of the site is clean.' : ( $scan ? 'The latest attempt has not completed all checks. Continue its work or review the reason before starting a new scan.' : 'Start your first local scan. Until it runs, this site has not been assessed.' ), 'url' => Admin::url( 'overview' ) . '#avai-scan-details', 'action' => 'Review scan', 'priority' => $scanComplete ? 10 : 90 ); $rules = RuleBundle::summary(); $connection = RuleUpdates::status(); $items[] = array( 'title' => 'Keep detection sources current', 'state' => 'current' === $connection['status'] ? 'Last download verified' : ( ! $connection['configured'] ? 'Local checks only' : str_replace( '_', ' ', $connection['status'] ) ), 'copy' => ! $connection['configured'] ? 'Bundled structural checks update with the plugin. No maintained external malware publisher is configured; review this coverage limit.' : 'Review publisher authorization, last verified download and indicator expiry. A successful download alone does not establish detection quality. Indicator state: ' . str_replace( '_', ' ', $rules['status'] ) . '.', 'url' => Admin::url( 'protection' ) . '#avai-rule-connection', 'action' => 'Review intelligence', 'priority' => 'current' === $connection['status'] ? 10 : 60 ); $mode = Firewall::configuration()['mode']; $disabled = defined( 'ANTIVIRUS_AI_DISABLE_FIREWALL' ) && ANTIVIRUS_AI_DISABLE_FIREWALL; $items[] = array( 'title' => 'Configure request protection', 'state' => $disabled ? 'Host recovery switch active' : ucfirst( $mode ), 'copy' => $disabled ? 'The host has suspended application filtering. Review the cause before restoring it; early PHP filtering has its own host recovery control.' : ( 'block' === $mode ? 'Supported matching requests are blocked in the application layer. Review exceptions and optional earlier PHP coverage.' : 'Use observation mode to test login, forms and checkout, then deliberately enable blocking for the supported rules.' ), 'url' => Admin::url( 'protection' ) . '#avai-firewall', 'action' => 'Review firewall', 'priority' => $disabled || 'off' === $mode ? 70 : 20 ); $enrolled = AccountSecurity::enrolled( get_current_user_id() ); $accountRecovery = AccountPolicy::recovery(); $items[] = array( 'title' => 'Protect administrator access', 'state' => $accountRecovery ? 'Host recovery switch active' : ( $enrolled ? 'Your second factor is enrolled' : 'Action needed' ), 'copy' => $accountRecovery ? 'The host has suspended second-factor enforcement. Review the recovery reason and restore account protection when access is recovered.' : ( $enrolled ? 'Check recovery codes and other browser sessions. Review the administrator enrollment policy for the rest of your team.' : 'Add an authenticator or passkey second factor, save recovery codes, then review the administrator enrollment policy.' ), 'url' => AccountSecurity::pageUrl(), 'action' => 'Protect accounts', 'priority' => $accountRecovery ? 95 : ( $enrolled ? 20 : 80 ) ); $email = ! empty( $settings['email'] ); $items[] = array( 'title' => 'Check notifications and timing', 'state' => ! $email ? 'Email alerts off' : 'Email enabled; inbox delivery unverified', 'copy' => ! $email ? 'Choose an alert address and independent email permission in Settings. Check missed or stalled schedules in Help & diagnostics.' : 'Send a test from Protection and check your inbox. A past successful mail-service response does not establish delivery to the current address. Review the host scheduler for traffic-independent scans.', 'url' => Admin::url( 'protection' ) . '#avai-notification-check', 'action' => 'Check alerts', 'priority' => 50 ); usort( $items, static fn( $a, $b ) => $b['priority'] <=> $a['priority'] ); return $items; } public static function render( Store $store, ?array $scan = null ): void { echo '

' . esc_html__( 'Your next actions', 'shieldlume-security' ) . '

' . esc_html__( 'Reopen guided setup', 'shieldlume-security' ) . '

' . esc_html__( 'Based on saved settings and observed results. Opening this checklist does not start a scan, enable a connection or change protection.', 'shieldlume-security' ) . '

    '; foreach ( self::items( $store, $scan ) as $item ) { echo '
  1. ' . esc_html( $item['title'] ) . '

    ' . esc_html( $item['state'] ) . '

    ' . esc_html( $item['copy'] ) . '

    ' . esc_html( $item['action'] ) . '
  2. '; } echo '
'; } }