1
votes

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 <[email protected]>' . "\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');
3

3 Answers

6
votes

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 .= ', [email protected]';
            return $recipient;
        }
    }

    return $recipient;
}
add_filter( 'woocommerce_email_recipient_new_order', 'sv_conditional_email_recipient', 10, 2 );
3
votes

WRONG :

$recipient .= ', ' . $order->billing_email

CORRECT:

$recipient .= "," . $order->get_billing_email();

I tested and debug this for a whole day.

2
votes

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.