Detection (recovery-bootstrap.php): - Match on plugin Name + Author instead of hard-coded folder slug, so the recovery plugin is found regardless of whether it was unpacked as site-recovery/, wp-site-recovery/, or anything else. One-click install (recovery-installer.php — new): - Pulls site-recovery from a private Gitea repo via the standard archive endpoint with token auth. - Ref resolution order: latest release → latest tag → main branch HEAD. Lets us tag pinned releases in Gitea later without changing code. - upgrader_source_selection filter forces the unpacked folder name to 'site-recovery' regardless of the gitea wrapper-folder suffix. - Config from constants in wp-config.php (WPH_GITEA_HOST/OWNER/REPO/TOKEN) beats DB option storage. Constants are visually locked in the settings UI so admins can see they're inherited. Settings page (hidden submenu, reachable at Tools → Site Healthcheck → 'Configure gitea source'): - Host / Owner / Repo / Token fields - Inline 'Install now' button when configured + plugin not installed Bootstrap status panel: - Shows the recovery plugin's actual file path when active - 'Install from gitea (latest)' button when configured + missing - 'Configure gitea source' button when not configured + missing Install handler shows a success message via transient on the main healthcheck page after a successful install + activate.
93 lines
4.4 KiB
PHP
93 lines
4.4 KiB
PHP
<?php
|
|
if (!defined('ABSPATH')) exit;
|
|
|
|
/**
|
|
* Step-0 bootstrap: ensure wp-site-recovery is installed + active before the
|
|
* stepper runs (bead hc-5ix.1, references decision hc-5ix.26).
|
|
*
|
|
* Detection is by plugin folder slug, not by main-file path, because the slug
|
|
* is stable across releases. If we ever publish a private update channel for
|
|
* the recovery plugin, this is also where we'd offer "fetch latest".
|
|
*/
|
|
final class WPH_Recovery_Bootstrap {
|
|
|
|
/**
|
|
* Detect by plugin Name + Author rather than folder slug — the recovery
|
|
* plugin can be installed under any folder (site-recovery/, wp-site-recovery/,
|
|
* etc.) depending on how it was unpacked. Cache the result per request.
|
|
*/
|
|
private const NAME = 'Site Recovery';
|
|
private const AUTHOR = 'Steve Hanlon';
|
|
|
|
/** Return the plugin_basename (folder/file.php) if installed, or null. */
|
|
public static function plugin_file(): ?string {
|
|
static $cached;
|
|
if ($cached !== null) return $cached === '' ? null : $cached;
|
|
if (!function_exists('get_plugins')) {
|
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
|
}
|
|
foreach (get_plugins() as $file => $meta) {
|
|
if (($meta['Name'] ?? '') === self::NAME && strpos((string) ($meta['Author'] ?? ''), self::AUTHOR) !== false) {
|
|
return $cached = $file;
|
|
}
|
|
}
|
|
$cached = '';
|
|
return null;
|
|
}
|
|
|
|
public static function is_installed(): bool {
|
|
return self::plugin_file() !== null;
|
|
}
|
|
|
|
public static function is_active(): bool {
|
|
$file = self::plugin_file();
|
|
if (!$file) return false;
|
|
if (!function_exists('is_plugin_active')) {
|
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
|
}
|
|
return is_plugin_active($file);
|
|
}
|
|
|
|
public static function recovery_admin_url(): string {
|
|
return admin_url('tools.php?page=site-recovery');
|
|
}
|
|
|
|
/**
|
|
* Render a status panel that the admin page calls from the "Before you start"
|
|
* section. Shows install state, links to recovery settings when active, and
|
|
* offers a one-click install from gitea when missing+configured.
|
|
*/
|
|
public static function render_status(): void {
|
|
$installed = self::is_installed();
|
|
$active = $installed && self::is_active();
|
|
$file = self::plugin_file();
|
|
$configured = WPH_Recovery_Installer::is_configured();
|
|
?>
|
|
<div class="wph-bootstrap-panel">
|
|
<h3>Recovery plugin status</h3>
|
|
<?php if ($active): ?>
|
|
<p class="wph-ok">✓ <strong>Site Recovery</strong> is installed and active <code><?php echo esc_html((string) $file); ?></code>.
|
|
<a href="<?php echo esc_url(self::recovery_admin_url()); ?>">Open recovery settings</a> to copy the URL + password into the client record.</p>
|
|
<?php elseif ($installed): ?>
|
|
<p class="wph-warn">⚠ <strong>Site Recovery</strong> is installed but inactive <code><?php echo esc_html((string) $file); ?></code>. <a href="<?php echo esc_url(admin_url('plugins.php')); ?>">Activate it</a> before starting work.</p>
|
|
<?php else: ?>
|
|
<p class="wph-bad">✗ <strong>Site Recovery</strong> is not installed. Install it before starting the healthcheck — it's the safety net while we work on the site.</p>
|
|
<?php if ($configured): ?>
|
|
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" style="display:inline" onsubmit="return confirm('Download and install Site Recovery from gitea?');">
|
|
<?php wp_nonce_field('wph_recovery_install'); ?>
|
|
<input type="hidden" name="action" value="wph_recovery_install">
|
|
<button class="button button-primary">Install from gitea (latest)</button>
|
|
</form>
|
|
<a href="<?php echo esc_url(admin_url('tools.php?page=site-healthcheck-settings')); ?>" class="button">Configure source</a>
|
|
<?php else: ?>
|
|
<p>
|
|
<a href="<?php echo esc_url(admin_url('tools.php?page=site-healthcheck-settings')); ?>" class="button button-primary">Configure gitea source</a>
|
|
<em>— or install manually via Plugins → Add New → Upload Plugin.</em>
|
|
</p>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
}
|
|
}
|