Add inventory value to low inventory level emails - php

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.

Related

Wordpress how to use line breaks while escaping html tags

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!

Change email subject for custom order statuses in Woocommerce 3

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.

Wordpress Plugin development for Contact Form

I am developing a simple WordPress plugin for contact form. But I don't know how to save the information in database? Could you gives some references?
The answer by Haninder has a great start but doesn't store the data in a database as per the OP.
This is where it starts getting tricky, as there are many options.
You can easily store the data in various places, but none are semantically correct, or maintainable over a long period of time.
In a single option in the options table
function save_request( $data ){
$opts = get_option( 'contact_requests' );
if( ! $opts || ! is_array( $opts ) ){
$opts = array();
}
$opts[] = $data;
update_option( 'contact_requests', $opts );
}
This would mean a slow request to save and defeats the point of a database in the first place, after several hundred contact requests, also diaplying and sorting the data would get tricky.
The best way would really to have a custom database table but there is a lot to consider when going down this path.
https://code.tutsplus.com/tutorials/custom-database-tables-creating-the-table--wp-28124
Custom Post Type
This is how I would approach this problem.
perhaps you could create a custom post type, say "contact_requests" and create a post with some post meta to represent a contact request.
This way you already get a neat list in admin, and can sort and access the data quickly and easily as required. This would be stable and fast through hundreds of thousands of entries.
function save_request( $data ){
$content = '';
foreach( $data as $key => $name ){
$content .= sprintf( '%s - %s' . PHP_EOL, $key, $name );
}
$post_data = array(
'post_title' => 'Contact Request ' . esc_html( $data['name'] ),
'post_content' => $content,
'post_type' => 'contact_requests'
);
$post_id = wp_insert_post( $post_data );
//Add Post Meta Here
add_post_meta( $post_id, 'contact_name', esc_html( $data['name'] ) );
add_post_meta( $post_id, 'contact_email', esc_html( $data['email'] ) );
add_post_meta( $post_id, 'contact_message', esc_html( $data['message'] ) );
return $post_id;
}

Send same Email to extra recipient as the admin received

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

Output HTML using existing PHP in wordpress functions.php

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.

Categories