2

In wooCommerce, I am changing add to cart button text when a product is in cart with the following code (added to functions.php of my child theme) that works well only for simple product type:

add_filter( 'woocommerce_product_single_add_to_cart_text', 'woocommerce_custom_add_cart_button_single_product' );
function woocommerce_custom_add_cart_button_single_product( $label ) {
   foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
      $product = $values['data'];
      if( get_the_ID() == $product->get_id() ) {
         $label = __('Already in Cart. Add again?', 'woocommerce');
      }
   }
   return $label;
}
// Edit Loop Pages Add to Cart
add_filter( 'woocommerce_product_add_to_cart_text', 'woocommerce_custom_add_cart_button_loop', 99, 2 );
function woocommerce_custom_add_cart_button_loop( $label, $product ) {
   if ( $product->is_purchasable() && $product->is_in_stock() ) {
      foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
         $_product = $values['data'];
         if( get_the_ID() == $_product->get_id() ) {
            $label = __('Already in Cart. Add again?', 'woocommerce');
         }
      }
   }
   return $label;
}

How to make it work for variable product type (and their product variations) too?

1

The following will work for simple products and variable products with product variations.

It requires jQuery to change the the add to cart button text depending on selected variation on variable products.

I have revisited your initial code completely.

// Conditional function that checks if a product is in cart and return the correct button text
function change_button_text( $product_id, $button_text ) {
    foreach( WC()->cart->get_cart() as $item ) {
        if( $product_id === $item['product_id'] ) {
            return __('Already in Cart. Add again?', 'woocommerce');
        }
    }
    return $button_text;
}

// Archive pages: For simple products (ajax add to cart button)
add_filter( 'woocommerce_product_add_to_cart_text', 'change_ajax_add_to_cart_button_text', 10, 2 );
function change_ajax_add_to_cart_button_text( $button_text, $product ) {
    if ( $product->is_type('simple') ) {
        $button_text = change_button_text( $product->get_id(), $button_text );
    }
    return $button_text;
}

// Single product pages: Simple and external products
add_filter( 'woocommerce_product_single_add_to_cart_text', 'change_single_add_to_cart_button_text', 10, 2 );
function change_single_add_to_cart_button_text( $button_text, $product ) {
    if (  ! $product->is_type('variable') ) {
        $button_text = change_button_text( $product->get_id(), $button_text );
    }
    return $button_text;
}

// Single product pages: Variable product and its variations
add_action( 'woocommerce_after_variations_form', 'action_after_variations_form_callback' );
function action_after_variations_form_callback() {
    global $product;

    // Get the produc variation Ids for the variable product
    $children_ids = $product->get_visible_children();

    $ids_in_cart  = [];

    // Loop through cart items
    foreach( WC()->cart->get_cart() as $item ) {
        if( in_array( $item['variation_id'], $children_ids ) ) {
            $ids_in_cart[] = $item['variation_id'];
        }
    }
    ?>
    <script type="text/javascript">
    jQuery(function($){
        var b = 'button.single_add_to_cart_button',
            t = '<?php echo $product->single_add_to_cart_text(); ?>';

        $('form.variations_form').on('show_variation hide_variation found_variation', function(){
            $.each(<?php echo json_encode($ids_in_cart); ?>, function(j, v){
                var i = $('input[name="variation_id"]').val();
                if(v == i && i != 0 ) {
                    $(b).html('<?php _e('Already in Cart. Add again?', 'woocommerce'); ?>');
                    return false;
                } else {
                    $(b).html(t);
                }
            });
        });
    });
    </script>
    <?php
}

Code goes in functions.php file of your active child theme (or active theme). Tested and work.


On a variable product when selecting a variation:

  • If the variation is not in cart (the text doesn't change):

enter image description here


  • If the variation is in cart (the text change):

enter image description here

|improve this answer|||||
  • Thank you very much for your reply and code. I have tested the code and it seems to work at the product page not at the shop or category page. I think that it's my mistake that I din't mention that I need the above functionality to work on the shop and category page. Sorry..... – its4yougr May 25 '19 at 14:25
  • @its4yougr On archive pages It only works for simple products which is logical (think about it)… On archive pages, for variable products, you don't add the product to cart as it's not an add to cart button but a "Select options" button. So you can't display "Already in Cart. Add again?" even if there is only one related variation that is in cart… My code works perfectly and logically. – LoicTheAztec May 25 '19 at 15:04
  • I agree with you totally but my customer wants it like this. He wants to have the visitor / user informed as soon as he lands on the shop / category page which products are in the basket even if those products are simple, variable or auction (since I have the Simple Auctions Plugin installed). I also have the mini cart on the upper right on all pages (where all products that are added to cart exist) but this is not enough.... :-( – its4yougr May 25 '19 at 15:22
  • I removed if ( $product->is_type('simple') ) and if ( ! $product->is_type('variable') ) and it seems to worked! ! ! How about products of type "auction" how could I manage those? Any idea? Thanks for your solution. I appreciated your help! ! ! – its4yougr May 25 '19 at 16:46
  • @its4yougr You should not remove if ( ! $product->is_type('variable') ) { from 3rd function, as the last function is handling variable products on single product pages… Now as product type "auction" is a custom product type made by some third party plugin, out of WooCommerce normal context, you could try to ask a new question related, but you will have very small chances to get an answer. – LoicTheAztec May 25 '19 at 16:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.