Search code examples
phpsqlwordpresswoocommercereview

Check if customer wrote a review for a product in Woocommerce


This code will check if the customer is logged in, if he/she purchased the product and if those statements are true, it will display a message.

I would like to include one more check before the message is shown and that is if the customer already left a review/ wrote a review for the product and if so, do not show the message.

In other words, if the customer did not write a review for the product, show message. If customer left a review, do not show message.

Here is the code:

add_action( 'woocommerce_before_single_product_summary', 'woo_review_discount_message');
function woo_review_discount_message() {
if ( is_user_logged_in() ) {
global $product;
$current_user = wp_get_current_user();
if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->get_id() && $order->status->complete ) ) echo '<div class="user-bought"><span style="color:#CA364D;font-weight:bold;font-size:18px;"><i class="wishlist-icon icon-heart-o"></i></span> Hi ' . $current_user->first_name . '! Please write a review below.</a></div>';
}
}

Any help on this is very much appreciated.


Solution

  • To check if a customer has posted a review on the current product, you will use this custom conditional function (using a very light SQL query):

    // Utility function to check if a customer has posted a review in a product
    function has_reviewed_product( $product_id ) {
        global $wpdb;
    
        $user = wp_get_current_user();
    
        if( $user->ID == 0 )
            return false;
    
        // Count the number of products
        $count = $wpdb->get_var( "
            SELECT COUNT(comment_ID) FROM {$wpdb->prefix}comments
            WHERE comment_post_ID = $product_id
            AND comment_author_email = '{$user->user_email}'
        " );
    
        return $count > 0 ? true : false;
    }
    

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

    So in your code (from this answer) you will use it as following:

    // Utility function to check if a customer has bought a product (Order with "completed" status only)
    function customer_has_bought_product( $product_id, $user_id = 0 ) {
        global $wpdb;
        $customer_id = $user_id == 0 || $user_id == '' ? get_current_user_id() : $user_id;
        $status      = 'wc-completed';
    
        if( ! $customer_id )
            return false;
    
        // Count the number of products
        $count = $wpdb->get_var( "
            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 = '$status'
            AND pm.meta_key = '_customer_user'
            AND pm.meta_value = $customer_id
            AND woim.meta_key IN ( '_product_id', '_variation_id' )
            AND woim.meta_value = $product_id
        " );
    
        // Return a boolean value if count is higher than 0
        return $count > 0 ? true : false;
    }
    
    add_action( 'woocommerce_before_single_product_summary', 'woo_review_discount_message');
    function woo_review_discount_message() {
        global $product;
    
        if ( customer_has_bought_product( $product->get_id() ) && ! $product->is_type('variable') && ! has_reviewed_product( $product->get_id() ) ) {
            $user = wp_get_current_user();
            echo '<div class="user-bought"><span style="color:#CA364D;font-weight:bold;font-size:18px;"><i class="wishlist-icon icon-heart-o"></i></span> Hi ' . $user->first_name . '! Please write a review below.</a></div>';
        }
    }
    

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

    Related answer: Display a custom text if user has already bought the current product In Woocommerce