Modify the WooCommerce emails templates (on-hold/processing/complete) - wordpress

I am using WooCommerce plugin for an e-commerce business and when I create an order or change its state there always an email being sent to informing the current state of the order. For some current reasons there is no information on the price of the products and the WooCommerce email templates having the price, subtotal, and total data within the email order details. What I need is to modify those templates to remove the price, subtotal, and total data and also to change the addresses headings.
I browsed the woocommerce plugin folder to find where the email templates are and I googled and found a detracted solution that lies in removing the hook that generating the order data, found at WC_Emails class constructor, then add it again and wire it to a custom function that generates the structure desired. The solution works partially for me as if I created an order the first time the order is at on-hold state and an email is sent and looks as needed, however, when I change the state of the order to, for example, processing, or any subsequent order states another email is sent now with two order details tables the one generated by my custom function and below it is the one generated by WooCommerce as shown by the image below.
// add the action
add_action( 'woocommerce_email_order_details', 'remove_order_details', 10, 4);
add_action( 'woocommerce_email_order_details','action_woocommerce_email_order_details', 10, 4);
// define the woocommerce_email_order_details callback
function action_woocommerce_email_order_details($order, $sent_to_admin, $plain_text, $email)
{
$text_align = is_rtl() ? 'right' : 'left';
?>
<h2>
<?php
if ($sent_to_admin) {
$before = '<a class="link" href="' . esc_url($order->get_edit_order_url()) . '">';
$after = '</a>';
} else {
$before = '';
$after = '';
}
/* translators: %s: Order ID. */
echo wp_kses_post($before . sprintf(__('[Order #%s]', 'woocommerce') . $after . ' (<time datetime="%s">%s</time>)', $order->get_order_number(), $order->get_date_created()->format('c'), wc_format_datetime($order->get_date_created())));
?>
</h2>
<div style="margin-bottom: 40px;">
<table class="td" cellspacing="0" cellpadding="6"
style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
<thead>
<tr>
<th class="td" scope="col"
style="text-align:<?php echo esc_attr($text_align); ?>;"><?php esc_html_e('Product', 'woocommerce'); ?></th>
<th class="td" scope="col"
style="text-align:<?php echo esc_attr($text_align); ?>;"><?php esc_html_e('Quantity', 'woocommerce'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($order->get_items() as $item_id => $item) { ?>
<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
// Product name.
echo wp_kses_post(apply_filters('woocommerce_order_item_name', $item->get_name(), $item, false));
// allow other plugins to add additional product information here.
do_action('woocommerce_order_item_meta_start', $item_id, $item, $order, $plain_text);
// 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(apply_filters('woocommerce_email_order_item_quantity', $item->get_quantity(), $item)); ?>
</td>
</tr>
<?php } ?>
</tbody>
<tfoot>
<?php
$meta_data = $order->get_meta('_custom_px_src');
if ($meta_data) {
?>
<tr>
<th class="td" scope="row" colspan="2"
style="text-align:<?php echo esc_attr($text_align); ?>;"><?php esc_html_e(is_rtl() ? 'وصفة طبية' : 'Prescription:'); ?></th>
<td class="td">
<img src="<?php echo $meta_data['value']; ?>" alt="Prescription image" height="42" width="42">
</td>
</tr>
<?php
}
if ($order->get_customer_note()) {
?>
<tr>
<th class="td" scope="row" colspan="2"
style="text-align:<?php echo esc_attr($text_align); ?>;"><?php esc_html_e('Note:', 'woocommerce'); ?></th>
<td class="td"
style="text-align:<?php echo esc_attr($text_align); ?>;"><?php echo wp_kses_post(wptexturize($order->get_customer_note())); ?></td>
</tr>
<?php
}
?>
</tfoot>
</table>
</div>
<?php
}
function remove_order_details()
{
$mailer = WC()->mailer(); // get the instance of the WC_Emails class
remove_action('woocommerce_email_order_details', array($mailer, 'order_details'));
}
What I expected is a solution that pertain only the order details table generated by my custom function

I found the problem that causes the order details table duplication within the email template and it was adding the woocommerce_email_order_details removal action with a priority equal to the doing action as showing below
add_action( 'woocommerce_email_order_details', 'remove_order_details', 10, 4);
add_action( 'woocommerce_email_order_details','action_woocommerce_email_order_details', 10, 4);
However, what I should do is prioritize the removal action with a higher priority instead
add_action( 'woocommerce_email_order_details', 'remove_order_details', 1, 4);
add_action( 'woocommerce_email_order_details','action_woocommerce_email_order_details', 10, 4);

Related

Add custom post meta to woocommerce order email

I’m trying to add a custom product meta to my woocommerce new order notification e-mails.
The custom product meta field is as follows:
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'OUDE DBV Artikelnummer', 'woocommerce' ),
'placeholder' => 'LET OP! Dit is het OUDE artikelnummer',
'desc_tip' => 'true',
'description' => __( 'LET OP! Dit is het OUDE Dordtse Bazar Verhuur artikelnummer.', 'woocommerce' )
)
);
I’ve copied the email-orders-details.php to my Child theme folder and the new column is showing perfectly fine in the email.
<tr>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'DBV Art. Nr.', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th>
</tr>
Now I’m struggling to retrieve the values of this custom field. I’ve copied the email-order-items.php to my child theme folder. I’ve added this code here, but no values are shown in the email. What am I doing wrong here?
// 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 get_post_meta( $post->ID, '_text_field', true ); ?>
</td>
Hope you can help me out on this.
You need to pass $product->get_id().
// 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 get_post_meta( $product->get_id(), '_text_field', true ); ?>
</td>

