mayvn
mayvn

Reputation: 191

Adding Custom Attribute selected value to Cart, Checkout, Order and email notification

My Environment is:
- WordPress 4.7.4
- Debian Linux 8
- WooCommerce 3.0.5
- 256M Memory

I've tried a number of solutions including:

However, I'm still not getting the right result and time is of the essence at this point of this project. A precision, I have the same price for all attribute values…

I created a custom single-product.php tempalte with a custom form:

<form id="add-product-form" class="add-product-form form-horizontal" method="post" action="">
    <input name="add-to-cart" value="15709" type="hidden">
    <div class="form-group color-dropdown">
        <label class="col-sm-3 control-label">Color</label>
        <select id="color-options" class="col-sm-9 color-select" name="color" required="">
        <option value="auburn">Auburn</option>
        <option value="black">Black</option>
        <option value="mahogany-ash">Mahogany Ash</option>
        <option value="mocha">Mocha</option>                            </select>
    </div>
    <div class="form-group quantity-area">
        <label class="col-sm-3 control-label">Qty.</label>
        <input name="quantity" id="quantity" maxlength="2" class="col-sm-9 quantity-input" required="" type="text">
    </div>
    <button id="submit-to-cart" value="Add to Cart" class="btn btn-a2c submit" name="submit" type="submit"><i class="fa fa-plus" aria-hidden="true"></i> Add to Cart</button>
</form>

This form uses an AJAX post method and adds to cart as intended.

However:

  1. I'm not seeing the color they chose listed on the WC Cart page
  2. I'm not seeing the color they chose listed on the WC Checkout page
  3. I'm not seeing the color they chose on the corresponding emails. I know I have to edit email-order-items.php but I don't know the right approach here.

My question:

So How can I add a Custom Attribute selected value to Cart, Checkout, Order and email notification?

I know I can take the Variable product approach, but even at 256M memory, the Variations menu in the Variable Product area constantly spins so I can never get to this area to Add Variations.

Upvotes: 1

Views: 4837

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253919

Instead of overriding your template single-product.php, it is better to use the original hook do_action('woocommerce_before_add_to_cart_button'); that are made to inject code in it through some custom hooked function.

As I have understood, you don't need to use a variable product. You want to use a single product that is going to display a custom selector field in which you set an existing "Color" attribute with the chosen values for this product.

Here is that hooked function:

// Add the custom field selector based on attribute "Color" values set in the simple product
add_action( 'woocommerce_before_add_to_cart_button', 'action_before_add_to_cart_button' );
function action_before_add_to_cart_button(){
    global $product;
    foreach($product->get_attributes() as $attribute_slug => $attribute_obj){
        if($attribute_slug == 'pa_color'){
            echo '<div class="form-group color-dropdown">
            <label class="col-sm-3 control-label" for="custom_pa_color">'. __('Color', 'woocommerce') .'</label>
            <select id="custom_pa_color" class="col-sm-9 color-select" name="custom_pa_color" required="">';

            foreach( $attribute_obj->get_terms() as $term_obj){
                $term_id   = $term_obj->id;
                $term_name = $term_obj->name;
                $term_slug = $term_obj->slug;
                echo '<option value="'.$term_slug.'">'.$term_name.'</option>';
            }
            echo '</select>
            </div>';
        }
    }
}

Then as you want to pass in cart item the selected "Color" attribute "value" when product is added to cart and finally to display it in cart, checkout, order and email notifications here is the code you need:

// Save the custom product custom field data in Cart item
add_action( 'woocommerce_add_cart_item_data', 'save_in_cart_my_custom_product_field', 10, 2 );
function save_in_cart_my_custom_product_field( $cart_item_data, $product_id ) {
    if( isset( $_POST['custom_pa_color'] ) ) {
        $cart_item_data[ 'custom_pa_color' ] = $_POST['custom_pa_color'];

        // When add to cart action make an unique line item
        $cart_item_data['unique_key'] = md5( microtime().rand() );
        WC()->session->set( 'custom_data', $_POST['custom_pa_color'] );
    }
    return $cart_item_data;
}

// Render the custom product custom field in cart and checkout
add_filter( 'woocommerce_get_item_data', 'render_custom_field_meta_on_cart_and_checkout', 10, 2 );
function render_custom_field_meta_on_cart_and_checkout( $cart_data, $cart_item ) {

    $custom_items = array();

    if( !empty( $cart_data ) )
        $custom_items = $cart_data;

    if( $custom_field_value = $cart_item['custom_pa_color'] )
        $custom_items[] = array(
            'name'      => __( 'Color', 'woocommerce' ),
            'value'     => $custom_field_value,
            'display'   => $custom_field_value,
        );

    return $custom_items;
}

// Add the the product custom field as item meta data in the order + email notifications
add_action( 'woocommerce_add_order_item_meta', 'tshirt_order_meta_handler', 10, 3 );
function tshirt_order_meta_handler( $item_id, $cart_item, $cart_item_key ) {
    $custom_field_value = $cart_item['custom_pa_color'];

    // We add the custom field value as an attribute for this product
    if( ! empty($custom_field_value) )
        wc_update_order_item_meta( $item_id, 'pa_color', $custom_field_value );
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

This code works and is tested for WooCommerce version from 2.5 to 3.0+

In your template

You will have to remove the selector code and to re-insert the oringinal hook:

<form id="add-product-form" class="add-product-form form-horizontal" method="post" action="">
<?php 
     // Here we re-insert the original hook
     do_action('woocommerce_before_add_to_cart_button');
?>
    <div class="form-group quantity-area">
        <label class="col-sm-3 control-label">Qty.</label>
        <input name="quantity" id="quantity" maxlength="2" class="col-sm-9 quantity-input" required="" type="text">
    </div>
    <button id="submit-to-cart" value="Add to Cart" class="btn btn-a2c submit" name="submit" type="submit"><i class="fa fa-plus" aria-hidden="true"></i> Add to Cart</button>
</form>

Related answer: Saving a product custom field and displaying it in cart page

Upvotes: 3

Related Questions