15

Before I ask this question, I know there is a (legitimate) hesitation to answer questions here about Woo products since they have their own support and their users should be encouraged to use that. I am a paying Woo user but couldn't solve this with their paid support, and my question is about overriding classes in WP so I hope it will get a fair hearing.

My question: when a completed order email is sent out to a customer, I also need to receive this email, verbatim and automatically, exactly as it is sent to the customer rather than in some other format such as is created by the various invoice PDF plugins for WooCommerce. I can very easily accomplish this by changing the following line in /woocommerce/classes/emails/class-wc-email-customer-completed-order.php:

$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );

to read:

$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
$this->send( [email protected], $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );

However, obviously a hack like this isn't going to survive an upgrade. I have a child theme which overrides WooCommerce templates. Is there any equivalent mechanism by which I can override a class in a similarly encapsulated way? Or can you recommend an alternate approach (besides setting the SMTP server to bcc all outgoing emails to the second address) for accomplishing my specific task of receiving this email when the customer also receives it?

1
  • I have used gmail/google as smtp servers before, and it actually puts alle the emails in the sent folder... (for what it's worth in your case)
    – Ewout
    Commented Mar 23, 2013 at 11:20

2 Answers 2

27

There's actually a filter that you can use, see abstract-wc-email.php, line 214:

return apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object );

you can put the following in your functions.php:

add_filter( 'woocommerce_email_recipient_customer_completed_order', 'your_email_recipient_filter_function', 10, 2);

function your_email_recipient_filter_function($recipient, $object) {
    $recipient = $recipient . ', [email protected]';
    return $recipient;
}

the only drawback is that the recipient will see both your address & his own in the To: field.


Alternatively, building on Steve's answer, you can use the woocommerce_email_headers filter. the $object passed allows you to only apply this to the completed order email:

add_filter( 'woocommerce_email_headers', 'mycustom_headers_filter_function', 10, 2);

function mycustom_headers_filter_function( $headers, $object ) {
    if ($object == 'customer_completed_order') {
        $headers .= 'BCC: My name <[email protected]>' . "\r\n";
    }

    return $headers;
}
6
  • This looks very promising. Is your suggestion to create a plugin for this functionality?
    – Halle
    Commented Mar 23, 2013 at 12:02
  • update the answer!
    – Ewout
    Commented Mar 23, 2013 at 13:45
  • That works perfectly, thank you very much. This really went above and beyond.
    – Halle
    Commented Mar 23, 2013 at 14:02
  • The code below "Alternatively, building on Steve's answer..." doesn't seem to work with WC 2.3... Any suggestion?
    – drake035
    Commented Jul 22, 2015 at 12:07
  • None of the codes are working on WC 2.5.5, do you know if they changed the name of the filter? Thanks!
    – Jaypee
    Commented Jun 13, 2016 at 22:17
10

And there is another filter that will give you access to the $header variable which can allow you to BCC your emails so that you get a carbon copy of every email that goes to your clients on Woocommerce. This is just as easy as the code above except your clients will not see your email address.

Just like the solution above you would add the following code:

add_filter( 'woocommerce_email_headers', 'mycustom_headers_filter_function', 10, 2);

function mycustom_headers_filter_function($headers, $object) {
    $headers = array();
    $headers[] = 'Bcc: your name <[email protected]>';
    $headers[] = 'Content-Type: text/html';
    return $headers;
}

This filter applies to all $headers and also hard codes the type as text/html. Note that you do not include the '/r/n' in the content type declaration - this might cause an error in wp_mail() - which is what Woocommerce uses to send your messages.

I'm using this code so I can verify that Woocommerce v2.0.14. Should also work in earlier versions but not sure how long the filter has been included.

2
  • Why not use the /r/n? I think that error only comes up when you add the /r/n in the array of headers. Your example actually overwrites the content setting, which you can reuse.
    – Ewout
    Commented Mar 6, 2014 at 13:37
  • 2
    I've answered on SO with a method to only add BCC to specific emails and to maintain the existing headers. Commented Oct 7, 2014 at 11:32

Not the answer you're looking for? Browse other questions tagged or ask your own question.