WooCommerce: How to hide prices in customer-on-hold-order Mail, but not in other Mails?

I need to customize WooCommerce and hide all Pricing Information in the customer-on-hold-order Mail, but not in the other Mails.
I have already copied Mail Templates to /mytheme/woocommerce/emails earlier, and because they are already modified, i copied
email-order-items.php and
email-order-details.php
to
email-order-items-noprice.php and
email-order-details-noprice.php
...and modified them to show no price.
Now I believe I must change customer-on-hold-order.php to call my new noprice files
In this file I can see
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
I wish that I could just change the line to
do_action( 'woocommerce_email_order_details_noprice', $order, $sent_to_admin, $plain_text, $email );
...but then nothing happens. It is probably because the hook 'woocommerce_email_order_details_noprice' does not exist.
What must I do to create this hook, and where?
Or is there a better solution to this?
Thanks a lot!
Just do as follows to achieve your requirements -
First copied email-order-details.php and email-order-items.php templates in yourtheme/woocommerce/emails/ as you have already done. But dont needs to renamed it.
Now in your template named email-order-details.php replace follows -
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th>
with follows -
<?php if( $order->get_status() !== 'on-hold' ) : ?>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th>
<?php endif; ?>
In your template named email-order-items.php replace follows -
<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>
with follows -
<?php if( $order->get_status() !== 'on-hold' ) : ?>
<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>
<?php endif; ?>
Thats it.

Display the product image in Woocommerce email notifications

