Need to add a field to the WooCommerce order details page where I can add a tracking number in the order page to be displayed for the customer.
I have added ACF to the order-details.php template as below, but it does not display. When I inspect page element all I can see is <h2></h2>. This is my current ACF code:
<h2><?php the_field('tracking_number'); ?></h2>
You can use the following to dis
// Display tracking information as a row on order totals everywhere
add_filter( 'woocommerce_get_order_item_totals', 'order_item_totals_tracking_row', 1000, 3 );
function order_item_totals_tracking_row( $total_rows, $order, $tax_display ){
if( $tracking_number = get_field('tracking_number', $order->get_id()) ) {
$new_total_rows = []; // Initializing
$has_tracking_row = false; // Initializing
$tracking_row = array( // tracking information array
'label' => __("Tracking number", "woocommerce"),
'value' => $tracking_number
);
// Loop through order total rows
foreach( $total_rows as $key => $values ) {
$new_total_rows[$key] = $values;
// Inserting tracking information array
if( $key === 'shipping' ) {
$new_total_rows['tracking'] = $tracking_row;
$has_tracking_row = true;
} elseif( $key === 'payment_method' && ! $has_tracking_row ) {
$new_total_rows['tracking'] = $tracking_row;
}
}
return $new_total_rows;
}
return $total_rows;
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
Related
I am trying to modify the product images in the auto generated WooCommerce order e-mails. Note, I am trying to do this with hooks, rather than creating a modified e-mail template.
To start, I have a hidden input on the single product page. I have some JS that sets the ID of the image, which is based on the product's colour (a custom attribute I made with ACF).
<input class="js-col-img-id" type="hidden" name="product-col-img-id" value="">
For reference, here's what I've done to get this to work on the cart page:
// Add custom attributes to cart item data
add_action('woocommerce_add_cart_item_data', 'jwd_add_custom_attr_to_cart', 10, 3);
function jwd_add_custom_attr_to_cart($cart_item_data, $product_id, $variation_id) {
$attrs = array(...,'product-col-img-id');
foreach ($attrs as $attr) {
$san_attr = filter_input( INPUT_POST, $attr );
if ( !empty( $san_attr ) ) {
$cart_item_data[$attr] = $san_attr;
}
}
return $cart_item_data;
}
// This function sets the image ID in the cart, and it displays the image properly
add_action( 'woocommerce_before_calculate_totals', 'bwa_new_price' );
function bwa_new_price($cart) {
// ...
$cart_items = $cart->get_cart();
foreach($cart_items as $item) {
$data = $item['data'];
// product-col-img-id is sent through the hidden input when the add to cart form is submitted
$colour_img_ID = $item['product-col-img-id'] ?? false;
if ($colour_img_ID) {
$data->set_image_id($colour_img_ID);
}
}
}
// Add custom attributes to order
add_action( 'woocommerce_checkout_create_order_line_item', 'jwd_add_attr_to_order_items', 10, 4 );
function jwd_add_attr_to_order_items( $item, $cart_item_key, $values, $order ) {
if ( !empty( $values['product-colour'] ) ) {
$item->add_meta_data( 'Colour', $values['product-colour'] );
}
// I tried replicating this for the img ID. It does display it in the var dump mentioned below, and it does display it as an actual label in the e-mail (which I'd want to get rid of). The difficulty then becomes reading the ID through code and setting the product to display that image
if ( !empty( $values['product-col-img-id'] ) ) {
$item->add_meta_data( 'col_img_id', $values['product-col-img-id'] );
}
}
That works fine, but I'm having difficulty replicating this in the order e-mail. So far I've come across the following. This shows images in the e-mail, but it's the product's featured image. Of note is the "show_image" key being set to true.
// Add prod IMG to e-mails
function jwd_add_images_woocommerce_emails( $output, $order ) {
// set a flag so we don't recursively call this filter
static $run = 0;
// if we've already run this filter, bail out
if ( $run ) {
return $output;
}
$args = array(
'show_image' => true,
//'image_size' => array( 300, 300 ),
'image_size' => 'full',
);
// increment our flag so we don't run again
$run++;
// if first run, give WooComm our updated table
return wc_get_email_order_items($order, $args);
}
add_filter( 'woocommerce_email_order_items_table', 'jwd_add_images_woocommerce_emails', 10, 2 );
To modify the image, I found this filter, but I'm just having a difficult time figuring out what I need to do to replicate what I've done on the cart page. The closest I've got is having $item_data work, and I do see the product-col-img-id key in the var dump, though it's in a protected object, which I'm not sure how to access. Even if I could access, I'm not sure how I could even set the image from here.
add_filter('woocommerce_order_item_thumbnail', 'jwd_add_colour_img', 10, 2);
function jwd_add_colour_img($image, $item) {
$item_id = $item->get_id();
//var_dump($item->get_current_data());
$product = $item->get_product();
$product_id = $item->get_product_id();
$item_data = $item->get_data();
$col_img_id = false;
$item->set_image_id(1);
foreach ($item_data as $key => $item) {
//current_data
var_dump($item);
//echo "<br><br>";
$col_img_id = $item['product-col-img-id'] ?? false;
if ($col_img_id) {
break;
}
}
//var_dump($col_img_id);
//$item_id = $item->get_product_id();
//var_dump(wc_get_order_item_meta( $item_id, 'col_img_id', true ) );
return $image;
}
To get WooCommerce custom meta data, you can use WC_Data method get_meta().
Try the following instead to display your custom image on email notifications:
// Save custom image ID as order item meta
add_action( 'woocommerce_checkout_create_order_line_item', 'save_custom_image_id_to_order_item', 10, 4 );
function save_custom_image_id_to_order_item( $item, $cart_item_key, $values, $order ) {
if ( isset($values['product-colour']) && ! empty($values['product-colour']) ) {
$item->add_meta_data('Colour', $values['product-colour'] );
}
if ( isset($values['product-col-img-id']) && ! empty($values['product-col-img-id']) ) {
$item->add_meta_data('_col_img_id', $values['product-col-img-id'] );
}
}
// (optional) Force display item image on emails
add_filter( 'woocommerce_email_order_items_args', 'show_image_on_email_notifications' );
function show_image_on_email_notifications( $args ) {
$args['show_image'] = true;
return $args;
}
// Display custom image on emails
add_filter( 'woocommerce_order_item_thumbnail', 'display_email_order_item_custom_image', 10, 2 );
function display_email_order_item_custom_image( $image, $item ) {
// Only on email notifications
if( is_wc_endpoint_url() )
return $image;
$image_id = $item->get_meta('_col_img_id');
if( $image_id ) {
$image = wp_get_attachment_image( $image_id, array( 32, 32 ), false, array() );
}
return $image;
}
Code goes in functions.php file of the active child theme (or active theme). It should work.
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;
}
We store some customer info in his/her Bio text area in user edit page.
How to display this stored data in user Bio field as a column in the Order admin page in woocommerce ?
I tried this code but its not working:
// Adding a custom new column to admin orders list
add_filter( 'manage_edit-shop_order_columns', 'custom_column_eldest_players', 20 );
function custom_column_eldest_players($columns)
{
$reordered_columns = array();
// Inserting columns to a specific location
foreach( $columns as $key => $column){
$reordered_columns[$key] = $column;
if( $key == 'order_status' ){
// Inserting after "Status" column
$reordered_columns['skb-client'] = __( 'Oudste Speler','theme_domain');
}
}
return $reordered_columns;
}
// Adding custom fields meta data for the column
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id )
{
if ( 'skb-client' != $column ) return;
global $the_order;
// Get the customer Bio
$user_bio = get_user_meta( $order->get_customer_id(), 'description', true );
$user_data = get_userdata( $user_bio );
echo $user_data->user_bio; // The WordPress user name
}
we need this stored data to displayed for each costumers purchase.
Best regards
The variable $order is not defined in your 2nd function, so you need to use instead $the_order. then I have revisited you code… Try the following instead:
// Adding a custom new column to admin orders list
add_filter( 'manage_edit-shop_order_columns', 'custom_column_eldest_players', 20 );
function custom_column_eldest_players($columns)
{
$reordered_columns = array();
// Inserting columns to a specific location
foreach( $columns as $key => $column){
$reordered_columns[$key] = $column;
if( $key == 'order_status' ){
// Inserting after "Status" column
$reordered_columns['user-bio'] = __( 'User bio', 'woocommerce');
}
}
return $reordered_columns;
}
// Adding custom fields meta data for the column
add_action( 'manage_shop_order_posts_custom_column' , 'custom_orders_list_column_content', 20, 2 );
function custom_orders_list_column_content( $column, $post_id ) {
if ( 'user-bio' === $column ) {
global $the_order;
echo ( $user = $the_order->get_user() ) ? $user->description : 'n/c';
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and work.
I would like to add futured image on admin view order pages in Woocommerce.
New Column created, but the product image does not appear.
What should I do to show the order thumbnail?
Thanks.
// Admin Order page new colums
add_filter( 'manage_edit-shop_order_columns', 'add_account_orders_column', 10, 1 );
function add_account_orders_column( $columns ){
$columns['custom-column'] = __( 'New Column', 'woocommerce' );
return $columns;
}
add_action( 'woocommerce_my_account_my_orders_column_custom-column', 'add_account_orders_column_rows' );
function add_account_orders_column_rows( $order ) {
// Example with a custom field
if ( $value = $order->get_meta( 'order_received_item_thumbnail_image' ) ) {
echo esc_html( $value );
}
}
Beware, as orders can have many products (many order items) and in this cas you will have many images (also it will weigh down the page)…
Now Your 2nd function hook is wrong and will not do anything.
To so you need to loop through order items as follow:
// Add a new custom column to admin order list
add_filter( 'manage_edit-shop_order_columns', 'admin_orders_list_add_column', 10, 1 );
function admin_orders_list_add_column( $columns ){
$columns['custom_column'] = __( 'New Column', 'woocommerce' );
return $columns;
}
// The data of the new custom column in admin order list
add_action( 'manage_shop_order_posts_custom_column' , 'admin_orders_list_column_content', 10, 2 );
function admin_orders_list_column_content( $column, $post_id ){
global $the_order;
if( 'custom_column' === $column ){
$count = 0;
// Loop through order items
foreach( $the_order->get_items() as $item ) {
$product = $item->get_product(); // The WC_Product Object
$style = $count > 0 ? ' style="padding-left:6px;"' : '';
// Display product thumbnail
printf( '<span%s>%s</span>', $style, $product->get_image( array( 50, 50 ) ) );
$count++;
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I am trying to find a way on how to add the customer email in the header row on the WooCommerce order view.
Any ideas, tips or pointers on how to make this happen?
To add the user email as a separated column, you will use the following:
// Add custom column after "Order number" column in admin orders list
add_filter('manage_edit-shop_order_columns', 'add_user_email_order_column', 10, 1 );
function add_user_email_order_column( $columns ) {
$new_columns = array();
foreach ($columns as $key => $column ){
$new_columns[$key] = $column;
// Insert the new column after 'order_number'
if( $key === 'order_number'){
$new_columns['customer_email'] = __("Email", "woocommerce");
}
}
return $new_columns;
}
// Display data to custom column in admin orders list
add_action( 'manage_shop_order_posts_custom_column' , 'display_user_email_order_column', 10, 2 );
function display_user_email_order_column( $column, $post_id ) {
global $the_order;
if( $column === 'customer_email' ) {
if( $the_order->get_customer_id() ){
$email = $the_order->get_billing_email(); // Billing email
// Outpup the email
echo '<strong>'.$email.'</strong>';
}
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.