I am trying to get some custom fields attached to my order in Woocommerce.
I have succeeded previously in getting some new fields entered by the user in the checkout based on this official documentation.
What I am trying to achieve is passing a set string value to a custom field based on some other product checking logic I have working. Basically if product of a certain category:
is in cart, display message one: (shipping_instructions_delivery_field_update_order_meta)
otherwise display message two (shipping_instructions_pickup_field_update_order_meta).
My code:
// adds order note at checkout page for the RRNC to pickup at home
add_action( 'woocommerce_before_checkout_form', 'specific_checkout_content', 12 );
function specific_checkout_content() {
// set your special category name, slug or ID here:
$special_cat = 'randwick-rugby-netball-club';
$bool = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$item = $cart_item['data'];
if ( has_term( $special_cat, 'product_cat', $item->id ) )
$bool = true;
}
// If the special category is detected in one items of the cart
// It displays the message
if ($bool)
{
echo '<div class="checkout-instructions"><p><strong>PLEASE PICK UP ORDER FROM THE CLUB.</strong></p></div>';
add_filter( 'woocommerce_cart_needs_shipping_address', '__return_false'); //Removes the ship to different address for club store items
add_filter( 'woocommerce_enable_order_notes_field', 'remove_wc_order_notes' ); //Removes the order notes
add_action( 'woocommerce_checkout_update_order_meta', 'shipping_instructions_pickup_field_update_order_meta' ); //Adds the pick up note for the pdf slip
add_action( 'woocommerce_checkout_process', 'my_custom_checkout_field_process_pickup' );
}
else
{
echo '<p><strong>Orders are dispatched within 2 business days and shipping times are estimated at between 3-7 business days depending on your location within Australia.</strong></p>';
add_action( 'woocommerce_before_order_notes', 'delivery_instructions_field', 10 ); //Adds the Delivery Instructions fields to the checkout
add_action( 'woocommerce_checkout_update_order_meta', 'shipping_instructions_delivery_field_update_order_meta' ); //Adds the delivery note for the pdf slip
add_action( 'woocommerce_checkout_process', 'my_custom_checkout_field_process_delivery' );
}
}
function my_custom_checkout_field_process_delivery( ) {
global $woocommerce;
// Check if set, if its not set add an error.
if ( !$_POST[ 'delivery_instructions' ] )
wc_add_notice( __( 'Please select from the delivery options.' ), 'error' );
/*$woocommerce->add_error( __( 'Please select from the delivery options.' ) );*/
if ( !$_POST[ 'sport_instructions' ] )
wc_add_notice( __( 'Please select the sport of the order' ), 'error' );
/*$woocommerce->add_error( __( 'Please select the sport of the order' ) );*/
}
function my_custom_checkout_field_process_pickup( ) {
global $woocommerce;
// Check if set, if its not set add an error.
if ( !$_POST[ 'sport_instructions' ] )
wc_add_notice( __( 'Please select the sport of the order' ), 'error' );
/*$woocommerce->add_error( __( 'Please select the sport of the order' ) );*/
}
// remove Order Notes from checkout field in Woocommerce
function remove_wc_order_notes() {
return false;
}
function shipping_instructions_delivery_field_update_order_meta( $order_id ) {
update_post_meta( $order_id, 'shipping_instructions', 'IF YOU HAVE NOT RECEIVED YOUR ORDER WITHIN 7 DAYS, PLEASE CONTACT US TO FOLLOW UP' );
}
function shipping_instructions_pickup_field_update_order_meta( $order_id ) {
update_post_meta( $order_id, 'shipping_instructions', 'PLEASE PICK UP FROM THE CLUB SHOP' );
}
//Admin side
/**
* Update the order meta with field value
**/
add_action( 'woocommerce_checkout_update_order_meta', 'delivery_instructions_field_update_order_meta' );
function delivery_instructions_field_update_order_meta( $order_id ) {
if ( $_POST[ 'delivery_instructions' ] )
update_post_meta( $order_id, 'delivery_instructions', esc_attr( $_POST[ 'delivery_instructions' ] ) );
}
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_shipping_fields_display_admin_order_meta', 10, 1);
function my_custom_shipping_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Shipping Note') . ':</strong><br> ' . get_post_meta($order->id, 'shipping_instructions', true) . '</p>';
}
$shipping_instructions = get_post_meta($wpo_wcpdf->export->order->id,'shipping_instructions',true);
if (isset($shipping_instructions)) {
echo $shipping_instructions;
}
/**
* Add the delivery instructions field to the checkout
**/
function delivery_instructions_field( $checkout ) {
echo '<div id="delivery_instructions_field"><h2>' . __('Delivery Instructions') . '</h2>';
woocommerce_form_field_radio( 'delivery_instructions', array(
'type' => 'select',
'class' => array(
'delivery_instructions form-row-wide'
),
'label' => __( '' ),
'placeholder' => __( '' ),
'required' => true,
'options' => array(
'Signature Required' => '<b> Signature Required</b><br/>A signature is required for the goods to be left at the intended address. If there is no one to sign for your delivery, a card will be left and it is then your responsibility to collect the items from the nearest depot or arrange for the courier to return. This will be at your expense<br/><br/>',
'Leave Unattended' => '<b> Authority to leave unattended</b><br/>Courier will leave your goods at the intended address. You can give directions in the “Order Notes” below for the best place to leave your delivery',
)
), $checkout->get_value( 'delivery_instructions' ) );
echo '</div>';
}
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_billing_fields_display_admin_order_meta', 10, 1);
function my_custom_billing_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Delivery Instructions') . ':</strong><br> ' . get_post_meta($order->id, 'delivery_instructions', true) . '</p>';
}
$delivery_instructions = get_post_meta($wpo_wcpdf->export->order->id,'_delivery_instructions',true);
if (isset($delivery_instructions)) {
echo $delivery_instructions;
}
/**
* Add the field to the checkout to get the sport of what the customer orders
**/
add_action( 'woocommerce_after_order_notes', 'sport_instructions_field', 20 );
function sport_instructions_field( $checkout ) {
echo '<div id="sport_instructions_field"><h2>' . __('Which sport is this order in relation to?') . '</h2>';
woocommerce_form_field_radio( 'sport_instructions', array(
'type' => 'select',
'class' => array(
'sport_instructions form-row-wide'
),
'label' => __( '' ),
'placeholder' => __( '' ),
'required' => true,
'options' => array(
'Rugby Union' => '<b>Rugby Union</b><br/>',
'Rugby League' => '<b>Rugby League</b><br/>',
'Netball' => '<b>Netball</b><br/>',
'Football' => '<b>Football</b><br/>',
'AFL' => '<b>AFL</b><br/>',
'Touch Tag' => '<b>Touch & Tag</b>',
)
), $checkout->get_value( 'sport_instructions' ) );
echo '</div>';
}
/**
* Update the order meta with field value
**/
add_action( 'woocommerce_checkout_update_order_meta', 'sport_instructions_field_update_order_meta' );
function sport_instructions_field_update_order_meta( $order_id ) {
if ( $_POST[ 'sport_instructions' ] )
update_post_meta( $order_id, 'sport_instructions', esc_attr( $_POST[ 'sport_instructions' ] ) );
}
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_sports_fields_display_admin_order_meta', 20, 1);
function my_custom_sports_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Sport in relation to') . ':</strong><br> ' . get_post_meta($order->id, 'sport_instructions', true) . '</p>';
}
$sport_instructions = get_post_meta($wpo_wcpdf->export->order->id,'_sport_instructions',true);
if (isset($sport_instructions)) {
echo $sport_instructions;
}
I would think that the update_post_meta() with a string at the end should set it but it does not appear to do anything. Or perhaps I don't have the proper fuctionality with:
function my_custom_checkout_field($checkout).
Any help is appreciated.
Try this code. _shipping_instructions replace this with shipping_instructions
$shipping_instructions = get_post_meta($wpo_wcpdf->export->order >id,'shipping_instructions',true);
if (isset($shipping_instructions)) {
echo $shipping_instructions;
}
Related
I have entered this code into my functions.php but only the second product field (302) is showing in test orders in the admin section. Is there a way to get the 2nd product (294)to pass to the admin with this implementation?
add_action( 'woocommerce_checkout_fields', 'woo_add_conditional_checkout_fields' );
function woo_add_conditional_checkout_fields( $fields ) {
foreach( WC()->cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
if( $product_id == 294 ) {
$fields['billing']['billing_field_' . $product_id] = array(
'label' => __( 'Enter License Plate and State' ),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
}
if( $product_id == 302 ) {
$fields['billing']['billing_field_' . $product_id] = array(
'label' => __( 'Enter License Plate, State AND CITATION Number' ),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
}
}
// Return checkout fields.
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>'.__('License Plate and State').':</strong> ' . get_post_meta( $order->get_id(), '_billing_field_294', true ) . '</p>';
echo '<p><strong>'.__('License Plate, State AND CITATION Number').':</strong> ' . get_post_meta( $order->get_id(), '_billing_field_302', true ) . '</p>';
}
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?
In short:
I want to display a new field on Woocommerce Checkout 'daypart'. This is a dropdown field with 3 options.
The code is working and I can see it on WooCommerce backend but I need to save the data in "Customer Notes" field but as an addition of the customer comments (if any) I'm stuck here, no clue in how to do this.
Additional information:
I need to save daypart in a core checkout field because the store synchs to another shipping service that doesn't synch order meta data.
Here's the code:
//define current user status to display things on checkout
if( current_user_can( 'rethunk_retailers' ) ){
// Retailers text
//* Add select field to the checkout page
add_action('woocommerce_before_order_notes', 'wps_add_select_checkout_field');
function wps_add_select_checkout_field( $checkout ) {
echo '<h2>'.__('Partial Shipment Options').'</h2>';
echo '<p>'.__('Option 1: details for option 1').'</p>';
echo '<p>'.__('Option 2: details for option 2').'</p>';
echo '<p>'.__('Option 3: details for option 3').'</p>';
woocommerce_form_field( 'daypart', array(
'label' => __( 'Delivery options' ),
'type' => 'select',
'class' => array( 'wps-drop' ),
'required' => true,
'options' => array(
'blank' => __( 'Please choose one', 'wps' ),
'Yes I want Partial Shipment' => __( 'Option 1: I want a partial shipment', 'wps' ),
'Please do not ship a partiel shipment' => __( 'Option 2: Do not ship a partial shipment to me.', 'wps' ),
'I will Wait do not refund anything' => __( 'Option 3: Do not refund anything', 'wps' )
)
),
$checkout->get_value( 'daypart' ));
}
//* Process the checkout
add_action('woocommerce_checkout_process', 'wps_select_checkout_field_process');
function wps_select_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if ($_POST['daypart'] == "blank")
wc_add_notice( '<strong>Please select a Partial Shipment Option </strong>', 'error' );
}
//* Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {
if ($_POST['daypart']) update_post_meta( $order_id, 'daypart', esc_attr($_POST['daypart']));
}
} else {
// not retailers text
}
//* Add selection field value to emails
add_filter('woocommerce_email_order_meta_keys', 'wps_select_order_meta_keys');
function wps_select_order_meta_keys( $keys ) {
$keys['Shipping Option:'] = 'daypart';
return $keys;
}
//* Display field value on the order edition page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'wps_select_checkout_field_display_admin_order_meta', 10, 1 );
function wps_select_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Delivery option').':</strong> ' . get_post_meta( $order->id, 'daypart', true ) . '</p>';
}
To include the "daypart" selected value to customer order notes, you will replace from your code:
// Update the order meta with field value
add_action('woocommerce_checkout_update_order_meta', 'wps_select_checkout_field_update_order_meta');
function wps_select_checkout_field_update_order_meta( $order_id ) {
if ( $_POST['daypart']) update_post_meta( $order_id, 'daypart', esc_attr($_POST['daypart']));
}
by the following:
// Update the order meta with field value
add_action( 'woocommerce_checkout_create_order', 'wps_update_order_meta', 20, 2 );
function wps_update_order_meta( $order, $data ) {
if ( isset($_POST['daypart']) && ! empty($_POST['daypart']) ) {
// Add "daypart" selected value as custom order meta data
$order->update_meta_data('daypart', esc_attr($_POST['daypart']));
// Get customer note
$customer_note = isset( $data['order_comments'] ) ? $data['order_comments'] . ' ' : '' );
// add to existing customer note the "daypart" selected value
$order->set_customer_note( $customer_note . esc_attr($_POST['daypart']) );
}
}
I read a few articles on the optgroup which is what i need, i manage to display it on the checkout page, but i need the selected option to be visible on email and the admin area where we view the order details.
Code comes from: "WooCommerce Select Dropdown With Optgroup On Checkout"
What I need: I'm creating a website where I need to add manually a few areas on the checkout page so the user can select his area so I can use it as validation and a way to limit the shipping, once the select area I need to be able to see this on the email order as well on the order that on Woocommerce zones doesn't fit in my case:
<?php
add_action('woocommerce_before_order_notes', 'custom_checkout_select_field_with_optgroup', 10, 1 );
function custom_checkout_select_field_with_optgroup( $checkout ) {
$domain = 'woocommerce';
$title = __("zona", $domain);
$slug = zone_limit;
$default = __("Selecione su Zona", $domain);
$value = $checkout->get_value($slug);
// Region option data array with optgroup
$options = array(
__("North zone", $domain) => array(
'region1' => __("Region 1", $domain),
'region2' => __("Region 2", $domain),
),
__("South zone", $domain) => array(
'region3' => __("Region 3", $domain),
'region4' => __("Region 4", $domain),
)
__("Middle zone", $domain) => array(
'region3' => __("Region 5", $domain),
'region4' => __("Region 6", $domain),
)
);
// The field
echo '<p class="form-row form-row-wide '.$slug.'-dropdown" id="'.$slug.'_field" data-priority="">
<label for="'.$slug.'" class="">'.$title.'</label>
<span class="woocommerce-input-wrapper">
<select name="'.$slug.'" id="'.$slug.'" class="select " data-placeholder="" autocomplete="'.$slug.'">
<option value="">'.$default.'</option>';
// Loop through "optgroup"
foreach( $options as $optgroup_label => $optgroup_options ) {
echo '<optgroup label="'.$optgroup_label.'">';
// Loop through "options" in the "optgroup"
foreach( $optgroup_options as $key => $label ) {
$selected = $value === $key ? ' selected="selected"': '';
echo '<option value="'.$key.'"'.$selected.'>'.$label.'</option>';
}
echo '</optgroup>';
}
echo '</select></span></p>';
}
I've tried this but not lucky
add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['meta_key'] = array(
'label' => __( 'Label' ),
'value' => get_post_meta( $order->id, 'meta_key', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = $value ; // This will look for a custom field called 'Tracking Code' and add it to emails
return $keys;
}
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[$value ] ) ) {
update_post_meta( $order_id, 'region', sanitize_text_field( $_POST[$value ] ) );
}
}
I hope i don't be penalized for this, my initial question was adding the selected value to the email order and use the optgroup collapse effect, however i was told the question was to broad, so i removed the jquery tag and effect and limit my self just the the php and getting it on the email order.
the php was fine i just couln'd get it on the email plus i needed the optgroup.
I did something else, i just used jquery instead of full php only, i created text type field and get it to send answer to email, then i created a modal manually(not wanted to use bootstrap) then a regular html for the optgroup and use jquery get the selected value and insert into the text field. here is my code.
The html is a basic that you can find here
And the css you can use this as example then bot css and html will need to be modify as you need
The php
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );
function my_custom_checkout_field( $checkout ) {
echo '<div id="myZoneLimit"><h2>' . __('valida tu zona') . '</h2>';
woocommerce_form_field( 'my_field_limit', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Fill in this field'),
'placeholder' => __('Enter something'),
), $checkout->get_value( 'my_field_limit' ));
echo '</div>';
}
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_limit'] )
wc_add_notice( __( 'Por favor seleccione su zona de envio.' ), 'error' );
}
add_filter('woocommerce_email_order_meta_keys', 'my_custom_order_meta_keys');
function my_custom_order_meta_keys( $keys ) {
$keys[] = 'valida tu zona'; // This will look for a custom field called 'Tracking Code' and add it to emails
return $keys;
}
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_limit'] ) ) {
update_post_meta( $order_id, 'valida tu zona', sanitize_text_field( $_POST['my_field_limit'] ) );
}
}
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>'.__('valida tu zona').':</strong> ' . get_post_meta( $order->id, 'valida tu zona', true ) . '</p>';
My jquery
/// button that opens the modal that was created the html
$("#my_field_limit").click(function(){
$("#myModalarea").show();
});
//// get the value from the selected option and place in into the the text field
$('#coveredareas').change(function(){
var areazone = $(this).val();
$("#my_field_limit").val(areazone);
In WooCommerce, I use code that shows a custom field on the checkout page. After filling out this field and placing the order by the client, the data is displayed on the "Thank You" page, when editing the order and in email notifications.
// Add the delivery custom field to the checkout
add_action( 'woocommerce_before_order_notes', 'my_delivery_custom_checkout_field' );
function my_delivery_custom_checkout_field( $checkout ) {
echo '<div><h3>' . __('Custom Delivery') . '</h3>';
woocommerce_form_field( 'my_custom_delivery', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My Custom Delivery'),
'placeholder' => __(''),
), $checkout->get_value( 'my_custom_delivery' ));
echo '</div>';
}
// Update the order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_delivery_checkout_field_update_order_meta' );
function my_custom_delivery_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_custom_delivery'] ) ) {
update_post_meta( $order_id, 'my_custom_delivery', sanitize_text_field( $_POST['my_custom_delivery'] ) );
}
}
// Display custom delivery field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_delivery_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_delivery_checkout_field_display_admin_order_meta($order){
echo '<div><strong>'.__('Custom Delivery').':</strong> ' . get_post_meta( $order->id, 'my_custom_delivery', true ) . '</div>';
}
// Display custom delivery field in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'my_custom_delivery_data_in_orders', 10 );
function my_custom_delivery_data_in_orders( $order ) {
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
}
// Display custom delivery field in Email notifications
add_filter( 'woocommerce_email_order_meta_fields', 'my_custom_delivery_data_in_emails', 10, 3 );
function my_custom_delivery_data_in_emails( $fields, $sent_to_admin, $order ) {
$fields['Custom Delivery'] = array(
'label' => __( 'Custom Delivery' ),
'value' => $order->get_meta( 'my_custom_delivery' ),
);
return $fields;
}
But there are two problems that I would like to fix:
The field name "Custom Delivery" is constantly displayed on the order editing page and in email notifications, even when this field is not filled in by the client.
I need to hide the name "Custom Delivery" on these pages if the field is not filled by the client.
The data of the "Custom Delivery" field is shown after the table with the order data.
I need to show the data of this field in the order table on the "Thank You" page and in email notifications.
I will be happy for your help!
The field name "Custom Delivery" is constantly displayed on the order editing page and in email notifications, even when this field is
not filled in by the client.
I need to hide the name "Custom Delivery" on these pages if the field
is not filled by the client.
Replace
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
With
$my_custom_delivery = get_post_meta( $order->id, 'my_custom_delivery', true );
if ( !empty( $my_custom_delivery ) ) {
echo '<div><strong>'.__('Custom Delivery').':</strong> ' . $my_custom_delivery . '</div>';
}
The data of the "Custom Delivery" field is shown after the table with the order data.
I need to show the data of this field in the order table on the "Thank
You" page and in email notifications.
Remove this
// Display custom delivery field in "Order received" and "Order view" pages (frontend)
add_action( 'woocommerce_order_details_after_order_table', 'my_custom_delivery_data_in_orders', 10 );
function my_custom_delivery_data_in_orders( $order ) {
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
echo '<div><span>'.__('Custom Delivery').':</span> ' . $my_custom_delivery . '</div>';
}
// Display custom delivery field in Email notifications
add_filter( 'woocommerce_email_order_meta_fields', 'my_custom_delivery_data_in_emails', 10, 3 );
function my_custom_delivery_data_in_emails( $fields, $sent_to_admin, $order ) {
$fields['Custom Delivery'] = array(
'label' => __( 'Custom Delivery' ),
'value' => $order->get_meta( 'my_custom_delivery' ),
);
return $fields;
}
And replace with
// Display the chosen delivery information everywhere on frontend order pages and on email notifications
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {
$new_total_rows = [];
// Loop through Order total lines
foreach($total_rows as $key => $total ){
// Get the custom delivery
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
// Display delivery information before payment method
if( ! empty($my_custom_delivery) && 'payment_method' === $key ){
$label = __('Custom Delivery:');
$value = $my_custom_delivery;
// Display 'Custom delivery' line
$new_total_rows['chosen_delivery'] = array( 'label' => $label, 'value' => $value );
}
$new_total_rows[$key] = $total;
}
return $new_total_rows;
}
So then you get
// Add the delivery custom field to the checkout (backend)
add_action( 'woocommerce_before_order_notes', 'my_delivery_custom_checkout_field' );
function my_delivery_custom_checkout_field( $checkout ) {
echo '<div><h3>' . __('Custom Delivery') . '</h3>';
woocommerce_form_field( 'my_custom_delivery', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('My Custom Delivery'),
'placeholder' => __(''),
), $checkout->get_value( 'my_custom_delivery' ));
echo '</div>';
}
// Update the order meta with field value (backend)
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_delivery_checkout_field_update_order_meta' );
function my_custom_delivery_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_custom_delivery'] ) ) {
update_post_meta( $order_id, 'my_custom_delivery', sanitize_text_field( $_POST['my_custom_delivery'] ) );
}
}
// Display custom delivery field value on the order edit page (frontend)
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_delivery_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_delivery_checkout_field_display_admin_order_meta($order){
echo '<div><strong>'.__('Custom Delivery').':</strong> ' . get_post_meta( $order->id, 'my_custom_delivery', true ) . '</div>';
}
// Display the chosen delivery information everywhere on frontend order pages and on email notifications (frontend)
add_filter( 'woocommerce_get_order_item_totals', 'chosen_delivery_item_order_totals', 10, 3 );
function chosen_delivery_item_order_totals( $total_rows, $order, $tax_display ) {
$new_total_rows = [];
// Loop through Order total lines
foreach($total_rows as $key => $total ){
// Get the custom delivery
$my_custom_delivery = $order->get_meta( 'my_custom_delivery' );
// Display delivery information before payment method
if( ! empty($my_custom_delivery) && 'payment_method' === $key ){
$label = __('Custom Delivery:');
$value = $my_custom_delivery;
// Display 'Custom delivery' line
$new_total_rows['chosen_delivery'] = array( 'label' => $label, 'value' => $value );
}
$new_total_rows[$key] = $total;
}
return $new_total_rows;
}