Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Modification of Woocommerce 'Product Add-ons' data in WC emails WordPress

  • SOLVED

Hey guys,

So.. I have this Woocommerce site where I am using the Product Add-ons plugin (http://www.woothemes.com/products/product-add-ons/) for adding input fields to products.

Now, for the admin email I obviously want to have all the "add-on data" from the customers order present (as it is now), but for all other emails (namely those to customers), I would like it removed.

I'm not strong on PHP but I have fiddled with it and can't seem to come up with a way to hide the add-on data if it's a customer email.

Have a look at line 56-58
https://github.com/woothemes/woocommerce/blob/master/templates/emails/email-order-items.php

I can of course do something like display:none;

// Variation
if ( $item_meta->meta ) {
echo '<br/><small style="display:none">' . nl2br( $item_meta->display( true, true ) ) . '</small>';
}

but then it will hide the add-on data for all emails, also the one to administrators.

So, basically I want to retain the info in this email template:
https://github.com/woothemes/woocommerce/blob/master/templates/emails/admin-new-order.php

And hide/remove it in all the others:
https://github.com/woothemes/woocommerce/tree/master/templates/emails

I hope that explanation is good enough, can someone help me?

Answers (1)

2014-05-19

Kyle answers:

For the line in customer-completed-order.php that looks like this (29):

<?php echo $order->email_order_items_table( true, false, true ); ?>

You may want to replace with just the code you want from email-order-items.php


Kyle comments:

Try this as your customer-completed-order.php

<?php
/**
* Customer completed order email
*
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 1.6.4
*/

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>

<?php do_action( 'woocommerce_email_header', $email_heading ); ?>

<p><?php printf( __( "Hi there. Your recent order on %s has been completed. Your order details are shown below for your reference:", 'woocommerce' ), get_option( 'blogname' ) ); ?></p>

<?php do_action( 'woocommerce_email_before_order_table', $order, $sent_to_admin, $plain_text ); ?>

<h2><?php echo __( 'Order:', 'woocommerce' ) . ' ' . $order->get_order_number(); ?></h2>

<table cellspacing="0" cellpadding="6" style="width: 100%; border: 1px solid #eee;" border="1" bordercolor="#eee">
<thead>
<tr>
<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Product', 'woocommerce' ); ?></th>
<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Price', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody> <?php

global $woocommerce;

foreach ( $items as $item ) :
$_product = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item );
$item_meta = new WC_Order_Item_Meta( $item['item_meta'], $_product );
?>
<tr>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee; word-wrap:break-word;"><?php

// Show title/image etc
if ( $show_image ) {
echo apply_filters( 'woocommerce_order_item_thumbnail', '<img src="' . ( $_product->get_image_id() ? current( wp_get_attachment_image_src( $_product->get_image_id(), 'thumbnail') ) : wc_placeholder_img_src() ) .'" alt="' . __( 'Product Image', 'woocommerce' ) . '" height="' . esc_attr( $image_size[1] ) . '" width="' . esc_attr( $image_size[0] ) . '" style="vertical-align:middle; margin-right: 10px;" />', $item );
}

// Product name
echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item );

// SKU
if ( $show_sku && is_object( $_product ) && $_product->get_sku() ) {
echo ' (#' . $_product->get_sku() . ')';
}

// File URLs
if ( $show_download_links && is_object( $_product ) && $_product->exists() && $_product->is_downloadable() ) {

$download_files = $order->get_item_downloads( $item );
$i = 0;

foreach ( $download_files as $download_id => $file ) {
$i++;

if ( count( $download_files ) > 1 ) {
$prefix = sprintf( __( 'Download %d', 'woocommerce' ), $i );
} elseif ( $i == 1 ) {
$prefix = __( 'Download', 'woocommerce' );
}

echo '<br/><small>' . $prefix . ': <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a></small>';
}
}

?></td>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo $item['qty'] ;?></td>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo $order->get_formatted_line_subtotal( $item ); ?></td>
</tr>

<?php if ( $show_purchase_note && is_object( $_product ) && $purchase_note = get_post_meta( $_product->id, '_purchase_note', true ) ) : ?>
<tr>
<td colspan="3" style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo apply_filters( 'the_content', $purchase_note ); ?></td>
</tr>
<?php endif; ?>

<?php endforeach; ?>
</tbody>
<tfoot>
<?php
if ( $totals = $order->get_order_item_totals() ) {
$i = 0;
foreach ( $totals as $total ) {
$i++;
?><tr>
<th scope="row" colspan="2" style="text-align:left; border: 1px solid #eee; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
<td style="text-align:left; border: 1px solid #eee; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
</tr><?php
}
}
?>
</tfoot>
</table>

