PluginProbe
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… / 2.10.0
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… v2.10.0
3.0.0 2.11.12 2.11.11 2.11.10 2.11.9 2.11.7 2.11.8 2.11.6 2.11.5 2.11.4 2.11.3 2.11.1 2.11.2 2.11.0 2.10.5 2.10.4 2.10.3 2.10.2 2.10.1 2.10.0 2.9.9 2.9.8 2.9.6 2.9.7 2.9.5 All 88 releases
vigilante / uninstall.php

uninstall.php in Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… 2.10.0, at uninstall.php

235 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Uninstall Vigilante AyudaWP
4 *
5 * This file runs when the plugin is deleted via WordPress admin.
6 * It removes all plugin data including database tables and options.
7 *
8 * @package Vigilante
9 */
10
11 // Exit if not called by WordPress
12 if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
13 exit;
14 }
15
16 // Load required files
17 require_once plugin_dir_path( __FILE__ ) . 'includes/class-settings.php';
18 require_once plugin_dir_path( __FILE__ ) . 'includes/class-database.php';
19 require_once plugin_dir_path( __FILE__ ) . 'includes/class-backup-manager.php';
20 require_once plugin_dir_path( __FILE__ ) . 'includes/class-deactivator.php';
21
22 // Define constants if not already defined
23 if ( ! defined( 'VIGILANTE_BACKUP_DIR' ) ) {
24 define( 'VIGILANTE_BACKUP_DIR', WP_CONTENT_DIR . '/vigilante-backups/' );
25 }
26
27 /**
28 * Uninstall function
29 */
30 function vigilante_uninstall() {
31 global $wpdb;
32
33 /*
34 * The scheduled events go first. WordPress can spawn wp-cron in the middle
35 * of an uninstall, and that loopback request runs in its own process with
36 * the plugin still on disk: clearing the events before anything else means
37 * it finds nothing to run.
38 */
39 // Clear scheduled hooks
40 $hooks_to_clear = array(
41 'vigilante_daily_maintenance',
42 'vigilante_hourly_check',
43 'vigilante_hourly_checks',
44 'vigilante_file_integrity_scan',
45 'vigilante_cleanup_logs',
46 'vigilante_password_expiry_reminder',
47 'vigilante_analyzer_weekly_scan',
48 'vigilante_under_attack_post_scan',
49 'vigilante_plugin_status_check',
50 );
51
52 foreach ( $hooks_to_clear as $hook ) {
53 wp_clear_scheduled_hook( $hook );
54 }
55
56 // Post-update verification events are scheduled with per-update arguments,
57 // so clear every instance regardless of args.
58 wp_unschedule_hook( 'vigilante_fi_postupdate_verify' );
59
60 // Drop custom tables
61 $tables = array(
62 $wpdb->prefix . 'vigilante_activity_log',
63 $wpdb->prefix . 'vigilante_login_attempts',
64 $wpdb->prefix . 'vigilante_file_integrity',
65 $wpdb->prefix . 'vigilante_2fa_codes',
66 $wpdb->prefix . 'vigilante_2fa_trusted_devices',
67 $wpdb->prefix . 'vigilante_2fa_notifications',
68 $wpdb->prefix . 'vigilante_2fa_totp',
69 );
70
71 foreach ( $tables as $table ) {
72 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
73 $wpdb->query( "DROP TABLE IF EXISTS {$table}" );
74 }
75
76 // Delete options
77 $options_to_delete = array(
78 'vigilante_options',
79 'vigilante_db_version',
80 'vigilante_backup_timestamp',
81 'vigilante_last_integrity_scan',
82 'vigilante_last_integrity_results',
83 'vigilante_ignored_files',
84 'vigilante_dismissed_notices',
85 'vigilante_under_attack_mode',
86 'vigilante_active_preset',
87 'vigilante_firewall_blocks',
88 'vigilante_critical_files_baseline',
89 'vigilante_activated_time',
90 'vigilante_analyzer_last_scan',
91 'vigilante_analyzer_history',
92 'vigilante_legacy_backups_cleaned',
93 'vigilante_css_exclusion_migrated',
94 'vigilante_checksum_cache_flushed_290',
95 'vigilante_server_software',
96 'vigilante_server_files_version',
97 'vigilante_server_files_pending',
98 'vigilante_server_files_retry_after',
99 // Safety copies taken before writing to the site's configuration files.
100 // The wp-config.php one holds the database credentials and the
101 // authentication salts, so leaving it behind would keep them readable in
102 // the options table long after the plugin is gone.
103 'vigilante_htaccess_backup',
104 'vigilante_wpconfig_backup',
105 'vigilante_plugin_status_state',
106 'vigilante_plugin_status_last_check',
107 'vigilante_ignored_closed_plugins',
108 );
109
110 foreach ( $options_to_delete as $option ) {
111 delete_option( $option );
112 }
113
114 // Per-backup records are named after their timestamp
115 // (vigilante_backup_info_<Y-m-d_H-i-s>), so a fixed list cannot reach them.
116 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
117 $wpdb->query(
118 "DELETE FROM {$wpdb->options} WHERE option_name LIKE 'vigilante_backup_info_%'"
119 );
120
121 // Delete all transients
122 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
123 $wpdb->query(
124 "DELETE FROM {$wpdb->options}
125 WHERE option_name LIKE '_transient_vigilante_%'
126 OR option_name LIKE '_transient_timeout_vigilante_%'"
127 );
128
129 // Remove backup directory
130 $backup_dir = WP_CONTENT_DIR . '/vigilante-backups/';
131 if ( is_dir( $backup_dir ) ) {
132 vigilante_recursive_rmdir( $backup_dir );
133 }
134
135
136 // Delete all user meta with vigilante_ prefix
137 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
138 $wpdb->query(
139 "DELETE FROM {$wpdb->usermeta} WHERE meta_key LIKE 'vigilante\_%'"
140 );
141
142 /*
143 * The plugin is still loaded in the request that runs this file, so
144 * whatever it does later, on shutdown or on a late hook, writes its data
145 * back after the cleanup above has finished. Measured on 22 aug 2026: an
146 * uninstall left 112 rows of plugin status transients and its last check
147 * timestamp behind, all of them written after this file had run. So the
148 * sweep is repeated at the very end of the request.
149 */
150 add_action( 'shutdown', 'vigilante_uninstall_final_sweep', PHP_INT_MAX );
151 }
152
153 /**
154 * Second pass at the end of the request, for anything written after the first one
155 *
156 * Deliberately not a blunt "vigilante%" wildcard: other plugins live under that
157 * name too, the network sync companion among them, and deleting their options
158 * from here would be a fine way to break somebody else's site.
159 *
160 * @since 2.9.9
161 */
162 function vigilante_uninstall_final_sweep() {
163 global $wpdb;
164
165 // The scheduled events go too: they are rescheduled by the plugin that is
166 // still loaded in this request, which is how vigilante_plugin_status_check
167 // survived an uninstall until 2.9.9.
168 $hooks = array(
169 'vigilante_daily_maintenance',
170 'vigilante_hourly_check',
171 'vigilante_hourly_checks',
172 'vigilante_file_integrity_scan',
173 'vigilante_cleanup_logs',
174 'vigilante_password_expiry_reminder',
175 'vigilante_analyzer_weekly_scan',
176 'vigilante_under_attack_post_scan',
177 'vigilante_plugin_status_check',
178 'vigilante_fi_postupdate_verify',
179 );
180
181 foreach ( $hooks as $hook ) {
182 wp_unschedule_hook( $hook );
183 }
184
185 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
186 $wpdb->query(
187 "DELETE FROM {$wpdb->options}
188 WHERE option_name LIKE '_transient_vigilante\_%'
189 OR option_name LIKE '_transient_timeout_vigilante\_%'
190 OR option_name LIKE 'vigilante_plugin_status\_%'
191 OR option_name LIKE 'vigilante_backup_info\_%'
192 OR option_name IN (
193 'vigilante_options',
194 'vigilante_db_version',
195 'vigilante_ignored_closed_plugins',
196 'vigilante_ignored_files',
197 'vigilante_dismissed_notices',
198 'vigilante_under_attack_mode',
199 'vigilante_active_preset',
200 'vigilante_server_software',
201 'vigilante_server_files_version',
202 'vigilante_server_files_pending',
203 'vigilante_server_files_retry_after'
204 )"
205 );
206 }
207
208 /**
209 * Recursively remove directory
210 *
211 * @param string $dir Directory path.
212 * @return bool
213 */
214 function vigilante_recursive_rmdir( $dir ) {
215 if ( ! is_dir( $dir ) ) {
216 return false;
217 }
218
219 // Initialize WP_Filesystem
220 global $wp_filesystem;
221 if ( ! function_exists( 'WP_Filesystem' ) ) {
222 require_once ABSPATH . 'wp-admin/includes/file.php';
223 }
224 WP_Filesystem();
225
226 if ( ! $wp_filesystem ) {
227 return false;
228 }
229
230 // Use WP_Filesystem delete with recursive flag
231 return $wp_filesystem->delete( $dir, true );
232 }
233
234 // Run uninstall
235 vigilante_uninstall();