Files
WP-LIT-MCP/src/Uninstaller.php
T
janniclas.loosenandClaude Opus 5.5 097fef2e32 fix: final review minors m-1 to m-8
- m-1: the no-change Divi result carries preview_url/edit_url too
- m-2: overview names replace-text's per-page tree_rev
- m-3: divi-shortform documents validation_failed vs not_found for unknown IDs
- m-4: DiviWriter/DiviPageLoader final (no mocks left), neutral NewDraft
  log detail, snapshots are Etappe 4
- m-5: Tested up to 7.1, changelog completed
- m-6: content-create warns when the extras changed the stored layout
- m-7: deleting a whole section outlines nothing instead of the next one
- m-8: uninstall removes the user meta lit_mcp_log_per_page; readme lists it

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
2026-09-26 19:35:24 +02:00

72 lines
2.7 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, the endpoint-check
* transient, 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, Admin\ConnectionStatus::
* ENDPOINT_TRANSIENT, ChangeLog\ChangeLogCleanup::HOOK, ChangeLog\ChangeLog::TABLE and
* Admin\LogTab::PER_PAGE_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'];
private const TRANSIENT = 'lit_mcp_endpoint_check';
private const CRON_HOOK = 'lit_mcp_log_cleanup';
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);
}
delete_transient(self::TRANSIENT);
wp_clear_scheduled_hook(self::CRON_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}");
}
}