I am using the below to send an email to a user each time a custom field within their profile is updated. I can output plain text into the email body using the $message line which is great. How can I adapt this so I can output html where the $message goes?
// IF CUSTOM FIELD CHANGES
function sr_user_profile_update_virtuosity( $user_id, $old_user_data ) {
$old_user_data = get_transient( 'sr_old_user_data_' . $user_id );
$user = get_userdata( $user_id );
if($old_user_data->virtuosity != $user->virtuosity) {
$admin_email = $user->user_email;
$message = sprintf( __( 'I want to output HTML here' ) ) . "\r\n\r\n";
wp_mail( $admin_email, sprintf( __( 'IMPORTANT: Your newly purchased product is ready for you' ), get_option('blogname') ), $message );
}
}
add_action( 'profile_update', 'sr_user_profile_update_virtuosity', 10, 2 );
You need to set the content type to html, by default its text/plain.
You can do this by using wp_mail_content_type filter.
add_filter( 'wp_mail_content_type', 'set_content_type' );
function set_content_type( $content_type ) {
return 'text/html';
}
For more info see here.
Related
I would like to separate the Welcome to %s and Thanks for creating account on %1$s by making each appear in a separate row.
They are currently jammed together/messed up when translating the phrases on a RTL site.
protected function send_account_email( $user_data, $user_id ) {
$to = $user_data['user_email'];
$subject = sprintf( esc_html__( 'Welcome to %s', 'my-plugin' ), get_option( 'blogname' ) );
$body = sprintf( esc_html__( 'Thanks for creating account on %1$s. Your username is: %2$s ',
'my-plugin' ), get_option( 'blogname' ), $user_data['user_login'] );
}
You need a "line break" to separate them out! You could use html tags such as:
br tag
p tag
h1 tag
Just to name a few!
BUT you're using esc_html__ to translate AND escape html. Why do you need to use esc_html__ to retrieve the name of your blog from your database? Why?
That being said, there is a whitelisting technique you could use to translate and escape unwanted html at the same time.
Using wp_kses you would be able to define a "white-list" for allowed html tags and escape the rest of them.
You could read more about it:
wp_ksesDocs
and
This post on whitelisting html tags
So your code would be something like this:
Using <br> tag:
protected function send_account_email( $user_data, $user_id ) {
$whitelist_tags = array(
'br' => array(),
);
$to = $user_data['user_email'];
$subject = sprintf(wp_kses(__('Welcome to %s <br>', 'my-plugin'), $whitelist_tags), get_option( 'blogname' ));
$body = sprintf( esc_html__( 'Thanks for creating account on %1$s. Your username is: %2$s ',
'my-plugin' ), get_option( 'blogname' ), $user_data['user_login'] );
}
OR using <p> tag:
protected function send_account_email( $user_data, $user_id ) {
$whitelist_tags = array(
'p' => array()
);
$to = $user_data['user_email'];
$subject = sprintf(wp_kses(__('<p>Welcome to %s </p>', 'my-plugin'), $whitelist_tags), get_option( 'blogname' ));
$body = sprintf( esc_html__( 'Thanks for creating account on %1$s. Your username is: %2$s ',
'my-plugin' ), get_option( 'blogname' ), $user_data['user_login'] );
}
OR using <h1> tag:
protected function send_account_email( $user_data, $user_id ) {
$whitelist_tags = array(
'h1' => array(),
);
$to = $user_data['user_email'];
$subject = sprintf(wp_kses(__('<h1>Welcome to %s </h1>', 'my-plugin'), $whitelist_tags), get_option( 'blogname' ));
$body = sprintf( esc_html__( 'Thanks for creating account on %1$s. Your username is: %2$s ',
'my-plugin' ), get_option( 'blogname' ), $user_data['user_login'] );
}
Note:
$whitelist_tags is an array, so you could add multiple tags to it!
Also, I've only used those tags in your $subject variable, you could use the exact technique in your $body variable too, if you need to!
I've also used __() with combination of wp_kses instead of esc_html__ in order to translate AND escape unwanted html!
I need to adjust text for email sent after updating password for user in Wordpress backend.
I did it in functions.php of my theme:
add_filter('password_change_email', 'change_code');
My function:
function change_code($pass_change_mail,$user,$userdata ){
$new_message_txt = __( 'Some text ###USERNAME### more text even more text ###EMAIL### more text after more text last bit of text ###SITENAME###' );
$pass_change_mail[ 'message' ] = $new_message_txt;
return $pass_change_mail;
Actually I need to connect with this filter in user.php, which envoke somethoing like that:
$pass_change_email = apply_filters( 'password_change_email', $pass_change_email, $user, $userdata );
$pass_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $pass_change_email['message'] );
$pass_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $pass_change_email['message'] );
$pass_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $pass_change_email['message'] );
$pass_change_email['message'] = str_replace( '###SITENAME###', $blog_name, $pass_change_email['message'] );
$pass_change_email['message'] = str_replace( '###SITEURL###', home_url(), $pass_change_email['message'] );
wp_mail( $pass_change_email['to'], sprintf( $pass_change_email['subject'], $blog_name ), $pass_change_email['message'], $pass_change_email['headers'] );
Maybe that code is not corrected and something better exists. Someone know, how to solve that, please?
I have successfully changed email subject for Woocommerce processing order (using this thread):
add_filter( 'woocommerce_email_subject_customer_processing_order', 'email_subject_procs_order', 10, 2 );
function email_subject_procs_order( $formated_subject, $order ){
return sprintf( esc_html__( 'Example of subject #%s', 'textdomain'), $order->get_id() );
}
But I want send processing order email again with new subject after order status is changed, so I followed this tread to tweak subject etc.
add_action('woocommerce_order_status_order-accepted', 'backorder_status_custom_notification', 20, 2);
function backorder_status_custom_notification( $order_id, $order ) {
// HERE below your settings
$heading = __('Your Awaiting delivery order','woocommerce');
$subject = sprintf( esc_html__( 'New subject #%s', 'textdomain'), $order->get_id() );
// Getting all WC_emails objects
$mailer = WC()->mailer()->get_emails();
// Customizing Heading and subject In the WC_email processing Order object
$mailer['WC_Email_Customer_Processing_Order']->heading = $heading;
$mailer['WC_Email_Customer_Processing_Order']->settings['heading'] = $heading;
$mailer['WC_Email_Customer_Processing_Order']->subject = $subject;
$mailer['WC_Email_Customer_Processing_Order']->settings['subject'] = $subject;
// Sending the customized email
$mailer['WC_Email_Customer_Processing_Order']->trigger( $order_id );
}
But only first email subject change is accepted. Is there way to get it work together?
Is if( $order->has_status( 'order-accepted' )) right to be used?
You need to use your custom status in a IF statement to avoid that problem, this way:
add_filter( 'woocommerce_email_subject_customer_processing_order', 'email_subject_procs_order', 10, 2 );
function email_subject_procs_order( $formated_subject, $order ){
// We exit for 'order-accepted' custom order status
if( $order->has_status('order-accepted') )
return $formated_subject;
return sprintf( esc_html__( 'Example of subject #%s', 'textdomain'), $order->get_id() );
}
Code goes in function.php file of your active child theme (or active theme). It should works.
On adding extra recipient on woocommerce order, the recipient generally receives the mail same as the customer receives.But i want to send extra recipient the mail what an admin receives.
Below is my working code which receives email in customer format
add_filter(
'woocommerce_email_recipient_customer_processing_order',
'shop_email_recipient_filter_function',
10,
2
);
add_filter(
'woocommerce_email_recipient_customer_completed_order',
'shop_email_recipient_filter_function',
10,
2
);
function shop_email_recipient_filter_function($recipient, $order) {
$shop = get_post_meta( $order->id, '_restaurant_id', true );
$shop_owner_email = get_the_author_meta(
'user_email',
get_post_field('post_author', $shop)
);
$recipient .= ', ' . $shop_owner_email;
return $recipient;
}
i want to send admin mail format
I'm trying to add the product inventory value to the low inventory level notification emails in Woocommerce.
The email notification code is on line 386 of WC_Emails class, however, it doesn't have an action so I'm not sure of the best way to add it without changing the core file.
This mail is just a function attached to a hook. You should be able to remove it and then add your own. 100% untested, so use at your own risk.
I'm not 100% sure on how to remove the callback from the woocommerce_low_stock_notification because I'm not certain how to access the WC_Emails instance.
function so_27786112_remove_notification(){
$emails = WC_Emails::instance();
remove_action( 'woocommerce_low_stock_notification', array( $emails, 'low_stock' ) );
}
add_action( 'woocommerce_init', 'so_27786112_remove_notification' );
But as Andrew suggested you can just duplicate the low_stock() callback and modify it as you'd like. I've simply added a custom function to the appropriate hook. I've really only changed the $message equation to use the get_stock_quantity() method.
function so_27786112_stock_notification( $product ) {
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$subject = apply_filters( 'woocommerce_email_subject_low_stock', sprintf( '[%s] %s', $blogname, __( 'Product low in stock', 'woocommerce' ) ), $product );
$sku = ($product->sku) ? '(' . $product->sku . ') ' : '';
if ( ! empty( $product->variation_id ) )
$title = sprintf(__( 'Variation #%s of %s', 'woocommerce' ), $product->variation_id, get_the_title($product->id)) . ' ' . $sku;
else
$title = sprintf(__( 'Product #%s - %s', 'woocommerce' ), $product->id, get_the_title($product->id)) . ' ' . $sku;
$qty = $product->get_stock_quantity();
$message = $title . sprintf( __( ' has %s remaining in stock.', $qty ) );
// CC, BCC, additional headers
$headers = apply_filters('woocommerce_email_headers', '', 'low_stock', $product);
// Attachments
$attachments = apply_filters('woocommerce_email_attachments', array(), 'low_stock', $product);
// Send the mail
wp_mail( get_option('woocommerce_stock_email_recipient'), $subject, $message, $headers, $attachments );
}
add_action( 'woocommerce_low_stock_notification', 'so_27786112_stock_notification' );
If the first part didn't work, you should get 2 emails.
One option would be to make your own class that extends the WC_Emails class. Then copy the low_stock() method from their class into yours, which will override their function with yours. That way you can adjust your own function however you want and you won't be editing the core file.
Another option would be to add the filters you would need there and submit a pull request back to WooThemes. They may just accept it and make it part of the core.