query( $wpdb->prepare( 'DELETE FROM %i WHERE meta_key LIKE %s', $wpdb->usermeta, $wpdb->esc_like( 'cuft_dismissed_update_' ) . '%' ) ); // Remove other plugin-related user meta (e.g. cuft_notice_dismissed_*) // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin's own user meta keys (cuft_*); one-time uninstall cleanup, not cacheable. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE meta_key LIKE %s', $wpdb->usermeta, $wpdb->esc_like( 'cuft_' ) . '%' ) ); // Clean up custom database tables $cuft_tables_to_remove = array( $wpdb->prefix . 'cuft_update_log', $wpdb->prefix . 'cuft_click_tracking', $wpdb->prefix . 'cuft_form_events', $wpdb->prefix . 'cuft_test_events' ); foreach ( $cuft_tables_to_remove as $cuft_table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Plugin's own tables; schema migration (uninstall) for the plugin's own table. $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $cuft_table ) ); } // Clean up scheduled events (hook names must match what CUFT_Cron_Manager, // the GitHub update checker, and the update-log migration actually schedule) wp_clear_scheduled_hook( 'cuft_check_updates' ); wp_clear_scheduled_hook( 'cuft_daily_cleanup' ); wp_clear_scheduled_hook( 'cuft_scheduled_health_check' ); wp_clear_scheduled_hook( 'cuft_gtg_health_check' ); // The click retention job also schedules a follow-up run with an argument, // which wp_clear_scheduled_hook() without arguments would leave behind. wp_unschedule_hook( 'cuft_click_retention' ); wp_clear_scheduled_hook( 'cuft_cleanup_orphaned_downloads' ); wp_clear_scheduled_hook( 'cuft_cleanup_update_logs' ); wp_clear_scheduled_hook( 'cuft_clear_update_progress' ); wp_clear_scheduled_hook( 'cuft_process_update' ); // Clean up any remaining plugin data (options, and their transient timeout // rows, that the explicit lists above might miss) // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin's own options (cuft_*); one-time uninstall cleanup, not cacheable. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE option_name LIKE %s', $wpdb->options, $wpdb->esc_like( 'cuft_' ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin's own transients (cuft_*); one-time uninstall cleanup, not cacheable. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE option_name LIKE %s', $wpdb->options, $wpdb->esc_like( '_transient_cuft_' ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin's own transients (cuft_*); one-time uninstall cleanup, not cacheable. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE option_name LIKE %s', $wpdb->options, $wpdb->esc_like( '_transient_timeout_cuft_' ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin's own site transients (cuft_*); one-time uninstall cleanup, not cacheable. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE option_name LIKE %s', $wpdb->options, $wpdb->esc_like( '_site_transient_cuft_' ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Plugin's own site transients (cuft_*); one-time uninstall cleanup, not cacheable. $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE option_name LIKE %s', $wpdb->options, $wpdb->esc_like( '_site_transient_timeout_cuft_' ) . '%' ) );