prepare( 'DELETE FROM %i WHERE option_name LIKE %s OR option_name LIKE %s', $wpdb->options, $wpdb->esc_like( '_transient_zip_ai_oauth_state_' ) . '%', $wpdb->esc_like( '_transient_timeout_zip_ai_oauth_state_' ) . '%' ); if ( is_string( $zip_ai_delete_transients_query ) ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- built via $wpdb->prepare() with a %i table placeholder above; guarded is_string. $wpdb->query( $zip_ai_delete_transients_query ); } // Capability removal from every role. // `manage_zip_mcp_assistant` is the capability the plugin adds today; // `manage_zip_ai_assistant` may linger from older releases. $zip_ai_roles = wp_roles(); foreach ( $zip_ai_roles->role_objects as $zip_ai_role ) { foreach ( array( 'manage_zip_mcp_assistant', 'manage_zip_ai_assistant' ) as $zip_ai_cap ) { if ( $zip_ai_role->has_cap( $zip_ai_cap ) ) { $zip_ai_role->remove_cap( $zip_ai_cap ); } } } // Scheduled cron events. wp_clear_scheduled_hook( 'zip_ai_site_scan' );