skip to Main Content

I am trying to find a way to hide a product from the Woocommerce shop page. If the logged in user has already purchased said product.

I have already been able to block the user from purchasing again using woocommerce_is_purchasable, and woocommerce_variation_is_purchasable. But I would like to hide it all together not even shown to them in the shop page. I have been coming up empty on this one. So any help would be appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    Bhautik's answer is technically correct based on the question asked. Hide product if user bought before.

    However as mentioned in my question I'm already disabling purchase of said products using woocommerce_is_purchasable .

    Meaning the logic of what should be hidden is already in the software. Using his idea as a template I have made the answer more generic to operate off of woocommerce_is_purchasable . Meaning I only have to implement any conditional logic in that function and the shop will reflect by hiding said products (that are not purchasable).

    I am posting this as a second answer in case it helps others searching this problem. But will keep his as the selected answer to the question.

    add_action( 'woocommerce_product_query', 'hide_product_from_shop_page_if_user_already_purchased', 20 );
    
    function hide_product_from_shop_page_if_user_already_purchased( $query ) {
      //Get all the products in the store.
      $products = wc_get_products(['limit' => -1]);
    
      //Blank exclusion array. 
      $product_ids = array();
    
      //Check each product to see if it is purchasable or not.
      foreach($products as $product){
        if(!$product->is_purchasable()){
          //If product is not purchasable then add to exclusion array.
          $product_ids[] = $product->get_id();
        }
      }
        //Use array of id's to exclude products in the shop page.
        $query->set( 'post__not_in', $product_ids );
    }
    

  2. You can change the product query using the pre_get_posts action hook and then you can get current user products that they already purchased. pass all products id to post__not_in. check the below code. code will go active theme function.php file.

    add_action( 'pre_get_posts', 'hide_product_from_shop_page_if_user_already_purchased', 20 );
    
    function hide_product_from_shop_page_if_user_already_purchased( $query ) {
       
        if ( ! $query->is_main_query() ) return;
       
        if ( ! is_admin() && is_shop() ) {
    
            $current_user = wp_get_current_user();
            if ( 0 == $current_user->ID ) return;
           
            $customer_orders = get_posts( array(
                'numberposts' => -1,
                'meta_key'    => '_customer_user',
                'meta_value'  => $current_user->ID,
                'post_type'   => 'shop_order',
                'post_status' => array( 'wc-processing', 'wc-completed' ),
            ) );
           
            if ( ! $customer_orders ) return;
            
            $product_ids = array();
            
            foreach ( $customer_orders as $customer_order ) {
                $order = wc_get_order( $customer_order->ID );
                if( $order ){
                    $items = $order->get_items();
                    foreach ( $items as $item ) {
                        $product_id    = $item->get_product_id();
                        $product_ids[] = $product_id;
                    }
                }
            }
    
            $product_ids = array_unique( $product_ids );
    
            $query->set( 'post__not_in', $product_ids );
        }
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search