I am new to WooCommerce and wanted to check if a user has purchased a specific product (product id # 514) within the past 60 days. This is a product I let people purchase monthly, so it will reoccur a lot. I wanted to just see if they purchased a recent one (that I consider active)
The way I was thinking of doing it now was:
- Get all orders from a user
- For each order, check if it occurred in the past 60 days
and and get all products for this order
- For each product, see if the id is x
While I'm sure this will work, I have a funny feeling there is a really concise get_posts(apply_filters( query that will save me some looping time.
Would anyone be wiling to share a few ideas or a solution?
Thanks!
Here is a conditional function partially based on the built-in woocommerce function wc_customer_bought_product
source code query:
There is an 3 optional argument $user_id
, $product_ids
and $days
:
$user_id
will allow you to specify a defined user ID (when is not used for current logged in user);
$product_ids
(string or an array) will allow to specify defined product Ids to check
$days
will allow you to specify the number of days to search for (or the period if you prefer)…
The code function:
function has_bought_multi( $user_id = 0, $product_ids = 0, $days = 0 ) {
global $wpdb;
$customer_id = $user_id == 0 || $user_id == '' ? get_current_user_id() : $user_id;
$statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() );
$date = date('Y-m-d H:i:s', strtotime("-$days day") );
if ( is_array( $product_ids ) )
$product_ids = implode(',', $product_ids);
if ( $product_ids != ( 0 || '' ) )
$query_line = "AND woim.meta_value IN ($product_ids)";
else
$query_line = "AND woim.meta_value != 0";
// Count the number of products
$product_count_query = $wpdb->get_col( "
SELECT COUNT(woim.meta_value) FROM {$wpdb->prefix}posts AS p
INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON p.ID = woi.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
AND p.post_date > '$date'
AND pm.meta_key = '_customer_user'
AND pm.meta_value = $customer_id
AND woim.meta_key IN ( '_product_id', '_variation_id' )
$query_line
" );
// Set the count in a string
$count = reset($product_count_query);
// Return a boolean value if count is higher than 0
return $count > 0 ? true : false;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works.
Similar answer: Check if a customer has purchased a specific products in WooCommerce
USAGE EXAMPLE (Customer is logged in):
Detecting if current user has bought your product id # 514 in past 60 days:
if( has_bought_multi( '', 514, 60 ) ){
echo "<p>Customer has bought product id # 514 in past 60 days</p>";
// do something
} else {
echo "<p>Customer <strong>HAS NOT</strong> bought product id # 514 in past 60 days</p>";
// do something else
}