You can do that making a custom sql query embedded in a function, using WPDB
Class, this way:
function get_completed_orders_for_user_from_product_id( $product_id, $user_id = 0 ) {
global $wpdb;
$order_status = 'wc-completed';
// If optional $user_id argument is not set, we use the current user ID
$customer_id = $user_id === 0 ? get_current_user_id() : $user_id;
// Return customer orders IDs containing the defined product ID
return $wpdb->get_col( $wpdb->prepare("
SELECT DISTINCT woi.order_id
FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}postmeta pm
ON p.ID = pm.post_id
INNER JOIN {$wpdb->prefix}woocommerce_order_items woi
ON p.ID = woi.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta woim
ON woi.order_item_id = woi.order_item_id
WHERE p.post_status = '%s'
AND pm.meta_key = '_customer_user'
AND pm.meta_value = '%d'
AND woim.meta_key IN ( '_product_id', '_variation_id' )
AND woim.meta_value LIKE '%d'
ORDER BY woi.order_item_id DESC
", $order_status, $customer_id, $product_id ) );
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
USAGE with wp_delete_post()
to remove related orders containing a specific product (id: 246014
):
// Get all orders containing 246014 product ID for the current user
$orders_ids = get_completed_orders_for_user_from_product_id( 246014 );
// Checking that, the orders IDs array is not empty
if( count($orders_ids) > 0 ) {
// Loop through orders IDs
foreach ( $orders_ids as $order_id ) {
// Delete order post data
wp_delete_post( $order_id, true );
}
// Add the order(s) ID(s) in user meta (example)
update_user_meta( get_current_user_id(), 'item_246014', implode( ',', $orders_ids ) );
}
Related threads: