PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.27.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.27.0
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 / includes / core / class-deactivator.php

class-deactivator.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.27.0, at includes/core/class-deactivator.php

133 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Deactivator Class
4 *
5 * Handles plugin deactivation tasks
6 *
7 * @package ThinkRank\Core
8 * @since 1.0.0
9 */
10
11 declare(strict_types=1);
12
13 namespace ThinkRank\Core;
14
15 // Prevent direct access
16 if (!defined('ABSPATH')) {
17 exit;
18 }
19
20 /**
21 * Deactivator Class
22 *
23 * Single Responsibility: Handle plugin deactivation tasks only
24 *
25 * @since 1.0.0
26 */
27 class Deactivator {
28
29 /**
30 * Plugin deactivation tasks
31 *
32 * @return void
33 */
34 public function deactivate(): void {
35 $this->clear_scheduled_hooks();
36 $this->clear_cache();
37 $this->remove_published_files();
38 $this->log_deactivation();
39
40 // Note: We don't delete user data on deactivation
41 // Data is only removed on uninstall
42 }
43
44 /**
45 * Remove physically published files so they stop serving once the plugin
46 * is inactive (the published llms.txt would otherwise keep serving forever).
47 *
48 * @return void
49 */
50 private function remove_published_files(): void {
51 if (class_exists('ThinkRank\\SEO\\LLMs_Txt_Manager')) {
52 (new \ThinkRank\SEO\LLMs_Txt_Manager())->delete_llms_txt_file();
53 }
54 }
55
56 /**
57 * Clear all scheduled hooks
58 *
59 * @return void
60 */
61 private function clear_scheduled_hooks(): void {
62 $scheduled_hooks = [
63 'thinkrank_cache_cleanup',
64 'thinkrank_usage_analytics',
65 // Email report tick (see ThinkRank\SEO\Email_Report_Scheduler::CRON_HOOK)
66 // — was previously left scheduled after deactivation.
67 'thinkrank_email_report_tick',
68 ];
69
70 // Clear all instances of our hooks
71 foreach ($scheduled_hooks as $hook) {
72 wp_clear_scheduled_hook($hook);
73 }
74 }
75
76 /**
77 * Clear plugin cache
78 *
79 * @return void
80 */
81 private function clear_cache(): void {
82 global $wpdb;
83
84 // Clear AI cache table with proper escaping
85 $cache_table = $wpdb->prefix . 'thinkrank_ai_cache';
86 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Plugin deactivation requires direct database access to check table existence
87 $table_exists = $wpdb->get_var(
88 $wpdb->prepare("SHOW TABLES LIKE %s", $cache_table)
89 );
90 if ($table_exists === $cache_table) {
91 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is properly constructed from controlled prefix, plugin deactivation requires direct database access
92 $wpdb->query("TRUNCATE TABLE {$cache_table}");
93 }
94
95 // Clear WordPress transients with proper escaping
96 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- $wpdb->options is a WordPress core property, plugin deactivation requires direct database access
97 $wpdb->query(
98 $wpdb->prepare(
99 "DELETE FROM {$wpdb->options}
100 WHERE option_name LIKE %s
101 OR option_name LIKE %s",
102 $wpdb->esc_like('_transient_thinkrank_') . '%',
103 $wpdb->esc_like('_transient_timeout_thinkrank_') . '%'
104 )
105 );
106
107 // Clear object cache if available
108 if (function_exists('wp_cache_flush_group')) {
109 wp_cache_flush_group('thinkrank');
110 }
111 }
112
113 /**
114 * Log deactivation for analytics
115 *
116 * @return void
117 */
118 private function log_deactivation(): void {
119 $deactivation_data = [
120 'timestamp' => time(),
121 'version' => THINKRANK_VERSION,
122 'wp_version' => get_bloginfo('version'),
123 'php_version' => PHP_VERSION,
124 ];
125
126 // Store deactivation data for potential feedback
127 update_option('thinkrank_last_deactivation', $deactivation_data);
128
129 // Remove activation flag
130 delete_option('thinkrank_activated');
131 }
132 }
133