Files
wp-healthcheck/includes/steps/10-backup.php
Steve Hanlon 6dd050ea1d Rename to ATT Site Healthcheck (private prefix)
Wholesale rename to avoid clashes with generic 'site healthcheck'
plugin names on a target site:

  - Plugin Name:        'Site Healthcheck' → 'ATT Site Healthcheck'
  - Main file:          site-healthcheck.php → att-site-healthcheck.php
  - Plugin folder:      site-healthcheck → att-site-healthcheck
  - Admin menu slug:    site-healthcheck → att-site-healthcheck
  - Settings slug:      site-healthcheck-settings → att-site-healthcheck-settings
  - PHP class prefix:   WPH_ → ATT_HC_
  - Function prefix:    wph_ → att_hc_
  - Option / transient: wph_* → att_hc_*
  - Action/filter:      wph_* → att_hc_*
  - CSS class prefix:   wph- → att-hc-
  - Constants:          WPH_GITEA_* → ATT_HC_GITEA_*
  - Class file names:   class-wph-*.php → class-att-hc-*.php
  - Dev folder:         ~/dev/wp-healthcheck → ~/dev/att-site-healthcheck

Existing in-progress sessions on installs that had the old wph_session
option will not migrate — they were intended for dev use only and the
user has confirmed this is OK for the rename window.

Smoke-tested on testsite: classes load, 14 steps discovered, save/load
round-trip works, admin page renders with new att-hc- CSS classes.

Recovery plugin detection unchanged — that lives in wp-site-recovery
and continues to be detected by Name + Author header.
2026-06-12 11:11:42 +01:00

98 lines
4.2 KiB
PHP

<?php
if (!defined('ABSPATH')) exit;
return new class extends ATT_HC_Step {
public function id(): string { return 'backup'; }
public function title(): string { return 'Step 1 — Take a Full Backup'; }
public function blurb(): string {
return 'Before any work takes place, take a complete backup manually. Do not rely on the most recent automated backup.';
}
public function sub_items(): array {
return [
'Back up both the database and all files (wp-content, wp-config.php, .htaccess)',
'Confirm the backup has completed and is accessible/downloadable',
'Note the backup location and timestamp in the client record',
];
}
public function escalation(): ?string {
return 'If the backup fails or cannot be confirmed, stop. Do not proceed until you have a verified backup.';
}
public function autocheck(array $session_state): array {
if (!function_exists('get_plugins')) require_once ABSPATH . 'wp-admin/includes/plugin.php';
$plugins = get_plugins();
// Map known backup plugins: slug → friendly label.
$known = [
'updraftplus/updraftplus.php' => 'UpdraftPlus',
'backwpup/backwpup.php' => 'BackWPup',
'backup-backup/backup-backup.php' => 'Backup Migration',
'duplicator/duplicator.php' => 'Duplicator',
'wpvivid-backuprestore/wpvivid-backuprestore.php' => 'WPvivid',
'all-in-one-wp-migration/all-in-one-wp-migration.php' => 'All-in-One WP Migration',
'blogvault-real-time-backup/blogvault.php' => 'BlogVault',
'jetpack/jetpack.php' => 'Jetpack (VaultPress)',
'solid-backups/backupbuddy.php' => 'Solid Backups',
'backupbuddy/backupbuddy.php' => 'BackupBuddy',
'wp-time-capsule/wp-time-capsule.php' => 'WP Time Capsule',
];
$found = [];
foreach ($known as $file => $label) {
if (isset($plugins[$file])) {
$found[$file] = [
'label' => $label,
'active' => is_plugin_active($file),
];
}
}
$f = [];
if (empty($found)) {
$f[] = $this->finding(
'no_backup_plugin', 'bad',
'No recognised backup plugin installed', '',
'None of the common backup plugins were detected. Confirm host-side backups instead, or install one.'
);
return $f;
}
$any_active = false;
foreach ($found as $file => $meta) {
if ($meta['active']) $any_active = true;
$f[] = $this->finding(
'plugin_' . sanitize_key($file),
$meta['active'] ? 'ok' : 'warn',
$meta['label'],
$meta['active'] ? 'active' : 'installed but inactive',
''
);
}
if (!$any_active) {
$f[] = $this->finding(
'no_active', 'bad',
'No backup plugin is active', '',
'A backup plugin is installed but not active — activate before proceeding.'
);
}
// UpdraftPlus — surface last backup timestamp if available.
if (isset($found['updraftplus/updraftplus.php'])) {
$last = get_option('updraft_last_backup');
if (is_array($last) && !empty($last['backup_time'])) {
$age_days = floor((time() - (int) $last['backup_time']) / DAY_IN_SECONDS);
$level = $age_days > 7 ? 'warn' : 'ok';
$f[] = $this->finding(
'updraft_last',
$level,
'UpdraftPlus — last backup',
date('Y-m-d H:i', (int) $last['backup_time']),
$age_days . ' day(s) ago' . (!empty($last['backup_nonce']) ? '. Nonce ' . substr((string) $last['backup_nonce'], 0, 8) : '')
);
}
}
return $f;
}
};