Henrik Schuller
Henrik Schuller

Reputation: 31

WooCommerce Ajax add to cart with additional custom data

I am having some difficulties with trying to add to cart with custom data from the front end.

My current PHP from the backend is as follows - this is placed in my functions.php for my child-theme (This code is from the following post: Adding a product to cart with custom info and price - considering I am indeed a PHP-noobie):

<?php // This captures additional posted information (all sent in one array)
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,10);
function wdm_add_item_data($cart_item_data, $product_id) {

    global $woocommerce;
    $new_value = array();
    $new_value['_custom_options'] = $_POST['custom_options'];

    if(empty($cart_item_data)) {
        return $new_value;
    } else {
        return array_merge($cart_item_data, $new_value);
    }
}

// This captures the information from the previous function and attaches it to the item.
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );
function wdm_get_cart_items_from_session($item,$values,$key) {

    if (array_key_exists( '_custom_options', $values ) ) {
        $item['_custom_options'] = $values['_custom_options'];
    }

    return $item;
}

// This displays extra information on basket & checkout from within the added info that was attached to the item.
add_filter('woocommerce_cart_item_name','add_usr_custom_session',1,3);
function add_usr_custom_session($product_name, $values, $cart_item_key ) {

    $return_string = $product_name . "<br />" . $values['_custom_options']['description'];// . "<br />" . print_r($values['_custom_options']);
    return $return_string;

}

//This adds the information as meta data so that it can be seen as part of the order (to hide any meta data from the customer just start it with an underscore)
add_action('woocommerce_add_order_item_meta','wdm_add_values_to_order_item_meta',1,2);
function wdm_add_values_to_order_item_meta($item_id, $values) {
    global $woocommerce,$wpdb;

    wc_add_order_item_meta($item_id,'item_details',$values['_custom_options']['description']);
    wc_add_order_item_meta($item_id,'customer_image',$values['_custom_options']['another_example_field']);
    wc_add_order_item_meta($item_id,'_hidden_field',$values['_custom_options']['hidden_info']);

} 

and then I have a button on the frontend that runs the following script when pressed - this runs on a custom wordpress post where I have scripted have done some scripting in the background that collects information based on the users actions on the post:

function cartData() {
        var metaData = {
            description: 'My test Description'
            another_example_field: 'test'
        };

        var activeVariationId = 10335;      

        var data = {
            action: 'wdm_add_item_data',
            product_id: 10324,
            "add-to-cart": 10324,
            quantity: 1,
            variation_id: activeVariationId,
            cart_item_data: metaData
        };

        $.ajax({
            type: 'post',
            url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add-to-cart' ),
            data: data,
            beforeSend: function (response) {
                //$thisbutton.removeClass('added').addClass('loading');
            },
            complete: function (response) {
                //$thisbutton.addClass('added').removeClass('loading');
            },
            success: function (response) {

                if (response.error & response.product_url) {
                    window.location = response.product_url;
                    return;
                } else {
                    alert('ajax response recieved');
                    jQuery( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash ] );
                }
            },
        });
    }

Unfortunately this only seems to add my current variation of the product to the to cart without any more custom information. Any help with nesting in this issue would be highly appreciated. If you need any more information and/or code examples I'd be happy to supply it :)

Upvotes: 1

Views: 11109

Answers (1)

Henrik Schuller
Henrik Schuller

Reputation: 31

I think that I might have solved it, or at least parts of it with this PHP (this is really just a small modification of this code - adding $cart_item_data https://quadmenu.com/add-to-cart-with-woocommerce-and-ajax-step-by-step/):

add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');

function woocommerce_ajax_add_to_cart() {

    $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
    $quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
    $variation_id = absint($_POST['variation_id']);
    // This is where you extra meta-data goes in
    $cart_item_data = $_POST['meta'];
    $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
    $product_status = get_post_status($product_id);

    // Remember to add $cart_item_data to WC->cart->add_to_cart
    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $cart_item_data) && 'publish' === $product_status) {

        do_action('woocommerce_ajax_added_to_cart', $product_id);

        if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
            wc_add_to_cart_message(array($product_id => $quantity), true);
        }

        WC_AJAX :: get_refreshed_fragments();
    } else {

        $data = array(
            'error' => true,
            'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));

        echo wp_send_json($data);
    }

    wp_die();
}

Where this is part of the JS-function:

var data = {
                action: 'woocommerce_ajax_add_to_cart',
                product_id: 10324,
                quantity: 1,
                variation_id: activeVariationId,
                meta: metaData
            };

            $.ajax({
                type: 'post',
                url: wc_add_to_cart_params.ajax_url,
                data: data, ...........

I am going to have to test it some more, as it seems now that all the data-fields also gets posted in the cart, email etc - I probably have to rewrite something so that some parts of it is hidden for the "non-admin", but available for me later on + adding custom product thumbnail on add to cart.

Upvotes: 2

Related Questions