Show custom data in emails, order details woocommerce - php

Updated:
I'm building a WooCommerce site where the user selects a series of options from dropdowns in the single product page which then display in the cart page and, thanks to help I've received on here, in the checkout as well. The options selected also influence the price of the product. I start with two product variations: 'Print' and 'Original' (the site is selling antique maps).
Everything works fine up till the checkout where all the order details display correctly but, after having placed the order, the details don't appear on the 'order received' screen under 'order details' nor do they appear in the customer confirmation email.
To give some background, the different variations are selected using jQuery, and added to hidden fields a per example below:
$( ":root" ).find("#mapchest-custom-fields").append("<input type='hidden'
name='test' value='wibble'>");
...and these hidden fields are then referenced to add the details to the cart in the following manner:
add_filter('woocommerce_add_cart_item_data','add_custom_field_data', 20,3);
function add_custom_field_data($cart_item_data, $product_id, $variation_id)
{
if(isset($_REQUEST['test']) && ! empty( 'test' )) { // not
$mc_test = sanitize_text_field($_POST['test']);
$cart_item_data['custom_data']['test'] = array(
'label' => 'Test',
'value' => $mc_test
);
}
if(isset($_REQUEST['original_map_vendor_details']) && ! empty(
'original_map_vendor_details' )) {
$mc_original_map_size =
sanitize_text_field($_REQUEST['original_map_vendor_details']);
$cart_item_data['custom_data']['original_map_vendor_details'] =
array(
'label' => 'Vendor',
'value' => $mc_original_map_size
);
}
// process above repeated for other fields
return $cart_item_data;
}
The details are displayed in the cart and checkout using the following function:
add_filter('woocommerce_get_item_data','wdm_add_item_meta',10,2);
function wdm_add_item_meta($cart_data, $cart_item)
{
$custom_items = array();
if( !empty( $cart_data ) )
$custom_items = $cart_data;
if( isset( $cart_item['custom_data'] ) ) {
foreach( $cart_item['custom_data'] as $key => $custom_data ){
if( $key != 'key' ){
$custom_items[] = array(
'name' => $custom_data['label'],
'value' => $custom_data['value'],
);
}
}
}
return $custom_items;
}
What I want to do, as I say is have the details display in the Order Received page and the emails but I can't make it work. I know that for emails I need to hook it to one of the email hooks but I don't know how to access the data sent to the cart in the function above.
I've tried adding using the woocommerce_checkout_create_order_line_item hook to along these lines:
add_action( 'woocommerce_checkout_create_order_line_item',
'add_custom_order_line_item_meta', 20,4 );
function add_custom_order_line_item_meta($item, $cart_item_key, $values,
$order)
{
if( array_key_exists('test', $values['custom_data']) ){
$item->update_meta_data( 'Test', $values['custom_data']['test'] );
}
}
...but whilst I can see the data if I var_dump it in the email like this:
add_action('woocommerce_email_customer_details',
'add_custom_checkout_field_to_emails_notifications', 25, 4 );
function add_custom_checkout_field_to_emails_notifications( $order,
$sent_to_admin, $plain_text, $email ) {
var_dump($order);
}
So, in summary, I have the data working and displaying up to the point of the checkout. After that, I want it to display in customer confirmation emails and on the 'order received' page but I'm having trouble accessing the data. Having looked through other questions on the same subject i would have thought that this would happen automatically regarding the order received page but it doesn't. I suspect there's a stage missing in the code but I can't work out what it should be.
Any tips as to what I'm doing wrong here?
Thanks in advance.
ps. I've now managed to display the fields in the confirmation email (after a fashion) using the following functions:
add_action( 'woocommerce_checkout_create_order_line_item',
'add_custom_order_line_item_meta', 20,4 );
function add_custom_order_line_item_meta($item, $cart_item_key, $values,
$order)
{
if ( isset( $values['custom_data'] ) ) {
$item->update_meta_data( __('The Custom Data', 'woocommerce'),
$values['custom_data'] );
}
}
and
add_action('woocommerce_email_customer_details',
'add_custom_checkout_field_to_emails_notifications', 25, 4 );
function add_custom_checkout_field_to_emails_notifications( $order,
$sent_to_admin, $plain_text, $email ) {
// var_dump($order);
foreach( $order->get_items() as $item_id => $item ){
$custom_data = $item->get_meta( 'The Custom Data' );
foreach( $custom_data as $key => $value ){
foreach( $value as $key1 => $value1 ){
$output = '';
$output .= '<span class="text">' . $value1 . '</span>';
echo $output;
}
echo "<br>";
}
echo "<br><br>";
// var_dump($custom_data );
}
'</strong> <span class="text">' . $order->get_data() . '</span></div>';
}
but this is a hacky solution and doesn't address the underlying problem of why the information isn't appearing in the order received page or directly in the order line items in the email.

Okay, I've worked this out. I'm putting the answer here for the benefit of anyone else having the same problem. Basically, my process was missing a stage. In order to achieve the above you do as follows:
Define the value you wish to pass as meta data. In my own case I used a hidden field but this can equally be set with a text input, a dropdown or other input field. In my case I used jquery to append this to an empty div with id 'mapchest-custom-fields' which I hooked into the process before the cart button. It can equally be set with a static value.
<?php
function define_container_div() {
?>
<div id="mapchest-custom-fields"></div>
<?php
}
add_action( 'woocommerce_before_add_to_cart_button', 'define_container_div', 20 );
?>
...jQuery code to append the value. Value can be dynamic as well:
$( ":root" ).find("#mapchest-custom-fields").append("<input type='hidden' name='test' value='wibble'>");
Next you add the value to your cart item data:
function add_values_to_cart_item_data( $cart_item_data, $product_id, $variation_id )
{
if(isset($_POST['test']) && ! empty( 'test' )) {
$test = filter_input( INPUT_POST, 'test' );
$cart_item_data['test'] = $test;
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'add_values_to_cart_item_data', 10, 3);
Next, you display the value in your cart:
function display_data_in_cart( $item_data, $cart_item ) {
$item_data[] = array(
'key' => __( 'Test', 'mapchest' ),
'value' => wc_clean( $cart_item['test'] ),
);
return $item_data;
}
add_filter( 'woocommerce_get_item_data', 'display_data_in_cart', 10, 2 );
And finally, you add the data to your order items:
function add_data_to_order_items( $item, $cart_item_key, $values, $order ) {
$item->add_meta_data( __( 'Test', 'mapchest' ), $values['test'] );
}
add_action( 'woocommerce_checkout_create_order_line_item', 'add_data_to_order_items', 10, 4 );
The above process works for me. It displays the custom data in the cart and in the checkout and persists it through to the 'Order Received' page archived orders and the confirmation email (not checked other emails yet).
Thanks to https://iconicwp.com/blog/add-custom-cart-item-data-woocommerce/ for explaining this process to me.

Related

Woocommerce add_filter vs. add_action when asking about specific product meta

I'm struggling with a basic php function.
I implemented a backend checkbox in wordpress / woocommerce general tab which works fine:
// Add checkbox in Backend
function action_woocommerce_product_options_general_product_data() {
// Checkbox
woocommerce_wp_checkbox( array(
'id' => '_prevent_add_to_cart_button', // Required, it's the meta_key for storing the value (is checked or not)
'label' => __( 'Warenkorb Button', 'woocommerce' ), // Text in the editor label
'desc_tip' => false, // true or false, show description directly or as tooltip
'description' => __( 'Warenkorb Button ausblenden', 'woocommerce' ) // Provide something useful here
) );
}
add_action( 'woocommerce_product_options_general_product_data', 'action_woocommerce_product_options_general_product_data', 10, 0 );
// Save Field
function action_woocommerce_admin_process_product_object( $product ) {
// Isset, yes or no
$checkbox = isset( $_POST['_prevent_add_to_cart_button'] ) ? 'yes' : 'no';
// Update meta
$product->update_meta_data( '_prevent_add_to_cart_button', $checkbox );
}
add_action( 'woocommerce_admin_process_product_object', 'action_woocommerce_admin_process_product_object', 10, 1 );
Now i want to ask for the value of that checkbox and do things based on it.
It works in this function as expected:
// Add function for category / listing page add to cart button hook
function hide_listingpage_button( $add_to_cart_html, $product, $args ){
$hide_add_to_cart_button = $product->get_meta( '_prevent_add_to_cart_button' );
if ( $hide_add_to_cart_button == 'yes' ) {
$before = '<span style="display:none;">';
$after = '</span>';
return $before . $add_to_cart_html . $after;
}
else {
return $add_to_cart_html;
}
}
add_filter( 'woocommerce_loop_add_to_cart_link', 'hide_listingpage_button', 10, 3 );
but it does not work in this function(s):
// Add functions for singlepage before / after add to cart button hook
function beforehide_singlepage_button( $product ) {
$hide_add_to_cart_button = $product->get_meta( '_prevent_add_to_cart_button' );
if ( $hide_add_to_cart_button == 'yes' ) {
echo 'test after';
}
}
function afterhide_singlepage_button( $product ) {
$hide_add_to_cart_button = $product->get_meta( '_prevent_add_to_cart_button' );
if ( $hide_add_to_cart_button == 'yes' ) {
echo 'test after';
}
}
add_action( 'woocommerce_before_add_to_cart_button', 'beforehide_singlepage_button' );
add_action( 'woocommerce_after_add_to_cart_button', 'afterhide_singlepage_button' );
Im my opinion im doing basically the same things?
I give the $product object as argument in the function, ask then for yes / no boolean with
$hide_add_to_cart_button = $product->get_meta( '_prevent_add_to_cart_button' );
and then echo something with the if clause.
however, i get no output of the page from that line, and also no error message.
What am i missing?
thank you!

WooCommerce: Add custom meta as hidden order item meta for internal use

I want to add some meta data to the order item in WooCommerce.
These meta fields are for internal use only and shouldn't be visible.
We have some extra fields in the product like an extra fee. I want to use that fee later to work with after I export the orders.
I found a very good answer here: https://stackoverflow.com/a/41988701/1788961
add_action('woocommerce_checkout_create_order_line_item', 'add_custom_hiden_order_item_meta_data', 20, 4 );
function add_custom_hiden_order_item_meta_data( $item, $cart_item_key, $values, $order ) {
// Set user meta custom field as order item meta
if( $meta_value = get_user_meta( $order->get_user_id(), 'billing_enumber', true ) )
$item->update_meta_data( 'pa_billing-e-number', $meta_value );
}
But with this example, the content from the meta fields will appear in the order details for the customer.
Is there a way to make these fields only visible in the backend and usable for internal functions?
Updated
The simple way set any meta value as hidden order item meta data only visible on admin Order edit pages is to add an underscore at the beginning of the meta key like:
add_action('woocommerce_checkout_create_order_line_item', 'add_custom_hiden_order_item_meta_data', 20, 4 );
function add_custom_hiden_order_item_meta_data( $item, $cart_item_key, $values, $order ) {
// Set user 'billing_enumber' custom field as admin order item meta (hidden from customer)
if( $meta_value = get_user_meta( $order->get_user_id(), 'billing_enumber', true ) )
$item->update_meta_data( '_billing_enumber', $meta_value );
}
Then to have a clean label name for this meta key on admin order items, you can use:
add_filter('woocommerce_order_item_display_meta_key', 'filter_wc_order_item_display_meta_key', 20, 3 );
function filter_wc_order_item_display_meta_key( $display_key, $meta, $item ) {
// Set user meta custom field as order item meta
if( $meta->key === '_billing_enumber' && is_admin() )
$display_key = __("Billing E Number", "woocommerce" );
return $display_key;
}
This code goes in function.php file of your active child theme (or cative theme). Tested and works.
add_action('woocommerce_add_order_item_meta','mau_add_values_to_order_item_meta',1,2);
if(!function_exists('mau_add_values_to_order_item_meta'))
{
function mau_add_values_to_order_item_meta($item_id, $values)
{
global $woocommerce,$wpdb;
$postcode = $values['postcode'];
$extend_date_delivery = $values['extend_date_delivery'];
$extend_date_collection = $values['extend_date_collection'];
$pro_rental_type_choose = $values['pro_rental_type_choose'];
if(!empty($postcode))
{
wc_add_order_item_meta($item_id,'postcode',$postcode);
}
if(!empty($extend_date_delivery))
{
wc_add_order_item_meta($item_id,'extend_date_delivery',$extend_date_delivery);
}
if(!empty($extend_date_collection))
{
wc_add_order_item_meta($item_id,'extend_date_collection',$extend_date_collection);
}
if(!empty($pro_rental_type_choose))
{
wc_add_order_item_meta($item_id,'pro_rental_type_choose',$pro_rental_type_choose);
}
}
}
add_filter( 'woocommerce_order_item_display_meta_key', 'mau_change_shipping_note_title', 20, 3 );
function mau_change_shipping_note_title( $key, $meta, $item ) {
if ( 'postcode' === $meta->key ) { $key = __( 'Postcode', 'your_textdomain'); }
if ( 'extend_date_delivery' === $meta->key ) { $key = __( 'Delivery Date', 'your_textdomain'); }
if ( 'extend_date_collection' === $meta->key ) { $key = __( 'Collection Date', 'your_textdomain'); }
if ( 'pro_rental_type_choose' === $meta->key ) { $key = __( 'Rental Type', 'your_textdomain'); }
return $key;
}

WooCommerce editable custom checkout field and displayed in formatted address

I am adding mandatory shipping phone to woocommerce checkout page with
add_filter( 'woocommerce_checkout_fields', 'add_shipping_phone_to_checkout_page' );
function add_shipping_phone_to_checkout_page( $fields ) {
$fields['shipping']['shipping_phone'] = array(
'label' => 'Phone',
'required' => true,
'class' => array( 'form-row-wide' ),
'priority' => 25,
);
return $fields;
}
then display it in admin order panel
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'shipping_phone_checkout_display_in_order_panel' );
function shipping_phone_checkout_display_in_order_panel( $order ){
echo '<p><b>Phone :</b> ' . get_post_meta( $order->get_id(), '_shipping_phone', true ) . '</p>';
}
and finally print it in email
add_action('woocommerce_email_customer_details','shipping_phone_display_in_order_email', 25, 4 );
function shipping_phone_display_in_order_email( $order, $sent_to_admin, $plain_text, $email ) {
$output = '';
$shipping_phone = get_post_meta( $order->id, '_shipping_phone', true );
if ( !empty($shipping_phone) )
$output = '<p><strong>' . __( "Phone:", "woocommerce" ) . '</strong> ' . $shipping_phone . '</p>';
echo $output;
}
All works as it should. I'd like to achieve 2 enhancements but I am unable to do:
Make the custom phone field editable in admin panel
In email, move the custom phone field value in shipping address block
Any help would be appreciated
You need to make some changes in your code… The following code will display the shipping phone field in:
Checkout
My Account > Address > Edit shipping address
Admin order edit pages
The code will also add the shipping phone to formatted displayed shipping address on emails shipping address section.
// display shipping phone in checkout and my account edit shipping address
add_filter( 'woocommerce_shipping_fields', 'add_shipping_phone_field' );
function add_shipping_phone_field( $fields ) {
$fields['shipping_phone'] = array(
'label' => __('Phone (Shipping)'),
'required' => true,
'class' => array( 'form-row-wide' ),
'priority' => 25,
);
return $fields;
}
// Editable field on admin order edit pages inside edit shipping section
add_filter( 'woocommerce_admin_shipping_fields' , 'add_order_admin_edit_shipping_phone' );
function add_order_admin_edit_shipping_phone( $fields ) {
// Include shipping phone as editable field
$fields['phone'] = array( 'label' => __("Shipping phone"), 'show' => '0' );
return $fields;
}
// Adding custom placeholder to woocommerce formatted address only on Backend
add_filter( 'woocommerce_localisation_address_formats', 'admin_localisation_address_formats', 50, 1 );
function admin_localisation_address_formats( $address_formats ){
// Only in backend (Admin)
if( is_admin() || ! is_wc_endpoint_url() ) {
foreach( $address_formats as $country_code => $address_format ) {
$address_formats[$country_code] .= "\n{phone}";
}
}
return $address_formats;
}
// Custom placeholder replacement to woocommerce formatted address
add_filter( 'woocommerce_formatted_address_replacements', 'custom_formatted_address_replacements', 10, 2 );
function custom_formatted_address_replacements( $replacements, $args ) {
$replacements['{phone}'] = ! empty($args['phone']) ? $args['phone'] : '';
return $replacements;
}
// Add the shipping phone value to be displayed on email notifications under shipping address
add_filter( 'woocommerce_order_formatted_shipping_address', 'add_shipping_phone_to_formatted_shipping_address', 100, 2 );
function add_shipping_phone_to_formatted_shipping_address( $shipping_address, $order ) {
global $pagenow, $post_type;
// Not on admin order edit pages (as it's already displayed).
if( ! ( $pagenow === 'post.php' && $post_type === 'shop_order' && isset($_GET['action']) && $_GET['action'] === 'edit' ) ) {
// Include shipping phone on formatted shipping address
$shipping_address['phone'] = $order->get_meta('_shipping_phone');
}
return $shipping_address;
}
// Remove double billing phone from email notifications (and admin) under billing address
add_filter( 'woocommerce_order_formatted_billing_address', 'remove_billing_phone_from_formatted_billing_address', 100, 2 );
function remove_billing_phone_from_formatted_billing_address( $billing_address, $order ) {
unset($billing_address['phone']);
return $billing_address;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
For billing custom fields, you will replace the hooks:
woocommerce_shipping_fields by woocommerce_billing_fields
woocommerce_admin_shipping_fields by woocommerce_admin_billing_fields
woocommerce_order_formatted_shipping_address by woocommerce_order_formatted_billing_address
(don't use the last function).
For the front endpoints:
On order received (thank you), order-pay, and myaccount / order-view, you will have to override via your active theme the template order/order-details-customer.php.
You will add inside the html tag <address> after line 52 the following:
<?php if ( $shipping_phone = $order->get_meta('_shipping_phone') ) : ?>
<p class="woocommerce-customer-details--phone"><?php echo esc_html( $shipping_phone ); ?></p>
<?php endif; ?>
On admin side, the shipping phone is displayed and editable:
On order-view, order-received and email notifications, the shipping phone is displayed at the end of the shipping address section:

Process custom bulk action on admin Orders list in Woocommerce

I have added a custom action in my woocommerce orders page like shown below, and I also have a custom order field "number of meals". Now what I want is when I select the orders in bulk and use that custom action then count of number of meals should get decreased by 1.
For example if order id 1 & 2 had 15 & 12 number of meals respectively then after using the action it should become 14 & 11…
The screenshot of my orders page, the custom hook and the custom order field I created:
My code:
add_filter( 'bulk_actions-edit-shop_order', 'decrease_number_of_meals_by_1' );
function decrease_number_of_meals_by_1( $bulk_actions ) {
$bulk_actions['decrease_number_of_meals'] = 'Decrease Number of Meals by 1';
return $bulk_actions;
}
add_action( 'admin_action_decrease_number_of_meals', 'fire_my_hook' );
function fire_my_hook() {
if( !isset( $_REQUEST['post'] ) && !is_array( $_REQUEST['post'] ) )
return;
foreach( $_REQUEST['post'] as $order_id ) {
$order = new WC_Order( $order_id );
$no_of_meals = $order->get_post_meta( $order_id, '_wc_acof_{3}', true );
}
}
I am stuck here and have no idea on how to do it further.
Please guide me on how can I achieve this.
You are not using the right way and hooks. Also the right custom field meta key should be _wc_acof_3 when using WooCommerce Admin Custom Order Fields plugin.
So try the following instead:
// Add a bulk action to Orders bulk actions dropdown
add_filter( 'bulk_actions-edit-shop_order', 'decrease_meals_orders_bulk_actions' );
function decrease_meals_orders_bulk_actions( $bulk_actions ) {
$bulk_actions['decrease_meals'] = 'Decrease Number of Meals by 1';
return $bulk_actions;
}
// Process the bulk action from selected orders
add_filter( 'handle_bulk_actions-edit-shop_order', 'decrease_meals_bulk_action_edit_shop_order', 10, 3 );
function decrease_meals_bulk_action_edit_shop_order( $redirect_to, $action, $post_ids ) {
if ( $action === 'decrease_meals' ){
$processed_ids = array(); // Initializing
foreach ( $post_ids as $post_id ) {
// Get number of meals
$nb_meal = (int) get_post_meta( $post_id, '_wc_acof_3', true );
// Save the decreased number of meals ($meals - 1)
update_post_meta( $post_id, '_wc_acof_3', $nb_meal - 1 );
$processed_ids[] = $post_id; // Adding processed order IDs to an array
}
// Adding the right query vars to the returned URL
$redirect_to = add_query_arg( array(
'decrease_meals' => '1',
'processed_count' => count( $processed_ids ),
'processed_ids' => implode( ',', $processed_ids ),
), $redirect_to );
}
return $redirect_to;
}
// Display the results notice from bulk action on orders
add_action( 'admin_notices', 'decrease_meals_bulk_action_admin_notice' );
function decrease_meals_bulk_action_admin_notice() {
global $pagenow;
if ( 'edit.php' === $pagenow && isset($_GET['post_type'])
&& 'shop_order' === $_GET['post_type'] && isset($_GET['decrease_meals']) {
$count = intval( $_REQUEST['processed_count'] );
printf( '<div class="notice notice-success fade is-dismissible"><p>' .
_n( 'Decreased meals for %s Order.',
'Decreased meals for %s Orders.',
$count,
'woocommerce'
) . '</p></div>', $count );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Display checkout field value in Woocommerce admin order list custom column

I am stuck with a task. I would like to add an extra column to the shop order columns in woocommerce backend.
This extra column should display an echo output if a customer checked a checkbox field on checkout.
So to add the extra column it is not that hard. I did it this way.
add_filter('manage_edit-shop_order_columns', 'invoice_order_overview');
function invoice_order_overview($columns) {
$new_columns = (is_array($columns)) ? $columns : array();
unset($new_columns['order_actions']);
//edit this for you column(s)
//all of your columns will be added before the actions column
$new_columns['MY_COLUMN_ID_2'] = 'Extra Column';
//stop editing
$new_columns['order_actions'] = $columns['order_actions'];
return $new_columns;
}
So now I would like to display something in this added column. The function for the checkbox at the checkout page is as follow. It already displays an echo output at the order edit page.
// Add custom checkbox field to checkout
add_action( 'woocommerce_review_order_before_submit', 'my_custom_checkout_field' );
function my_custom_checkout_field() {
echo '<div id="my_custom_checkout_field">';
woocommerce_form_field( 'my_field_name', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('Rechnung beilegen? (Sonst nur Lieferschein)'),
), WC()->checkout->get_value( 'my_field_name' ) );
echo '</div>';
}
// Save the custom checkout field in the order meta, when checkbox has
been checked
add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_field_update_order_meta', 10, 1 );
function custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['my_field_name'] ) )
update_post_meta( $order_id, 'my_field_name',
$_POST['my_field_name'] );
}
// Display the custom field result on the order edit page (backend)
when checkbox has been checked
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
function display_custom_field_on_order_edit_pages( $order ){
$my_field_name = get_post_meta( $order->get_id(), 'my_field_name',
true );
if( $my_field_name == 1 )
echo '<p style="background: #dba029; padding: 1em !important;
color: #fff; font-weight: 700;"><strong>Rechnung beilegen! </strong>
</p>';
}
So I thought it should be possible to grab that $my_field_name variable and put it to my new extra column like this.
add_action('manage_shop_order_posts_custom_column', 'invoice_order_overview_value', 2);
function invoice_order_overview_value($column) {
global $post;
if ($column == 'MY_COLUMN_ID_2') {
$my_field_name = get_post_meta( $order->get_id(), 'my_field_name', true );
if( $my_field_name == 1 )
echo 'Rechnung beilegen!';
}
}
But this is giving me an "undefined variable" error in the added column.
If I only put echo 'Rechnung beilegen!'; into the function it outputs "Rechnung beilegen" into every row in MY_COLUMN_ID_2.
Like this:
add_action('manage_shop_order_posts_custom_column', 'invoice_order_overview_value', 2);
function invoice_order_overview_value($column) {
global $post;
if ($column == 'MY_COLUMN_ID_2') {
echo 'Rechnung beilegen!';
}
}
So the question is:
How can I get the output based on the selection made in $my_field_name into MY_COLUMN_ID_2 ?
Any help is appreciated.
The following revisited code will add a custom column and will display the custom checkout field "Enclosed Invoice" value:
// Add custom checkbox field to checkout
add_action( 'woocommerce_review_order_before_submit', 'my_custom_checkout_field' );
function my_custom_checkout_field() {
echo '<div id="my_custom_checkout_field">';
woocommerce_form_field( '_enclosed_invoice', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('Enclose invoice? (Otherwise only delivery note)'),
), WC()->checkout->get_value( '_enclosed_invoice' ) );
echo '</div>';
}
// Save the custom checkout field in the order meta, when checkbox has been checked
add_action( 'woocommerce_checkout_create_order', 'save_order_custom_meta_data', 10, 2 );
function save_order_custom_meta_data( $order, $data ) {
if ( isset($_POST['_enclosed_invoice']) )
$order->update_meta_data('_enclosed_invoice', '1' );
}
// Display the custom field result on the order edit page (backend) when checkbox has been checked
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_custom_field_on_order_edit_pages', 10, 1 );
function display_custom_field_on_order_edit_pages( $order ){
if( $my_field_name = $order->get_meta( '_enclosed_invoice' ) )
echo '<p style="background: #dba029; padding: 1em !important; color: #fff; font-weight: 700;"><strong>Enclosed invoice!</strong></p>';
}
// Add custom column before "Actions" column in admin orders list
add_filter('manage_edit-shop_order_columns', 'add_enclosed_invoice_order_column', 10, 1 );
function add_enclosed_invoice_order_column( $columns ) {
// Woocommerce compatibility since version 3.3
$actions_key = isset($columns['wc_actions']) ? 'wc_actions' : 'order_actions';
$order_actions = $columns[$actions_key];
unset($columns[$actions_key]);
$columns['enclosed_invoice'] = __("Enc. Invoice", "woocommerce");
$columns[$actions_key] = $order_actions;
return $columns;
}
// Display data to custom column in admin orders list
add_action( 'manage_shop_order_posts_custom_column' , 'display_enclosed_invoice_order_column_data' );
function display_enclosed_invoice_order_column_data( $column ) {
global $the_order, $post;
if( $column == 'enclosed_invoice' ) {
if( $enclosed_invoice = $the_order->get_meta( '_enclosed_invoice' ) ) {
echo __("Yes", "woocommerce");
} else {
echo ' - ';
}
}
}
Code goes in function.php file of your active child theme (active theme). tested and works.
Since Woocommmerce version 3.3, the admin order list actions column has been renamed 'wc_actions' instead of 'order_actions'

Categories