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.
Lighter and improved code version in HERE that handle multiple product IDs
Updated (compatibility for Woocommerce 3+)
Yes it's possible, writing a conditional function that returns "true" if current customer has already bought specifics defined products IDs. This code goes on function.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 is tested and works.
USAGE:
For example, you can use it in some WooCommerce templates that you will have previously copied to your active child theme or theme:
add-to-cart
button is loop/add-to-cart.php
. add-to-cart
button are in single-product/add-to-cart
folder depending on your product types.Here is an example that you could use in those templates (above):
// 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
}
And here the complete applied example to add-to-cart
button template on Shop page:
<?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 );
}
You will style the inactive button with greyed_button
class in the style.css
file of your active child theme or theme. Same thing for the message with greyed_button-message
class.