WooCommerce: Add custom meta as hidden order item meta for internal use
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 user meta data as order meta on WooCommerce order status change
There are some mistakes in your code (the hooked function arguments are wrong).
See the related source code for this composite hook located in WC_Order
status_transition()
method (on line 363):
do_action( 'woocommerce_order_status_' . $status_transition['to'], $this->get_id(), $this );
where $this
is $order
(the WC_Order
Object) and $this->get_id()
is $order_id
(the order Id).
Use instead the following:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order_id, $order ) {
$user_id = $order->get_user_id(); // Get the user id
$wf_email = get_user_meta( $user_id, 'KVK_nummer_2', true );
if( ! empty($wf_email) ) {
$order->update_meta_data( 'WeFact_email', $wf_email );
$order->save();
}
}
or also this works too:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
function add_order_meta_from_custom_user_meta( $order_id, $order ) {
$user_id = $order->get_user_id(); // Get the user id
$wf_email = get_user_meta( $user_id, 'KVK_nummer_2', true );
if( ! empty($wf_email) ) {
update_post_meta( $order_id, 'WeFact_email', $wf_email );
}
}
Code goes in functions.php file of the active child theme (or active theme). both should work.
For processing
status, replace:
add_action( 'woocommerce_order_status_wordt-verwerkt', 'add_order_meta_from_custom_user_meta', 10, 2 );
with:
add_action( 'woocommerce_order_status_processing', 'add_order_meta_from_custom_user_meta', 10, 2 );
Automatically add custom order shipping item meta data in WooCommerce
The following will add custom specific order "shipping" item meta data on orders via checkout and/or manual admin orders too:
// For new orders via checkout
add_action( 'woocommerce_checkout_create_order_shipping_item', 'action_checkout_create_order_shipping_item', 10, 4 );
function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
$item->update_meta_data( 'num_packages', 0 );
}
// For manual admin orders
add_action( 'woocommerce_saved_order_items', 'action_saved_order_items_callback', 10, 2 );
function action_saved_order_items_callback( $order_id, $items ) {
if ( isset( $items['shipping_method_id'] ) ) {
foreach( $items['shipping_method_id'] as $item_id ) {
$num_packages = wc_get_order_item_meta($item_id, 'num_packages');
if ( empty($num_packages) || $num_packages != 0 ) {
wc_update_order_item_meta( $item_id, 'num_packages', 0 );
}
}
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
To use this code in a plugin with a class (OOP), add the following inside the constructor function:
// For checkout order
add_action( 'woocommerce_checkout_create_order_shipping_item', [$this, 'action_checkout_create_order_shipping_item'], 10, 4 );
// For checkout order
add_action( 'woocommerce_saved_order_items', [$this, 'action_saved_order_items_callback'], 10, 2 );
And the following outside the constructor function:
public function action_checkout_create_order_shipping_item ( $item, $package_key, $package, $order ){
$item->update_meta_data( 'num_packages', 0 );
}
public function action_saved_order_items_callback( $order_id, $items ) {
if ( isset( $items['shipping_method_id'] ) ) {
foreach( $items['shipping_method_id'] as $item_id ) {
$num_packages = wc_get_order_item_meta($item_id, 'num_packages');
if ( empty($num_packages) || $num_packages != 0 ) {
wc_update_order_item_meta( $item_id, 'num_packages', 0 );
}
}
}
}
Add a custom meta field value to WooCommerce order if status changes to custom status
For a custom order status you can use woocommerce_order_status_{$status_transition[to]}
composite action hook, where you will replace {$status_transition[to]}
by the custom status slug.
So you get:
function action_woocommerce_order_status_kurzuhradena( $order_id, $order ) {
// Set your default time zone (http://php.net/manual/en/timezones.php)
// Set your locale information (https://www.php.net/manual/en/function.setlocale.php)
date_default_timezone_set( 'Europe/Brussels' );
setlocale( LC_ALL, 'nl_BE' );
// Get current month & year
$month = strftime( '%B' );
$year = strftime( '%Y' );
// Update meta
$order->update_meta_data( 'shipped_date', $month . ' ' . $year );
$order->save();
}
add_action( 'woocommerce_order_status_kurzuhradena', 'action_woocommerce_order_status_kurzuhradena', 10, 2 );
To allow this only once, when changing to custom order status, use:
function action_woocommerce_order_status_kurzuhradena( $order_id, $order ) {
// Set your default time zone (http://php.net/manual/en/timezones.php)
// Set your locale information (https://www.php.net/manual/en/function.setlocale.php)
date_default_timezone_set( 'Europe/Brussels' );
setlocale( LC_ALL, 'nl_BE' );
// Get meta (flag)
$flag = $order->get_meta( 'shipped_date_flag' );
// NOT true
if ( ! $flag ) {
// Set flag
$flag = true;
// Update meta
$order->update_meta_data( 'shipped_date_flag', $flag );
// Get current month & year
$month = strftime( '%B' );
$year = strftime( '%Y' );
// Update meta
$order->update_meta_data( 'shipped_date', $month . ' ' . $year );
}
// Save
$order->save();
}
add_action( 'woocommerce_order_status_kurzuhradena', 'action_woocommerce_order_status_kurzuhradena', 10, 2 );
Add order number as custom order item meta data in WooCommerce
In the end I managed to make it work with the following code:
function print_order_line_item_meta( $items, $order ) {
$order_number = $order->get_order_number();
$items = $order->get_items();
foreach ( $items as $item ) {
$item->update_meta_data( '_org_ordernummer', $order_number );
$item->save_meta_data();
}
}
add_action( 'woocommerce_order_status_on-hold', 'print_order_line_item_meta', 10, 2 );
Because all my orders are starting with the status "on-hold", I added the line item meta when the order has this status instead of adding it when the order is created. This is returning the order number instead of 0.
Save product custom meta as order item meta when manually adding products to WooCommerce admin orders
You are not using the right function hook arguments which are $item_id
, $item
, $order
and not using the right way. Try the following instead (code is commented):
add_action( 'woocommerce_ajax_add_order_item_meta', 'action_before_save_order_item_callback', 9999, 3 );
function action_before_save_order_item_callback( $item_id, $item, $order ) {
$product = $item->get_product(); // Get the WC_Product Object
$location = $product->get_meta('location'); // Get custom meta data
// If custom field is empty on a product variation check on the parent variable product
if( empty($location) && $item->get_variation_id() > 0 ) {
$parent_product = wc_get_product( $item->get_product_id() ); // Get parent WC_Product Object
$location = $product->get_meta('location'); // Get custom meta data
}
// If product meta data exist
if( ! empty($location) ) {
$item->update_meta_data( 'location', $location ); // Set it as order item meta
$item->save(); // save it
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Add unique line item meta as order meta data in WooCommerce
Update: Use the following simplified code with a different hook, based on your comment, when order status is changed to "we-fact" custom order status:
add_action('woocommerce_order_status_we-fact', 'add_unique_order_nummers_to_order', 20, 2 );
function add_unique_order_nummers_to_order( $order_id, $order ) {
$allenummers = array(); // Initializing
// Loop through order
foreach ( $order->get_items() as $item ) {
$allenummers[] = $item->get_meta( '_org_ordernummer' );
}
if ( ! empty($allenummers) ) {
$order->update_meta_data('_Unieke_nummers', sprintf( __("These are your numbers: %s"), implode(', ', array_unique($allenummers) ) ) );
}
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
Related Topics
How to Add Anchor Tag to a Url from Text Input
How to Retrieve Utf-8 Accented Characters from Access via Pdo_Odbc
PHP Move_Uploaded_File() Fails Without Reason
PHP Session Side-Effect Warning with Global Variables as a Source of Data
Mysqli Query Results to Show All Rows
Simple HTML Dom: How to Remove Elements
How to Install/Enable the PHP Phar Extension
PHP and Mod_Fcgid: Ap_Pass_Brigade Failed in Handle_Request_Ipc Function
PHP Commands Out of Sync Error
Display the Discounted Percentage Near Sale Price in Single Product Pages for Wc 3.0+
How to Chain Method on a Newly Created Object
Strip All HTML Tags, Except Allowed
Unserialize PHP Array in JavaScript
How to Turn Off PHP Safe_Mode Off for a Particular Directory in a Shared Hosting Environment
More Concise Way to Check to See If an Array Contains Only Numbers (Integers)