PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, February 17, 2022

[FIXED] How to display a custom message during WooCommerce checkout to customers who previously purchase products with order status of 'processing'

 February 17, 2022     checkout, orders, product, woocommerce, wordpress     No comments   

Issue

I will like to display a message on the checkout page notifying the customers that they have purchased this product in the past (the product they are about to purchase), but this message should only run if these conditions are met.

  1. Customer must be logged in
  2. User role is administrator or customer
  3. previously purchased product should still have order status of 'processing.'

So far, I have been able to get the first 2 conditions working fine:

function user_logged_in_product_already_bought() {

    global $woocommerce;

    if ( ! is_user_logged_in() ) return;
            

    $items = $woocommerce->cart->get_cart();

    $has_bought = false;

    foreach($items as $item => $values) { 
        if ( wc_customer_bought_product( '', get_current_user_id(), $values['data']->get_id() ) ) {
            $has_bought = true;
            break;
        }
    } 


    
    $user = wp_get_current_user();
$allowed_roles = array( 'administrator', 'customer' );
if ( array_intersect( $allowed_roles, $user->roles ) ) {
    
    if( $has_bought ){
        wc_print_notice( "You purchased this in the past. Buy again?", 'success' );
    }
}
        


}
add_action( 'woocommerce_before_checkout_form', 'user_logged_in_product_already_bought' );

Note: the reason I'm using the foreach is that users only purchase one product at a time (can't have more than a single appointment product in the cart)

But I don't know how to go about with the third condition. Any advice?


Solution

Your first 2 steps indeed work, for the 3rd step you will have to use a custom function which only checks for the order status 'processing'.

The advantage of this custom function is that it is much faster and lighter compared to going through all existing orders.

So you get:

function has_bought_items( $user_id = 0, $product_ids = 0 ) {
    // When empty, return false
    if ( empty ( $product_ids ) ) return false;

    global $wpdb;
    
    $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-processing' )
        AND pm.meta_key = '_customer_user'
        AND pm.meta_value = '$user_id'
        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;
}
 
function action_woocommerce_before_checkout_form() {
    // Customer must be logged in
    if ( ! is_user_logged_in() ) return;
    
    // Get current user
    $user = wp_get_current_user();
    
    // Allowed user roles
    $allowed_roles = array( 'administrator', 'customer' );
    
    // Compare
    if ( array_intersect( $allowed_roles, $user->roles ) ) {
        // WC Cart NOT null
        if ( ! is_null( WC()->cart ) ) {
            // Initialize
            $product_ids = array();
            
            // Loop through cart contents
            foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
                // Get product ID and push to array
                $product_ids[] = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
            }
            
            // Call function, and if true
            if ( has_bought_items( $user->ID, $product_ids ) ) {
                // Notice
                wc_print_notice( __( 'You purchased this in the past. Buy again?', 'woocommerce' ), 'success' );
            }
        }
    }
}
add_action( 'woocommerce_before_checkout_form', 'action_woocommerce_before_checkout_form' );

Result: a general message

enter image description here


Optional: Instead of displaying a general message, but showing this separately per product, you can use the woocommerce_checkout_cart_item_quantity hook

So you would get:

function has_bought_items( $user_id = 0, $product_ids = 0 ) {
    // When empty, return false
    if ( empty ( $product_ids ) ) return false;

    global $wpdb;
    
    $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-processing' )
        AND pm.meta_key = '_customer_user'
        AND pm.meta_value = '$user_id'
        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;
}
 
function filter_woocommerce_checkout_cart_item_quantity( $item_qty, $cart_item, $cart_item_key ) {
    // Customer must be logged in
    if ( ! is_user_logged_in() ) return;
    
    // Get current user
    $user = wp_get_current_user();
    
    // Allowed user roles
    $allowed_roles = array( 'administrator', 'customer' );
    
    // Initialize
    $message = '';
    
    // Compare
    if ( array_intersect( $allowed_roles, $user->roles ) ) {
        // Get product id
        $product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
        
        // Call function, and if true
        if ( has_bought_items( $user->ID, $product_id ) ) {
            $message = '<p>' . __( 'You purchased this in the past. Buy again?', 'woocommerce' ) . '</p>';
        }
    }

    // Return
    return $item_qty . $message;
}
add_filter( 'woocommerce_checkout_cart_item_quantity', 'filter_woocommerce_checkout_cart_item_quantity', 10, 3 );

Result: show separately by product

enter image description here


Note: the has_bought_items() function is based on Check if a user has purchased specific products in WooCommerce answer code

Related: Display message below product name on WooCommerce cart page if user has bought product before



Answered By - 7uc1f3r
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing