Remove vectors). $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_index')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange // The link assistant's words and links, worked out from the embedded posts. $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_terms')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_terms_df')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_links')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange // Search insights: the logged searches. $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_searches')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange // The site assistant's saved chats. $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_chats')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange // The activity log. A Reset made from the screen is the first entry of the new log. $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_activity_items')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange $wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS %i', $wpdb->prefix . 'aipcf_activity')); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange // Legacy per-day notice flags, response cache, regenerate markers, receipts, // notices. Deleted one by one through the API so the object cache drops them too. $names = $wpdb->get_col( // phpcs:ignore WordPress.DB.DirectDatabaseQuery "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE 'aipcf\\_budget\\_notice\\_%' OR option_name LIKE 'aipcf\\_lock\\_%' OR option_name LIKE '\\_transient\\_aipcf\\_%'" ); foreach ((array) $names as $name) { $name = (string) $name; if (strpos($name, '_transient_') === 0) { delete_transient(substr($name, strlen('_transient_'))); } else { delete_option($name); } } // Orphaned timeouts whose value row is already gone. $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '\\_transient\\_timeout\\_aipcf\\_%'"); // phpcs:ignore WordPress.DB.DirectDatabaseQuery // Targeted, not wp_cache_flush(): a shared object cache serves other sites too. foreach (self::OPTIONS as $option) { wp_cache_delete($option, 'options'); } wp_cache_delete('alloptions', 'options'); wp_cache_delete('notoptions', 'options'); self::removeConnectorApproval(); if (function_exists(__NAMESPACE__ . '\\flush_model_caches')) { flush_model_caches(); } do_action('aipcf_reset'); } /** * On deactivation: stop the cron events and forget the running version, so that * reactivating runs the same catch-up as an update (content may change meanwhile). */ public static function deactivate(): void { self::unschedule(); delete_option('aipcf_version'); } /** * Unschedules the cron events; the plugin schedules them again on init when * it is active. */ public static function unschedule(): void { foreach (self::CRON as $hook) { wp_clear_scheduled_hook($hook); } } /** * Drops only this plugin's entry from the AI plugin's shared approvals option. */ private static function removeConnectorApproval(): void { $approvals = get_option('wpai_connector_approvals', null); if (!is_array($approvals)) { return; } // Reset.php lives in src/, so this is the plugin's own main file even during uninstall. $plugin = plugin_basename(dirname(__DIR__) . '/plugin.php'); $changed = false; if (isset($approvals[$plugin]) && is_array($approvals[$plugin]) && array_key_exists('cloudflare-workers-ai', $approvals[$plugin])) { unset($approvals[$plugin]['cloudflare-workers-ai']); if ($approvals[$plugin] === []) { unset($approvals[$plugin]); } $changed = true; } if ($changed) { update_option('wpai_connector_approvals', $approvals); } } }