<?php do_action( 'woocommerce_email_after_order_table', $order, $sent_to_admin, $plain_text ); ?>

<?php do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text ); ?>

<h2><?php _e( 'Customer details', 'woocommerce' ); ?></h2>

<?php if ($order->billing_email) : ?>
<p><strong><?php _e( 'Email:', 'woocommerce' ); ?></strong> <?php echo $order->billing_email; ?></p>
<?php endif; ?>
<?php if ($order->billing_phone) : ?>
<p><strong><?php _e( 'Tel:', 'woocommerce' ); ?></strong> <?php echo $order->billing_phone; ?></p>
<?php endif; ?>

<?php wc_get_template( 'emails/email-addresses.php', array( 'order' => $order ) ); ?>

<?php do_action( 'woocommerce_email_footer' ); ?>


cruiseback comments:

Hi Kyle,

Yes, I did try that, like this [[LINK href="http://pastebin.com/M7sXt1BR"]][[/LINK]]
But an error happens when I try to send the email from within wp-admin and it's not working.

Besides, I want all information except the 'add-on data' to go to the customer so it probably make more sense to go the other way around. Otherwise I would have to edit all 'customer-xxx.php' files instead of just editing 'admin-new'order.php'.

Thanks, cb


Kyle comments:

We could also write a new template all together (like email-order-items_2.php)

Then add this to your functions.php

function email_order_items_table_2( $show_download_links = false, $show_sku = false, $show_purchase_note = false, $show_image = false, $image_size = array( 32, 32 ), $plain_text = false ) {

ob_start();

$template = ***put your filepath here***/'email-order-items_2.php';

wc_get_template( $template, array(
'order' => $this,
'items' => $this->get_items(),
'show_download_links' => $show_download_links,
'show_sku' => $show_sku,
'show_purchase_note' => $show_purchase_note,
'show_image' => $show_image,
'image_size' => $image_size
) );

$return = apply_filters( 'woocommerce_email_order_items_table', ob_get_clean(), $this );

return $return;
}



Then map the line starting with $template to email-order-items_2.php, where ever you put it. Then make the changes you want to see. Does that make sense?


cruiseback comments:

Hi again,

Sorry, I misunderstood parts of your email, and yes, this is working.

But the following templates would also need to be changed, and they look different to me than 'customer-completed-order.php'.

Specifically, I cannot find
<?php echo $order->email_order_items_table( true, false, true ); ?>

customer-invoice.php
https://github.com/woothemes/woocommerce/blob/master/templates/emails/customer-invoice.php

customer-processing-order.php
https://github.com/woothemes/woocommerce/blob/master/templates/emails/customer-processing-order.php

Thanks, cb


Kyle comments:

Then you change line 28 of admin-new-order.php to <?php echo email_order_items_table_2( false, true ); ?> to call your new template with your new funciton


Kyle comments:

The email_order_items_table function is in the class-wc-order.php file line 1022 (/includes directory)


Kyle comments:

Sorry, got wires crossed there.

I think we can circle back and use what you suggested, where we change the admin email instead of the customer (so it removes by default but then includes it for the admin)

Change your admin-new-order.php to the following, and remove the variation line you had originally posted from email-order-items.php

