3

I have a seemingly simple task, that I can't, for the life of me, seem to figure out.

I have a custom field on the admin page of my Woocommerce products. I just need the value I set here to display in the Woocommerce Checkout page and email.

I have managed to get the field to display on the product page using the following code:

add_action( 'woocommerce_product_options_general_product_data', 'create_shipdate_custom_field' );
function create_shipdate_custom_field() {
woocommerce_wp_text_input( array(
'id'            => '_shipdate',
'type'          => 'text',
'label'         => __('Shipping Date', 'woocommerce' ),
'description'   => '',
'desc_tip'      => 'true',
'placeholder'   =>  __('i.e. 16 December 2017', 'woocommerce' ),
) );
}

// save the data value from this custom field on product admin tab
add_action( 'woocommerce_process_product_meta', 'save_shipdate_custom_field' );
function save_shipdate_custom_field( $post_id ) {
$wc_text_field = $_POST['_shipdate'];
if ( !empty($wc_text_field) ) {
update_post_meta( $post_id, '_shipdate', esc_attr( $wc_text_field ) );
}
}

function product_date() {
echo get_post_meta( get_the_ID(), '_shipdate', true );
}

add_action('woocommerce_single_product_summary', 'product_date', 30);

I am able to get static text to display on the checkout page, using the following code, but it just won't work with my custom field:

function emaildate() { echo "This will display fine"; } 

add_action('woocommerce_order_item_meta_start', 'emaildate', 10, 1);

Thanks in advance for the help!

  • _I am able to get static text to display on the checkout page_ - Possible to show how you are trying this, ie, the `emaildate` method? – Michael Doye Sep 08 '17 at 12:37
  • So, doing this for example: `function emaildate() { echo "This will display fine"; }` `add_action('woocommerce_order_item_meta_start', 'emaildate', 10, 1);` – Conor Campbell Sep 08 '17 at 12:50
  • Please add any additional relevant information to your question. Information in comments can be easily missed. – FluffyKitten Sep 08 '17 at 12:56
  • You should be able to use `echo get_post_meta( get_the_ID(), '_shipdate', true ); ` to show the `_shipdate` value. – Michael Doye Sep 08 '17 at 12:56
  • Thanks for the help so far. I've edited my question with the additional info. @Und3rTow, that code works just fine for displaying the field in a single product page. However, the checkout page just doesn't show it. – Conor Campbell Sep 08 '17 at 13:03

1 Answers1

0

You are missing a couple of steps to have your custom value display on the cart/checkout pages, namely, storing the custom field in the cart and in the order as meta data. Here is the full code which should work as expected:

 // create the custom field on product admin tab
add_action( 'woocommerce_product_options_general_product_data', 'create_shipping_custom_field' );
function create_shipping_custom_field() {
    // Create a custom text field
    woocommerce_wp_text_input( array(
        'id'            => '_shipdate',
        'type'          => 'text',
        'label'         => __('Shipping Date', 'woocommerce' ),
        'description'   => '',
        'desc_tip'      => 'true',
        'placeholder'   =>  __('i.e. 16 December 2017', 'woocommerce' ),
    ) );
}

// save the data value from this custom field on product admin tab
add_action( 'woocommerce_process_product_meta', 'save_shipping_custom_field' );
function save_shipping_custom_field( $post_id ) {
    $wc_text_field = $_POST['_shipdate'];
    if ( !empty($wc_text_field) ) {
        update_post_meta( $post_id, '_shipdate', esc_attr( $wc_text_field ) );
    }
}

// Store custom field in Cart
add_action( 'woocommerce_add_cart_item_data', 'store_shipping_custom_field', 10, 2 );
function store_shipping_custom_field( $cart_item_data, $product_id ) {
    $ship_date = get_post_meta( $product_id , '_shipdate', true );
    if( !empty($ship_date) ) {
        $cart_item_data[ '_shipdate' ] = $ship_date;

        $cart_item_data['unique_key'] = md5( microtime().rand() );
        WC()->session->set( 'date_shipping', $ship_date );
    }
    return $cart_item_data;
}


// Render meta on cart and checkout
add_filter( 'woocommerce_get_item_data', 'rendering_meta_field_on_cart_and_checkout', 10, 2 );
function rendering_meta_field_on_cart_and_checkout( $cart_data, $cart_item ) {
    $custom_items = array();
    // Woo 2.4.2 updates
    if( !empty( $cart_data ) ) {
        $custom_items = $cart_data;
    }
    if( isset( $cart_item['_shipdate'] ) ) {
        $custom_items[] = array( "name" => __( "Shipping Date", "woocommerce" ), "value" => $cart_item['_shipdate'] );
    }
    return $custom_items;
}

// Add the information in the order as meta data
add_action('woocommerce_add_order_item_meta','add_shipping_to_order_item_meta', 1, 3 );
function add_shipping_to_order_item_meta( $item_id, $values, $cart_item_key ) {
    $prod_id = wc_get_order_item_meta( $item_id, '_product_id', true );
    $shipdate = get_post_meta( $prod_id, '_shipdate', true );
    wc_add_order_item_meta( $item_id, 'Shipping Date', $shipdate, true );
}
Michael Doye
  • 8,063
  • 5
  • 40
  • 56
  • You're a legend. It's almost perfect. The only thing not showing the date now is the order receipt email. – Conor Campbell Sep 08 '17 at 17:05
  • Oh right, will have a look today when I get a gap :) – Michael Doye Sep 11 '17 at 06:41
  • I really appreciate it, thanks again! – Conor Campbell Sep 11 '17 at 07:54
  • Turns out it was just a typo, have modified the last function - `add_shipping_to_order_item_meta` above, you just need to replace `$product_id` with `$prod_id` in your code and value should then show on the order received page as well as in the order emails – Michael Doye Sep 11 '17 at 08:45
  • Brilliant! I really appreciate the help. It works perfectly. For interests sake, I added this line of code to get it to display on the single product page as well: `function product_date() { echo get_post_meta( get_the_ID(), '_shipdate', true ); } add_action('woocommerce_single_product_summary', 'product_date', 30);` – Conor Campbell Sep 11 '17 at 09:07
  • Nice one! Glad to help :) – Michael Doye Sep 11 '17 at 09:22