Search code examples
phpwordpresswoocommerceproductorders

Hide product prices and add-to-cart buttons but not variations for unregistered users in WooCommerce


In my WooCommerce shop I want to hide the prices until the customer has logged in. I've got the following code working that does exactly that:

add_action('init','hide_price');
function hide_price(){
    if(!is_user_logged_in()){
        remove_action('woocommerce_after_shop_loop_item','woocommerce_template_loop_add_to_cart',10);
        remove_action('woocommerce_single_product_summary','woocommerce_template_single_add_to_cart',30);
        remove_action('woocommerce_single_product_summary','woocommerce_template_single_price',10);
        remove_action('woocommerce_after_shop_loop_item_title','woocommerce_template_loop_price',10);
        add_action('woocommerce_single_product_summary','print_login_to_see',31);
        add_action('woocommerce_after_shop_loop_item','print_login_to_see',11);
    }
}

function print_login_to_see(){
    echo '<a href="' . get_permalink(woocommerce_get_page_id('myaccount')) . '">' . __('Login to see prices','theme_name') . '</a>';
}

However this also removes the variation drop down and I would like to keep that.

Is there any direct way to keep the variation drop down menu but still hide the prices until the customer has logged in?

Thanks


Solution

  • Updated:

    You will need to separate shop and archives pages from single product pages. In single product pages you will target variable products to add and remove the specific hooked functions.

    Last thing, in your function print_login_to_see(), woocommerce_get_page_id() is obsolete and it's replaced by wc_get_page_id()

    So your code will look to this:

    // For product archives pages
    add_action( 'init', 'hide_product_archives_prices' );
    function hide_product_archives_prices(){
        if( is_user_logged_in() ) return;
    
        remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
        remove_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10) ;
        add_action ( 'woocommerce_after_shop_loop_item', 'print_login_to_see', 10 );
    }
    
    //
    add_action( 'woocommerce_single_product_summary', 'hide_single_product_prices', 1 );
    function hide_single_product_prices(){
        if( is_user_logged_in() ) return;
    
        global $product;
    
        remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
    
        if( ! $product->is_type('variable') ){
            remove_action('woocommerce_single_product_summary','woocommerce_template_single_add_to_cart', 30 );
            add_action( 'woocommerce_single_product_summary','print_login_to_see', 30 );
        } else {
            remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation', 10);
            remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
            add_action( 'woocommerce_single_variation', 'print_login_to_see', 20 );
        }
    }
    
    // Display a my account link 
    function print_login_to_see(){
        echo '<a href="' . get_permalink( wc_get_page_id( 'myaccount' ) ) . '" class="button">' . __('Login to see prices','theme_name') . '</a>';
    }
    

    Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

    This code is tested on WooCommerce 3+ and works.