Demonstrates the drop-in pattern: adding a step with a form is a single new file under includes/steps/, plus one small extension to the base abstraction. WPH_Step gains: - render_extra($session_state) — emit extra HTML inside the step card - handle_action($name, $input) — handle a step-specific POST and return a finding to record New generic admin-post handler wph_step_action routes form submissions to the matching step's handle_action() with nonce verification. The email step (includes/steps/115-email.php): - Detects 7 known SMTP plugins, surfaces default From address - Renders a To: input prefilled with the current admin's email - Sends via wp_mail() with wp_mail_failed capture so failures show the underlying error - Records the outcome as a 'last_send' finding so it appears on the step card, in the summary, and in the downloadable report
76 lines
3.1 KiB
PHP
76 lines
3.1 KiB
PHP
<?php
|
|
if (!defined('ABSPATH')) exit;
|
|
|
|
/**
|
|
* Base class for a healthcheck step.
|
|
*
|
|
* Each step lives in its own file under includes/steps/ with a numeric prefix
|
|
* (e.g. 10-backup.php). The file returns an instance of a subclass of WPH_Step.
|
|
* Drop a new file in that directory and it shows up; delete a file and it
|
|
* disappears. The numeric prefix controls order so re-ordering is a rename.
|
|
*
|
|
* Stable string IDs (returned by id()) are stored in the session, so renaming
|
|
* the file does NOT lose data as long as id() stays the same.
|
|
*/
|
|
abstract class WPH_Step {
|
|
|
|
/** Stable identifier (lowercase slug). NEVER change once shipped. */
|
|
abstract public function id(): string;
|
|
|
|
/** Human-readable title shown in the UI and report. */
|
|
abstract public function title(): string;
|
|
|
|
/** Intro paragraph shown under the title (plain text or simple inline HTML). */
|
|
public function blurb(): string { return ''; }
|
|
|
|
/** Sub-items the technician should tick through (plain strings). */
|
|
public function sub_items(): array { return []; }
|
|
|
|
/** "Watch out for" callouts (plain strings). */
|
|
public function watch_outs(): array { return []; }
|
|
|
|
/**
|
|
* If this step has a stop/escalate condition (e.g. backup failed → stop),
|
|
* return the guidance string. Rendered as a banner when status=blocked.
|
|
*/
|
|
public function escalation(): ?string { return null; }
|
|
|
|
/**
|
|
* Phase 3 hook — return an array of findings for the technician to verify.
|
|
* Each finding: ['id'=>str, 'level'=>'ok'|'warn'|'bad'|'info', 'label'=>str, 'value'=>str, 'detail'=>str].
|
|
* Override in subclasses. Default returns nothing.
|
|
*
|
|
* @return array<int,array<string,string>>
|
|
*/
|
|
public function autocheck(array $session_state): array { return []; }
|
|
|
|
/** Convenience finding builder for subclasses. */
|
|
protected function finding(string $id, string $level, string $label, string $value = '', string $detail = ''): array {
|
|
if (!in_array($level, ['ok', 'warn', 'bad', 'info'], true)) $level = 'info';
|
|
return compact('id', 'level', 'label', 'value', 'detail');
|
|
}
|
|
|
|
/** Returns true if any of this step's automation is implemented. Override or rely on autocheck() returning [] by default. */
|
|
public function has_autocheck(): bool {
|
|
$r = new ReflectionMethod($this, 'autocheck');
|
|
return $r->getDeclaringClass()->getName() !== WPH_Step::class;
|
|
}
|
|
|
|
/**
|
|
* Optional: render extra UI inside this step's card (forms, inputs, etc.).
|
|
* Default: nothing. Override when the step needs interactive controls
|
|
* beyond the standard status + notes pattern.
|
|
*/
|
|
public function render_extra(array $session_state): void {}
|
|
|
|
/**
|
|
* Optional: handle a step-specific POST (submitted from a form rendered by
|
|
* render_extra). Return a finding to append to the autocheck list, or null
|
|
* to do nothing.
|
|
*
|
|
* @param string $action_name name from the form's step_action field
|
|
* @param array<string,mixed>$input $_POST contents (sanitised by caller)
|
|
*/
|
|
public function handle_action(string $action_name, array $input): ?array { return null; }
|
|
}
|