Display custom data on Woocommerce admin order preview
You can't get the order object as it's a template that loads specific data via Ajax and there is no arguments for woocommerce_admin_order_preview_end
action hook.
Instead the filter hook woocommerce_admin_order_preview_get_order_details
will allow you first to add some custom data that you will be able to call and display it after in woocommerce_admin_order_preview_end
action hook.
The code:
// Add custom order meta data to make it accessible in Order preview template
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'admin_order_preview_add_custom_meta_data', 10, 2 );
function admin_order_preview_add_custom_meta_data( $data, $order ) {
// Replace '_custom_meta_key' by the correct postmeta key
if( $custom_value = $order->get_meta('_custom_meta_key') )
$data['custom_key'] = $custom_value; // <= Store the value in the data array.
return $data;
}
// Display custom values in Order preview
add_action( 'woocommerce_admin_order_preview_end', 'custom_display_order_data_in_admin' );
function custom_display_order_data_in_admin(){
// Call the stored value and display it
echo '<div>Value: {{data.custom_key}}</div><br>';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.Note: You can also use
woocommerce_admin_order_preview_start
hook if needed…
Add product data to WooCommerce admin order preview
To avoid your issue, you need to target only order "line" items on your 2nd function, this way:
add_action('woocommerce_admin_order_item_values', 'my_woocommerce_admin_order_item_values', 10, 3);
function my_woocommerce_admin_order_item_values($product, $item, $item_id = null) {
// Only for "line_item" items type, to avoid errors
if( ! $item->is_type('line_item') ) return;
echo '<td>' . get_the_term_list( $product->get_id(), 'pa_location', '', ',', '' ) . '</td>';
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.Related: Add product short description to Woocommerce admin orders preview
Show custom fields in WooCommerce quick order preview
In the code below, for each of your billing custom fields, you will have to set the correct meta key. It will display your billing custom fields in the quick order preview under Billing section:
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'admin_order_preview_add_custom_billing_data', 10, 2 );
function admin_order_preview_add_custom_billing_data( $data, $order ) {
$custom_billing_data = []; // initializing
// Custom field 1: Replace '_custom_meta_key1' by the correct custom field metakey
if( $custom_value1 = $order->get_meta('_custom_meta_key1') ) {
$custom_billing_data[] = $custom_value1;
}
// Custom field 2: Replace '_custom_meta_key1' by the correct custom field metakey
if( $custom_value2 = $order->get_meta('_custom_meta_key1') ) {
$custom_billing_data[] = $custom_value2;
}
## ……… And so on (for each additional custom field).
// Check that our custom fields array is not empty
if( count($custom_billing_data) > 0 ) {
// Converting the array in a formatted string
$formatted_custom_billing_data = implode( '<br>', $custom_billing_data );
if( $data['formatted_billing_address'] === __( 'N/A', 'woocommerce' ) ) {
$data['formatted_billing_address'] = $formatted_custom_billing_data;
} else {
$data['formatted_billing_address'] .= '<br>' . $formatted_custom_billing_data;
}
}
return $data;
}
Code goes in function.php file of your active child theme (or active theme). It should work.Related: Display custom data on Woocommerce admin order preview
Add cart metadata to admin order screen in Woocommerce?
You must use the woocommerce_checkout_create_order_line_item
hook to store the cart data as the order item meta data.
So:
add_action('woocommerce_checkout_create_order_line_item', 'save_custom_order_item_meta_data', 10, 4 );
function save_custom_order_item_meta_data( $item, $cart_item_key, $values, $order ) {
if ( isset( $values['polarity_information'] ) ) {
$item->update_meta_data( '_polarity_information', $values['polarity_information'] );
}
}
You can now access the order item meta data from the woocommerce_admin_order_data_after_order_details
hook.The code has been tested and worked. Add it to your active theme's functions.php.
RELATED ANSWERS
- Save Woocommerce cart item custom data as order item meta data displaying it on orders and emails
- How to get cart item key from order item in WooCommerce
- Add and display custom cart item data in WooCommerce orders and emails
- Update order meta with cart item custom data in Woocommerce 3
Display custom order item metadata only on WooCommerce admin orders
Use the following to display a custom download button on admin order items only (code is commented):
// Save custom order item meta
add_action( 'woocommerce_checkout_create_order_line_item', 'save_custom_order_item_meta', 10, 4 );
function save_custom_order_item_meta( $item, $cart_item_key, $values, $order ) {
if ( isset($values['file']) && ! empty($values['file']) ) {
// Save it in an array to hide meta data from admin order items
$item->add_meta_data('file', array( $values['file'] ) );
}
}
// Get custom order item meta and display a linked download button
add_action( 'woocommerce_after_order_itemmeta', 'display_admin_order_item_custom_button', 10, 3 );
function display_admin_order_item_custom_button( $item_id, $item, $product ){
// Only "line" items and backend order pages
if( ! ( is_admin() && $item->is_type('line_item') ) )
return;
$file_url = $item->get_meta('file'); // Get custom item meta data (array)
if( ! empty($file_url) ) {
// Display a custom download button using custom meta for the link
echo '<a href="' . reset($file_url) . '" class="button download" download>' . __("Download", "woocommerce") . '</a>';
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.The custom download button is only displayed in admin order items.
Customize content in WooCommerce admin quick order preview
— Code updated 2 — (FOUND THE PROBLEMS, see comments in code) —Just under your custom code in
html-order-item.php
core file, if you take a look to existing code, you have woocommerce_admin_order_item_values
hook that you can use for your code, instead overriding a WooCommerce core file.But you will also need to use woocommerce_admin_order_item_headers
as you will see below in my code snippets…
Because YES you are going to loose your code customization in that PHP file when WooCommerce will be updated. That's why you will find everywhere in WordPress and WooCommerce core files a lot of different hooks to use, for customizations.Now, first you are going to replace back the original core file in the plugin.You can NOT copy this core files to your active child theme (or active theme) and doing this will not have any effect on it.
What you can do is copy the
templates
folder located in WooCommerce plugin, to your active child theme (or active theme) and rename itwoocommerce
. This way you can override the WooCommerce templates via your theme, as explained here in this documentation.
In your child theme, you normally have a function.php file where you are going to add the code below (a hooked function):
add_action( 'woocommerce_admin_order_item_headers', 'download_image_admin_order_item_headers', 10, 0 );
function download_image_admin_order_item_headers(){
echo '<th class="item sortable" colspan="1" data-sort="string-ins">' . __( 'Downloads', 'woocommerce' ) .'</th>';
}
add_action( 'woocommerce_admin_order_item_values', 'download_image_order_item_values', 10, 3 );
function download_image_order_item_values( $_product, $item, $item_id ){
// Calling global $post to get the order ID
global $post;
// The Order ID
$order_id = $post->ID;
// the Product ID and variation ID (if different of zero for variations)
$product_id = $item['product_id'];
$variation_id = $item['variation_id'];
// If is not a variable product we replace the variation ID by the product ID
if (empty($variation_id)) $variation_id = $product_id;
// HERE ==> Getting an instance of product object, Avoiding an error:
// "Fatal error: Call to a member function get_gallery_attachment_ids()"
$product = new WC_Product($product_id);
// the Product post object
$post_product = $product->post;
$attachment_count = count($product->get_gallery_attachment_ids());
$gallery = $attachment_count > 0 ? '[product-gallery]' : '';
// CODE ERROR ===> This was returning empty before. You need to put
// the product ID in get_post_thumbnail_id() function to get something
$props = wc_get_product_attachment_props(get_post_thumbnail_id($product_id), $post_product);
// Testing $props output (array not empty) => comment/uncomment line below
// echo '<br>ITEM ID: ' . $item_id . '<br><pre>'; var_dump($props); echo '</pre><br>';
$image = get_the_post_thumbnail( $product->id, apply_filters('single_product_large_thumbnail_size', 'shop_single' ), array(
'title' => $props['title'],
'alt' => $props['alt'],
));
// Added a condition to avoid other line items than products (like shipping line)
if(!empty($product_id))
echo apply_filters(
'woocommerce_single_product_image_html', sprintf(
'<td class="name" colspan="1" ><a style="text-decoration: none;clear:both;float: left;margin-top: 5px;" href="%s" download = "Order#' . $order_id . '-' . $variation_id . '"><input type = "button" value="Download image"/></a></td>', esc_url($props['url'])
), $product->id
);
}
In Admin Order edit pages on item metabox you will see:Code goes in function.php file of your active child theme (active theme or in any plugin file).
This code is tested and works.
Display product custom field as order item meta on WooCommerce admin order pages
You need to target order "line" items only and admin to avoid errors, as follow:
add_action( 'woocommerce_before_order_itemmeta', 'unit_before_order_itemmeta', 10, 3 );
function unit_before_order_itemmeta( $item_id, $item, $product ){
// Only "line" items and backend order pages
if( ! ( is_admin() && $item->is_type('line_item') ) ) return;
$unit = $product->get_meta('unite');
if( ! empty($unit) ) {
echo '<p>'.$unit.'</p>';
}
}
It should better work now without errors. woocommerce order notes in order preview
There is no no arguments for woocommerce_admin_order_preview_end
action hook. so first you have use woocommerce_admin_order_preview_get_order_details
action hook where you can access $order
object
For order notes you can use wc_get_order_notes
function you can use check their parameter here.
// Add order notes so you can accees in `woocommerce_admin_order_preview_start`
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'admin_order_preview_add_order_notes_data', 10, 2 );
function admin_order_preview_add_order_notes_data( $data, $order ) {
$notes = wc_get_order_notes([
'order_id' => $order->get_id(),
]);
ob_start();
?>
<div class="wc-order-preview-order-note-container" style="padding: 20px;">
<div class="wc-order-preview-custom-note">
<h2 class="order-note">Order Note:</h2>
<ul class="order_notes">
<?php
if ( $notes ) {
foreach ( $notes as $note ) {
$css_class = array( 'note' );
$css_class[] = $note->customer_note ? 'customer-note' : '';
$css_class[] = 'system' === $note->added_by ? 'system-note' : '';
$css_class = apply_filters( 'woocommerce_order_note_class', array_filter( $css_class ), $note );
?>
<li rel="<?php echo absint( $note->id ); ?>" class="<?php echo esc_attr( implode( ' ', $css_class ) ); ?>">
<div class="note_content">
<?php echo wpautop( wptexturize( wp_kses_post( $note->content ) ) ); // @codingStandardsIgnoreLine ?>
</div>
<p class="meta">
<abbr class="exact-date" title="<?php echo esc_attr( $note->date_created->date( 'Y-m-d H:i:s' ) ); ?>">
<?php
echo esc_html( sprintf( __( '%1$s at %2$s', 'woocommerce' ), $note->date_created->date_i18n( wc_date_format() ), $note->date_created->date_i18n( wc_time_format() ) ) );
?>
</abbr>
<?php
if ( 'system' !== $note->added_by ) :
echo esc_html( sprintf( ' ' . __( 'by %s', 'woocommerce' ), $note->added_by ) );
endif;
?>
<a href="#" class="delete_note" role="button"><?php esc_html_e( 'Delete note', 'woocommerce' ); ?></a>
</p>
</li>
<?php
}
} else {
?>
<li class="no-items"><?php esc_html_e( 'There are no notes yet.', 'woocommerce' ); ?></li>
<?php
}
?>
</ul>
</div>
</div>
<?php
$order_notes = ob_get_clean();
$data['order_notes'] = $order_notes;
return $data;
}
//order notes
add_action( 'woocommerce_admin_order_preview_start', 'woocommerce_admin_order_preview_order_notes' );
function woocommerce_admin_order_preview_order_notes() {
?> {{{data.order_notes}}} <?php
}
Tested and works.
Related Topics
Creating and Invoking an Anonymous Function in a Single Statement
Compare Object Properties and Show Diff in PHP
Posting to a Facebook Page as the Page (Not a Person)
Built in Support for Sets in PHP
Remove "(Optional)" Text from Checkout Fields in Woocommerce 3.4+
What Is an Appropriate Content-Type Header for JavaScript Files
Jquery Ajax Form Data Serialize Using PHP
Why Doesn't PHP Permit Private Const
How to Remove All Dtddwrappers and Labels on Zend Form Elements
Setting Max_Input_Vars PHP.Ini Directive Using Ini_Set
How to Resize and Convert an Uploaded Image to a Png Using Gd
PHP Considers Null Is Equal to Zero
Force Download via Ajax and PHP
Why Is MySQLi_Insert_Id() Always Returning 0
How to Remove Email Addresses and Links from a String in PHP
Change Mime Type of Output in PHP