admin-new-order.php :
<?php
/**
* Admin new order email
*
* @author WooThemes
* @package WooCommerce/Templates/Emails/HTML
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>

<?php do_action( 'woocommerce_email_header', $email_heading ); ?>

<p><?php printf( __( 'You have received an order from %s. Their order is as follows:', 'woocommerce' ), $order->billing_first_name . ' ' . $order->billing_last_name ); ?></p>

<?php do_action( 'woocommerce_email_before_order_table', $order, true, false ); ?>

<h2><a href="<?php echo admin_url( 'post.php?post=' . $order->id . '&action=edit' ); ?>"><?php printf( __( 'Order: %s', 'woocommerce'), $order->get_order_number() ); ?></a> (<?php printf( '<time datetime="%s">%s</time>', date_i18n( 'c', strtotime( $order->order_date ) ), date_i18n( wc_date_format(), strtotime( $order->order_date ) ) ); ?>)</h2>

<table cellspacing="0" cellpadding="6" style="width: 100%; border: 1px solid #eee;" border="1" bordercolor="#eee">
<thead>
<tr>
<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Product', 'woocommerce' ); ?></th>
<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
<th scope="col" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Price', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>

<?php
global $woocommerce;

foreach ( $items as $item ) :
$_product = apply_filters( 'woocommerce_order_item_product', $order->get_product_from_item( $item ), $item );
$item_meta = new WC_Order_Item_Meta( $item['item_meta'], $_product );
?>
<tr>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee; word-wrap:break-word;"><?php

// Show title/image etc
if ( $show_image ) {
echo apply_filters( 'woocommerce_order_item_thumbnail', '<img src="' . ( $_product->get_image_id() ? current( wp_get_attachment_image_src( $_product->get_image_id(), 'thumbnail') ) : wc_placeholder_img_src() ) .'" alt="' . __( 'Product Image', 'woocommerce' ) . '" height="' . esc_attr( $image_size[1] ) . '" width="' . esc_attr( $image_size[0] ) . '" style="vertical-align:middle; margin-right: 10px;" />', $item );
}

// Product name
echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item );

// SKU
if ( $show_sku && is_object( $_product ) && $_product->get_sku() ) {
echo ' (#' . $_product->get_sku() . ')';
}

// File URLs
if ( $show_download_links && is_object( $_product ) && $_product->exists() && $_product->is_downloadable() ) {

$download_files = $order->get_item_downloads( $item );
$i = 0;

foreach ( $download_files as $download_id => $file ) {
$i++;

if ( count( $download_files ) > 1 ) {
$prefix = sprintf( __( 'Download %d', 'woocommerce' ), $i );
} elseif ( $i == 1 ) {
$prefix = __( 'Download', 'woocommerce' );
}

echo '<br/><small>' . $prefix . ': <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a></small>';
}
}

// Variation
if ( $item_meta->meta ) {
echo '<br/><small>' . nl2br( $item_meta->display( true, true ) ) . '</small>';
}

?></td>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo $item['qty'] ;?></td>
<td style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo $order->get_formatted_line_subtotal( $item ); ?></td>
</tr>

<?php if ( $show_purchase_note && is_object( $_product ) && $purchase_note = get_post_meta( $_product->id, '_purchase_note', true ) ) : ?>
<tr>
<td colspan="3" style="text-align:left; vertical-align:middle; border: 1px solid #eee;"><?php echo apply_filters( 'the_content', $purchase_note ); ?></td>
</tr>
<?php endif; ?>

<?php endforeach; ?>

</tbody>
<tfoot>
<?php
if ( $totals = $order->get_order_item_totals() ) {
$i = 0;
foreach ( $totals as $total ) {
$i++;
?><tr>
<th scope="row" colspan="2" style="text-align:left; border: 1px solid #eee; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
<td style="text-align:left; border: 1px solid #eee; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
</tr><?php
}
}
?>
</tfoot>
</table>

<?php do_action( 'woocommerce_email_after_order_table', $order, true, false ); ?>

<?php do_action( 'woocommerce_email_order_meta', $order, true, false ); ?>

<h2><?php _e( 'Customer details', 'woocommerce' ); ?></h2>

<?php if ( $order->billing_email ) : ?>
<p><strong><?php _e( 'Email:', 'woocommerce' ); ?></strong> <?php echo $order->billing_email; ?></p>
<?php endif; ?>
<?php if ( $order->billing_phone ) : ?>
<p><strong><?php _e( 'Tel:', 'woocommerce' ); ?></strong> <?php echo $order->billing_phone; ?></p>
<?php endif; ?>

<?php wc_get_template( 'emails/email-addresses.php', array( 'order' => $order ) ); ?>

<?php do_action( 'woocommerce_email_footer' ); ?>


cruiseback comments:

Right ok, yea, that makes the most sense to me.

I have done as you have prescribed but nothing is showing in the admin email (admin-new-order.php)

Here are my modified templates for inspection:
[[LINK href="http://pastebin.com/fxCvBLVy"]]admin-new-order.php[[/LINK]]
[[LINK href="http://pastebin.com/cHNq0GbS"]]email-order-items.php[[/LINK]]

Am I doing something wrong?

Thanks, cb


Kyle comments:

When you said this was working earlier, was it showing for you?


cruiseback comments:

What worked earlier for me was to change the 'customer-completed-order.php' as per your instructions.

When I then requested a 'customer order completed'-email and an 'admin new order'-email it worked as it was meant to.

But the problem with that solution was that I also need to modify the other 'customer-xxx.php'-email templates, and they look different from the 'customer-completed-order.php'-email template, specifically they do not hold the line:
<?php echo $order->email_order_items_table( true, false, true ); ?>

Otherwise it would have been an easy copy/paste job.

So my thought was that having to do modifications to 3 templates was a hassle when all I needed was to retain the info in the admin email template (admin-new-order.php).

Thanks, cb


Kyle comments:

So when you did the changes the admin email template that you had done to the customer order completed, you weren't getting the same result?


cruiseback comments:

Err, I'm a little confused by your question, but basically..

<strong>Option 1 - modify customer email templates</strong>
Here we leave 'admin-new-order.php' as it is, and instead we modify 'customer-completed-order.php' into this [[LINK href="http://pastebin.com/GTrisvFg"]]http://pastebin.com/GTrisvFg[[/LINK]]
(We also need to change the 2 other customer-xxx.php templates with this option)

<strong>Option 2 - modify admin email template</strong>
Here we leave the 'customer-completed-order.php' (and 2 other) customer templates alone and change 'admin-new-order.php' into this [[LINK href="http://pastebin.com/fxCvBLVy"]]http://pastebin.com/fxCvBLVy[[/LINK]]

Ok, so option 1 works, but isn't complete

Option 2 does not work, the add-on data is lacking in both the 'customer-completed-order.php' template (which is correct) and in the 'admin-new-order.php' template (which is wrong).

Does that make sense?

Thanks, cb


Kyle comments:

Let's stick with #2 and get that to show the data

So we would be down to admin-new-order.php not show the data. Can you just double check and post the template once more. I'm going to pm my email, and you can forward me a fresh test of the admin email.


cruiseback comments:

Done.

Thanks, cb


cruiseback comments:

Oh, post the template you said, right, here we go: [[LINK href="http://pastebin.com/Aq1H9Mcp"]]admin-new-order.php[[/LINK]]

Thanks, cb


Kyle comments:

Hmm I'm trying to figure why it would work when we spliced it into the customer file but doesnt work in the admin one. Give me a few minutes.


cruiseback comments:

Sure, no worries.

Thanks, cb


Kyle comments:

We may want to build a new template, so we aren't missing any vars. like email-order-items_2.php

Then add this to your functions.php

function email_order_items_table_2( $show_download_links = false, $show_sku = false, $show_purchase_note = false, $show_image = false, $image_size = array( 32, 32 ), $plain_text = false ) {



ob_start();



$template = ***put your filepath here***/'email-order-items_2.php';



