Add custom post meta to woocommerce order email - wordpress

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>

Related

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.

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

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);

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.

Product variation error on cart page, not showing buttons, price or quantity

I have a big issue right now on my Wordpress site. Simple products do work just fine, but when I add product variations in attribute, and add that product, cart page just bugs out. After the description nothing is loaded, don't have the price, quantity, even footer doesn't load, as it stops loading there.
I tried overriding Woocommerce files with theme woocommerce files, but with no luck. I searched everything and everywhere for solution, but there is none. I tried everything with Product variations, but with no luck also.
The website is: https://ticketshoprd.com
Also, mini-cart in the menu is working just fine with product variations.
The event which is with variations is the Boat Party one.
Code from cart.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
wc_print_notices();
do_action( 'woocommerce_before_cart' ); ?>
<form action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post">
<?php do_action( 'woocommerce_before_cart_table' ); ?>
<table class="shop_table shop_table_responsive cart" cellspacing="0">
<thead>
<tr>
<th class="product-remove"> </th>
<th class="product-thumbnail"> </th>
<th class="product-name"><?php esc_html_e( 'Evento', 'startit' ); ?></th>
<th class="product-price"><?php esc_html_e( 'Precio', 'startit' ); ?></th>
<th class="product-quantity"><?php esc_html_e( 'Cantidad', 'startit' ); ?></th>
<th class="product-subtotal"><?php esc_html_e( 'Total', 'startit' ); ?></th>
</tr>
</thead>
<tbody>
<?php do_action( 'woocommerce_before_cart_contents' ); ?>
<?php
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>">
<td class="product-remove">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( WC()->cart->get_remove_url( $cart_item_key ) ),
esc_html__( 'Remove this item', 'startit' ),
esc_attr( $product_id ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</td>
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $product_permalink ) {
echo qode_startit_kses_img($thumbnail);
} else {
printf( '%s', esc_url( $product_permalink ), $thumbnail );
}
?>
</td>
<td class="product-name" data-title="<?php _e( 'Product', 'startit' ); ?>">
<?php
if ( ! $product_permalink ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . ' ';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_title() ), $cart_item, $cart_item_key );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'startit' ) . '</p>';
}
?>
</td>
<td class="product-price" data-title="<?php _e( 'Price', 'startit' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
</td>
<td class="product-quantity" data-title="<?php _e( 'Quantity', 'startit' ); ?>">
<?php
if ( $_product->is_sold_individually() ) {
$product_quantity = sprintf( '1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key );
} else {
$product_quantity = woocommerce_quantity_input( array(
'input_name' => "cart[{$cart_item_key}][qty]",
'input_value' => $cart_item['quantity'],
'max_value' => $_product->backorders_allowed() ? '' : $_product->get_stock_quantity(),
'min_value' => '0'
), $_product, false );
}
echo apply_filters( 'woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item );
?>
</td>
<td class="product-subtotal" data-title="<?php _e( 'Total', 'startit' ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key );
?>
</td>
</tr>
<?php
}
}
do_action( 'woocommerce_cart_contents' );
?>
<tr>
<td colspan="6" class="actions">
<?php if ( wc_coupons_enabled() ) { ?>
<div class="coupon">
<label for="coupon_code"><?php esc_html_e( 'Coupon', 'startit' ); ?>:</label>
<input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Código del cupón', 'startit' ); ?>" />
<?php
//Override Apply Coupon Button
do_action('qode_startit_woocommerce_apply_coupon_button');
?>
<?php do_action( 'woocommerce_cart_coupon' ); ?>
</div>
<?php } ?>
<div class="qodef-cart-proceed-update">
<?php do_action( 'woocommerce_proceed_to_checkout' ); ?>
<input type="submit" class="qodef-btn qodef-btn-medium qodef-btn-default checkout-button alt wc-forward" name="update_cart" value="<?php esc_attr_e( 'Actualizar Carrito', 'woocommerce' ); ?>" />
<?php
//Override Apply Coupon Button
do_action('qode_startit_woocommerce_update_cart_button');
?>
<?php do_action( 'woocommerce_cart_actions' ); ?>
<?php wp_nonce_field( 'woocommerce-cart' ); ?>
</div>
</td>
</tr>
<?php do_action( 'woocommerce_after_cart_contents' ); ?>
</tbody>
</table>
<?php do_action( 'woocommerce_after_cart_table' ); ?>
</form>
<div class="cart-collaterals">
<?php if ( is_cart() ) : ?>
<div class="qodef-shipping-calculator">
<?php woocommerce_shipping_calculator(); ?>
</div>
<?php endif; ?>
<div class="qodef-cart-totals">
<?php do_action( 'woocommerce_cart_collaterals' ); ?>
</div>
</div>
<?php do_action( 'woocommerce_after_cart' ); ?>

