blog_id); Dwarpal_Install::install(); restore_current_blog(); } add_action('wp_initialize_site', 'dwarpal_initialize_new_site', 20); // Register deactivation hook register_deactivation_hook(__FILE__, 'dwarpal_deactivate'); /** * Plugin deactivation function * * @return void */ function dwarpal_deactivate() { foreach (array('dwarpal_daily_malware_scan', 'dwarpal_integrity_check', 'dwarpal_check_updates', 'dwarpal_vulnerability_scan', 'dwarpal_blocklist_check', 'dwarpal_daily_cloaking_scan', 'dwarpal_signature_feed_sync', 'dwarpal_alert_digest_send', 'dwarpal_traffic_cleanup', 'dwarpal_convert_engine', 'dwarpal_log_cleanup', 'dwarpal_log_cleanup_now') as $dwarpal_hook) { wp_clear_scheduled_hook($dwarpal_hook); } } // Register uninstall hook register_uninstall_hook(__FILE__, 'dwarpal_uninstall'); /** * Plugin uninstall function * Cleans up all database tables and options * * @return void */ function dwarpal_uninstall() { // Wrap everything in try-catch to prevent fatal errors try { // Check if WordPress is ready if (!defined('ABSPATH')) { return; } global $wpdb; // Check if wpdb is available if (!isset($wpdb) || !is_object($wpdb) || empty($wpdb->prefix)) { return; } // Delete all database tables $tables = array( 'dwarpal_logs', 'dwarpal_http_errors', 'dwarpal_traffic', ); foreach ($tables as $table) { $table_name = $wpdb->prefix . $table; // Check if table exists before dropping if (method_exists($wpdb, 'get_var')) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin uninstall cleanup. $table_exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)); if ($table_exists == $table_name) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Plugin uninstall cleanup. $wpdb->query("DROP TABLE IF EXISTS `" . esc_sql($table_name) . "`"); } } } // Delete all plugin options if (method_exists($wpdb, 'get_col') && method_exists($wpdb, 'prepare') && isset($wpdb->options)) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin uninstall cleanup. $options = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", 'dwarpal_%' ) ); if (is_array($options) && function_exists('delete_option')) { foreach ($options as $option) { delete_option($option); } } } // Delete all transients if (method_exists($wpdb, 'query') && method_exists($wpdb, 'prepare') && isset($wpdb->options)) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin uninstall cleanup. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s", '_transient_dwarpal_%', '_transient_timeout_dwarpal_%' ) ); } // Clear scheduled events if (function_exists('wp_clear_scheduled_hook')) { $cron_hooks = array( 'dwarpal_daily_malware_scan', 'dwarpal_integrity_check', 'dwarpal_check_updates', 'dwarpal_vulnerability_scan', 'dwarpal_blocklist_check', 'dwarpal_daily_cloaking_scan', 'dwarpal_signature_feed_sync', 'dwarpal_alert_digest_send', 'dwarpal_traffic_cleanup', 'dwarpal_convert_engine', 'dwarpal_log_cleanup', 'dwarpal_log_cleanup_now', ); foreach ($cron_hooks as $cron_hook) { wp_clear_scheduled_hook($cron_hook); } } } catch (Exception $e) { // Silently ignore uninstall errors to prevent fatal uninstall failures. unset($e); } catch (Error $e) { // Silently ignore fatal errors during uninstall. unset($e); } } /** * Load the plugin class file * Only load when WordPress is ready * * @return void */ function dwarpal_load_plugin() { // Only load if WordPress is ready if (!defined('ABSPATH') || !function_exists('add_action')) { return; } // Load the main plugin class $class_file = DWARPAL_PLUGIN_DIR . 'includes/class-dwarpal.php'; if (file_exists($class_file)) { require_once $class_file; } } /** * Initialize the plugin * * @return Dwarpal|false */ function dwarpal() { // Load class file first if not already loaded if (!class_exists('Dwarpal')) { dwarpal_load_plugin(); } // Only proceed if class exists if (!class_exists('Dwarpal')) { return false; } return Dwarpal::get_instance(); } // Start the plugin after WordPress is loaded // This prevents fatal errors during activation and uninstall // NEVER load the class during file parse - always wait for plugins_loaded hook if (!defined('WP_UNINSTALL_PLUGIN') && !defined('WP_INSTALLING')) { // Check if we're in uninstall context $dwarpal_is_uninstall = false; // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- WordPress core plugin deletion request detection. if (isset($_REQUEST['action']) && sanitize_text_field(wp_unslash($_REQUEST['action'])) === 'delete-selected') { // Bulk delete action $dwarpal_checked_raw = isset($_REQUEST['checked']) ? wp_unslash($_REQUEST['checked']) : array(); if (is_array($dwarpal_checked_raw)) { $dwarpal_plugin_basename = defined('DWARPAL_PLUGIN_BASENAME') ? DWARPAL_PLUGIN_BASENAME : 'dwarpal/dwarpal.php'; $dwarpal_checked = array_map('sanitize_text_field', $dwarpal_checked_raw); if (in_array($dwarpal_plugin_basename, $dwarpal_checked, true)) { $dwarpal_is_uninstall = true; } } } elseif (isset($_GET['action']) && sanitize_text_field(wp_unslash($_GET['action'])) === 'delete') { // Single delete action if (isset($_GET['plugin'])) { $dwarpal_plugin_basename = defined('DWARPAL_PLUGIN_BASENAME') ? DWARPAL_PLUGIN_BASENAME : 'dwarpal/dwarpal.php'; if (sanitize_text_field(wp_unslash($_GET['plugin'])) === $dwarpal_plugin_basename) { $dwarpal_is_uninstall = true; } } } // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized // Don't load class during uninstall if (!$dwarpal_is_uninstall) { // Always delay loading until plugins_loaded hook fires // This ensures WordPress is fully initialized before we load any classes if (function_exists('add_action')) { add_action('plugins_loaded', 'dwarpal', 1); } } }