# thinkrank/1.10.0/uninstall.php

ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console &amp; Local SEO, version 1.10.0. 222 lines.

- Page: https://pluginprobe.com/plugins/thinkrank/1.10.0/code/uninstall.php
- Raw: https://pluginprobe.com/plugins/thinkrank/1.10.0/raw/uninstall.php
- Modified: 2025-08-10T07:35:04+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/thinkrank/1.10.0/code/uninstall.php#L10-L20`.

```php
<?php
/**
 * Plugin Uninstall Script
 * 
 * Handles complete plugin removal and cleanup
 * 
 * @package ThinkRank
 * @since 1.0.0
 */

declare(strict_types=1);

// Prevent direct access
if (!defined('WP_UNINSTALL_PLUGIN')) {
    exit;
}

/**
 * ThinkRank Uninstaller Class
 * 
 * Single Responsibility: Handle complete plugin removal
 */
class ThinkRank_Uninstaller {
    
    /**
     * Run uninstall process
     * 
     * @return void
     */
    public static function uninstall(): void {
        // Check if user wants to keep data
        $keep_data = get_option('thinkrank_keep_data_on_uninstall', false);
        
        if (!$keep_data) {
            self::remove_database_tables();
            self::remove_options();
            self::remove_user_meta();
            self::remove_post_meta();
        }
        
        self::clear_caches();
        self::remove_cron_jobs();
        self::remove_capabilities();
    }
    
    /**
     * Remove custom database tables
     *
     * @return void
     */
    private static function remove_database_tables(): void {
        global $wpdb;

        $tables = [
            $wpdb->prefix . 'thinkrank_ai_cache',
            $wpdb->prefix . 'thinkrank_ai_usage',
            $wpdb->prefix . 'thinkrank_content_briefs',
            $wpdb->prefix . 'thinkrank_seo_scores',
        ];

        foreach ($tables as $table) {
            // Check WordPress version for %i support (introduced in 6.2)
            if (version_compare($GLOBALS['wp_version'], '6.2', '>=')) {
                // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
                $wpdb->query($wpdb->prepare("DROP TABLE IF EXISTS %i", $table));
                // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
            } else {
                // Fallback for older WordPress versions - table name is from our controlled list
                $escaped_table = esc_sql($table);
                // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
                $wpdb->query("DROP TABLE IF EXISTS `{$escaped_table}`");
                // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
            }
        }
    }
    
    /**
     * Remove plugin options
     * 
     * @return void
     */
    private static function remove_options(): void {
        $options = [
            'thinkrank_version',
            'thinkrank_free_credits',
            'thinkrank_ai_provider',
            'thinkrank_cache_duration',
            'thinkrank_max_requests_per_minute',
            'thinkrank_enable_logging',
            'thinkrank_auto_optimize',
            'thinkrank_seo_score_threshold',
            'thinkrank_activated',
            'thinkrank_activation_time',
            'thinkrank_show_welcome',
            'thinkrank_encryption_key',
            'thinkrank_keep_data_on_uninstall',
            'thinkrank_last_deactivation',
        ];
        
        foreach ($options as $option) {
            delete_option($option);
        }
        
        // Remove transients with proper escaping
        global $wpdb;
        // 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
        $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->options}
                 WHERE option_name LIKE %s
                 OR option_name LIKE %s",
                $wpdb->esc_like('_transient_thinkrank_') . '%',
                $wpdb->esc_like('_transient_timeout_thinkrank_') . '%'
            )
        );
        // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
    }
    
    /**
     * Remove user meta data
     *
     * @return void
     */
    private static function remove_user_meta(): void {
        global $wpdb;

        // 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
        $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->usermeta}
                 WHERE meta_key LIKE %s",
                $wpdb->esc_like('thinkrank_') . '%'
            )
        );
        // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
    }
    
    /**
     * Remove post meta data
     *
     * @return void
     */
    private static function remove_post_meta(): void {
        global $wpdb;

        // 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
        $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->postmeta}
                 WHERE meta_key LIKE %s
                 OR meta_key LIKE %s",
                $wpdb->esc_like('thinkrank_') . '%',
                $wpdb->esc_like('_thinkrank_') . '%'
            )
        );
        // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
    }
    

    /**
     * Clear all caches
     * 
     * @return void
     */
    private static function clear_caches(): void {
        // Clear object cache
        if (function_exists('wp_cache_flush_group')) {
            wp_cache_flush_group('thinkrank');
        }
        
        // Clear any external caches
        if (function_exists('wp_cache_flush')) {
            wp_cache_flush();
        }
    }
    
    /**
     * Remove scheduled cron jobs
     * 
     * @return void
     */
    private static function remove_cron_jobs(): void {
        $cron_jobs = [
            'thinkrank_monthly_credit_reset',
            'thinkrank_cache_cleanup',
            'thinkrank_usage_analytics',
        ];
        
        foreach ($cron_jobs as $job) {
            wp_clear_scheduled_hook($job);
        }
    }
    
    /**
     * Remove custom capabilities
     * 
     * @return void
     */
    private static function remove_capabilities(): void {
        $capabilities = [
            'thinkrank_manage_settings',
            'thinkrank_view_analytics',
            'thinkrank_manage_credits',
            'thinkrank_use_ai_features',
        ];
        
        $roles = wp_roles();
        
        foreach ($roles->roles as $role_name => $role_info) {
            $role = get_role($role_name);
            if ($role) {
                foreach ($capabilities as $cap) {
                    $role->remove_cap($cap);
                }
            }
        }
    }
}

// Run the uninstaller
ThinkRank_Uninstaller::uninstall();

```