Return Posts as single table

query_posts( array(
'post_type' => 'ts_result',
'meta_query' => array(
array(
'key' => '_ts_student_class',
'value' => $exam_reg,
'compare' => '='
),
array(
'key' => '_ts_school_term',
'value' => $exam_term,
),
array(
'key' => '_ts_school_year',
'value' => $exam_year,
)
),
'posts_per_page' => 100
)
);
?>
<table style="border:1px solid black" cellpadding="1.5" cellspacing="5">
<style type="text/css" media="print">
table{
border-collapse:collapse;
}
</style>
<tbody>
<tr>
<th><strong>NAME\SUBJECT</strong></th>
<th><strong>English Studies</strong></th>
<th align='center'><strong>Mathematics</strong></th>
<th align='center'><strong>CCA</strong></th>
<th align='center'><strong>Yoruba Language</strong></th>
<th align='center'><strong>French</strong></th>
<th align='center'><strong>Business Education</strong></th>
</tr>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php
$subject_english_studies_exam_total= get_post_meta(
get_the_ID(),'_ts_subject_english_studies_exam_total',true );
$subject_maths_exam_total= get_post_meta(
get_the_ID(),'_ts_subject_maths_exam_total',true );
$subject_creative_arts_exam_total= get_post_meta(
get_the_ID(),'_ts_subject_creative_arts_exam_total',true );
$subject_yoruba_lang_exam_total= get_post_meta(
get_the_ID(),'_ts_subject_yoruba_lang_exam_total',true );
$subject_french_exam_total= get_post_meta(
get_the_ID(),'_ts_subject_french_exam_total',true );
$subject_business_edu_exam_total= get_post_meta(
get_the_ID(),'_ts_subject_business_edu_exam_total',true );
?>
<tr>
<td><?php the_title(); ?></td>
<td><?php echo $subject_english_studies_exam_total ;?></td>
<td><?php echo $subject_maths_exam_total ;?></td>
<td><?php echo $subject_creative_arts_exam_total ;?></td>
<td><?php echo $subject_yoruba_lang_exam_total ;?></td>
<td><?php echo $subject_french_exam_total ;?></td>
<td><?php echo $subject_business_edu_exam_total ;?></td>
</tr>
</tbody>
</table>
the above query in Wordpress returns the following:
What I seek to achieve is a table with one header and the other post content as rows. presently only the first post values is being formatted properly as table rows.
You have done small mistake by not closing the while loop before the </tbody>. Code will be like the following :
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<tr>
<td><?php the_title(); ?></td>
<td><?php echo $subject_english_studies_exam_total ;?></td>
<td><?php echo $subject_maths_exam_total ;?></td>
<td><?php echo $subject_creative_arts_exam_total ;?></td>
<td><?php echo $subject_yoruba_lang_exam_total ;?></td>
<td><?php echo $subject_french_exam_total ;?></td>
<td><?php echo $subject_business_edu_exam_total ;?></td>
</tr>
<?php endwhile;endif; ?>
Hope it helps you.

Resources