On Woocommerce, I have changed $show_image variable to true in email order details php template file, but I am still unable to get the image displayed in email notifications:
<div style="margin-bottom: 40px;">
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
<thead>
<tr>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th>
<th class="td" scope="col" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
echo wc_get_email_order_items( $order, array( // WPCS: XSS ok.
'show_sku' => $sent_to_admin,
'show_image' => true,
'image_size' => array( 100, 100 ),
'plain_text' => $plain_text,
'sent_to_admin' => $sent_to_admin,
) );
?>
</tbody>
<tfoot>
<?php
$totals = $order->get_order_item_totals();
if ( $totals ) {
$i = 0;
foreach ( $totals as $total ) {
$i++;
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['label'] ); ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>; <?php echo ( 1 === $i ) ? 'border-top-width: 4px;' : ''; ?>"><?php echo wp_kses_post( $total['value'] ); ?></td>
</tr>
<?php
}
}
if ( $order->get_customer_note() ) {
?>
<tr>
<th class="td" scope="row" colspan="2" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php esc_html_e( 'Personal Message:', 'woocommerce' ); ?></th>
<td class="td" style="text-align:<?php echo esc_attr( $text_align ); ?>;"><?php echo wp_kses_post( wptexturize( $order->get_customer_note() ) ); ?></td>
</tr>
<?php
}
?>
</tfoot>
</table>
I need to add link as well to the product image.Once the user click on the image it should redirect to the particular page.
Changed the message from false to true still the image is not displayed in the site.
To display the image in Email notifications, revert back your changes to original template and use instead:
add_filter( 'woocommerce_email_order_items_args', 'custom_email_order_items_args', 10, 1 );
function custom_email_order_items_args( $args ) {
$args['show_image'] = true;
return $args;
}
To add the product link to the image and to the item name (optionally) you will use:
add_filter( 'woocommerce_order_item_thumbnail', 'add_email_order_item_permalink', 10, 2 ); // Product image
add_filter( 'woocommerce_order_item_name', 'add_email_order_item_permalink', 10, 2 ); // Product name
function add_email_order_item_permalink( $output_html, $item, $bool = false ) {
// Only email notifications
if( is_wc_endpoint_url() )
return $output_html;
$product = $item->get_product();
return '' . $output_html . '';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Thumbnail size change:
You can also manipulate the thumbnail size in this hook which is by default 32 x 32 pixels using under $args['show_image'] = true; adding this line:
$args['image_size'] = array( 48, 48 );
Tested and works too.

Custom post type to work with html auto reply

I'm trying to setup a custom post type for Landing Pages in WordPress, including the option to customize the text for the html auto response email.
I am able to call the post meta on a different page using using the following loop, but I can't figure out how to put it in a format that works in the html auto response.
Is it possible to turn the following loop into this ". $_POST['content'] ." or something more appropriate?
<?php
$args = array( 'post_type' => 'landing_pages');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
echo esc_html( get_post_meta( get_the_ID(), 'landing_pages_short_description', true ) );
endwhile;
wp_reset_query();
?>
Here is the html auto response
<?php
if(!empty($_POST['rev_captcha'])) {
die('Nice try robot. Nothing for you here.');
}
$autoResponse = true;
$autoResponseSubject = "Brand Name: A copy of your message";
$autoResponseMessage = "<html>
<head>
<title>Brand Name: A copy of your message</title>
</head>
<body>
<table cellpadding='0' cellspacing='0' width='100%' border='0' bgcolor='#f0f3f5' style='margin:0;padding:0;padding-bottom:15px;width:100%!important;height:100%!important;line-height:100%!important;background:#f0f3f5'>
<tbody>
<tr>
<td width='100%' height='110px' valign='top'>
<table cellpadding='0' cellspacing='0' width='95%' border='0' align='center'>
<tbody>
<tr>
<td width='40%' align='center' style='padding:25px 0 0'>
<img src='' width='160' height='55' alt=''>
</td>
<td width='60%' style='padding:40px 0 0'>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td width='100%' valign='top' align='center'>
<table cellpadding='0' cellspacing='0' border='0' align='center' width='95%' bgcolor='#ffffff' style='background:#ffffff;padding-top:0px;border:1px solid #eeeeee;border-top:none' valign='top'>
<tbody>
<tr>
<td align='center' style='padding-bottom:30px;padding-top:50px;border-bottom:1px solid #eeeeee'>
<p style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;color:#444444;margin:0 30px 5px;padding-top:10px;line-height:1.5\">
<strong style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:32px;line-height:30px;color:#444444\">Good news, ". $_POST['name'] ."!</strong></p>
<p style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;color:#444444;margin:0;padding: 10px 50px 30px;line-height:1.5;text-align:center\">Your message has been sent.</p>
<p style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;color:#444444;margin:0;padding: 10px 50px 0;line-height:1.5;text-align:left\">Here is a copy for your records:</p>
<p style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;color:#444444;margin:10px 0 10px 52px;padding:0 50px 0 20px;border-left:4px solid #666666;line-height:1.5;text-align:left\"><em>". $_POST['notes'] ."<br>--<br>". $_POST['name'] ."<br>". $_POST['phone'] ."<br>". $_POST['email'] ."</em></p>
<br>
<p style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;color:#444444;margin:0;padding: 10px 50px 0;line-height:1.5;text-align:left\">Sent from: ". $_POST['referrer'] ."</p>
</td>
</tr>
<tr>
<td align='center'>
<p style=\"font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;color:#888888;line-height:1.3;padding:10px 50px\">Thanks for contacting</p>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
";
$autoResponseHeaders = "From: ___#___.ca"."\r\n";
$autoResponseHeaders .= "MIME-Version: 1.0"."\r\n";
$autoResponseHeaders .= "Content-type: text/html; charset=iso-8859-1"."\r\n";
$email_to = $_POST['email'];
$name = $_POST['name'];
$phone = $_POST['phone'];
$notes = $_POST['notes'];
$referrer = $_POST['referrer'];
$time = date('F j, Y g:i:s A T', time());
$message = "From: $name "."\r\n"."Email: $email_to "."\r\n"."Time: $time "."\r\n";
$headers = "From: $email_to"."\r\n";
$headers .= "Reply-To: $email_to"."\r\n";
if(mail('___#___.ca', 'Brand Name', $notes . "\r\n \r\n" . $name . "\r\n". $phone . "\r\n". $email_to . "\r\n \r\n" . 'Sent from: ' . $referrer , $headers)){
if($autoResponse === true){
mail($email_to, $autoResponseSubject, $autoResponseMessage, $autoResponseHeaders);
}
header("Location:/sent.php" ); // send to the proper page when done.
}else{
echo 'failed';// ... or this one to tell it that it wasn't sent
}
?>
on the file single-landing_page.php create a hidden form field
<input type="hidden" name="custom_postmeta" value="<?php echo esc_html( get_post_meta( get_the_ID(), 'landing_pages_short_description', true ) ); ?>" />
then on the other file as you get all other fields you can get this hidden field too like
$custompostmeta = $_POST['custom_postmeta'];
then concatinate this $custompostmeta variable within your html table
Hope it will work

Logic rules want pop up if Enable conditional logic?

This is code....
<?php
if (!defined('IPHORM_VERSION')) exit;
if (!isset($element['logic'])) $element['logic'] = false;
?>
<tr valign="top">
<th scope="row">
<label for="prevent_duplicates_<?php echo $id; ?>"><?php esc_html_e('Enable conditional logic', 'iphorm'); ?></label>
</th>
<td>
<input type="checkbox" id="logic_<?php echo $id; ?>" name="logic_<?php echo $id; ?>" <?php checked(true, $element['logic']); ?> onclick="iPhorm.toggleLogic(iPhorm.getElementById(<?php echo $id; ?>));" />
<p class="description">
<?php
if ($element['type'] == 'groupstart') {
esc_html_e('Enables you to create rules to show or hide this group depending on the values of other fields', 'iphorm');
} else {
esc_html_e('Enables you to create rules to show or hide this field depending on the values of other fields', 'iphorm');
}
?>
</p>
</td>
</tr>
<?php
if (!isset($element['logic_action'])) $element['logic_action'] = 'show';
if (!isset($element['logic_match'])) $element['logic_match'] = 'all';
if (!isset($element['logic_rules'])) $element['logic_rules'] = array();
?>
<tr valign="top" class="ifb-show-if-logic-on <?php if (!$element['logic']) echo 'ifb-hidden'; ?>">
<th scope="row">
<label><?php esc_html_e('Logic rules', 'iphorm'); ?></label>
</th>
<td>
<div id="ifb_logic_rules_<?php echo $id; ?>"></div>
</td>
</tr>
Create toggleLogic() javascript function and put your popup box code and check your logic to display content.
Like this.
function toggleLogic(someid)
{
// your logic code
...
}

Resources