Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a user has purchased specific products in WooCommerce

I need to check if a customer has purchased a specific product earlier in WooCommerce.

The case is this: The customer shall not be able to purchase product "c", "d", "e" unless they have purchased product "a" or "b" at an earlier time.

If the customer has purchased product "a" or "b" earlier, then the purchase button of product "c", "d" and "e" is activated and they are allowed to buy them.

If they haven´t purchased "a" or "b" earlier, they will not be allowed to purchase "c", "d", "e" and the purchase button is deactivated.

How can I achieve this?

Thanks.

like image 891
alegjos Avatar asked Aug 04 '16 14:08

alegjos


People also ask

How do I know if an item is on sale WooCommerce?

You can use following to check if product has sale price: $sale_price = get_post_meta( $product_id, '_sale_price', true); If the $sale_price is greater than 0 and not empty, the product is on sale.

How do I check stock in WooCommerce?

If the 'Stock display format' option on WooCommerce → Settings → Products → Inventory is set to display the quantity remaining in stock, then every product will have detailed stock information. In stock products will display the exact number remaining in stock.


2 Answers

The built-in woocommerce function wc_customer_bought_product can also be used in this case.

See function usage here.

like image 187
Tim Avatar answered Oct 28 '22 22:10

Tim


2020 update: Now handles guest users from their billing email.

New version compact, lighter, faster and compatible with all versions of woocommerce (from version 2.4 and above)

This is a new enhanced and lighter conditional function partially based on built-in woocommerce function wc_customer_bought_product source code.

There are 2 optional arguments:

  • $user_var will allow you to:
  • specify a defined user ID (when is not used for current logged in user)
  • or the billing email for guests users;
  • $product_ids (array) will allow to specify one or multiple product Ids to check

Here is that code:

function has_bought_items( $user_var = 0,  $product_ids = 0 ) {
    global $wpdb;
    
    // Based on user ID (registered users)
    if ( is_numeric( $user_var) ) { 
        $meta_key     = '_customer_user';
        $meta_value   = $user_var == 0 ? (int) get_current_user_id() : (int) $user_var;
    } 
    // Based on billing email (Guest users)
    else { 
        $meta_key     = '_billing_email';
        $meta_value   = sanitize_email( $user_var );
    }
    
    $paid_statuses    = array_map( 'esc_sql', wc_get_is_paid_statuses() );
    $product_ids      = is_array( $product_ids ) ? implode(',', $product_ids) : $product_ids;

    $line_meta_value  = $product_ids !=  ( 0 || '' ) ? 'AND woim.meta_value IN ('.$product_ids.')' : 'AND woim.meta_value != 0';

    // Count the number of products
    $count = $wpdb->get_var( "
        SELECT COUNT(p.ID) 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-", $paid_statuses ) . "' )
        AND pm.meta_key = '$meta_key'
        AND pm.meta_value = '$meta_value'
        AND woim.meta_key IN ( '_product_id', '_variation_id' ) $line_meta_value 
    " );

    // Return true if count is higher than 0 (or false)
    return $count > 0 ? true : false;
}

Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.

This code is tested on WooCommerce 3+ and works (It should work on previous versions too).


USAGE EXAMPLES:

Example 1 (logged in customer): Detecting if current user has bought one of the defined products (product Ids needs to be an array)

// Define the targeted Products IDs
$product_ids = array( 38, 41, 85, 95 );

if( has_bought_items( '', $product_ids ) )
    echo "<p>You have already purchased one of this products</p>";
else
    echo "<p>You have not yet purchased one of this products</p>";

Example 2 (for a defined user id) Detecting if the defined user has bought one of the defined products (product Ids needs to be set in an array)

// Define the user ID
$user_id = 85;

// Define the targeted Products IDs
$product_ids = array( 38, 41, 85, 95 );

if( has_bought_items( $user_id, $product_ids ) )
    echo "<p>This user have already purchased one of this products</p>";
else
    echo "<p>This user have not yet purchased one of this products</p>";

If the $user_id is not defined and the current user is not logged in, this function will return false.

Example 3 (for guest user) Detecting if guest user has bought one of the defined products from his billing email (product Ids needs to be set in an array)

// Define guest Billing email (string)
$user_email = '[email protected]';

// Define the targeted Products IDs
$product_ids = array( 38, 41, 85, 95 );

if( has_bought_items( $user_email, $product_ids ) )
    echo "<p>This user have already purchased one of this products</p>";
else
    echo "<p>This user have not yet purchased one of this products</p>";

If the $user_id is not defined and the current user is not logged in, this function will return false.

Example 4 (logged in customer): Detecting if current user has already made a purchase

if( has_bought_items() )
    echo '<p>You have already made a purchase</p>';
else
    echo '<p>Welcome, for your first purchase you will get a discount of 10%</p>';

Example 5 (Defining the user id) - Detecting if the defined user has already made a purchase

// Define the user ID
$user_id = 85;

if( has_bought_items( $user_id ) )
        echo '<p>customer have already made a purchase</p>';
    else
        echo '<p>Customer with 0 purshases</p>';

Now, if user id is equal to 0 and the current user is not logged in, this function will return false (if no billing email is defined for guest users).

like image 34
LoicTheAztec Avatar answered Oct 28 '22 22:10

LoicTheAztec