Check if a customer has purchased certain products on WooCommerce

I need to check if a customer has bought a specific product before in WooCommerce.

The fact is that the customer will not be able to purchase products "c", "d", "e" if they have not previously purchased product "a" or "b".

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

If they have not previously purchased "a" or "b", they are not allowed to purchase "c", "d", "e", and the purchase button is deactivated.

How can i achieve this?

Thank.

+4
source share
4 answers

Updated (compatibility for Woocommerce 3+)

Yes, perhaps a conditional function record that returns true if the current customer has already purchased specific product identifiers. This code continues in the functions.php file of your active child theme or theme.

Here is the conditional function:

function has_bought_items() {
    $bought = false;

    // Set HERE ine the array your specific target product IDs
    $prod_arr = array( '21', '67' );

    // Get all customer orders
    $customer_orders = get_posts( array(
        'numberposts' => -1,
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        'post_type'   => 'shop_order', // WC orders post type
        'post_status' => 'wc-completed' // Only orders with status "completed"
    ) );
    foreach ( $customer_orders as $customer_order ) {
        // Updated compatibility with WooCommerce 3+
        $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
        $order = wc_get_order( $customer_order );

        // Iterating through each current customer products bought in the order
        foreach ($order->get_items() as $item) {
            // WC 3+ compatibility
            if ( version_compare( WC_VERSION, '3.0', '<' ) ) 
                $product_id = $item['product_id'];
            else
                $product_id = $item->get_product_id();

            // Your condition related to your 2 specific products Ids
            if ( in_array( $product_id, $prod_arr ) ) 
                $bought = true;
        }
    }
    // return "true" if one the specifics products have been bought before by customer
    return $bought;
}

This code has been verified and works.


APPLICATION:
For example, you can use it in some WooCommerce templates that you previously copied into your active child theme or theme:

, ():

// Replace the numbers by your special restricted products IDs
$restricted_products = array( '20', '32', '75' );

// compatibility with WC +3
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;

// customer has NOT already bought a specific product for this restricted products
if ( !has_bought_items() && in_array( $product_id, $restricted_products ) ) { 

    // Displaying an INACTIVE add-to-cart button (With a custom text, style and without the link).
    // (AND optionally) an explicit message for example.

// ALL OTHER PRODUCTS OR RESTRICTED PRODUCTS IF COSTUMER HAS ALREADY BOUGHT SPECIAL PRODUCTS
} else { 

    // place for normal Add-To-Cart button code here
}

add-to-cart :

<?php
/**
 * Loop Add to Cart
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/loop/add-to-cart.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see         https://docs.woocommerce.com/document/template-structure/
 * @author      WooThemes
 * @package     WooCommerce/Templates
 * @version     2.5.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

global $product;

// Replace the numbers by your special restricted products IDs
$restricted_products = array( '37', '53', '70' );

// compatibility with WC +3
$product_id = method_exists( $product, 'get_id' ) ? $product->get_id() : $product->id;

if ( !has_bought_items() && in_array( $product_id, $restricted_products ) ) {

    echo '<a class="button greyed_button">' . __("Disabled", "your_theme_slug") . '</a>';
    echo '<br><span class="greyed_button-message">' . __("Your message goes here…", "your_theme_slug") . '</span>';

} else {

echo apply_filters( 'woocommerce_loop_add_to_cart_link',
    sprintf( '<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>',
        esc_url( $product->add_to_cart_url() ),
        esc_attr( isset( $quantity ) ? $quantity : 1 ),
        esc_attr( $product_id ),
        esc_attr( $product->get_sku() ),
        esc_attr( isset( $class ) ? $class : 'button' ),
        esc_html( $product->add_to_cart_text() )
    ),
$product );

}

greyed_button style.css . greyed_button-message.

+5

:

woocommerce, woocommerce_is_purchasable

,

  • , , 2.6 +, woocommerce wc_customer_bought_product, , , , docs ​​, , , ;

    function cmk_check_product_brought( $ids=array() ) {
        if ( ! $ids ) return false;
        foreach ( $ids as $product => $id ) {
            if ( wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $id ) ) {
                return true;
            }
        }
    }
    

, , , , , , , ID

function cmk_product_ordered( $id ) {
    // Get All order of current user
    $orders = get_posts( array(
        'numberposts' => -1,
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        'post_type'   => wc_get_order_types( 'view-orders' ),
        'post_status' => array_keys( wc_get_order_statuses() )
    ) );

    if ( !$orders ) return false; // return if no order found

    $all_ordered_product = array(); // store all products ordered by ID in an array

    foreach ( $orders as $order => $data ) { // Loop through each order
        $order_data = new WC_Order( $data->ID ); // create new object for each order
        foreach ( $order_data->get_items() as $key => $item ) {  // loop through each order item
            // store in array with product ID as key and order date a value
            $all_ordered_product[ $item['product_id'] ] = $data->post_date; 
        }
    }
    // check if defined ID is found in array
    if ( isset( $all_ordered_product[ $id ] ) ) return true;
    else return false;
}
  1. , , , woocommerce_is_purchasable, , - , ,

$required_purchased $conditional_purchase.

function cmk_disable_product_purchase( $purchasable, $product ) {

    // array of products required to be purchase first
    $required_purchased = array( 1, 2);

    // array of restricted/conditional products to be purchase
    $conditional_purchase = array( 3,4,5);

    // Get the ID for the current product
    $product_id = $product->is_type( 'variation' ) ? $product->variation_id : $product->id;

    //return default $purchasable if current product ID is not in restricted array
    if ( !in_array($product_id, $conditional_purchase)) return $purchasable;

    /**
     ** Check if one required products has been purchase;
     **/

    // using cmk_check_product_brought() function, return false if product is not purchase
    if ( ! cmk_check_product_brought( $required_purchased ) ) $purchasable = false;

    // using cmk_product_ordered() function, you can use this instead
    /*if ( cmk_product_ordered( 1 )  || cmk_product_ordered( 2 ) ) {
        $purchasable = $purchasable; //return default if one product is purchased
    } else {
        $purchasable = false;
    }*/

    // Double-check for variations: if parent is not purchasable, then variation is not
    if ( $purchasable && $product->is_type( 'variation' ) ) {
        $purchasable = $product->parent->is_purchasable();
    }

    return $purchasable;
}
add_filter( 'woocommerce_variation_is_purchasable', 'cmk_disable_product_purchase', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'cmk_disable_product_purchase', 10, 2 );

( " " ). , , cmk_disable_product_purchase, woocommerce_single_product_summary , .

+2

woocommerce wc_customer_bought_product.

.

+2

, , woocommerce (2.4 +)

, woocommerce wc_customer_bought_product :

2 $user_id $product_ids:

  • $user_id ( );
  • $product_ids ()

:

function has_bought_items( $user_id = 0,  $product_ids = 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() );

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

function.php ( ), .

Woocommerce 3+ ( ).


:

1 ( ): , ( )

// 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>";

2 ( $user_id) , ( )

// 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>";

$user_id , false.

3 ( ): ,

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

4 ( $user_id) ,

// Define the user ID
$user_id = 85;

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

$user_id , false.

+1

Source: https://habr.com/ru/post/1650185/


All Articles