1

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.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
mayvn
  • 191
  • 1
  • 9
  • "I know I can take the Variable product approach, but even at 256M memory, the Variations menu in the Variable Product area constantly spins" are you checking your console? That sounds like you probably have an error that is preventing the Javascript from completing. I would try debugging that before trying to write your own alternative to variable products. Switch to a default theme. Disable plugins. Enable `WP_DEBUG_LOG`... the whole debug works. – helgatheviking May 03 '17 at 17:06
  • I found the issue on that, none the less, still having an issue bringing the attribute to cart. – mayvn May 03 '17 at 21:02
  • What was the issue? Is your theme overriding any cart templates? Are they out of date? Because I think the variation attributes are shown in the cart by default. – helgatheviking May 04 '17 at 14:40

1 Answers1

3

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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • What a great and informative answer. Thank you Loic! – mayvn May 04 '17 at 02:52
  • Kudos on the answer. It still looks/sounds like a variable product to me with a single, color, attribute, but it's late here and I can't think straight any more. – helgatheviking May 04 '17 at 03:11