wc_get_template( $template, array(

'order' => $this,

'items' => $this->get_items(),

'show_download_links' => $show_download_links,

'show_sku' => $show_sku,

'show_purchase_note' => $show_purchase_note,

'show_image' => $show_image,

'image_size' => $image_size

) );



$return = apply_filters( 'woocommerce_email_order_items_table', ob_get_clean(), $this );



return $return;

}




Then map the line starting with $template to email-order-items_2.php, where ever you put it. Then make the changes you want to see. Does that make sense?


cruiseback comments:

Sort of.. I've done what you have instructed now.

So I should also create a new file (email-order-items_2.php) which should be a duplicate of email-order-items.php and then strip out the variations section of email-order-items.php?

Thanks, cb


cruiseback comments:

It's getting late here in Denmark and I need to get some sleep, will check back in the morning.

Thanks, cb


Kyle comments:

Yes, or in this case add back in the variations chunk.

Sounds good, I am on EST time, so should be on early tomorrow.

Skal!


cruiseback comments:

Hi Kyle,

It's not working, here is what I did.

I added the latest code you posted to my functions.php.

I then duplicated 'email-order-items.php' and renamed it 'email-order-items_2.php.

In 'email-order-items_2.php' I then put some "lorem ipsum" text which.

Then I edited line 28 in 'admin-new-order.php' from being
<?php echo $order->email_order_items_table( false, true ); ?>

to

<?php echo $order->email_order_items_table_2( false, true ); ?>

When I try to send an admin-mail now from within Wordpress it's not really working and no mails get through.

Thanks, cb


Kyle comments:

What does the filepath in the new functions vs where you placed the new template look like?


cruiseback comments:

Hi Kyle,

The latest notification from wpquestions.com had gone in my spam-folder, so I never saw your reply until now.

The filepath is
$template = 'woocommerce/emails/email-order-items_2.php';

Which is where I have put the email-order-items_2.php template.

When I try to send a new admin notificiation email, I am just being taken to the template directly, which might not make sense, so I have made a little video showing you what happens.
[[LINK href="https://dl.dropboxusercontent.com/u/2666961/spiritcard-admin-mail-works.mov"]]This is what happens normally[[/LINK]]

[[LINK href="https://dl.dropboxusercontent.com/u/2666961/spiritcard-admin-mail-notworking.mov"]]This is what happens when I have made the changes mentioned in my last reply[[/LINK]]

Thanks, cb