Advanced Custom Fields in WooCommerce Email templates - php

I am using Advanced Custom Fields (ACF) plugin in WooCommerce and I have set a custom field named "tracking-no".
How can I display the value of this custom field in the Woocommerce template emails/customer-completed-order.php?
I am using this code:
<?php
if(get_field('tracking-no'))
{
echo '<p>' . get_field('tracking-no') . '</p>';
}
?>
But I doesn't get anything.
Thanks

In your WooCommerce template you should get first the order ID as argument in get_field():
<?php
// Get the $order ID (WooCommerce version compatibility)
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$order_id = int_val( $order->id ); // Older than 3.0
} else {
$order_id = int_val( $order->get_id() ); // 3.0+
}
$tracking_num = get_field('tracking-no', $order_id );
if( $tracking_num ){
echo '<p>' . $tracking_num . '</p>';
}
?>
You can also use instead any email notification hook that you can find on this template, this way:
add_action( 'woocommerce_email_order_details', 'my_custom_field_in_completed_notification', 10, 4 );
function my_custom_field_in_completed_notification( $order, $sent_to_admin, $plain_text, $email ){
// Get the $order ID (WooCommerce version compatibility)
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$order_id = int_val( $order->id ); // Older than 3.0
} else {
$order_id = int_val( $order->get_id() ); // 3.0+
}
$tracking_num = get_field('tracking-no', $order_id );
if( $tracking_num ){
echo '<p>' . $tracking_num . '</p>';
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
In this case we don't override WooCommerce templates. You can also use that 2 similar hooks:
woocommerce_email_order_meta
woocommerce_email_customer_details

Related

How to show WooCommerce custom product meta in new order emails?

I'm currently successfully saving custom post meta for a single product as follows:
function save_payment_terms( $product_id ) {
if ( isset( $_POST['payment_terms'] ) ) {
update_post_meta( $product_id, 'payment_terms', is_numeric( $_POST['payment_terms'] ) ? absint( wp_unslash( $_POST['payment_terms'] ) ) : '1' );
}
}
How would I go about adding that custom post meta to a new order confirmation email? I've tried the following hooks without success: woocommerce_email_order_meta and woocommerce_order_item_meta_start. The latest iteration looking as follows:
add_action('woocommerce_order_item_meta_start', 'email_confirmation_display_order_items', 10, 4);
function email_confirmation_display_order_items($item_id, $item, $order, $plain_text) {
echo '<div>Terms: '. wc_get_order_item_meta( $item_id, 'payment_terms') .'</div>';
}
Resulting in:
Doing a var_dump of wc_get_order_item_meta, I get: ../snippet-ops.php(446) : eval()'d code:7:boolean false
Anyone that could shed some light on this?
Try the following instead:
add_action( 'woocommerce_order_item_meta_start', 'email_confirmation_display_order_items', 10, 3 );
function email_confirmation_display_order_items( $item_id, $item, $order ) {
// On email notifications for line items
if ( ! is_wc_endpoint_url() && $item->is_type('line_item') ) {
$payment_terms = get_post_meta( $item->get_product_id(), 'payment_terms', true );
if ( ! empty($payment_terms) ) {
printf( '<div>' . __("Terms: %s", "woocommerce") . '</div>', $payment_terms );
}
}
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Related: WooCommerce Display avanced custom fields (ACF) inside order notification

Display specific product attribute in WooCommerce email notifications

I can't manage to add a product attribute to a WooCommerce new order email. I have added the snippet below to email-order-items.php (after // SKU.. part), but nothing happens. Even the titel 'Location:' isn't visible. Any thoughts on this?
// Attribute
if ( $item_meta->meta ) {echo '<br/><small>Location: ' . nl2br( $product->get_attribute( 'location' ) ) . '</small>';}
Updated - Instead of overriding Woocommerce templates, always try first to use available hooks like:
add_action( 'woocommerce_order_item_meta_start', 'add_download_links_to_thank_you_page', 10, 3 );
function add_download_links_to_thank_you_page( $item_id, $item, $order ) {
// Set below your product attribute taxonomy (always starts with "pa_")
$taxonomy = 'pa_location';
// On email notifications
if ( ! is_wc_endpoint_url() && $item->is_type('line_item') ) {
$product = $item->get_product();
$label_name = get_taxonomy( $taxonomy )->labels->singular_name;
if ( $term_names = $product->get_attribute( $taxonomy ) ) {
echo '<br/><small>' . $label_name . ': ' . nl2br( $term_names ) . '</small>';
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
You can also use woocommerce_order_item_meta_end hook instead.

Save custom values from Woocommerce checkout as custom order meta data

In Woocommerce, I have a checkout page (review order) with custom data.
I need to find a hook to register some custom data ($totaleiva_1 and $totalefinitocarrello) in the order and then I have to send them in email new order.
I'm not able to make it for instance. Any advice or help please?
Edit - That is my code:
$totaleiva_1 = 0;
$items = $woocommerce->cart->get_cart();
foreach($items as $item ) {
$totaleiva_1 += $totalForSebeneArray[$item ['data']->get_id()];
}
$totaleiva_1 = number_format($totaleiva_1, 2, '.', '');
$totalefinitocarrello = $totaleiva_1 + $total; echo "€";
echo $totalefinitocarrello;
You will need to add and display 2 hidden fields with the 2 desired values (to be able to get and save them as custom order meta data on submission).
Also your code is a bit outdated and can be simplified.
Here is your revisited code:
$totaleiva_1 = 0;
// Loop through cart items
foreach (WC()->cart->get_cart() as $cart_item ) {
$totale_iva_1 += $totalForSebeneArray[$cart_item['data']->get_id()];
}
$totale_finito_carrello = wc_price( $totale_iva_1 + $total );
echo $totale_finito_carrello;
// Display 2 hidden input fields
echo '<input type="hidden" id="totaleiva1" name="totaleiva1" value="'.$totale_iva_1.'">
<input type="hidden" id="tfcarrello" name="tfcarrello" value="'.$totale_finito_carrello.'">';
Then you will save that data as custom order meta data using:
add_action('woocommerce_checkout_create_order', 'save_order_custom_meta_data', 10, 2 );
function save_order_custom_meta_data( $order, $data ) {
if( isset($_POST['totaleiva1']) && ! empty($_POST['totaleiva1']) ) {
$order->update_meta_data( '_totale_iva_1', esc_attr( $_POST['totaleiva1'] ) );
}
if( isset($_POST['tfcarrello']) && ! empty($_POST['tfcarrello']) ) {
$order->update_meta_data( '_totale_fin_carrello', esc_attr( $_POST['tfcarrello'] ) );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Now to get that data and use it anywhere:
1) from the order ID variable, use:
$totaleiva_1 = get_post_meta( $order_id, '_totale_iva_1', true );
$totalefinitocarrello = get_post_meta( $order_id, '_totale_fin_carrello', true );
2 from the WC_Order Object:
$totaleiva_1 = $order->get_meta('_totale_iva_1');
$totalefinitocarrello = $order->get_meta('_totale_fin_carrello');
To display those in Woocommerce new order notification, ou will use:
add_action( 'woocommerce_email_order_details', 'email_order_details_action_callback', 5, 4 );
function email_order_details_action_callback( $order, $sent_to_admin, $plain_text, $email ){
if( $email->id === 'new_order' ) {
if ( $tiva1 = $order->get_meta('_totale_iva_1') ) {
echo '<p>'. __("Totale IVA") . ': ' . $tiva1 . '</p>';
}
if ( $tfcarr = $order->get_meta('_totale_fin_carrello') ) {
echo '<p>'. __("Totale finito carrello") . ': ' . $tfcarr . '</p>';
}
}
}
Display the fields in Admin order pages:
add_action( 'woocommerce_admin_order_data_after_billing_address', 'admin_order_after_billing_address_callback', 10, 1 );
function admin_order_after_billing_address_callback( $order ){
if ( $tiva1 = $order->get_meta('_totale_iva_1') ) {
echo '<p>'. __("Totale IVA") . ': ' . $tiva1 . '</p>';
}
if ( $tfcarr = $order->get_meta('_totale_fin_carrello') ) {
echo '<p>'. __("Totale finito carrello") . ': ' . $tfcarr . '</p>';
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Now I think that all your IVA custom calculations can be handled by Woocommerce using available settings possibilities, as you are making things Much more complicated everywhere.

Customize order item meta only for WooCommerce admin email notifications

I need to add custom taxonomy to admin new order emails but not to customer emails. My current code displays my custom taxonomy for each item in the order but it is showing up in both admin and customer emails, which I don't want.
Looking thru email-order-items.php I don't see a way to utilize $sent_to_admin in the hook that I am using. Am I missing something?
How do I add my custom taxonomy only to admin emails using just hooks and filters?
add_action( 'woocommerce_order_item_meta_end', 'custom_woocommerce_order_item_meta_end', 10, 3 );
function custom_woocommerce_order_item_meta_end( $item_id, $item, $order ) {
$product = $item->get_product();
$locations = get_the_terms( $product->get_id(), 'my_custom_taxonomy' );
echo '<br/>';
echo '<div style="margin-top: 20px;">';
foreach( $locations as $location ) {
echo 'Location: <b>' . $location->name . '</b>';
echo '<br/>';
}
echo '</div>
}
This can be done using $GLOBAL variable. I have revisited a bit your code too. Try this:
// Setting the "sent_to_admin" as a global variable
add_action('woocommerce_email_before_order_table', 'email_order_id_as_a_global', 1, 4);
function email_order_id_as_a_global($order, $sent_to_admin, $plain_text, $email){
$GLOBALS['email_data'] = array(
'sent_to_admin' => $sent_to_admin, // <== HERE we set "$sent_to_admin" value
'email_id' => $email->id, // The email ID (to target specific email notification)
);
}
// Conditionally customizing footer email text
add_action( 'woocommerce_order_item_meta_end', 'custom_email_order_item_meta_end', 10, 3 );
function custom_email_order_item_meta_end( $item_id, $item, $order ){
// Getting the custom 'email_data' global variable
$refNameGlobalsVar = $GLOBALS;
$email_data = $refNameGlobalsVar['email_data'];
// Only for admin email notifications
if( ! ( is_array( $email_data ) && $email_data['sent_to_admin'] ) ) return;
## -------------------------- Your Code below -------------------------- ##
$taxonomy = 'my_custom_taxonomy'; // <= Your custom taxonomy
echo '<br/><div style="margin-top: 20px;">';
foreach( get_the_terms( $item->get_product_id(), $taxonomy ) as $term )
echo 'Location: <b>' . $term->name . '</b><br/>';
echo '</div>';
}
Code goes in function.php file of the active child theme (or active theme).
Tested and works.

Adding a custom field value to Woocommerce order email template

In Woocommerce with Advanced Custom Fields plugin, we have added a custom field to products and this field value is specific to each product.
Now I am trying to add this custom field value to our Woocommerce order confirmation emails.
I have tried the following code with no success:
<?php
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$order_id = int_val( $order->id ); // Older than 3.0
} else {
$order_id = int_val( $order->get_id() ); // 3.0+
}
$inst1 = get_field(‘how1’, $order_id );
if( $inst1 ){
echo '<p>' . $inst1 . '</p>';
}
?> with Advanced Custom Fields plugin
As your custom field is specific to "product" post type (but NOT to "order" post type) you need to get first the order items to get the product ID that you should use with ACF get_field() function this way:
<?php
foreach ( $order->get_items() as $item ) {
// Get the product ID
if ( version_compare( WC_VERSION, '3.0', '<' ) ) {
$product_id = $item['product_id']; // Older than 3.0
} else {
$product_id = $item->get_product_id(); // 3.0+
}
$inst1 = get_field( 'how1', $product_id );
if( $inst1 ){
echo '<p>' . $inst1 . '</p>';
}
}
<?
The custom field value will be displayed for each item in the order, as an order can have many items in it.
References:
How to get WooCommerce order details
Get Order items and WC_Order_Item_Product in Woocommerce 3

Categories