I have a custom email which is triggered if product has meta in woocommerce order. Everything works great but I can't get the billing_first_name into the text. I use <?php echo $menomeno; ?>which is declared as $order->get_billing_first_name(); and I've also tried <?php echo $order->get_billing_first_name(); ?> Nothing worked, I get everytime empty string in the email. I have also tried to use sprintf method but it did not sent email. Any ideas how may I solve this?
Note: HTML code is shortened, its much bigger but I did not want to post the whole big code because its not neccesary in this situation when we need to get billing name in the part of the code.
function send_a_custom_email( $order_id, $order ) {
global $woocommerce;
$order = new WC_Order( $order_id );
$mailer = $woocommerce->mailer();
$product_ids = array( ); // Initializing
$customer_email = $order->get_billing_email();
$customer_name = $order->get_billing_first_name();
foreach ( $order->get_items() as $item ) {
$meta_data = $item->get_meta('meno'); // Zisti ake je meno
$venovanie = $item->get_meta('venovanie'); // // Zisti ake je venovanie
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if( empty($meta_data) ) {
$product_ids[] = $item->get_variation_id() > 0 ? $item->get_variation_id() : $item->get_product_id();
}
}
if ( empty($product_ids) && $product_id == 2805 ) {
$recipient = $customer_email; // Set email recipient
$menomeno = $customer_name;
$subject = sprintf( __('Order #%d: Has missing item meta data'), $order_id );
$content = '<table border="0" cellpadding="0" cellspacing="0" class="text_block" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word;" width="100%">
<tr>
<td style="padding-bottom:30px;padding-left:30px;padding-right:30px;padding-top:15px;">
<div style="font-family: sans-serif">
<div style="font-size: 14px; mso-line-height-alt: 25.2px; color: #ffffff; line-height: 1.8; font-family: Montserrat, Trebuchet MS, Lucida Grande, Lucida Sans Unicode, Lucida Sans, Tahoma, sans-serif;">
<p style="margin: 0; font-size: 16px; text-align: center;"><strong>S láskou <?php echo $menomeno; ?>
</strong></p>
</div>
</div>
</td>
</tr>
</table>';
//wp_mail( $recipient, $subject, $content ); // Send email
$mailer->send( $order->billing_email, sprintf( __( 'DTerapia s láskou' ), $order->get_order_number() ), $content );
}
}
Thanks in advance.
Please see this explanation about concatenation:
https://www.php.net/manual/en/language.operators.string.php
Related
I'm building a webshop in WooCommerce for selling Cream Soaps and Antiseptic Gels. They are being sold by unit, by box, or by pallet (3 different attributes). I am using a code snippet to insert the unit price from the product edit page:
https://paste.pics/a2f918d2b3e233dce1e445f6b843561f (sorry about these links i cant post image so far.)
this is the code to get this new field to add the unit price:
// Backend: Add and display a custom field for variable products
add_action('woocommerce_product_options_general_product_data', 'add_custom_product_general_field');
function add_custom_product_general_field()
{
global $post;
echo '<div class="options_group hide_if_simple hide_if_external">';
woocommerce_wp_text_input(array(
'id' => '_min_unit_price',
'label' => __('Min Unit price', 'woocommerce') ,
'placeholder' => '',
'description' => __('Enter the minimum unit price here.', 'woocommerce'),
'desc_tip' => 'true',
));
echo '</div>';
}
// Backend: Save the custom field value for variable products
add_action('woocommerce_process_product_meta', 'save_custom_product_general_field');
function save_custom_product_general_field($post_id)
{
if (isset($_POST['_min_unit_price'])){
$min_unit_price = sanitize_text_field($_POST['_min_unit_price']);
// Cleaning the min unit price for float numbers in PHP
$min_unit_price = str_replace(array(',', ' '), array('.',''), $min_unit_price);
// Save
update_post_meta($post_id, '_min_unit_price', $min_unit_price);
}
}
I want to get this unit price and print to the new order email (image below)
https://paste.pics/30b2584762396a558f3591461ae87be1
I added the new field (unit price) through email-order-details.php file
And now i need to print this unit price that i put on the product (first screenshot)
on the email-order-items.php file.
The code from email-order-items.php
<?php
/**
* Email Order Items
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-order-items.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #package WooCommerce/Templates/Emails
* #version 3.4.0
*/
defined( 'ABSPATH' ) || exit;
$text_align = is_rtl() ? 'right' : 'left';
foreach ( $items as $item_id => $item ) :
$product = $item->get_product();
$sku = '';
$purchase_note = '';
$image = '';
if ( ! apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
continue;
}
if ( is_object( $product ) ) {
$sku = $product->get_sku();
$purchase_note = $product->get_purchase_note();
$image = $product->get_image( $image_size );
}
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>">
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align: middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; word-wrap:break-word;">
<?php
// Show title/image etc.
if ( $show_image ) {
echo wp_kses_post( apply_filters( 'woocommerce_order_item_thumbnail', $image, $item ) );
}
// Product name.
echo wp_kses_post( apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, false ) );
// SKU.
if ( $show_sku && $sku ) {
echo wp_kses_post( ' (#' . $sku . ')' );
}
// allow other plugins to add additional product information here.
do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text );
wc_display_item_meta( $item );
// allow other plugins to add additional product information here.
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, $plain_text );
?>
</td>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align:middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;">
<?php echo wp_kses_post( wc_price( $order->get_item_subtotal( $item ), array( 'currency' => $order->get_currency() ) ) ) ?>
</td>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align:middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;">
<?php echo wp_kses_post( apply_filters( 'woocommerce_email_order_item_quantity', $item->get_quantity(), $item ) ); ?>
</td>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align:middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;">
<?php echo wp_kses_post( $order->get_formatted_line_subtotal( $item ) ); ?>
</td>
</tr>
<?php
if ( $show_purchase_note && $purchase_note ) {
?>
<tr>
<td colspan="3" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align:middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;">
<?php
echo wp_kses_post( wpautop( do_shortcode( $purchase_note ) ) );
?>
</td>
</tr>
<?php
}
?>
<?php endforeach; ?>
More specifically on this line here:
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; vertical-align:middle; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;">
<?php echo wp_kses_post( wc_price( $order->get_item_subtotal( $item ), array( 'currency' => $order->get_currency() ) ) ) ?>
</td>
How can i hook the unit price and echo it on the "unit price" field?
Anyone has experience and a possible solution with this issue? Any help would be highly appreciated. Thanks!
i've been searching around for a long time now and for some reason i cant get it to work.
i need to hide from admin email only, but for some reason it also apply to customer email. i want to hide, shipping from the other, and in client details, phone and email adress.
<?php
add_filter( 'woocommerce_get_order_item_totals', 'custom_woocommerce_get_order_item_totals' );
function custom_woocommerce_get_order_item_totals( $totals ) {
unset( $totals['shipping'] );
return $totals;
}
///// so far is what i got to hide everything and not just the specific fields i wanted
function removing_customer_details_in_emails( $order, $sent_to_admin, $plain_text, $email ){
$wmail = WC()->mailer();
if($sent_to_admin)
remove_action( 'woocommerce_email_customer_details', array( $wmail, 'email_addresses' ), 20, 3 );
}
add_action( 'woocommerce_email_customer_details', 'removing_customer_details_in_emails', 5, 4 );
as mentioned above it hides the fields from the customer email as well and i need just for the admin email, and for some reason all i found did not work,
To hide billing phone, billing email and shipping address on email notifications sent to the admin, use the following instead:
add_action( 'woocommerce_email_customer_details', 'sent_to_admin_custom_email_addresses', 5, 4 );
function sent_to_admin_custom_email_addresses( $order, $sent_to_admin, $plain_text, $email ){
if( in_array( $email->id, array( 'new_order', 'cancelled_order', 'failed_order' ) ) ) {
$mailer = WC()->mailer();
remove_action( 'woocommerce_email_customer_details', array( $mailer, 'email_addresses' ), 20 );
add_action( 'woocommerce_email_customer_details', 'custom_email_addresses', 20, 1 );
}
}
function custom_email_addresses( $order ) {
if ( is_a( $order, 'WC_Order' ) ) :
$text_align = is_rtl() ? 'right' : 'left';
$address = $order->get_formatted_billing_address();
?><table id="addresses" cellspacing="0" cellpadding="0" style="width: 100%; vertical-align: top; margin-bottom: 40px; padding:0;" border="0">
<tr>
<td style="text-align:<?php echo esc_attr( $text_align ); ?>; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; border:0; padding:0;" valign="top" width="50%">
<h2><?php esc_html_e( 'Billing address', 'woocommerce' ); ?></h2>
<address class="address">
<?php echo wp_kses_post( $address ? $address : esc_html__( 'N/A', 'woocommerce' ) ); ?>
</address>
</td>
</tr>
</table>
<?php
endif;
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
Related: Removing customer details and addresses from email notification templates
I want to sort items on the Woocommerce notification emails by categories, as by default they are sorted by the order the customer picks them and add them to the cart. Any help in this regard would be appreciated. Thanks
I actually had a solution added to the email-order-items.php - this adds the categories to the admin email and sorts by using the category (I have categories with numbers that relate to warehouse location - so to have all the same locations together really helps the client pick the order.)
the template is the older version but it still works
//**
* Email Order Items
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-order-items.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates/Emails
* #version 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$text_align = is_rtl() ? 'right' : 'left';
global $woocommerce , $wpdb;
$c1 = $wpdb->get_results("select t1.order_item_name,t1.order_item_id,t5.name,t2.meta_value from wp_woocommerce_order_items as t1 LEFT JOIN wp_woocommerce_order_itemmeta as t2 ON t1.order_item_id = t2.order_item_id LEFT JOIN wp_term_relationships as t3 ON t2.meta_value = t3.object_id LEFT JOIN wp_term_taxonomy as t4 ON t3.term_taxonomy_id = t4.term_taxonomy_id LEFT JOIN wp_terms as t5 ON t4.term_id = t5.term_id where t1.order_id = '".$order->id."' and t1.order_item_type='line_item' and t2.meta_key='_product_id' and t4.taxonomy='product_cat' ORDER BY `t5`.`name` ASC");
$array = array();
foreach($c1 as $data)
{
if (!in_array($data->order_item_id , $array)) {
$array[] = $data->order_item_id;
}
}
//foreach ( $items as $item_id => $item ) :
foreach($array as $newdata) :
$item = $order->get_item($newdata);
if ( apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
$product = $item->get_product();
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>">
<td class="td" style="text-align:<?php echo $text_align; ?>; vertical-align:middle; border: 1px solid #eee; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; word-wrap:break-word;"><?php
// Show title/image etc
if ( $show_image ) {
echo apply_filters( 'woocommerce_order_item_thumbnail', '<div style="margin-bottom: 5px"><img src="' . ( $product->get_image_id() ? current( wp_get_attachment_image_src( $product->get_image_id(), 'thumbnail' ) ) : wc_placeholder_img_src() ) . '" alt="' . esc_attr__( 'Product image', 'woocommerce' ) . '" height="' . esc_attr( $image_size[1] ) . '" width="' . esc_attr( $image_size[0] ) . '" style="vertical-align:middle; margin-' . ( is_rtl() ? 'left' : 'right' ) . ': 10px;" /></div>', $item );
}
// Product name
echo apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, false );
// SKU
if ( $show_sku && is_object( $product ) && $product->get_sku() ) {
echo ' (#' . $product->get_sku() . ')';
}
// allow other plugins to add additional product information here
do_action( 'woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text );
wc_display_item_meta( $item );
if ( $show_download_links ) {
wc_display_item_downloads( $item );
}
// allow other plugins to add additional product information here
do_action( 'woocommerce_order_item_meta_end', $item_id, $item, $order, $plain_text );
// get category for admin email only
if( $sent_to_admin ) {
echo get_the_term_list( $product->id, 'product_cat', __( 'Categories', 'woocommerce' ).': ', ', ' );
}
?></td>
<td class="td" style="text-align:<?php echo $text_align; ?>; vertical-align:middle; border: 1px solid #eee; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php echo apply_filters( 'woocommerce_email_order_item_quantity', $item->get_quantity(), $item ); ?></td>
<td class="td" style="text-align:<?php echo $text_align; ?>; vertical-align:middle; border: 1px solid #eee; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php echo $order->get_formatted_line_subtotal( $item ); ?></td>
</tr>
<?php
}
if ( $show_purchase_note && is_object( $product ) && ( $purchase_note = $product->get_purchase_note() ) ) : ?>
<tr>
<td colspan="3" style="text-align:<?php echo $text_align; ?>; vertical-align:middle; border: 1px solid #eee; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php echo wpautop( do_shortcode( wp_kses_post( $purchase_note ) ) ); ?></td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
Go to WooCommerce > Settings in your WordPress admin. On the Products tab, under the Display settings,change the Default Product Sorting.
Change the "Order by" in your sql query.
I'm using WooCommerce 3.1.1 and I am trying to replace the "price amount" with some text for specific product categories in New order noification for customers and admin.
I have almost tried everything but I am unable to locate the order item detail table for email notifications.
This email looks like this for now:
Any help would be really appreciated.
You will need first to read this official documentation, to learn about Overriding WooCommerce Templates via your active Theme
The templates that you need to change and override is emails/email-order-items.php
At line 58 for your WC version (Or line 55 in WC version 3.2+), you will replace:
<td class="td" style="text-align:<?php echo $text_align; ?>; vertical-align:middle; border: 1px solid #eee; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php echo $order->get_formatted_line_subtotal( $item ); ?></td>
By this (where you should set your own category and replacement text string):
<?php
## ---- Variables to define (below)---- ##
$categories = array( 'clothing' ); // The Product categories coma separated (IDs slugs or names)
$replacement_text = __( 'Replacement text (here)' ); // The replacement text
// Getting the email ID global variable (From our function below)
$refNameGlobalsVar = $GLOBALS;
$email_id = $refNameGlobalsVar['email_id_str'];
// When matching product categories, "New Order", "Processing" and "On Hold" email notifications
if( has_term( $categories, 'product_cat', $product->get_id() )
&& ( $email_id == 'new_order' || $email_id == 'customer_processing_order' || $email_id == 'customer_on_hold_order' ) )
$formated_line_subtotal = $replacement_text;
else
$formated_line_subtotal = $order->get_formatted_line_subtotal( $item );
?>
<td class="td" style="text-align:<?php echo $text_align; ?>; vertical-align:middle; border: 1px solid #eee; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php echo $formated_line_subtotal; ?></td>
To Get the email ID you will need to add this in function.php file of your active child theme (or active theme):
// Setting the email_id as a global variable
add_action('woocommerce_email_before_order_table', 'the_email_id_as_a_global', 1, 4);
function the_email_id_as_a_global($order, $sent_to_admin, $plain_text, $email){
$GLOBALS['email_id_str'] = $email->id;
}
Now you will get this when product category matches and for "New Order" (admin), "Customer On Hold Order" and "Customer Processing Order" email notifications only:
I have a problem and it sounds stupid, but I'm really stucked.
I need to send "new order" email also to customer. I tried adding function to functions.php file, and it sends email, but doesn't show most of variables. I inserted the same code into sample php file, added as page in wordpress and it works really well. I really don't know what is going on.
Any solutions? Maybe there is more simple way, like adding recipent to "new order"email in woocommerce? I checked class-wc-email-new-order.php file, but I was not able to change anything in there, I don't understand how it works.
screen: code working on page VS what is visible in received email
function create_email_body($order_id){
global $woocommerce;
if ( !$order_id )
return;
$order = new WC_Order( $order_id );
$body = '';
$product_list = '';
$order_item = $order->get_items();
foreach( $order_item as $product ) {
$body .= $product['name'];
}
$order = new WC_Order( $order_id );
$body =' <div style = "width: 100%; clear: both; color: #000;">';
$body .=' <div style="width: 50%; float: left;">';
$body .=' <p> Numer zamówienia:<b> '. $order->get_order_number() .'</b> </p>';
$body .=' <p> Imię i nazwisko:<b> '. $order->billing_first_name . " " . $order->billing_last_name . '</b> </p>';
$body .=' <p> Sposób dostawy: <b> '. $order->get_shipping_method() .'</b> </p>';
$body .=' <p> Status zamówienia:<b> przyjęte</b> </p>';
$body .=' <p> Adres dostawy: <b> '. $order->shipping_address_1 . " " . $order->shipping_address_2 . ", " . $order->shipping_postcode . " " . $order->shipping_city . ", " . $order->shipping_state . $order->shipping_country .'</b> </p>';
$body .=' </div>';
$body .=' <div style="width: 50%; float: left;">';
$body .=' <p> Data zamówienia:<b> '. $order->order_date . '</b> </p>';
$body .=' <p> Email: <b><span style = "color: #000 !important"> '. $order->billing_email . '</b> </span></p> ';
$body .=' <p> Metoda płatności: <b> '. $order->payment_method_title .'</p>';
$body .=' <p> Numer telefonu:<b> '. $order->billing_phone .'</b> </p> ';
$body .=' </div>';
$body .=' </div>';
$body .=' <div style = "width: 100%; clear: both; color: #000; margin-top: 30px;">';
$body .=' <table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: "Myriad", sans-serif;" border="1">';
$body .=' <thead>';
$body .=' <tr>';
$body .=' <th class="td" scope="col" style="text-align:left;" style = "border: none; color: #000;"></th>';
$body .=' <th class="td" scope="col" style="text-align:left;" style = "border: none; color: #000;">Produkt</th>';
$body .=' <th class="td" scope="col" style="text-align:left;" style = "border: none; color: #000;">Ilość</th>';
$body .=' <th class="td" scope="col" style="text-align:left;" style = "border: none; color: #000;">Cena</th>';
$body .=' <th class="td" scope="col" style="text-align:left;" style = "border: none; color: #000;">Wartość</th>';
$body .=' </tr>';
$body .=' </thead>';
$body .=' <tbody>';
$items = $order->get_items();
foreach ( $items as $item_id => $item ) :
$_product = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item );
$item_meta = new WC_Order_Item_Meta( $item, $_product );
if ( apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
$body .=' <tr class=' . esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ) .'">';
$body .=' <td class="td" style="text-align:left; vertical-align:middle; border: none; font-family: "Myriad", sans-serif; word-wrap:break-word; color: #000;">';
$body .=' </td><td style = "border: none; color: #000">';
// Product name
$body .=$item['name'];///' <p style = "display: inline-block; float: left">' . apply_filters( 'woocommerce_order_item_name', $item['name'], $item, false );
if ( ! empty( $item_meta->meta ) ) {
$body .= nl2br( $item_meta->display( true, true, '_', "\n" ) );
}
$body .= "</p>";
$body .= '</td>';
$body .=' <td class="td" style="text-align:left; vertical-align:middle; border: none; font-family: "Myriad", sans-serif; color: #000">' . apply_filters( 'woocommerce_email_order_item_quantity', $item['qty'], $item ) .'</td>';
$body .=' <td class="td" style="text-align:left; vertical-align:middle; border: none; font-family: "Myriad", sans-serif; color: #000">' . $_product->get_price();
$body .=' </td>';
$body .=' <td class="td" style="text-align:left; vertical-align:middle; border: none; font-family: "Myriad", sans-serif; color: #000">' . $order->get_formatted_line_subtotal( $item );
$body .=' </td></tr>';
}
endforeach;
$body .=' </tbody>';
$body .=' <tfoot><td style = "border: none;"></td><td style = "border: none;"></td><td style = "border: none; color: #000;"></td>';
$body .=' <td style = "border: none; color: #000;">';
$body .=' <p> Wartość produktów </p> ';
$body .=' <p> Cena wysyłki </p>';
$body .=' <p> Do zapłaty </p>';
$body .=' </td>';
$body .=' <td style = "border: none; color: #000;">';
$body .=' <p>' . number_format((float)$order->get_subtotal(), 2, '.', '') . " zł" . '</p>';
$body .=' <p>' . number_format((float)$order->get_total_shipping(), 2, '.', '') . " zł" . '</p>';
$body .=' <p>' . $order->get_formatted_order_total(). '</p>';
$body .=' </td>';
$body .=' </tfoot>';
$body .=' </table>';
$body .=' </div>';
$body .= file_get_contents(get_stylesheet_directory_uri() . '/woocommerce/emails/customer-on-hold.order.php');
return $body;
}
function send_email_also_to_customer($order_id){
$order = new WC_Order( $order_id );
$to_email = $order->billing_email;
$headers = 'Od: AB.com <a#b.com>' . "\r\n";
$mailer = WC()->mailer();
$subject = 'Potwierdzenie przyjęcia zamówienia numer # ' . $order_id;
$body = create_email_body($order_id);
$mailer->send( $to_email, $subject, $mailer->wrap_message( $subject, $body), '', '' );
}
add_action( 'woocommerce_new_order', 'send_email_also_to_customer');
You do not need to do all these stuff again for sending multiple emails. You can simply add recipient to "New Order" email(with customer's email). Here is the code you can try:
<?php
/**
* Add another email recipient for admin New Order emails if a shippable product is ordered
*
* #param string $recipient a comma-separated string of email recipients (will turn into an array after this filter!)
* #param \WC_Order $order the order object for which the email is sent
* #return string $recipient the updated list of email recipients
*/
function sv_conditional_email_recipient( $recipient, $order ) {
// Bail on WC settings pages since the order object isn't yet set yet
// Not sure why this is even a thing, but shikata ga nai
$page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
if ( 'wc-settings' === $page ) {
return $recipient;
}
// just in case
if ( ! $order instanceof WC_Order ) {
return $recipient;
}
$items = $order->get_items();
// check if a shipped product is in the order
foreach ( $items as $item ) {
$product = $order->get_product_from_item( $item );
// add our extra recipient if there's a shipped product - commas needed!
// we can bail if we've found one, no need to add the recipient more than once
if ( $product && $product->needs_shipping() ) {
$recipient .= ', warehouse-manager#example.com';
return $recipient;
}
}
return $recipient;
}
add_filter( 'woocommerce_email_recipient_new_order', 'sv_conditional_email_recipient', 10, 2 );
WRONG :
$recipient .= ', ' . $order->billing_email
CORRECT:
$recipient .= "," . $order->get_billing_email();
I tested and debug this for a whole day.
Update 2018-2019 - For Woocommerce 3+
The accepted answer code is outdated since Woocommerce 3, with some errors in the code.
get_product_from_item() method is deprecated and replaced by $item->get_product().
The Customer email is missing
There is unnecessary code (removed and replaced).
Here is a similar up to date and clean version:
add_filter( 'woocommerce_email_recipient_new_order', 'custom_new_order_email_recipient', 10, 2 );
function custom_new_order_email_recipient( $recipient, $order ) {
// Avoiding backend displayed error in Woocommerce email settings for undefined $order
if ( ! is_a( $order, 'WC_Order' ) )
return $recipient;
// Check order items for a shipped product is in the order
foreach ( $order->get_items() as $item ) {
$product = $item->get_product(); // Get WC_Product instance Object
// When a product needs shipping we add the customer email to email recipients
if ( $product->needs_shipping() ) {
return $recipient . ',' . $order->get_billing_email();
}
}
return $recipient;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.