Files
WP-LIT-MCP/src/Uninstaller.php
T
Jan-Niclas LoosenandClaude Opus 5.5 05bf890481 feat(cache): WP Super Cache über den Kompatibilitätskern anbinden
SuperCacheFeature, SuperCacheCompatibility (LockOnFailure, getestet 3.1.5, Version aus dem Plugin-Header) und SuperCacheIntegration ohne Tools. Der SuperCacheListener sammelt Änderungen über lit_mcp_changed und leert einmal am Request-Ende: einen Beitrag per wp_cache_post_edit, mehrere Beiträge oder seitenweite Änderungen per wp_cache_clear_cache (Multisite: eigener Blog). Komplett-Purges höchstens alle 30 s, mit genau einem Nachlauf per WP-Cron. Freigabe-Einträge leeren nichts. Uninstaller räumt Optionen, Transient und Cron-Hook ab; Reiter und lit-site-status zeigen das Profil automatisch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 14:50:35 +01:00

95 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace LIT\MCP;
defined('ABSPATH') || exit;
/**
* Removes WP-LIT-MCP's own data (uninstall.php, Task 12): options (incl. the Snapshots des
* Designsystems and their change locks, Etappe 4), the endpoint-check and Divi-release
* transients, the log-cleanup cron hook and the change log table – on every site of a
* network – and the Protokoll tab's per-user screen option.
*
* Deliberately self-contained (no reference to any other LIT\MCP\* class): uninstall.php
* is executed by WordPress core standalone, without loading the plugin's main file first,
* so the Composer/Jetpack autoloader is not guaranteed to have run. The option/hook/table
* names below are therefore duplicated from Access::OPTION, Abilities\ExposurePolicy::OPTION,
* Limits::OPTION, ChangeLog\ChangeLogInstaller::VERSION_OPTION, Integrations\Divi\Release\
* lit_mcp_<profile>_releases (Compatibility\ReleaseStore), lit_mcp_<profile>_check_report
* (Compatibility\CheckReportStore) and lit_mcp_<profile>_check_lock (Admin\CheckRoute) for the
* profiles divi, pods and wpsc (an explicit list: a LIKE pattern could hit foreign options),
* Integrations\Divi\Design\DesignLock::option(), Admin\ConnectionStatus::ENDPOINT_TRANSIENT,
* Integrations\Divi\Release\ReleaseResolver::CACHE,
* Integrations\SuperCache\SuperCacheListener::PURGED_AT (transient),
* ChangeLog\ChangeLogCleanup::HOOK, Integrations\SuperCache\SuperCacheListener::TRAILING_HOOK (cron),
* ChangeLog\ChangeLog::TABLE, Admin\LogTab::PER_PAGE_OPTION and
* Updater\RecheckOnInstall::OPTION on purpose;
* tests/Unit/UninstallerTest.php and tests/Unit/UninstallTest.php keep them in sync with
* those constants.
*
* Never touches the bundled wp-media/mcp-oauth library's data (option mcp_jwt_secret,
* option wpmedia_mcp_oauth_rewrite_version, user meta mcp_refresh_jti_*, application
* passwords of connected clients) – that library may be shared with other plugins on
* this site. Never deletes posts, attachments or revisions.
*/
final class Uninstaller
{
private const OPTIONS = [
'lit_mcp_allowed_roles', 'lit_mcp_exposure', 'lit_mcp_limits', 'lit_mcp_db_version',
'lit_mcp_divi_releases', 'lit_mcp_divi_check_report', 'lit_mcp_divi_check_lock',
'lit_mcp_pods_releases', 'lit_mcp_pods_check_report', 'lit_mcp_pods_check_lock',
'lit_mcp_wpsc_releases', 'lit_mcp_wpsc_check_report', 'lit_mcp_wpsc_check_lock',
'lit_mcp_snapshots_colors', 'lit_mcp_snapshots_variables', 'lit_mcp_snapshots_presets',
'lit_mcp_snapshots_theme_options', 'lit_mcp_snapshots_custom_css',
'lit_mcp_lock_divi_options', 'lit_mcp_lock_variables', 'lit_mcp_lock_presets', 'lit_mcp_lock_custom_css',
// Locks of versions before the shared one (audit L5) may still sit in the table.
'lit_mcp_lock_colors', 'lit_mcp_lock_theme_options',
'lit_mcp_installed_version',
];
private const TRANSIENTS = ['lit_mcp_endpoint_check', 'lit_mcp_divi_state', 'lit_mcp_wpsc_purged_at'];
private const CRON_HOOKS = ['lit_mcp_log_cleanup', 'lit_mcp_wpsc_trailing_purge'];
private const TABLE = 'lit_mcp_log';
/** Screen option "Einträge pro Seite" of the Protokoll tab (Admin\LogTab::PER_PAGE_OPTION): user meta. */
private const USER_META = 'lit_mcp_log_per_page';
public static function run(): void
{
// User meta is shared by every site of a network: removed once, for all users.
delete_metadata('user', 0, self::USER_META, '', true);
if (! is_multisite()) {
self::removeSiteData();
return;
}
foreach (get_sites(['fields' => 'ids', 'number' => 0]) as $site_id) {
switch_to_blog((int) $site_id);
self::removeSiteData();
restore_current_blog();
}
}
public static function removeSiteData(): void
{
global $wpdb;
foreach (self::OPTIONS as $option) {
delete_option($option);
}
foreach (self::TRANSIENTS as $transient) {
delete_transient($transient);
}
foreach (self::CRON_HOOKS as $hook) {
wp_clear_scheduled_hook($hook);
}
$table = $wpdb->prefix . self::TABLE;
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- own table name, not user input.
$wpdb->query("DROP TABLE IF EXISTS {$table}");
}
}