I have a similar like in here: I don't understand why the value of this custom field is not saved. Here's my code:
add_filter( 'woocommerce_checkout_fields' , 'altri_campi' );
function altri_campi( $fields ) {
$fields['billing']['codice_fiscale'] = array(
'class' => array('form-row-wide'),
'label' => __('Codice Fiscale', 'woocommerce'),
'placeholder' => _x('Scrivere anche il Codice Fiscale', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide')
);
return $fields;
}
// like LoizTheAztec above
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta', 10, 1 );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['codice_fiscale'] ) ) {
update_post_meta( $order_id, 'Codice Fiscale', sanitize_text_field( $_POST['codice_fiscale'] ) );
}
}
// then I'm expecting that custom field value will be saved somehow, but won't
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Codice Fiscale', 'woocommerce').':</strong> ' . get_post_meta( $order->get_id(), '_codice_fiscale', true ) . '</p>';
}
Meta field is correctly saved and printed, but I cannot add the custom field value in the order data view.
What I am doing wrong and how to display this custom field value in the Order edit view?
Otherwise the text I expect to find after Customer's billing and shipping data is void, since I read only the html part of the latest snippet.
Here is the correct commented and explained code:
// Creating and displaying the custom checkout field in checkout page
add_filter( 'woocommerce_checkout_fields' , 'altri_campi' );
function altri_campi( $fields ) {
$fields['billing']['codice_fiscale'] = array(
'class' => array('form-row-wide'),
'label' => __('Codice Fiscale', 'woocommerce'),
'placeholder' => _x('Scrivere anche il Codice Fiscale', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide')
);
return $fields;
}
// Saving the custom checkout field value in the order meta data
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta', 10, 1 );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['codice_fiscale'] ) ){
update_post_meta( $order_id, 'codice_fiscale', sanitize_text_field( $_POST['codice_fiscale'] ) );
// get the customer ID
$customer_id = get_post_meta( $order_id, '_customer_user', true );
// Update customer user data
update_user_meta( $customer_id, 'codice_fiscale', true );
}
}
// Displaying the custom checkout field value in the order edit page (backend)
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'custom_checkout_field_display_admin_order_meta', 10, 1 );
function custom_checkout_field_display_admin_order_meta( $order ){
$codice_fiscale = get_post_meta( $order->get_id(), 'codice_fiscale', true );
if( ! empty( $codice_fiscale ))
echo '<p><strong>'.__('Codice Fiscale', 'woocommerce').':</strong> ' . $codice_fiscale . '</p>';
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works. You will get in backend order edit page something like (below addresses):
Related
Im looking to find some php code that will allow me to extract information (Name, address etc) from the checkout fields and add it to the order meta data.
Looking for this to be a simple as possible
Ive previously found this code which allows a custom box to be added to the checkout page, and I sort of understand how it works, however I want to capture their name when they type it into the billing first name box. I can seem to grasp how to capture this data and put it into the order meta data, Ive tried shortening the code and editing it a few times but I dont seem to be winning
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Phone From Checkout Form').':</strong> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
/**
* Add the field to the checkout
*/
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_name', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_name' ));
echo '</div>';
}
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['my_field_name'] )
wc_add_notice( __( 'Please enter something into this new shiny field.' ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) ) {
update_post_meta( $order_id, 'My Field', sanitize_text_field( $_POST['my_field_name'] ) );
}
}
I like this and it does work but just not in the way i need it to work. thanks for any and all help
There are some mistakes and missing things in your code… Try the following replacement code instead:
// Add shipping phone (in checkout and My account edit shipping address) and save field value
add_action( 'woocommerce_shipping_fields', 'add_shipping_phone_field' );
function add_shipping_phone_field( $fields ) {
$fields['shipping_phone'] = array(
'label' => __('Phone', 'woocommerce'),
'placeholder' => _x('Phone', 'placeholder', 'woocommerce'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
// Display shipping phone value on the order edit pages under shipping section
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_shipping_phone_in_admin_orders' );
function display_shipping_phone_in_admin_orders( $order ){
$phone_value = $order->get_meta('_shipping_phone');
if ( ! empty($phone_value) ) {
echo '<p><strong>'.__('Shipping phone').':</strong> ' . $phone_value . '</p>';
}
}
// Add a custom checkout field
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="my_custom_checkout_field"><h2>' . __('My Field') . '</h2>';
woocommerce_form_field( 'my_field_slug', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My custom field'),
'placeholder' => __('Enter something… '),
'required' => true,
), $checkout->get_value( 'my_field_slug' ) );
echo '</div>';
}
// Validate required checkout fields
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( isset($_POST['my_field_slug']) && empty($_POST['my_field_slug']) ) {
wc_add_notice( __( '"My custom field" is a required field.' ), 'error' );
}
}
// Add custom checkout field value as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order ) {
if ( isset($_POST['my_field_slug']) && ! empty($_POST['my_field_slug']) ) {
$order->update_meta_data( 'My Field', sanitize_text_field( $_POST['my_field_slug'] ) );
}
}
// Display "My field" value on the order edit pages under billing section
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_my_custom_checkout_field_in_admin_orders', 10, 1 );
function display_my_custom_checkout_field_in_admin_orders($order){
$my_field_value = $order->get_meta('My Field');
if ( ! empty($my_field_value) ) {
echo '<p><strong>'.__('My field').':</strong> ' . $my_field_value . '</p>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Now If you need to extract some data from Woocommerce existing checkout fields and combine it in a custom way to save it as custom order meta data, try to be more explicit:
What fields?
How you want to combine it?
What is the custom field slug to be used to save that data combination?
We managed to put a custom field for variation products following Remi Corson guide here
At this point, we are able to show the custom text field in the single product page when users select the variation, but this is not enough in the purchase process since we need to:
A) Display this text in Cart and Checkout
B) Save this information so it shows in Thank You Page, Emails and Admin Order Edit Page
Something similar to Save and display product custom meta on WooCommerce orders and emails, but with product variations instead of simple products.
This is the code we added to our functions.php to add the custom field to the product variations
// Add Variation Settings
add_action( 'woocommerce_product_after_variable_attributes', 'variation_settings_fields', 10, 3 );
// Save Variation Settings
add_action( 'woocommerce_save_product_variation', 'save_variation_settings_fields', 10, 2 );
/**
* Create new fields for variations
*
*/
function variation_settings_fields( $loop, $variation_data, $variation ) {
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field[' . $variation->ID . ']',
'label' => __( 'My Text Field', 'woocommerce' ),
'placeholder' => 'http://',
'desc_tip' => 'true',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'value' => get_post_meta( $variation->ID, '_text_field', true )
)
);
// Hidden field
woocommerce_wp_hidden_input(
array(
'id' => '_hidden_field[' . $variation->ID . ']',
'value' => 'hidden_value'
)
);
}
/**
* Save new fields for variations
*
*/
function save_variation_settings_fields( $post_id ) {
// Text Field
$text_field = $_POST['_text_field'][ $post_id ];
if( ! empty( $text_field ) ) {
update_post_meta( $post_id, '_text_field', esc_attr( $text_field ) );
}
// Hidden field
$hidden = $_POST['_hidden_field'][ $post_id ];
if( ! empty( $hidden ) ) {
update_post_meta( $post_id, '_hidden_field', esc_attr( $hidden ) );
}
}
// Add New Variation Settings
add_filter( 'woocommerce_available_variation', 'load_variation_settings_fields' );
/**
* Add custom fields for variations
*
*/
function load_variation_settings_fields( $variations ) {
// duplicate the line for each field
$variations['text_field'] = get_post_meta( $variations[ 'variation_id' ], '_text_field', true );
return $variations;
}
So the goal here is how can we show this custom field for each variation in the Cart and Checkout below the items (Something like the image below - Look at the Shipping delay notice)
And to save that custom field info that each variation has to the Thank You Page, Emails and Order Page (We did it for simple products with this code, but this doesn't work for variable ones)
// Save and display "Custom Field for Simple Products" on order items everywhere
add_filter( 'woocommerce_checkout_create_order_line_item', 'action_wc_checkout_create_order_line_item', 10, 4 );
function action_wc_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
// Get the Custom Field
$value = $values['data']->get_meta( 'custom_field_for_simple_products' );
if( ! empty( $value ) ) {
// Save it and display it
$item->update_meta_data( __( 'Custom Fields', 'woocommerce' ), $value );
}
}
Please help!!
Updated
There are some mistakes in your code… The following revisited code will solve your issue:
// Display Variation custom fields (admin)
add_action( 'woocommerce_product_after_variable_attributes', 'display_variation_setting_custom_fields', 10, 3 );
function display_variation_setting_custom_fields( $loop, $variation_data, $variation ) {
echo '<div>';
woocommerce_wp_text_input( array( // Text Field
'id' => "_text_field[$loop]",
'label' => __("My Text Field", "woocommerce"),
'placeholder' => "http://",
'desc_tip' => true,
'description' => __("Enter the custom value here.", "woocommerce"),
'wrapper_class' => 'form-row form-row-full',
'value' => get_post_meta( $variation->ID, '_text_field', true ),
) );
woocommerce_wp_hidden_input( array( // Hidden field
'id' => "_hidden_field[$loop]",
'value' => 'hidden_value',
) );
echo '</div>';
}
// Save Variation custom fields
add_action( 'woocommerce_save_product_variation', 'save_variation_custom_fields', 10, 2 );
function save_variation_custom_fields( $variation_id, $i ) {
// Save Text Field
if( isset( $_POST['_text_field'][$i] ) && ! empty( $_POST['_text_field'][$i] ) )
update_post_meta( $variation_id, '_text_field', sanitize_text_field( $_POST['_text_field'][$i] ) );
// Save Hidden Field
if( isset( $_POST['_hidden_field'][$i] ) && ! empty( $_POST['_hidden_field'][$i] ) )
update_post_meta( $variation_id, '_hidden_field', esc_attr( $_POST['_hidden_field'][$i] ) );
}
// Include our variation custom field
add_filter( 'woocommerce_available_variation', 'include_variation_custom_field', 10, 3) ;
function include_variation_custom_field( $data, $product, $variation ) {
$data['text_field'] = $variation->get_meta( '_text_field' );
return $data;
}
// Save and display "Custom Field for Simple Products" on order items everywhere
add_filter( 'woocommerce_checkout_create_order_line_item', 'action_wc_checkout_create_order_line_item_2', 10, 4 );
function action_wc_checkout_create_order_line_item_2( $item, $cart_item_key, $values, $order ) {
// Get the Custom Field
$value = $values['data']->get_meta( '_text_field' );
if( ! empty( $value ) ) {
// Save it and display it
$item->update_meta_data( __( 'Custom Field', 'woocommerce' ), $value );
}
}
Code goes in functions.php file of your active child theme (or active theme) . Tested and works.
Related: Save and display product custom meta on WooCommerce orders and emails
Somme screenshots
On admin product variations settings:
On order received page (thankyou):
On admin edit orders pages:
I created a some custom fields for Woocommerce in the check-out page. I was able to display them in WP admin area, email and invoices but not in the Front-End for User's Dashboard.
This is the code I used to create the field "CODICE SNEP" in my CHILD-THEM on function.php file:
// Create hook - CODICE SNEP
add_filter( 'woocommerce_checkout_fields' , 'codice_snep' );
function codice_snep ( $fields ) {
$fields['billing']['codice_snep'] = array(
'label' => __('Codice Snep', 'woocommerce'),
'placeholder' => _x('Codice Snep', 'placeholder', 'woocommerce'),
'required' => true,
'clear' => true
);
return $fields;
}
add_action( 'woocommerce_checkout_update_order_meta', 'codice_snep_order_meta' );
function codice_snep_order_meta( $order_id ) {
if ( ! empty( $_POST['codice_snep'] ) ) {
update_post_meta( $order_id, 'Codice Snep', sanitize_text_field( $_POST['codice_snep'] ) );
}
}
// Save the custom field 'codice_snep'
add_action( 'woocommerce_save_account_details', 'save_codice_snep_account_details', 12, 1 );
function save_codice_snep_account_details( $user_id ) {
// For Codice Snep
if( isset( $_POST['codice_snep'] ) )
update_user_meta( $user_id, 'codice_snep', sanitize_text_field( $_POST['codice_snep'] ) );
}
After that I show an error if you don't put the field:
// Show error if you don't insert CODICE SNEP
add_action('woocommerce_checkout_process', 'required_codice_snep_checkout_field_process');
function required_codice_snep_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['codice_snep'] )
wc_add_notice( __( 'Compila il campo Codice SNEP .' ), 'error' );
}
Than I show the code in the Admin Area of WC, emails and invoice:
// Show field codice snep in the Wc pdf invoices plugin
add_action( 'wpo_wcpdf_after_order_data', 'wpo_wcpdf_codice_snep', 10, 2 );
function wpo_wcpdf_codice_snep ($template_type, $order) {
$document = wcpdf_get_document( $template_type, $order );
if ($template_type == 'invoice') {
?>
<tr>
<th>Codice Snep:</th>
<td><?php $document->custom_field('Codice Snep'); ?></td>
</tr>
<?php
}
}
// Show CODICE SNEP in Back End Wp
add_action( 'woocommerce_admin_order_data_after_billing_address', 'codice_snep_order_meta_admin', 10, 1 );
function codice_snep_order_meta_admin($order){
echo '<p><strong>'.__('Codice Snep').':</strong> ' . get_post_meta( $order->id, 'Codice Snep', true ) . '</p>';
}
// Show codoce snep in the order email
add_filter('woocommerce_email_order_meta_keys', 'my_custom_codice_snep_order_meta_keys');
function my_custom_codice_snep_order_meta_keys( $keys ) {
$keys[] = 'Codice Snep';
return $keys;
}
Everything seems to work until here.
The problem now is to just show (must be not editable) this field (codice_snep) in the Dashboard front-end.
Right now I'm trying with this but I can only see the label without the value of the field.
// Show codice snep in the Dashboard of the user in front-end.
add_action( 'woocommerce_account_dashboard', 'codice_snep_order_dashboard', 12, 1 );
function codice_snep_order_dashboard ($order){
echo '<p><strong>'.__('Codice Snep').':</strong> ' . get_post_meta( $order->id, 'Codice Snep', true ) . '</p>';
}
This is what happens: Field not showing on dashboard
Can you help me to fix this problem in order to show the value that the user insert in the check-out?
The code you are using is a bit outdated and/or some hooks are deprecated (even if they come from Woocommerce documentation).
The code below uses different hooks. It allows to display this field and the related data (when it exist), in checkout and in My account > Adresses > Billing fields, without any need of additional validation code.
Also when order is placed, the data is saved with one hook in the order and in the user meta data at the same time. So the code is more compact and uses the right hooks with the new CRUD methods introduced in Woocommerce 3.
Your revisited code:
// Display a custom field on checkout and on My account > edit billing address
add_filter( 'woocommerce_billing_fields' , 'adding_billing_codice_snep', 20, 1 );
function adding_billing_codice_snep ( $fields ) {
$fields['billing_codice_snep'] = array(
'label' => __('Codice Snep', 'woocommerce'),
'placeholder' => _x('Codice Snep', 'placeholder', 'woocommerce'),
'class' => array('form-row-wide'),
'required' => true,
'clear' => true,
);
return $fields;
}
// Save the custom field data to the order meta data and to user meta data
add_action( 'woocommerce_checkout_create_order', 'codice_snep_order_meta', 20, 2 );
function codice_snep_order_meta( $order, $data ) {
if ( isset( $_POST['billing_codice_snep'] ) && ! empty( $_POST['billing_codice_snep'] ) ) {
$order->update_meta_data('_billing_codice_snep', sanitize_text_field( $_POST['billing_codice_snep'] ) );
update_user_meta( $order->get_customer_id(), 'billing_codice_snep', sanitize_text_field( $_POST['billing_codice_snep'] ) );
}
}
// Order pages (frontend and admin): Display custom field "codice snep"
add_filter( 'woocommerce_order_details_after_order_table' , 'display_admin_order_meta_codice_snep', 20, 1 ); // Front
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_admin_order_meta_codice_snep', 20, 1 ); // Admin
function display_admin_order_meta_codice_snep( $order ){
$codice_snep = $order->get_meta('_billing_codice_snep', true );
if( ! empty( $codice_snep ) ){
$label = __('Codice Snep');
if( is_admin() ){ // Admin
echo '<p><strong>' . $label . ':</strong> ' . $codice_snep . '</p>';
}
else { // Front end: order view and Order received (thankyou)
echo '<table class="woocommerce-table"><tbody><tr>
<th>' . $label . ':</th><td>' . $codice_snep . '</td>
</tr></tbody></table>';
}
}
}
// Email notifications: Display custom field "codice snep"
add_filter( 'woocommerce_email_order_meta_fields' , 'display_email_codice_snep', 20, 3 );
function display_email_codice_snep ( $fields, $sent_to_admin, $order ) {
$codice_snep = $order->get_meta('_billing_codice_snep', true );
if( ! empty( $codice_snep ) )
$fields['codice_snep'] = array(
'label' => __("Codice Snep"),
'value' => $codice_snep,
);
return $fields;
}
// PDF Invoices: Display custom field "codice snep"
add_action( 'wpo_wcpdf_after_order_data', 'display_pdf_invoice_codice_snep', 20, 2 );
function display_pdf_invoice_codice_snep ($template_type, $order) {
$document = wcpdf_get_document( $template_type, $order );
if ($template_type == 'invoice') {
echo '<tr>
<th>' . __("Codice Snep") . ':</th>
<td>' . $order->get_meta('_billing_codice_snep', true ) . '</td>
</tr>';
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Order view:
My account > adresses > Billing
I've added a custom field to the checkout page on my Woocommerce store. The field is 'Restaurant Location'. Upon a customer placing an order, my goal is to use the 'Restaurant Location' field to determine which email to send the order confirmation to.
Here's how I defined the custom field.
/////// Hook custom field in ///////
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields' );
function custom_checkout_fields( $fields ) {
$fields['order']['restaurant_location'] = array(
'label' => __('Food options', 'woocommerce'),
'placeholder' => _x('', 'placeholder', 'woocommerce'),
'required' => true,
'clear' => false,
'type' => 'select',
'options' => array(
'no' => __('New Orleans', 'woocommerce' ),
'br' => __('Baton Rouge', 'woocommerce' )
)
);
return $fields;
}
Here's my attempt at the email filter.
add_filter( 'woocommerce_email_recipient_new_order', 'gon_conditional_email_recipient', 10, 2 );
function gon_conditional_email_recipient( $recipient, $order ) {
$gon_order_data = $order->get_data();
$gon_restaurant_location = $gon_order_data['order']['restaurant_location'];
if ( $gon_restaurant_location == 'New Orleans' ) {
$recipient = 'test1#gmail.com';
return $recipient;
}
else if ( $gon_restaurant_location == 'Baton Rouge' ) {
$recipient = 'test2#gmail.com';
return $recipient;
}
return $recipient;
}
The email filter is working, i.e. I can get an email to go to either address, but I can't seem to pull in the '$gon_restaurant_location' variable properly. Any ideas?
Thanks,
pS
Your custom field value is not saved in database, so that's why is not working. Try this complete solution instead:
// Add the custom checkout field
add_filter( 'woocommerce_after_order_notes', 'restaurant_location_checkout_field' );
function restaurant_location_checkout_field( $checkout ) {
woocommerce_form_field( 'restaurant_location', array(
'type' => 'select',
'class' => array('my-field-class form-row-wide'),
'label' => __('Food options', 'woocommerce'),
'required' => true,
'options' => array(
'' => __('Please select an option', 'woocommerce' ),
'New Orleans' => __('New Orleans', 'woocommerce' ),
'Baton Rouge' => __('Baton Rouge', 'woocommerce' )
)
), $checkout->get_value( 'restaurant_location' ));
}
// Process the checkout (checking)
add_action('woocommerce_checkout_process', 'restaurant_location_field_process');
function restaurant_location_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['restaurant_location'] )
wc_add_notice( __( 'Please select a food option .' ), 'error' );
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'restaurant_location_field_update_order_meta' );
function restaurant_location_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['restaurant_location'] ) ) {
update_post_meta( $order_id, '_restaurant_location', sanitize_text_field( $_POST['restaurant_location'] ) );
}
}
// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Food options', 'woocommerce').':</strong> ' . get_post_meta( $order->get_id(), '_restaurant_location', true ) . '</p>';
}
// Conditional Email recipient filter based on restaurant location
add_filter( 'woocommerce_email_recipient_new_order', 'conditional_email_recipient', 10, 2 );
function conditional_email_recipient( $recipient, $order ) {
if( is_admin() ) return $recipient;
$location = get_post_meta( $order->get_id(), '_restaurant_location', true );
$recipient = $location == 'New Orleans' ? ',test1#example.com' : ',test1#example.com';
return $recipient;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works
Based on official developer documentation: Adding a custom special field
This question already has an answer here:
Admin product pages custom field displayed in Cart and checkout
(1 answer)
Closed 5 years ago.
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!
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 );
}