Home » WooCommerce: Check if User Has Bought Product in the Last 365 Days

WooCommerce: Check if User Has Bought Product in the Last 365 Days

by Tutor Aspire

A few snippets ago we introduced the magic WooCommerce inbuilt function “wc_customer_bought_product” – automatically, with a single line of PHP, you can find out if the user has already purchased a product ID.

But when building my new #BloomerArmada section, I had to know if a user purchased a product ID in the last 365 days… so I rewrote the function, changed its name and added a little edit to it – easy peasy!

The original “wc_customer_bought_product” function in WooCommerce

PHP Snippet: Check if User Has Bought Product ID in the Last 365 Days

/**
 * @snippet       New version of "wc_customer_bought_product" function (last 365 days)
 * @how-to        Get tutoraspire.com FREE
 * @author        Tutor Aspire
 * @compatible    WooCommerce 5
 * @donate $9     https://www.tutoraspire.com
 */

function wc_customer_bought_product_last_365( $customer_email, $user_id, $product_id ) {
   global $wpdb;

$result = apply_filters( 'woocommerce_pre_customer_bought_product', null, $customer_email, $user_id, $product_id );

if ( null !== $result ) {
return $result;
}

$transient_name = 'wc_cbp_' . md5( $customer_email . $user_id . WC_Cache_Helper::get_transient_version( 'orders' ) );

if ( false === ( $result = get_transient( $transient_name ) ) ) {
$customer_data = array( $user_id );

if ( $user_id ) {
$user = get_user_by( 'id', $user_id );

if ( isset( $user->user_email ) ) {
$customer_data[] = $user->user_email;
}
}

if ( is_email( $customer_email ) ) {
$customer_data[] = $customer_email;
}

$customer_data = array_map( 'esc_sql', array_filter( array_unique( $customer_data ) ) );
$statuses      = array_map( 'esc_sql', wc_get_is_paid_statuses() );

if ( sizeof( $customer_data ) == 0 ) {
return false;
}

$result = $wpdb->get_col( "
SELECT im.meta_value FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
WHERE p.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' )
            AND p.post_date > '" . date('Y-m-d', strtotime('-365 days')) . "'
AND pm.meta_key IN ( '_billing_email', '_customer_user' )
AND im.meta_key IN ( '_product_id', '_variation_id' )
AND im.meta_value != 0
AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
" );
$result = array_map( 'absint', $result );

set_transient( $transient_name, $result, DAY_IN_SECONDS * 30 );
}
return in_array( absint( $product_id ), $result );
}

[/php]

Now that the “wc_customer_bought_product_last_year” exists in your functions.php, you can use it in a snippet or shortcode! The only major difference with “wc_customer_bought_product” is this line:

AND p.post_date > '" . date('Y-m-d', strtotime('-365 days')) . "'

You may also like