Phase 3 v1: autocheck framework + six step automations

Infrastructure:
- WPH_Step::autocheck($session_state) returns an array of findings
  shaped {id, level: ok/warn/bad/info, label, value, detail}.
- WPH_Session stores results keyed by step id (persisted in the option-
  backed session).
- WPH_Step::has_autocheck() reflection check so the UI only renders the
  panel for steps that implement automation.
- 'Run checks' / 'Refresh' button per step, admin-post handler runs
  autocheck() and stashes the result on the session.
- Findings rendered as a coloured table on the step card; included
  verbatim in the Markdown report with status icons.

Step automations implemented:
- Step 1 (Backup): detection of 11 known backup plugins by slug;
  active/inactive state; UpdraftPlus last-backup timestamp.
- Step 2 (Environment): PHP version + EOL, WP version vs latest, disk
  usage, wp-config flags, file perms on wp-config/wp-content/uploads,
  error-log sizes.
- Step 4 (Plugins): WP.org API enrichment with 24h transient cache —
  last_updated, active_installs, abandonment flag, removed-from-repo
  flag, update-available count. Summary line at the top.
- Step 8 (Security): SSL cert expiry via stream_socket_client +
  openssl_x509_parse, administrator audit, xmlrpc reachability, login
  URL hardening detection.
- Step 9 (Database): spam comments, post revisions, autoload size (WP
  6.6+ value handling), top 3 largest tables.
- Step 11 (Small fixes): deactivated-but-installed plugin list,
  homepage alt-text scan.

Smoke-tested on testsite — all six steps return findings with
correctly-classified levels. Report regenerated with automated findings
section.
This commit is contained in:
2026-06-11 16:02:34 +01:00
parent 8de7cad0de
commit 0d51fc3b59
11 changed files with 646 additions and 9 deletions

View File

@@ -66,6 +66,20 @@ function wph_build_markdown_report(WPH_Session $session): string {
$lines[] = '> ' . $nl;
}
}
$auto = $session->get_autocheck($step->id());
if ($auto && !empty($auto['findings'])) {
$lines[] = '';
$lines[] = '**Automated checks** (run ' . date('Y-m-d H:i', (int) ($auto['checked_at'] ?? 0)) . '):';
$lines[] = '';
foreach ($auto['findings'] as $finding) {
$icon = ['ok' => '✅', 'warn' => '⚠️', 'bad' => '❌', 'info' => ''][$finding['level']] ?? '·';
$bits = [$icon, '**' . $finding['label'] . '**'];
if (!empty($finding['value'])) $bits[] = $finding['value'];
if (!empty($finding['detail'])) $bits[] = '— ' . $finding['detail'];
$lines[] = '- ' . implode(' ', $bits);
}
}
if ($state['status'] === WPH_Session::STATUS_BLOCKED && ($esc = $step->escalation())) {
$lines[] = '';
$lines[] = '> ⚠ **Escalation:** ' . $esc;