12

In the ecommerce store:

  • There are items displayed on Homepage and each of the items have an "Add to Cart" button underneath them. When this button is clicked, the item is added to cart. If this button is clicked again, the Quantity of the item that is already existing in cart, is incremented by 1. I believe this is the loop. So far, so good.

  • On the Single Product page, there is an "Add to Cart" button. When this button is clicked, the item gets added to cart. There is a Quantity input textbox as well that can be used to change the quantity. This is fine too.

THE ISSUE:

I need to differentiate between the "Add to Cart" button that was clicked within the loop (currently on Homepage, but can also be used on other pages such as Archive page, etc.) vs the "Add to Cart" button that was clicked on the Single Product page. Based on this differentiation, here is what I need to do:

  • If the "Add to Cart" button appearing within the loop was clicked, grab the Quantity of this item that is already existing in cart using the $cart_item_key, increment it by 1 and send this to a custom function that will do additional processing and save the details to cart again.
  • If the "Add to Cart" button appearing in the Single Product page was clicked, grab the Quantity of this item that is already existing in cart using the $cart_item_key, multiply it by 3 and send this to a custom function that will do additional processing and save the details to cart again.
  • In both the above cases, the Quantity is being changed, based on different logics and this Quantity needs to be sent to a custom function call.

WHAT I TRIED:

I tried the following code:

add_action('woocommerce_add_to_cart', 'custom_action_add_to_cart', 20, 6);
function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
{

    $cart = WC()->cart->get_cart();    

    $product = wc_get_product($product_id);

    // NEED TO RUN CUSTOM CODE HERE BASED ON THE CHECKS
    if (add to cart within loop is clicked) {
        // Get existing $quantity_from_cart from cart using $cart_item_key, but how???? 
        $new_quantity = $quantity_from_cart + 1;
    }
    else if (add to cart on single product page is clicked) {
        // Get existing $quantity_from_cart from cart using $cart_item_key, but how????
        $new_quantity = $quantity_from_cart * 3;
    }
    // Need to send the $new_quantity along with the $cart_item_key to the custom function so that the data can be saved using $cart_item_key
    my_custom_function($new_quantity, $cart_item_key);
}


function my_custom_function($new_quantity, $cart_item_key)
{
    echo $new_quantity;

    WC()->cart->cart_contents[$cart_item_key]['custom_quantity'] = $new_quantity;
    WC()->cart->set_session();
}

The issue with the above code is that it if I don't have the if... else if... logic, then the code is executed regardless of where the "Add to Cart" button is located. In other words, whether I click the "Add to Cart" button that is located in the loop (Homepage, Archive page or any page that uses the loop) or I click the "Add to Cart" button located in the Single Product page, the above code gets executed in the absence of the if... else if... logic.

So, I want to run separate code when the "Add to Cart" button that is located in the loop is clicked (regardless of its location, whether Homepage, Archives, etc.) and run different code when the "Add to Cart" button that is located on the Single Product page is clicked. How can I achieve this?

Expecting something like this:

  • If button appearing inside the loop is clicked -> Do this.
  • If button appearing in Single Product page is clicked -> Do that.
Devner
  • 6,825
  • 11
  • 63
  • 104

4 Answers4

1

you can use wp_get_referer or check_ajax_referer() for example:

function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
{

    $cart = WC()->cart->get_cart();    

    $product = wc_get_product($product_id);
    $referer = wp_get_referer();
    // HOMEPAGE
    if (strpos($referer ,'http://yourwebsite.com/') !== false) { 
        $new_quantity = $quantity_from_cart + 1;
    }
    //from some product page like http://yourwebsite.com/product/my-product-page
    else if (strpos($referer ,'http://yourwebsite.com/product/') !== false) {
        $new_quantity = $quantity_from_cart * 3;
    }
    // Need to send the $new_quantity along with the $cart_item_key to the custom function so that the data can be saved using $cart_item_key
    my_custom_function($new_quantity, $cart_item_key);
}

