Woocommerce: detecta dónde se hizo clic en el botón Agregar al carrito y ejecuta un código diferente

7 minutos de lectura

En la tienda de comercio electrónico:

  • Hay elementos que se muestran en la página de inicio y cada uno de los elementos tiene un botón “Agregar al carrito” debajo de ellos. Cuando se hace clic en este botón, el artículo se agrega al carrito. Si se vuelve a hacer clic en este botón, la Cantidad del artículo que ya existe en el carrito se incrementa en 1. Creo que este es el bucle.. Hasta aquí todo bien.

  • En la página de un solo producto, hay un botón “Agregar al carrito”. Cuando se hace clic en este botón, el artículo se agrega al carrito. También hay un cuadro de texto de entrada de cantidad que se puede usar para cambiar la cantidad. Esto también está bien.

LA CUESTIÓN:

necesito diferenciar entre el botón “Agregar al carrito” en el que se hizo clic dentro del ciclo (actualmente en la página de inicio, pero también se puede usar en otras páginas, como la página de archivo, etc.) frente al botón “Agregar al carrito” en el que se hizo clic en la página de un solo producto. Basado en esta diferenciación, esto es lo que debo hacer:

  • Si se hizo clic en el botón “Agregar al carrito” que aparece dentro del bucle, tome el Cantidad de este artículo que ya existe en el carrito usando el $cart_item_keyincreméntalo en 1 y envíalo a una función personalizada que realizará un procesamiento adicional y guardará los detalles en el carrito nuevamente.
  • Si se hizo clic en el botón “Agregar al carrito” que aparece en la página de un solo producto, tome el Cantidad de este artículo que ya existe en el carrito usando el $cart_item_keymultiplíquelo por 3 y envíelo a una función personalizada que realizará un procesamiento adicional y guardará los detalles en el carrito nuevamente.
  • En los dos casos anteriores, la Cantidad se cambia, en función de diferentes lógicas y esta Cantidad debe enviarse a una llamada de función personalizada.

LO QUE PROBÉ:

Probé el siguiente código:

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

El problema con el código anterior es que si no tengo el if... else if... lógica, entonces el código se ejecuta independientemente de dónde se encuentre el botón “Agregar al carrito”. En otras palabras, ya sea que haga clic en el botón “Agregar al carrito” que se encuentra en el bucle (página de inicio, página de archivo o cualquier página que use el bucle) o haga clic en el botón “Agregar al carrito” ubicado en la página de un solo producto, el código anterior se ejecuta en ausencia del if... else if... lógica.

Por lo tanto, quiero ejecutar un código separado cuando se hace clic en el botón “Agregar al carrito” que se encuentra en el bucle (independientemente de su ubicación, ya sea Página de inicio, Archivos, etc.) y ejecutar un código diferente cuando se presiona el botón “Agregar al carrito” que se encuentra en la página de un solo producto. ¿Cómo puedo conseguir esto?

Esperando algo como esto:

  • Si se hace clic en el botón que aparece dentro del bucle -> Haga esto.
  • Si se hace clic en el botón que aparece en la página de un solo producto -> Hazlo.

puedes usar wp_get_referer o comprobar_ajax_referer() por ejemplo:

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

Consulte: Funciones relacionadas con WordPress Nonces

  • Las comprobaciones manuales de la página de inicio, la página del producto, etc. son una exageración. Estoy tratando de no codificar los nombres de las páginas y más bien hacer que WP lo maneje internamente.

    – Desarrollador

    22 de enero de 2020 a las 11:50

avatar de usuario
Dmitri

Puedes probar de esta manera:

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("https://stackoverflow.com/", $path) ) );
    if (in_array( 'product', $args) ) {
        // Product Page
    } elseif (in_array('product-category', $args)) {
        // Product Category
    } else {
        // Default
    }
}

Pero necesita verificar su configuración. Settings > Permalinks.

  • Las comprobaciones manuales de la página de inicio, la página del producto, etc. son una exageración. Estoy tratando de no codificar los nombres de las páginas y más bien hacer que WP lo maneje internamente.

    – Desarrollador

    23 de enero de 2020 a las 11:30

avatar de usuario
invitado1

puedes usar is_product(),is_product_category() función

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

  • Cansé tu solución. Cuando estoy en la página de un solo producto y agregué el producto al carrito, esperaba el código $new_quantity = $quantity_from_cart * 3; trabajar. Pero no es así. Simplemente incrementa la cantidad actual existente en el carrito, pero no NO multiplicar la cantidad por 3. ¿Cómo arreglar esto?

    – Desarrollador

    23 de enero de 2020 a las 11:29

  • Pruébalo ahora multiplicará la cantidad por 3

    – invitado1

    24 de enero de 2020 a las 5:12

  • Acabo de probar su solución revisada. Pero de alguna manera, el resultado es el mismo que mi comentario anterior. Parece que por alguna extraña razón, el código if ( is_product() ) es NO ser ejecutado. ¡Parece que no puedo encontrar la razón por la cual! ¿Importa que sea un botón Agregar al carrito de AJAX?

    – Desarrollador

    24 de enero de 2020 a las 17:45


Hay un par de soluciones que se me ocurren. Pero aquí hay uno:

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

Podríamos agregar una entrada oculta dentro del formulario, ese código anterior lo hace.
Entonces podría verificar su valor como:

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

Tenga en cuenta que esto es solo una idea y no una solución completa… Debe cuidar el botón ajax.

¿Ha sido útil esta solución?