WooCommerce: esempio di carrello AJAX avanzato

Di seguito vedremo un esempio di carrello in AJAX con WooCommerce che gestisce le maggiorazioni sul totale.

Partiamo dalla nostra action AJAX di aggiunta di un prodotto al carrello:

function my_add_to_cart() {
    $product_id = (int) $_POST['product_id'];
    $quantity = (int) $_POST['quantity'];
    $variation_id = 0;
    $variation = array();
    $cart_item_data = array();
    WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $cart_item_data );
     wp_send_json( array( 'ok' => true ) );
     
}

add_action( 'wp_ajax_my_addtocart', 'my_add_to_cart' );
add_action( 'wp_ajax_nopriv_my_addtocart', 'my_add_to_cart' );

A questo punto possiamo associare la maggiorazione ai prodotti usando un custom field che chiameremo maggiorazione (se non lo avete già installato, si consiglia vivamente di usare il plugin Advanced Custom Fields che semplifica enormemente la gestione dei custom field).

Se questo custom field ha un valore numerico, assoceremo l’ID del prodotto al valore nella sessione di WooCommerce:

function my_add_to_cart() {
    $product_id = (int) $_POST['product_id'];
    $quantity = (int) $_POST['quantity'];
    $variation_id = 0;
    $variation = array();
    $cart_item_data = array();
$value = get_post_meta( $product_id, 'maggiorazione', true );
if( is_numeric( $value ) && intval( $value ) > 0 ) {
        $data = WC()->session->get( 'maggiorazione' );
        if( $data === null ) {
            WC()->session->set( 'maggiorazione', json_encode( array( array( 'prodotto' => $product_id, 'maggiorazione' => intval( $value ) ) ) ) );
        } else {
            $meta = json_decode( $data, true );
            $update = array( 'prodotto' => $product_id, 'maggiorazione' => intval( $value ) );
            $in = false;
            foreach( $meta as $m ) {
                if( $m['product'] == $product_id ) {
                    $in = true;
                }
            }
            if( !$in ) {
                $meta[] = $update;
                WC()->session->set( 'maggiorazione', json_encode( $meta ) );
            }
        }
}

    WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $cart_item_data );
     wp_send_json( array( 'ok' => true ) );
     
}

add_action( 'wp_ajax_my_addtocart', 'my_add_to_cart' );
add_action( 'wp_ajax_nopriv_my_addtocart', 'my_add_to_cart' );

Se nella sessione non è già presente alcuna maggiorazione, salviamo l’associazione valore/prodotto come stringa JSON. Altrimenti aggiorniamo l’array associativo ottenuto con la funzione json_decode() con i nuovi dati stando attenti a non inserire valori duplicati e quindi salviamo i dati aggiornati nella sessione.

A questo punto entra in gioco la action di WooCommerce woocommerce_calculate_fees che serve appunto a calcolare eventuali aggiunte al totale finale del carrello:

function my_add_charge() {
  $charge = 0.00;
  $data = WC()->session->get( 'maggiorazione' );
  $meta = json_decode( $data, true );
  foreach( WC()->cart->cart_contents as $key => $product_in_cart ) {
      $id = $product_in_cart['product_id'];
      foreach( $meta as $d ) {
          if( intval( $d['prodotto'] ) === intval( $id ) ) {
              $add = (int) $d['maggiorazione'];
              $charge += $add;
          }
      }
  }
  if( $charge > 0.00 ) { 
      WC()->cart->add_fee( 'Maggiorazione', $charge, true, 'standard' );
  }    
}

add_action( 'woocommerce_cart_calculate_fees', 'my_add_charge' );

Eseguiamo un loop sui prodotti presenti nel carrello e se c’è una corrispondenza tra un prodotto nel carrello e un prodotto dell’array associativo della sessione incrementiamo il valore numerico della variabile $charge che poi verrà usata con il metodo add_fee().

Infine non ci resta che resecare la nostra variabile di sessione quando il carrello è vuoto:

function my_empty_cart_action() {
    $data = WC()->session->get( 'maggiorazione' ); 
    if( $data !== null ) {
        $meta = json_decode( $data, true );
        if( count( $meta ) > 0 ) {
          WC()->session->set( 'maggiorazione', json_encode( array() ) );
        }  
    }     
}

add_action( 'woocommerce_cart_emptied', 'my_empty_cart_action' );

Conclusione

Abbiamo visto come usando la sessione di WooCommerce sia possibile salvare valori temporanei che possono essere utilizzati per modificare il totale del carrello del nostro e-commerce.