On my site (using Woocommerce 3.2.6), I want to hide "Add to Cart" button only for logged in users.
I have this code:
add_action('init', 'hide_price_add_cart_logged_in');
function hide_price_add_cart_logged_in() {
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 );
}
}
EDIT: Someone suggested me to use this:
add_action('init', 'hide_price_add_cart_logged_in');
function hide_price_add_cart_logged_in() {
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 );
return WooCommerce::instance();
}
}
But that did not work...
I have inserted this code into functions.php file into my theme, but it don't seems to make any change. I still see add to cart button when check some product.
How to remove that button? Where is error in my function?
You should try this instead:
add_action( 'woocommerce_after_shop_loop_item', 'remove_loop_add_to_cart_button', 1 );
function remove_loop_add_to_cart_button() {
// Only for logged in users
if( ! is_user_logged_in() ) return;
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
}
add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_button', 1 );
function remove_add_to_cart_button() {
// Only for logged in users
if( ! is_user_logged_in() ) return;
global $product;
// For variable product types (keeping attribute select fields)
if( $product->is_type( 'variable' ) ) {
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
}
// For all other product types
else {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works
Instead of hiding add to cart button on archives pages (like shop) you could replace it with a button linked to the product. So the code will be instead:
// Replacing the button add to cart by a link to the product in Shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_link', 'replace_loop_add_to_cart_button', 10, 2 );
function replace_loop_add_to_cart_button( $button, $product ) {
// Only for logged in users
if( ! is_user_logged_in() ) return;
$button_text = __( "View product", "woocommerce" );
$button = '<a class="button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
return $button;
}
add_action( 'woocommerce_single_product_summary', 'remove_add_to_cart_button', 1 );
function remove_add_to_cart_button() {
// Only for logged in users
if( ! is_user_logged_in() ) return;
global $product;
// For variable product types (keeping attribute select fields)
if( $product->is_type( 'variable' ) ) {
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
}
// For all other product types
else {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );;
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works
add_action( 'init', 'shessvy_hide_price_add_cart_not_logged_in' );
function shessvy_hide_price_add_cart_not_logged_in() {
if ( ! is_user_logged_in() ) {
add_filter( 'woocommerce_is_purchasable', '__return_false');
add_action( 'woocommerce_single_product_summary', 'shessvy_print_login_to_see', 31 );
add_action( 'woocommerce_after_shop_loop_item', 'shessvy_print_login_to_see', 11 );
add_action( 'woocommerce_simple_add_to_cart', 'shessvy_print_login_to_see', 30 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
}
function shessvy_print_login_to_see() {
echo '' . __('Login to add this item to your cart', 'theme_name') . '';
}
Related
I want to hide the price for the users that aren't logged on to my site. I managed to hide the price for single products and for variable products. In variable products that have different prices for single variants, this code does not work. How can I fix it?
add_action( 'init', 'nascondi_prezzo_se_non_loggato' );
function nascondi_prezzo_se_non_loggato() {
if ( ! is_user_logged_in() ) {
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 );
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
add_filter( 'woocommerce_is_purchasable', '__return_false' );
add_action( 'woocommerce_single_product_summary', 'mostra_testo_alternativo', 31 );
add_action( 'woocommerce_after_shop_loop_item', 'mostra_testo_alternativo', 11 );
}
}
function mostra_testo_alternativo() {
echo '<div class="button-prezzo">' . __( 'Accedi per vedere i prezzi', 'JupiterX' ) . '</div>';
}
This is the code that I used and that only partially solves the problem.
Try the code snippet below. The price is set to an empty string that won't display the price for users who aren't logged in. This uses the filter woocommerce_get_price_html which returns the code that outputs the price. In the empty string, add what you want displayed instead of the price.
add_filter( 'woocommerce_get_price_html', 'hide_price_not_logged_in', 10, 2 );
function hide_price_not_logged_in( $price, $product ) {
if ( ! is_user_logged_in() ) {
$price = '';
}
return $price;
}
To help everyone: I use the code above that hides the price and part of my code to hide the add to cart button
add_filter( 'woocommerce_get_price_html', 'hide_price_not_logged_in', 10, 2 );
function hide_price_not_logged_in( $price, $product ) {
if ( ! is_user_logged_in() ) {
$price = '';
}
return $price;
}
add_action( 'init', 'nascondi_prezzo_se_non_loggato' );
function nascondi_prezzo_se_non_loggato() {
if ( ! is_user_logged_in() ) {
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
add_filter( 'woocommerce_is_purchasable', '__return_false' );
add_action( 'woocommerce_single_product_summary', 'mostra_testo_alternativo', 31 );
add_action( 'woocommerce_after_shop_loop_item', 'mostra_testo_alternativo', 11 );
}
}
function mostra_testo_alternativo() {
echo '<div class="button-prezzo">' . __( 'Accedi per vedere i prezzi', 'your-theme-name' ) . '</div>';
}
For non logged in users I use the php snippet below. Visitors see a "Where to buy" button and a "Ask a demo" button instead of the Woocommerce Add to cart button. Logged in users / customers with a specific role gets the "Add to cart button" instead of the 2 buttons for not logged in customers. There is also a viewonly role who has a login and can download materials but don't have an Add to cart button on single product pages. However with the code below the viewonly users can still see the regular Add to cart button. Any idea how i can fix this?
add_action( 'init', 'disable_add_to_cart' );
function disable_add_to_cart() {
if ( !is_user_logged_in() OR $user_role == 'viewonly' ) {
add_filter( 'woocommerce_is_purchasable', '__return_false');
}
function hide_price( $price ) {
if ( !is_user_logged_in() ) {
$price = '';
$user_role = 'viewonly';
}
return $price;
}
add_filter( 'woocommerce_get_price_html', 'hide_price' );
add_filter( 'woocommerce_cart_item_price', 'hide_price' );
add_filter( 'woocommerce_cart_item_subtotal', 'hide_price' );
add_filter( 'woocommerce_order_formatted_line_subtotal', 'hide_price' );
add_filter( 'woocommerce_cart_subtotal', 'hide_price' );
add_filter( 'woocommerce_cart_totals_order_total_html', 'hide_price' );
}
add_action( 'init', 'hide_price_add_cart_not_logged_in' );
function print_login_to_see() {
echo '<div class="var-prod-container"><a class="btn-where-to-buy" href="/where-to-buy">' . __('Where to buy', 'company') . '</a>';
echo '<a class="btn-ask-a-demo" href="/#uagb-tabs__tab1">' . __('Ask a demo', 'company') . '</a>';
echo '</div>';
}
function hide_price_add_cart_not_logged_in() {
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 );
}
}```
To replace the buttons, all you have to do is use the actions you removed and place your button function into it. I am using the author role for testing purposes, but this will check if the user is not logged in and what their role is. Then, remove the add to cart button from the shop page loop and also the single product page. Once they are removed, we add what we want into where we just removed the button from.
If you need to, just change the conditions within the if statement and that will change who sees which set of buttons.
Now all you have to do is style your buttons the way you'd like them!
$user_role = wp_get_current_user(
function print_login_to_see() {
echo '<div class="var-prod-container"><a class="btn-where-to-buy" href="/where-to-buy">' . __('Where to buy', 'company') . '</a>';
echo '<a class="btn-ask-a-demo" href="/#uagb-tabs__tab1">' . __('Ask a demo', 'company') . '</a>';
echo '</div>';
}
if ( current_user_can( 'viewonly' ) || !is_user_logged_in() ) { // Set the user role to the specific role you want to replace the buttons for.
// Remove button from products in the loop and single product page
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart');
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
// Add the actions you just removed, but insert your button function
add_action( 'woocommerce_after_shop_loop_item', 'print_login_to_see');
add_action( 'woocommerce_single_product_summary', 'print_login_to_see', 30 );
}
I am trying to make some changes to code I have found off here that will allow me to hide all the prices of my woocommerce store EXCEPT for one category.
The category I want to display prices for all the time is 'courses' but I want to hide the rest of the products prices until the user is logged in. I am trying to make changes to this code
add_action( 'init', 'bbloomer_hide_price_add_cart_not_logged_in' );
function bbloomer_hide_price_add_cart_not_logged_in() {
if (! is_user_logged_in() &&
! has_term( 'courses', 'product_cat' ) )
{
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', 'bbloomer_print_login_to_see', 31 );
add_action( 'woocommerce_after_shop_loop_item', 'bbloomer_print_login_to_see', 11 );
}
}
function bbloomer_print_login_to_see() {
echo '<a class="button product_type_simple" href="' .
get_permalink(wc_get_page_id('myaccount')) . '">' .
__('Login to see prices', 'theme_name') . '</a>';
}
Any help would be much appreciated!
Instead of removing every action that outputs the price simply, remove the price.
This code would filter the get_price_html() function from the WC_Product class and return an empty string.
function bbloomer_hide_price_add_cart_not_logged_in() {
global $product;
if (! is_user_logged_in() &&
!has_term( 'courses', 'product_cat', $product->get_id()))
{
add_filter('woocommerce_get_price_html', '__return_empty_string', 10);
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 );
}
}
or... to add your click to login button...
function bbloomer_hide_price_add_cart_not_logged_in() {
global $product;
if (!is_user_logged_in() &&
!has_term( 'courses', 'product_cat', $product->get_id())) // add product ID to check if that specific product is part of courses category.
{
add_filter('woocommerce_get_price_html', 'bbloomer_print_login_to_see'),
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 ); 10);
}
}
function bbloomer_print_login_to_see() {
// Modify the function to return the value, not echo it.
return '<a class="button product_type_simple" href="' .
get_permalink(wc_get_page_id('myaccount')) . '">' .
__('Login to see prices', 'theme_name') . '</a>';
}
Revised Answer Additions
Access the current $product inside your loop to check if it's part of courses category.
Remove add to cart button from single product pages if the product is part of the category courses
I want to remove some information on checkout page when there is only virtual products in cart.
The following is removing what I want on checkout page:
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_checkout_privacy_policy_text', 20 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_terms_and_conditions_page_content', 30 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'woocontracts_terms_fields', );
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
remove_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review', 10 );
remove_action( 'woocommerce_checkout_after_terms_and_conditions', 'woocontracts_checkout_additional_checkboxes', 10 );
remove_action( 'woocommerce_checkout_process', 'woocontracts_checkout_field_process', 10 );
how to make the same when there is only virtual products in cart?
I Tried the following:
add_filter( 'woocommerce_checkout_after_terms_and_conditions' , 'bbloomer_simplify_checkout_virtualab' );
function bbloomer_simplify_checkout_virtualab( $fields ) {
$only_virtual = true;
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// Check if there are non-virtual products
if ( ! $cart_item['data']->is_virtual() ) $only_virtual = false;
}
if( $only_virtual ) {
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_checkout_privacy_policy_text', 20 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_terms_and_conditions_page_content', 30 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'woocontracts_terms_fields', );
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
remove_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review', 10 );
return $fields;
}
return $fields;
}
But it doesn't work. Any suggestions?
Update 2 - The right hook to use in this case is woocommerce_checkout_init action hook:
// Custom conditional function that checks if there is only virtual items in cart
function has_only_virtual_items_in_cart(){
$only_virtual = true;
// Check if there are non-virtual items in cart
foreach( WC()->cart->get_cart() as $cart_item ) {
if ( ! $cart_item['data']->is_virtual() ) {
$only_virtual = false;
break;
}
}
return $only_virtual;
}
// Unhook some functions conditionally
add_action( 'woocommerce_checkout_init', 'simplify_checkout_for_virtual_items_only' );
function simplify_checkout_for_virtual_items_only() {
if( has_only_virtual_items_in_cart() ) {
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
remove_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review', 10 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_checkout_privacy_policy_text', 20 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_terms_and_conditions_page_content', 30 );
remove_action( 'woocommerce_checkout_terms_and_conditions', 'woocontracts_terms_fields' ); // <== missing priority
remove_action( 'woocommerce_checkout_after_terms_and_conditions', 'woocontracts_checkout_additional_checkboxes', 10 );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Then you can reuse the custom contional function has_only_virtual_items_in_cart() inside woocontracts_checkout_field_process() function hooked in woocommerce_checkout_process hook.
I would like to replace the 'Add to cart' button for a specific product category and when product type isa a 'simple product'.
I would like to do that on the page where I can see all the products (shop and archive pages) and in single product pages.
The code bellow just hide my add-to cart buttons from all post of my product category:
function western_custom_buy_buttons(){
$product = get_product();
if ( has_term( 'categ1', 'product_cat') ){
// removing the purchase buttons
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
remove_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
remove_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
remove_action( 'woocommerce_external_add_to_cart', 'woocommerce_external_add_to_cart', 30 );
}
}
add_action( 'wp', 'western_custom_buy_buttons' );
How can I achieve that? Any help please.
Here is a complete working solution that will replace all add-to-cart buttons for your defined product category and simple products only, by a custom "read more" button.
This code is tested and works on WooCommerce versions from 2.6.x to 3.0+:
// Replacing add-to-cart button in shop pages and archives pages
add_filter( 'woocommerce_loop_add_to_cart_link',
'quantity_inputs_for_woocommerce_loop_add_to_cart_link', 10, 2 );
function quantity_inputs_for_woocommerce_loop_add_to_cart_link( $html, $product ) {
// WooCommerce compatibility
if ( method_exists( $product, 'get_id' ) ) {
$product_id = $product->get_id();
} else {
$product_id = $product->id;
}
if ( has_term( 'categ1', 'product_cat', $product_id ) && $product->is_type( 'simple') ) {
// Set HERE your button link
$link = get_permalink($product_id);
$html = ''.__("Read More", "woocommerce").'';
}
return $html;
}
// Outputing a custom button in Single product pages (you need to set the button link)
function single_product_custom_button( ) {
global $product;
// WooCommerce compatibility
if ( method_exists( $product, 'get_id' ) ) {
$product_id = $product->get_id();
} else {
$product_id = $product->id;
}
if ( has_term( 'categ1', 'product_cat', $product_id ) ) {
// Set HERE your button link
$link = '#';
echo ''.__("Read More", "woocommerce").'';
}
}
// Replacing add-to-cart button in Single product pages
add_action( 'woocommerce_single_product_summary', 'removing_addtocart_buttons', 1 );
function removing_addtocart_buttons()
{
global $product;
// WooCommerce compatibility
if ( method_exists( $product, 'get_id' ) ) {
$product_id = $product->get_id();
} else {
$product_id = $product->id;
}
if ( has_term( 'categ1', 'product_cat', $product_id ) )
{
#### Removing the add-to-cart button ####
## Simple products
remove_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
## Other products types
// remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
// remove_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
// remove_action( 'woocommerce_external_add_to_cart', 'woocommerce_external_add_to_cart', 30 );
// remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
// remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
#### Adding a custom replacement button ####
## Simple products
add_action( 'woocommerce_simple_add_to_cart', 'single_product_custom_button', 30 );
## Other products types
// add_action( 'woocommerce_grouped_add_to_cart', 'single_product_custom_button', 30 );
// add_action( 'woocommerce_variable_add_to_cart', 'single_product_custom_button', 30 );
// add_action( 'woocommerce_external_add_to_cart', 'single_product_custom_button', 30 );
// add_action( 'woocommerce_single_product_summary', 'single_product_custom_button', 30 );
// add_action( 'woocommerce_single_variation', 'single_product_custom_button', 20 );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.