Search code examples
phpwordpresswoocommercecountnotice

Display different notices based on Customer order count in Woocommerce


I'm looking for a lightweight way to count all customer orders with "Completed" status and based on the order count, display different messages using wc_print_notice.

Doing the count works fine, but I'm hoping that someone has a more lightweight way of doing it.

Displaying the first message works, but it does not show the 2nd message (when complete orders are 2 or more).

The idea is to extend this into a total of 10 different messages and to provide the customer with various discount codes throughout their shopping on the site.

Hopefully, by looking at the code, you understand what I'm trying to achieve. So, what I'm asking for is a combination of TWO things;

  1. how do I make the elseif work so that it displays different messages and not all messages at the same time?

  2. is there a more lightweight way of counting the order total?

Here's my code:

add_action( 'woocommerce_before_my_account', 'shop_loyalty_program' );
add_action( 'woocommerce_before_shop_loop', 'shop_loyalty_program' );
add_action( 'woocommerce_before_single_product_summary', 'shop_loyalty_program' );

function shop_loyalty_program() {

    $customer = wp_get_current_user();

    // count how many orders by the customer with "completed" status
    // we only count the completed status since completed = paid
    $customer_orders = get_posts( array(
        'numberposts' => -1,
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        'post_type'   => 'shop_order',
        'post_status' => 'wc-completed' // only "completed" as completed = paid
    ) );


    // discount counter for our loyalty system
    $first_order = 0;
    $third_order = 2;

    // messages to be shown depending on how many completed orders

    // FIRST ORDER message when 0 orders exist
    $first_order_message = sprintf( 'Hey %1$s 😀 For your first order, we\'ll give you a 10 percent discount and with that we say - WELCOME to our store!', $customer->display_name, $first_order );


    // THIRD ORDER message when 2 orders exist
    $third_order_message = sprintf( 'Hey %1$s 😀 We noticed you\'ve placed more than %2$s orders with us – thanks for being a loyal customer!', $customer->display_name, $third_order );


    // discount control
    if ( count( $customer_orders ) >= $first_order ) {
        wc_print_notice( $first_order_message, 'notice' );
    }

    elseif ( count( $customer_orders ) >= $third_order ) {
        wc_print_notice( $third_order_message, 'notice' );
        }
    }

Solution

  • The following revisited code should work as expected (with a much more light SQL query for orders count):

    add_action( 'woocommerce_before_my_account', 'shop_loyalty_program' );
    add_action( 'woocommerce_before_shop_loop', 'shop_loyalty_program' );
    add_action( 'woocommerce_before_single_product_summary', 'shop_loyalty_program' );
    function shop_loyalty_program() {
        global $wpdb;
    
        // Get current WP User Object instance
        $user = wp_get_current_user();
    
        // Only for logged in users
        if( $user->ID == 0 ) return false;
    
        // Count customer orders with "Completed" status (Paid)
        $orders_count = $wpdb->get_var( "
            SELECT COUNT(ID) FROM {$wpdb->prefix}posts as p
            INNER JOIN {$wpdb->prefix}postmeta as pm ON p.ID = pm.post_id
            WHERE p.post_status LIKE 'wc-completed' AND p.post_type LIKE 'shop_order'
            AND pm.meta_key LIKE '_customer_user' AND pm.meta_value = {$user->ID}
        " );
    
         // FIRST ORDER Message (0 orders)
        if ( $orders_count == 0 ) {
            $message = sprintf( __("Hey %s 😀 For your first order, we'll give you a 10 %% discount and with that we say - WELCOME to our store!"), $user->display_name );
        }
        // TWO ORDERS AT LEAST Message (when 2 orders or more exist)
        elseif ( $orders_count >= 2 ) {
            $message = sprintf( __("Hey %s 😀 We noticed you've placed at least 2 orders with us – Thanks for being a loyal customer!"), $user->display_name );
        }
    
        // Display message
        if ( isset($message) ) {
            wc_print_notice( $message, 'notice' );
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and work.

    enter image description here


    enter image description here