I've already succeeded in finding a way to change the subject of the WooCommerce new order email notification. The problem I'm facing is that the object $order doesn't process the shipping_state of the user profile.
Here is the code:
add_filter('woocommerce_email_subject_new_order', 'change_admin_email_subject', 1, 2);
function change_admin_email_subject( $subject, $order ) {
global $woocommerce;
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$subject = sprintf( 'Commande pour %s', $order->shipping_state);
return $subject;
}
I tried calling it directly from the user metadata, but it doesn't work, where it should appear the data, it appears blank.
Here is the code I tried:
function change_admin_email_subject( $subject, $user) {
global $woocommerce;
$user = wp_get_current_user(); $current_user_id =
$user -> ID;
$user_billing_state = get_user_meta($current_user_id, 'shipping_state', true);
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$subject = sprintf( 'Commande pour %s',
$user_billing_state);
return $subject;
}
Any advice would be appreciated.
Your code attempt(s) contain some mistakes:
$order->shipping_state is no longer applicable since WooCommerce 3 and has been replaced by $order->get_shipping_state()
The use of global $woocommerce; is not necessary
You use $blogname, but you don't do anything with this data, for example you don't display it in the subject
So you get:
function filter_woocommerce_email_subject_new_order( $subject, $order ) {
// Get shipping state
$shipping_state = $order->get_shipping_state();
// NOT empty
if ( ! empty( $shipping_state ) ) {
// Get blogname
$blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
// Change subject
$subject = sprintf( __( '%s: Commande pour %s', 'woocommerce' ), $blogname, $shipping_state );
}
return $subject;
}
add_filter( 'woocommerce_email_subject_new_order', 'filter_woocommerce_email_subject_new_order', 10, 2 );
Related
I am using the following code which works fine.
function send_comment_email_notification( $comment_ID, $commentdata ) {
$comment = get_comment( $comment_id );
$postid = $comment->comment_post_ID;
$master_email = 'email#gmail.com';
var_dump($commentdata);
if( isset( $master_email ) && is_email( $master_email ) ) {
$message = 'New comment on ' . get_the_title( $postid ) . '';
add_filter( 'wp_mail_content_type', create_function( '', 'return "text/html";' ) );
wp_mail( $master_email, 'New Comment', $message );
}
}
add_action( 'comment_post', 'send_comment_email_notification', 11, 2 );
However, I would like to send an email to the user who just reviewed on a product page so I can offer them a coupon and a thank you for giving a review.
The problem is the $master_email variable, that is "hard coded". I need to capture the email entered by the user after he/she submitted the product review
Any advice?
To get the email entered by the user after he/she submitted the product review, you can use $commentdata['comment_author_email']
So you get:
function action_comment_post( $comment_ID, $comment_approved, $commentdata ) {
// Isset
if ( isset ( $commentdata['comment_author_email'] ) ) {
// Get author email
$author_email = $commentdata['comment_author_email'];
if ( is_email( $author_email ) ) {
// Post ID
$post_id = $commentdata['comment_post_ID'];
// Send e-mail
$to = $author_email;
$subject = 'The subject';
$body = sprintf( __(' Thank you for giving a review on %s', 'woocommerce' ), '' . get_the_title( $post_id ) . '' );
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
wp_mail( $to, $subject, $body, $headers );
}
}
}
add_action( 'comment_post', 'action_comment_post', 10, 3 );
We found this question https://wordpress.stackexchange.com/questions/320924/woocommerce-order-processing-email-subject-not-changing and it's working fine. We now want to extend this by display the vendor on a order in the order completed mail.
But we are not able to output the vendor store name.
Is there a obvious error in our code?
add_filter( 'woocommerce_email_subject_customer_completed_order',
'change_completed_email_subject', 1, 2 );
function change_completed_email_subject( $subject, $order ) {
global $woocommerce;
// Order ID
$order->get_items();
// Author id
$author_id = $product->post->post_author;
// Shopname
$vendor = dokan()->vendor->get( $author_id );
$shop_name = $vendor->get_shop_name();
// Blogname
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
// Output subject
$subject = sprintf( '%s, Deine %s Bestellung (#%s) wurde versendet! Vendor: %s', $order->billing_first_name, $blogname, $order->get_order_number(), $shop_name );
return $subject;
}
Update:
I already tried to get the name via $shop_name = dokan()->vendor->get( $author_id )->get_shop_name(); but no success.
The use of global $woocommerce is not necessary
You use $order->get_items();, but don't do anything with it
$product is not defined
Use $order->get_billing_first_name() VS $order->billing_first_name
So you get:
function filter_woocommerce_email_subject_customer_completed_order( $subject, $order ) {
// Empty array
$shop_names = array();
// Loop through order items
foreach ( $order->get_items() as $item ) {
// Get product object
$product = $item->get_product();
// Author id
$author_id = $product->post->post_author;
// Shopname
$vendor = dokan()->vendor->get( $author_id );
$shop_name = $vendor->get_shop_name();
// OR JUST USE THIS FOR SHOPNAME
// Shop name
// $shop_name = dokan()->vendor->get( $author_id )->get_shop_name();
// NOT in array
if ( ! in_array( $shop_name, $shop_names ) ) {
// Push to array
$shop_names[] = $shop_name;
}
}
// Blogname
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
// Set subject
$subject = sprintf( __( '%s, Deine %s Bestellung (#%s) wurde versendet! Vendor: %s', 'woocommerce' ), $order->get_billing_first_name(), $blogname, $order->get_order_number(), implode( ', ', $shop_names ) );
// Return
return $subject;
}
add_filter( 'woocommerce_email_subject_customer_completed_order', 'filter_woocommerce_email_subject_customer_completed_order', 10, 2 );
I'm trying to hook into 'woocommerce_email_recipient_booking_confirmed' to update/add to the recipient field. The link below works perfectly for default WooCommerce emails (and their actions). The action works if I manually type in an email within the action but I need the email to come from the customer input (via a Custom Field on the product page).
I believe it is something to do with class-wc-email-booking-confirmed.php. When I compare it against class-wc-email-customer-completed-order.php
class-wc-email-booking-confirmed.php
public function trigger( $booking_id )
class-wc-email-customer-completed-order.php
public function trigger( $order_id, $order = false )
My code (which I haven't changed from the resource below):
add_filter( 'woocommerce_email_recipient_booking_confirmed', 'additional_customer_email_recipient', 9999, 2 ); // Completed Order
function additional_customer_email_recipient( $recipient, $order ) {
if ( ! is_a( $order, 'WC_Order' ) ) return $recipient; // when I comment this out, an ajax error is thrown. This is why I believe the order object directly accessible yet.
$additional_recipients = array(); // Initializing…
foreach( $order->get_items() as $item_id => $item_data ){
$email = wc_get_order_item_meta( $item_id, 'Email Address', true );
if( ! in_array( $email, $additional_recipients ) && strpos( $recipient, $email ) === false )
$additional_recipients[] = $email;
}
$additional_recipients = implode( ',', $additional_recipients);
if( count($additional_recipients) > 0)
{
$recipient = ','.$additional_recipients;
}
return $recipient;
}
Send Woocommerce Order to email address listed on product page
It was because it wasn't the order object, I just had to call get_order().
$order = $order->get_order();
Code:
add_filter( 'woocommerce_email_recipient_booking_confirmed', 'additional_customer_email_recipient', 10, 2 );
function additional_customer_email_recipient( $recipient, $order ) {
$order = $order->get_order();
$additional_recipients = array();
foreach( $order->get_items() as $item_id => $item_data ){
$email = wc_get_order_item_meta( $item_id, 'Email Address', true );
if( ! in_array( $email, $additional_recipients ) && strpos( $recipient, $email ) === false )
$additional_recipients[] = $email;
}
$additional_recipients = implode( ',', $additional_recipients);
if( count($additional_recipients) > 0)
{
$recipient = $additional_recipients;
}
return $recipient;
}
I have developed a custom code which sends e-mails to the customers based on the category of the product they buy. The problem with my site is one product is having many categories. The script is working correctly, other than that it sends many emails equal to the number of categories a product have. I want it to send only one e-mail per product.
Here is the code:
add_action("woocommerce_order_status_changed", "wcepp_notification_email");
function wcepp_notification_email( $order_id, $checkout = null ) {
global $woocommerce;
$order = new WC_Order( $order_id );
if($order->status === 'processing' ) {
function wcepp_get_custom_email_html( $order, $heading = false, $mailer, $cat_slug ) {
$template = 'emails/woo-custom-emails-per-product-'.$cat_slug.'.php';
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => true,
'plain_text' => false,
'email' => $mailer
)
);
}
$liquify_array = array('cutting-agent', 'dabjuice-liquify');
$terpene_array = array('terpene-blends', 'strain-specific', 'hybrid', 'indica', 'sativa', 'terpene-sample-kits', 'hybrid-sample-kit', 'indica-sample-kit', 'sativa-sample-kit');
$isolates_array = array('raw-terpene-isolates', 'alpha', 'beta');
// getting the order products
$items = $order->get_items();
// let's loop through each of the items
foreach ( $items as $item ) {
$categories = get_the_terms( $item['product_id'] , 'product_cat' );
foreach( $categories as $categorie ) {
$cat_slug = $categorie->slug;
if(in_array($cat_slug, $liquify_array)) {
$new_cat_slug = 'liquify';
} elseif(in_array($cat_slug, $terpene_array)) {
$new_cat_slug = 'terpenes';
} elseif(in_array($cat_slug, $isolates_array)) {
$new_cat_slug = 'isolates';
}
if(isset($new_cat_slug)) {
// Create a mailer
$mailer = $woocommerce->mailer();
//Prepare Email
$recipient = $order->billing_email;
if($new_cat_slug == 'liquify') {
$subject = 'Instructions for usage of your Liquify Product';
} elseif($new_cat_slug == 'terpenes') {
$subject = 'Instructions for usage of your Terpenes Product';
} elseif($new_cat_slug == 'isolates') {
$subject = 'Instructions for usage of your Raw Terpenes Isolates';
}
$content = wcepp_get_custom_email_html( $order, $subject, $mailer, $new_cat_slug );
$headers = "Content-Type: text/html\r\n";
//send the email through wordpress
$mailer->send( $recipient, $subject, $content, $headers );
}
}
}
}
}
Any help in this regard will be appraciated.
Your code is outdated since Woocommerce 3 and have many mistakes. If you enable the debug on Wordpress you will get a lot of error messages. Try the following instead that will send an email for each product when it matches with a defined product category:
// Get email content from the custom template
function get_custom_email_content_html( $order, $heading = false, $mailer, $category_slug ) {
$template = 'emails/woo-custom-emails-per-product-'.$category_slug.'.php';
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => true,
'plain_text' => false,
'email' => $mailer
)
);
}
// Send a custom email notification for each order item on order processing status change
add_action( 'woocommerce_order_status_changed', 'processing_custom_email_notification', 10, 4 );
function processing_custom_email_notification( $order_id, $status_from, $status_to, $order ) {
if( $status_to === 'processing' ) {
$liquify_array = array('cutting-agent', 'dabjuice-liquify');
$terpene_array = array('terpene-blends', 'strain-specific', 'hybrid', 'indica', 'sativa', 'terpene-sample-kits', 'hybrid-sample-kit', 'indica-sample-kit', 'sativa-sample-kit');
$isolates_array = array('raw-terpene-isolates', 'alpha', 'beta');
// Loop through order items
foreach ( $order->get_items() as $item ) {
$product_category = '';
$categories_slugs = get_the_terms( $item->get_product_id() , 'product_cat', array( 'fields' => 'slugs' ) );
foreach( $categories_slugs as $term_slug ) {
if( in_array( $term_slug, $liquify_array ) ) {
$product_category = 'liquify';
break;
} elseif(in_array( $term_slug, $terpene_array ) ) {
$product_category = 'terpenes';
break;
} elseif(in_array( $term_slug, $isolates_array ) ) {
$product_category = 'isolates';
break;
}
}
if( isset( $product_category ) ) {
// Email subject
if( $product_category == 'liquify' ) {
$subject = __("Instructions for usage of your Liquify Product");
} elseif($product_category == 'terpenes' ) {
$subject = __("Instructions for usage of your Terpenes Product");
} elseif( $product_category == 'isolates' ) {
$subject = __("Instructions for usage of your Raw Terpenes Isolates");
}
$mailer = WC()->mailer(); // Get an instance of the WC_Emails Object
$recipient = $order->get_billing_email(); // Email recipient
$content = get_custom_email_content_html( $order, $subject, $mailer, $product_category ); // Email content (template)
$headers = "Content-Type: text/html\r\n"; // Email headers
// Send the email
WC()->mailer()->send( $recipient, $subject, $content, $headers );
}
}
}
}
It should better work now (but not tested with your product categories).
3 custom email templates should be located in the woocommerce folder > emails subfolder (of the active theme):
woo-custom-emails-per-product-liquify.php
woo-custom-emails-per-product-terpenes.php
woo-custom-emails-per-product-isolates.php
I have a site that allows users(sellers) to enter products on the frontend. When there product sells I would like to email seller to let them know product has been sold.
Heres what I have so far
add_filter ('woocommerce_payment_complete', 'send_seller_email');
function send_seller_email($order_id) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
//foreach loop to get sellers email from order start
foreach ( $items as $item ) {
$product_name = $item->get_name();
$product_id = $item->get_product_id();
$sent_to = wp_get_object_terms( $product_id, 'soldby', false );
$seller_send_email = $sent_to[0]->name;
$seller_email = get_user_by('ID', $seller_send_email);
$email_to_sent_sold_conformation .= $seller_email->user_email;
}//foreach loop to get sellers email end
//Send seller email start
$to = $email_to_sent_sold_conformation;
$subject = 'Sold! ship now: ' . get_the_title($product_id);
$message = '';
$message .= '<p>' . get_the_excerpt($product_id) . '…</p>';
$message .= '<p></p>';
wp_mail($to, $subject, $message );
//Send seller email end
}
I have completely revisited your code:
The main code is in an utility function called by the 2 hooked functions
function hooked in woocommerce_new_order that will trigger paid orders.
function hooked in woocommerce_order_status_changed that will trigger validated orders on update status change.
The code:
// Utility function sending the email notification
function send_seller_email( $order ) {
$data = array();
// Loop through each order item
foreach ( $order->get_items() as $item_id => $item ) {
if( get_post_meta( $order->get_id(), '_sent_to_seller_'.$item_id, true ) )
continue; // Go to next loop iteration
$product_id = $item->get_product_id();
// Untested part
$soldby = wp_get_object_terms( $product_id, 'soldby', false );
if( empty($soldby) ) continue; // Go to next loop iteration
$seller_id = $soldby[0]->name;
$seller = get_user_by( 'ID', $seller_id );
$seller_email = $seller->user_email;
// Set the data in an array (avoiding seller email repetitions)
$data[$seller_email][] = array(
'excerpt' => get_the_excerpt($product_id),
'title' => get_the_title($product_id),
'link' => get_permalink($product_id),
);
// Update order to avoid notification repetitions
update_post_meta( $order->get_id(), '_sent_to_seller_'.$item_id, true );
}
if( count($data) == 0 ) return;
// Loop through custom data array to send mails to sellers
foreach ( $data as $email_key => $values ) {
$to = $email_key;
$subject_arr = array();
$message = '';
foreach ( $values as $value ) {
$subject_arr[] = $value['title'];
$message .= '<p>'.$value['title'].'</p>';
$message .= '<p>'.$value['excerpt'].'…</p>';
}
$subject = 'Sold! ship now: '.implode( ', ', $subject_arr );
// Send email to seller
wp_mail( $to, $subject, $message );
}
exit();
}
add_action('woocommerce_new_order', 'new_order_seller_notification', 10, 1 );
function new_order_seller_notification( $order_id ) {
$order = wc_get_order( $order_id );
if( ! ( $order->has_status('processing') || $order->has_status('completed') ) )
return; // Exit
send_seller_email( $order );
}
add_action( 'woocommerce_order_status_changed', 'order_status_seller_notification', 20, 4 );
function order_status_seller_notification( $order_id, $status_from, $status_to, $order ) {
if( ! ( $status_to == 'processing' || $status_to == 'completed' ) )
return; // Exit
send_seller_email( $order );
}
Code goes in function.php file of your active child theme (or theme).
The code is not really tested, but doesn't make errors. It should work.