← Back
Editing: uninstall.php
<?php declare(strict_types=1); /** * Uninstall script for Simple Password Protect Plugin * * This file is executed when the plugin is uninstalled from WordPress. * It removes all plugin data including options, transients, and cookies. * * @package SimplePasswordProtect */ // If uninstall not called from WordPress, exit if (!defined('WP_UNINSTALL_PLUGIN')) { exit; } // Security check - verify this is being called properly if (!defined('ABSPATH')) { exit; } /** * Clean up plugin data on uninstall */ function spwdprot_uninstall_cleanup(): void { // Remove all plugin options $options_to_delete = [ 'spwdprot_plugin_enabled', 'spwdprot_password_hash', 'spwdprot_page_title', 'spwdprot_login_text', 'spwdprot_logo_url', 'spwdprot_logo_shape', 'spwdprot_impressum_page', 'spwdprot_privacy_page', 'spwdprot_background_color', 'spwdprot_button_color', 'spwdprot_button_text_color', 'spwdprot_link_color', 'spwdprot_version' ]; foreach ($options_to_delete as $option) { delete_option($option); // Also delete from multisite if applicable if (is_multisite()) { delete_site_option($option); } } // Clean up any transients that might have been created $transients_to_delete = [ 'spwdprot_version_check', 'spwdprot_settings_cache', 'spwdprot_page_cache' ]; foreach ($transients_to_delete as $transient) { delete_transient($transient); // Also delete site transients in multisite if (is_multisite()) { delete_site_transient($transient); } } // Clear any authentication cookies that might still be set // Note: This won't affect cookies already set in browsers, // but prevents issues if plugin is reinstalled if (isset($_COOKIE['wp_password_protect_auth'])) { setcookie('wp_password_protect_auth', '', time() - 3600, '/'); } // Clean up any custom database tables if they were created // (This plugin doesn't create custom tables, but good practice to check) global $wpdb; if (isset($wpdb)) { // Remove any plugin-specific user meta using WordPress functions when possible if (function_exists('delete_user_meta')) { // Use WordPress function to remove user meta $users = get_users(['fields' => 'ID']); foreach ($users as $user_id) { delete_user_meta($user_id, 'spwdprot_last_login'); } } else { // Fallback to direct query if WordPress functions unavailable // Check cache first $cache_key = 'spwdprot_user_meta_cleanup'; $cached_result = wp_cache_get($cache_key, 'spwdprot_cleanup'); if (false === $cached_result) { // Direct database query is intentional for complete plugin uninstall cleanup // This ensures all plugin data is removed when WordPress functions are unavailable // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $result = $wpdb->query($wpdb->prepare( "DELETE FROM {$wpdb->usermeta} WHERE meta_key = %s", 'spwdprot_last_login' )); // Cache the result for a short time during cleanup wp_cache_set($cache_key, $result, 'spwdprot_cleanup', 300); } } // Remove any plugin-specific post meta using WordPress functions when possible if (function_exists('delete_post_meta_by_key')) { delete_post_meta_by_key('spwdprot_excluded_page'); } else { // Fallback to direct query if WordPress functions unavailable // Check cache first $cache_key = 'spwdprot_post_meta_cleanup'; $cached_result = wp_cache_get($cache_key, 'spwdprot_cleanup'); if (false === $cached_result) { // Direct database query is intentional for complete plugin uninstall cleanup // This ensures all plugin data is removed when WordPress functions are unavailable // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $result = $wpdb->query($wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", 'spwdprot_excluded_page' )); // Cache the result for a short time during cleanup wp_cache_set($cache_key, $result, 'spwdprot_cleanup', 300); } } } // Clear any cached data if (function_exists('wp_cache_flush')) { wp_cache_flush(); } // Clear opcache if available if (function_exists('opcache_reset')) { opcache_reset(); } } /** * Multisite cleanup */ function spwdprot_multisite_uninstall_cleanup(): void { if (!is_multisite()) { return; } // Get all blog IDs $blog_ids = get_sites(['fields' => 'ids']); foreach ($blog_ids as $blog_id) { switch_to_blog($blog_id); spwdprot_uninstall_cleanup(); restore_current_blog(); } } /** * Remove plugin files from uploads directory */ function spwdprot_remove_uploaded_files(): void { $upload_dir = wp_upload_dir(); $plugin_upload_path = $upload_dir['basedir'] . '/simple-password-protect/'; if (is_dir($plugin_upload_path)) { // Use WP_Filesystem for file operations spwdprot_remove_directory_wp_filesystem($plugin_upload_path); } } /** * Recursively remove directory using WP_Filesystem */ function spwdprot_remove_directory_wp_filesystem(string $dir): bool { if (!is_dir($dir)) { return false; } // Initialize WP_Filesystem if (!function_exists('WP_Filesystem')) { require_once ABSPATH . 'wp-admin/includes/file.php'; } WP_Filesystem(); global $wp_filesystem; if ($wp_filesystem && $wp_filesystem->exists($dir)) { return $wp_filesystem->rmdir($dir, true); } // Fallback to manual removal if WP_Filesystem fails return spwdprot_remove_directory_fallback($dir); } /** * Fallback directory removal method using WP_Filesystem only */ function spwdprot_remove_directory_fallback(string $dir): bool { if (!is_dir($dir)) { return false; } // Initialize WP_Filesystem if not already done if (!function_exists('WP_Filesystem')) { require_once ABSPATH . 'wp-admin/includes/file.php'; } if (!WP_Filesystem()) { // If WP_Filesystem fails to initialize, we can't proceed safely return false; } global $wp_filesystem; if (!$wp_filesystem || !$wp_filesystem->exists($dir)) { return false; } // Use WP_Filesystem to remove directory recursively return $wp_filesystem->rmdir($dir, true); } /** * Remove any scheduled cron events */ function spwdprot_remove_cron_events(): void { // Remove any cron events that might have been scheduled $cron_events = [ 'spwdprot_cleanup_expired_sessions', 'spwdprot_security_check', 'spwdprot_maintenance_task' ]; foreach ($cron_events as $hook) { $timestamp = wp_next_scheduled($hook); if ($timestamp) { wp_unschedule_event($timestamp, $hook); } // Also clear any recurring events wp_clear_scheduled_hook($hook); } } /** * Clean up wp_options table from any orphaned entries */ function spwdprot_cleanup_wp_options(): void { // Clean up any autoloaded options that might slow down the site $orphaned_patterns = [ 'spwdprot_temp_%', 'spwdprot_cache_%', 'spwdprot_backup_%' ]; // Use WordPress functions when possible foreach ($orphaned_patterns as $pattern) { // For uninstall, we need to use direct queries as WordPress doesn't have // a function to delete options by pattern global $wpdb; if (isset($wpdb)) { // Check cache first $cache_key = 'spwdprot_options_cleanup_' . md5($pattern); $cached_result = wp_cache_get($cache_key, 'spwdprot_cleanup'); if (false === $cached_result) { // Direct database query is intentional for complete plugin uninstall cleanup // WordPress doesn't provide a function to delete options by pattern // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery $result = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", $pattern ) ); // Cache the result for a short time during cleanup wp_cache_set($cache_key, $result, 'spwdprot_cleanup', 300); } } } } /** * Send cleanup notification (if configured) */ function spwdprot_send_cleanup_notification(): void { // Only send notification if explicitly configured if (!defined('SPWDPROT_SEND_UNINSTALL_NOTIFICATION') || !SPWDPROT_SEND_UNINSTALL_NOTIFICATION) { return; } // Send notification email to admin $admin_email = get_option('admin_email'); $site_name = get_option('blogname'); $date = current_time('mysql'); // translators: %s is the site name $subject = sprintf(__('Simple Password Protect Plugin Uninstalled - %s', 'simple-password-protect'), $site_name); // translators: %1$s is the site name, %2$s is the date $message = sprintf(__('The Simple Password Protect plugin has been uninstalled from %1$s on %2$s.', 'simple-password-protect'), $site_name, $date); wp_mail($admin_email, $subject, $message); } // Perform the cleanup try { // Main cleanup for single site or multisite if (is_multisite()) { spwdprot_multisite_uninstall_cleanup(); } else { spwdprot_uninstall_cleanup(); } // Additional cleanup tasks spwdprot_remove_uploaded_files(); spwdprot_remove_cron_events(); spwdprot_cleanup_wp_options(); spwdprot_send_cleanup_notification(); // Final cache flush if (function_exists('wp_cache_flush')) { wp_cache_flush(); } } catch (Exception $e) { // Don't let uninstall errors break the WordPress admin // The plugin will still be removed even if cleanup fails // Silent failure for production stability }
Save File
Cancel