Marie
Marie

Reputation: 23

How to use wc_customer_bought_product function to check if customer bought product in an array

First of all, I am a beginner and new to php so please forgive my ignorance. I asked my first question on stackoverflow today and somebody was kind enough to provide a great solution, so I am giving this another try.

I am trying to use a function to check if a customer bought a product inside an array of product ids as in his account pages when logged in I need to display a different menu if he bought product from array A or product from array B, array C, you get it. I would like to create a different function for each array of product ids and associate it with a different shortcode.

I have found the wc_customer_bought_product_function in the woocommerce functions reference, which is written like this :

/**
* Checks if a user (by email) has bought an item
*
* @access public
* @param string $customer_email
* @param int $user_id
* @param int $product_id
* @return bool
*/
function wc_customer_bought_product( $customer_email, $user_id, $product_id ) {
    global $wpdb;
 
    $emails = array();

    if ( $user_id ) {
        $user     = get_user_by( 'id', $user_id );
        $emails[] = $user->user_email;
    }

    if ( is_email( $customer_email ) ) {
        $emails[] = $customer_email;
    }

    if ( sizeof( $emails ) == 0 ) {
        return false;
    }

    return $wpdb->get_var(
        $wpdb->prepare( "
            FROM {$wpdb->prefix}woocommerce_order_items as order_items
            LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta ON order_items.order_item_id = itemmeta.order_item_id
            LEFT JOIN {$wpdb->postmeta} AS postmeta ON order_items.order_id = postmeta.post_id
            LEFT JOIN {$wpdb->posts} AS posts ON order_items.order_id = posts.ID
            WHERE
            posts.post_status IN ( 'wc-completed', 'wc-processing' ) AND
            itemmeta.meta_value  = %s AND
            itemmeta.meta_key    IN ( '_variation_id', '_product_id' ) AND
            postmeta.meta_key    IN ( '_billing_email', '_customer_user' ) AND
            (
                postmeta.meta_value  IN ( '" . implode( "','", array_unique( $emails ) ) . "' ) OR
                (
                    postmeta.meta_value = %s AND
                    postmeta.meta_value > 0
                )
            )
         ", $product_id, $user_id
      )
   );
}

So I tried to use it to achieve what I wanted by transforming just the last parameter:

// Create function to check if client bought a product from array A
function check_is_category_A_customer()
{
    global $woocommerce;
    $user_id = get_current_user_id();
    $customer_email = $current_user->email;

    if (wc_customer_bought_product( $customer_email, $user_id, $product_id=array ('2258', '2253',     
'2242')))

        return true;

    return false;
}

// Create shortcode to display menu for customers cat A
add_shortcode('CATA','check_cat_bought_A');
function check_cat_bought_A($atts,$content=""){
    if( check_is_category_A_customer() ){
        return do_shortcode($content);
    }
}

But it did not work. When I use the shortcode the menu no longer appears, but it does not show once I bought a product which id is in the array.

I tried this version of the function based on another example:

function check_is_category_A_customer()
{
    global $woocommerce;
    $user_id = get_current_user_id();
    $customer_email = $current_user->email;

    if ( '' !=wc_customer_bought_product( $customer_email, $user_id, $product_id=array ('2258',    
'2253', '2242'), true))

        return true;

    return false;
}

But that did not work either. The shortcode no longer has effect, the menu appears in all situations.

I wrote this using different functions I took as models and information I stumbled upon, and I probably made terrible mistakes, because it is not working. If someone has any idea of what I did wrong or how to achieve this goal differently, that would be a huge help! Thank you.

Upvotes: 1

Views: 11984

Answers (3)

Marie
Marie

Reputation: 23

So David helped me get on the right track and I should have known how to pass 1 product id at a time inside the same function but I didn't.

After some research and study, I wrote a new function using else if statements for each product id, tested it, and so far it is working.

So, even if using an array or a category id would have been more practical (but I don't know how to do it, yet) I am sharing this solution for other people who might wanna achieve the same goal :

// Create function to check if client bought a product from array A
function check_is_category_A_customer()
{
    global $woocommerce;
    $user_id = get_current_user_id();
    $current_user= wp_get_current_user();
    $customer_email = $current_user->email;

    if ( wc_customer_bought_product( $customer_email, $user_id,'2258')) {
        return true;
    } else if ( wc_customer_bought_product( $customer_email, $user_id,'2253')) {
        return true;
    } else if ( wc_customer_bought_product( $customer_email, $user_id,'2242')) {
        return true;
    }

    return false;
}

// Create shortcode to display menu for customers cat A
add_shortcode('CATA','check_cat_bought_A');
function check_cat_bought_A($atts,$content=""){
    if( check_is_category_A_customer() ){
        return do_shortcode($content);
    }
}

Thanks again to David for pointing the direction :) Of course if someone has a better solution, or sees any mistakes in this, please speak up.

Upvotes: 0

Mahdi Jafarzadeh
Mahdi Jafarzadeh

Reputation: 1

I've used this and it worked:

function has_bought_items($product_ids)
{
    global $woocommerce;
    $user_id = get_current_user_id();
    $current_user = wp_get_current_user();
    $customer_email = $current_user->email;
    $ex = false;
    
    foreach($product_ids as $item):
        if ( wc_customer_bought_product( $customer_email, $user_id, $item) )
            $ex = true;
    endforeach; 
    return $ex;
}

Upvotes: 0

David
David

Reputation: 5937

function check_is_category_A_customer(array $product_ids)
{
    $product_ids= array ('2258','2253','2242');//for testing
    global $woocommerce;
    $user_id = get_current_user_id();
    $current_user= wp_get_current_user();
    $customer_email = $current_user->email;


    foreach($product_ids as $item):
        if ( wc_customer_bought_product( $customer_email, $user_id, $item) )
           return true;
    endforeach; 

    return false;
}

You were not setting the $current_user object, see above for the correction.

Upvotes: 3

Related Questions