简体   繁体   中英

Woocommerce: Detect where Add to Cart button was clicked and run different code

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.

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

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 .

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM