PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.0.1
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.0.1
2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / uninstall.php

uninstall.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.0.1, at uninstall.php

222 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Uninstall Script
4 *
5 * Handles complete plugin removal and cleanup
6 *
7 * @package ThinkRank
8 * @since 1.0.0
9 */
10
11 declare(strict_types=1);
12
13 // Prevent direct access
14 if (!defined('WP_UNINSTALL_PLUGIN')) {
15 exit;
16 }
17
18 /**
19 * ThinkRank Uninstaller Class
20 *
21 * Single Responsibility: Handle complete plugin removal
22 */
23 class ThinkRank_Uninstaller {
24
25 /**
26 * Run uninstall process
27 *
28 * @return void
29 */
30 public static function uninstall(): void {
31 // Check if user wants to keep data
32 $keep_data = get_option('thinkrank_keep_data_on_uninstall', false);
33
34 if (!$keep_data) {
35 self::remove_database_tables();
36 self::remove_options();
37 self::remove_user_meta();
38 self::remove_post_meta();
39 }
40
41 self::clear_caches();
42 self::remove_cron_jobs();
43 self::remove_capabilities();
44 }
45
46 /**
47 * Remove custom database tables
48 *
49 * @return void
50 */
51 private static function remove_database_tables(): void {
52 global $wpdb;
53
54 $tables = [
55 $wpdb->prefix . 'thinkrank_ai_cache',
56 $wpdb->prefix . 'thinkrank_ai_usage',
57 $wpdb->prefix . 'thinkrank_content_briefs',
58 $wpdb->prefix . 'thinkrank_seo_scores',
59 ];
60
61 foreach ($tables as $table) {
62 // Check WordPress version for %i support (introduced in 6.2)
63 if (version_compare($GLOBALS['wp_version'], '6.2', '>=')) {
64 // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
65 $wpdb->query($wpdb->prepare("DROP TABLE IF EXISTS %i", $table));
66 // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
67 } else {
68 // Fallback for older WordPress versions - table name is from our controlled list
69 $escaped_table = esc_sql($table);
70 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
71 $wpdb->query("DROP TABLE IF EXISTS `{$escaped_table}`");
72 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
73 }
74 }
75 }
76
77 /**
78 * Remove plugin options
79 *
80 * @return void
81 */
82 private static function remove_options(): void {
83 $options = [
84 'thinkrank_version',
85 'thinkrank_free_credits',
86 'thinkrank_ai_provider',
87 'thinkrank_cache_duration',
88 'thinkrank_max_requests_per_minute',
89 'thinkrank_enable_logging',
90 'thinkrank_auto_optimize',
91 'thinkrank_seo_score_threshold',
92 'thinkrank_activated',
93 'thinkrank_activation_time',
94 'thinkrank_show_welcome',
95 'thinkrank_encryption_key',
96 'thinkrank_keep_data_on_uninstall',
97 'thinkrank_last_deactivation',
98 ];
99
100 foreach ($options as $option) {
101 delete_option($option);
102 }
103
104 // Remove transients with proper escaping
105 global $wpdb;
106 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Core table name is safe, uninstall cleanup requires direct database access
107 $wpdb->query(
108 $wpdb->prepare(
109 "DELETE FROM {$wpdb->options}
110 WHERE option_name LIKE %s
111 OR option_name LIKE %s",
112 $wpdb->esc_like('_transient_thinkrank_') . '%',
113 $wpdb->esc_like('_transient_timeout_thinkrank_') . '%'
114 )
115 );
116 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
117 }
118
119 /**
120 * Remove user meta data
121 *
122 * @return void
123 */
124 private static function remove_user_meta(): void {
125 global $wpdb;
126
127 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Core table name is safe, uninstall cleanup requires direct database access
128 $wpdb->query(
129 $wpdb->prepare(
130 "DELETE FROM {$wpdb->usermeta}
131 WHERE meta_key LIKE %s",
132 $wpdb->esc_like('thinkrank_') . '%'
133 )
134 );
135 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
136 }
137
138 /**
139 * Remove post meta data
140 *
141 * @return void
142 */
143 private static function remove_post_meta(): void {
144 global $wpdb;
145
146 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Core table name is safe, uninstall cleanup requires direct database access
147 $wpdb->query(
148 $wpdb->prepare(
149 "DELETE FROM {$wpdb->postmeta}
150 WHERE meta_key LIKE %s
151 OR meta_key LIKE %s",
152 $wpdb->esc_like('thinkrank_') . '%',
153 $wpdb->esc_like('_thinkrank_') . '%'
154 )
155 );
156 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
157 }
158
159
160 /**
161 * Clear all caches
162 *
163 * @return void
164 */
165 private static function clear_caches(): void {
166 // Clear object cache
167 if (function_exists('wp_cache_flush_group')) {
168 wp_cache_flush_group('thinkrank');
169 }
170
171 // Clear any external caches
172 if (function_exists('wp_cache_flush')) {
173 wp_cache_flush();
174 }
175 }
176
177 /**
178 * Remove scheduled cron jobs
179 *
180 * @return void
181 */
182 private static function remove_cron_jobs(): void {
183 $cron_jobs = [
184 'thinkrank_monthly_credit_reset',
185 'thinkrank_cache_cleanup',
186 'thinkrank_usage_analytics',
187 ];
188
189 foreach ($cron_jobs as $job) {
190 wp_clear_scheduled_hook($job);
191 }
192 }
193
194 /**
195 * Remove custom capabilities
196 *
197 * @return void
198 */
199 private static function remove_capabilities(): void {
200 $capabilities = [
201 'thinkrank_manage_settings',
202 'thinkrank_view_analytics',
203 'thinkrank_manage_credits',
204 'thinkrank_use_ai_features',
205 ];
206
207 $roles = wp_roles();
208
209 foreach ($roles->roles as $role_name => $role_info) {
210 $role = get_role($role_name);
211 if ($role) {
212 foreach ($capabilities as $cap) {
213 $role->remove_cap($cap);
214 }
215 }
216 }
217 }
218 }
219
220 // Run the uninstaller
221 ThinkRank_Uninstaller::uninstall();
222