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 CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=21885
 * @author        Rodolfo Melogli
 * @compatible    WC 3.3.4
 */

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 );
}

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')) . "'
Share:

Leave a Reply