Replace add to cart button with a custom button on WooCommerce - php

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.

Related

Hide price until login and display button - woocommerce

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>';
}

WooCommerce - Change Add to Cart button text for products £40 or more

I am attempting to alter the "Add to Cart" button test on single product pages only when a product is £40 or more. I have attempted the below snippet but it does not alter anything.
/**
* Change Add to Cart button text for products £40 or more
*
* #return string
*/
function banks_cart_button_text() {
global $product;
if( $product->get_regular_price >= '40' ) {
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woocommerce_custom_single_add_to_cart_text' );
function woocommerce_custom_single_add_to_cart_text() {
return __( 'Add to Cart with FREE UK Shipping', 'woocommerce' );
}
}
return $product->get_regular_price();
}
I was about to post and came across the below post which I updated but this also does not work.
Link: Change add to cart button and text based on WooCommerce product type Author: LoicTheAztec
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 ) {
// Products above X amount
if( $product->get_regular_price >= '40' ) {
$button_text = __( "Add to Cart with FREE UK Shipping", "woocommerce" );
}
return '<a class="view-product button" href="' . $product->get_permalink() . '">' . $button_text . '</a>';
}
UPDATE:
Adapted another snippet I used a while back but does not work. Is the issue the this line:
if( $product->get_regular_price >= '40' ) {
Snippet
// Replacing the single product button add to cart by a custom button when store is closed
add_action( 'woocommerce_single_product_summary', 'replace_single_add_to_cart_button', 1 );
function replace_single_add_to_cart_button() {
global $product, $url, $request ;
// Products equal to or more than X amount
if( $product->get_regular_price >= '40' ) {
// 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 );
add_action( 'woocommerce_single_variation', 'custom_product_button', 20 );
}
// For all other product types
if( $product->is_type( 'simple' ) ) {
remove_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
add_action( 'woocommerce_simple_add_to_cart', 'custom_product_button', 30 );
}
// For all other product types
else {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
add_action( 'woocommerce_simple_add_to_cart', 'custom_product_button', 30 );
}
}
else {
// Products equal to or more than X amount
if( $product->get_regular_price >= '40' ) {
// 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 );
add_action( 'woocommerce_single_variation', 'custom_product_button', 20 );
}
// For all other product types
if( $product->is_type( 'simple' ) ) {
remove_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
add_action( 'woocommerce_simple_add_to_cart', 'custom_product_button', 30 );
}
// For all other product types
else {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
add_action( 'woocommerce_simple_add_to_cart', 'custom_product_button', 30 );
}
}
}
}
function custom_product_button(){
// Display button
printf( '<a class="button disabled">%s</a>', __( "Add to Cart with FREE UK Shipping", "woocommerce" ) );
}
no need to place a function inside another. this should be enough.
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woocommerce_custom_single_add_to_cart_text', 100, 2 );
function woocommerce_custom_single_add_to_cart_text( $add_to_cart_text, $product ) {
if ( $product->get_regular_price() >= '40' ) {
return __( 'Add to Cart with FREE UK Shipping', 'woocommerce' );
}
return $add_to_cart_text;
}
Try
if( $product->get_regular_price() >= 40 ) {
(brackets on the end and compare price against int not a string).
Also check that you're getting a value.
Depending on your setup you may need to check for
$product->get_sale_price()
or
$product->get_price()
You can use the functions above, or by using Locotranslate plugin, it creates templates for the site's texts (separated by files based on the origin of the word, for example woocommerce file, theme file, plugins file) for each language, so you just replace the "add to cart" word in the english language template of woocommerce file with the text you want.

Remove some hooked functions based on virtual products in WooCommerce Checkout

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.

Hide "Add to Cart" button for logged in users in Woocommerce

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') . '';
}

Conditionally removing add-to-cart button and hiding prices for product categories

In WooCommerce, I am trying to remove Add-to-cart button from my homepage slider based on certain product categories and hiding the prices.
I have tried to use that code:
/* Code for authorisation */
function show_price_logged($price){
if(! is_user_logged_in()) {
if(has_term( 'teamine', 'product_cat' )){ /* sub categories need not authorisation, but thier parent category needs authorisation */
return $price;
}
if(has_term( 'epicuren', 'product_cat' ) || has_term( 'revision', 'product_cat' ) || has_term( 'image-2', 'product_cat' )){ /* categories needs authorisation */
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_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
return '<a class="amount authorizelink" href="/how-to-get-authorized-its-easy">Authorization needed to purchase <span>Click Here</span></a>';
}
if(has_term( 'skinceuticals', 'product_cat' ) || has_term( 'lira', '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_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
return 'Please contact the Spa to arrange a consultation and to purchase this product <span></span>';
}
else{
return $price;
}
}
else return $price;
}
But it's not working as expected and add-to-cart buttons are not removed when conditions are matched.
Any help will be appreciated. How can I achieve this?
Thanks.
UPDATED
As you don't provide any hook for your function usage, to test it and make it work I have used here woocommerce_price_html and woocommerce_sale_price_html filters hooks (for simple products).
I have changed a little bit your code and it is working successfully now:
add_filter('woocommerce_price_html','show_price_logged', 10, 2 );
add_filter('woocommerce_sale_price_html','show_price_logged', 10, 2 );
function show_price_logged( $price, $product ){
if( !is_user_logged_in() && !has_term( 'teamine', 'product_cat', $product->id ) ){
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_simple_add_to_cart', 'woocommerce_simple_add_to_cart', 30 );
remove_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
if( has_term( 'epicuren', 'product_cat', $product->id ) || has_term( 'revision', 'product_cat', $product->id ) || has_term( 'image-2', 'product_cat', $product->id ) )
{
$price = '<a class="amount authorizelink" href="/how-to-get-authorized-its-easy">Authorization needed to purchase <span>Click Here</span></a>';
}
elseif( has_term( 'skinceuticals', 'product_cat', $product->id ) || has_term( 'lira', 'product_cat', $product->id ) )
{
$price = 'Please contact the Spa to arrange a consultation and to purchase this product <span></span>';
}
else // set here another text + link in case of…
{
$price = 'LINK <span>NON LOGGED USER / NO TARGETED CATEGORY</span>';
}
}
return $price;
}
I have add a final condition (in case of) that will need a custom text + link…
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works, it should also work for you.
Update: See the result here on a test server:
SHOP PAGE (OR ARCHIVES):
PRODUCT PAGES:
This just works perfectly…
Related to your error in the comments:
Warning: Missing argument 2 for show_price_logged() …:
This means that you have forget the $product argument in four function. you need to have this:
function show_price_logged( $price, $product ){
Instead of this:
function show_price_logged( $price ){
As you are declaring 2 arguments at the end of your add_filter() hooks…

Categories