Please refer: Wordpress Nonces related functions

Ronak Dhoot
  • 2,322
  • 1
  • 12
  • 19
  • The manual checks for the Homepage, Product page, etc. are an overkill. I am trying not to hardcode the page names and rather have WP handle it internally. – Devner Jan 22 '20 at 11:50
1

You can try this way:

add_action('woocommerce_add_to_cart', 'custom_action_add_to_cart', 20, 6);
function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
    $cart = WC()->cart->get_cart();
    $product = wc_get_product($product_id);
    $referer = $_SERVER['HTTP_REFERER'];
    $route = parse_url( $referer );
    $path = $route['path'] ?? 'home' ;
    $args = array_filter( ( explode('/', $path) ) );
    if (in_array( 'product', $args) ) {
        // Product Page
    } elseif (in_array('product-category', $args)) {
        // Product Category
    } else {
        // Default
    }
}

But you need check your settings. Settings > Permalinks.

Dmitry Leiko
  • 3,970
  • 3
  • 25
  • 42
  • The manual checks for the Homepage, Product page, etc. are an overkill. I am trying not to hardcode the page names and rather have WP handle it internally. – Devner Jan 23 '20 at 11:30
1

you can use is_product(),is_product_category() function

function custom_action_add_to_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data)
{

    $cart = WC()->cart->get_cart();    

    $product = wc_get_product($product_id);

    if ( is_product() ) {
    global $product;
    $id = $product->get_id();
    foreach ( WC()->cart->get_cart() as $cart_item ) { 
       if($cart_item['product_id'] == $id ){
           $quantity_from_cart =  $cart_item['quantity'];
           break; // stop the loop if product is found
       }
     }

        $new_quantity = $quantity_from_cart * 3;
    }
  else if (is_product_category()) {
        $new_quantity = $quantity_from_cart + 1;
    }
    my_custom_function($new_quantity, $cart_item_key);
}
bhaghyasandar
  • 516
  • 4
  • 16
  • I tired your solution. When I am on the Single Product page and added the product to cart, I expected the code `$new_quantity = $quantity_from_cart * 3;` to work. But it does not. It simply increments the current existing quantity in cart, but does **NOT** multiply the quantity by **3**. How to fix this? – Devner Jan 23 '20 at 11:29
  • Try Now it will multiply the quantity by 3 – bhaghyasandar Jan 24 '20 at 05:12
  • I just tried your revised solution. But somehow, the result is same as my previous comment. It seems like that for some weird reason, the code `if ( is_product() )` is **NOT** being executed. I can't seem to find the reason why! Does it matter that it is an AJAX Add to Cart button?? – Devner Jan 24 '20 at 17:45
0

There are couple solutions I could think of. But here's one:

add_action( 'woocommerce_after_add_to_cart_button', 'rmg_woocommerce_after_add_to_cart_button' );
function rmg_woocommerce_after_add_to_cart_button() {
    $button_location = 0;
    // if (is_home() || is_front_page()) {
    //     // we're at the home page
    //     $button_location = 1;
    // }
    if (is_product()) {
        // where at product page
        $button_location = 2;
    } else {
        // pages other than product page
        $button_location = 1;
    }
    echo '<input type="hidden" name="button-location" value="'. $button_location .'" />';
}

We could add an hidden input inside the form, that above code does it.
Then could check it's value like:

$button_location = $_REQUEST['button-location'];
if ($button_location && $button_location === 2) {
    // add to cart button clicked at or came from product page..
    $new_quantity = $quantity_from_cart + 1;
}

Please note that this is just an idea and not a complete solution... You need to take care of the ajax button.

Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
  • It seems like that for some weird reason, the code if ( is_product() ) is **NOT** being executed. I can't seem to find the reason why! Does it matter that it is an AJAX Add to Cart button?? – Devner Jan 25 '20 at 18:50
  • with ajax, you need to pass the value of `$button_location` in the request.. – Reigel Gallarde Jan 26 '20 at 06:17