I am a bit new to WordPress and i have a small problem.
I'm checking if my mail was send or not and i want to save this information in a custom table that i made. I need to retrieve this information in a different function where I then save this in my custom table.
This is the function where i check if the mail is send or not.
/*
* Send notification when stock is low
*/
function boilerplate_custom_low_stock_notification( $order ) {
foreach ( $order->get_items() as $item ) {
print_r($item);
if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->managing_stock() ) {
$new_stock = get_post_meta( $product->get_id(), '_stock', true );
$minimum_stock = get_post_meta( $product->get_id(), '_stock_minimum', true );
$stock = $product->get_stock_quantity();
$name = $product->get_name();
if ( $new_stock <= $minimum_stock ) {
//Send email to admin
$notification = wp_insert_post(
array(
'post_type' => 'shop_history',
'post_title' => 'The stock of '. $name . ' is running low.',
'post_content' => 'The stock is running low. There are only ' . $stock . " pieces left.",
'post_status' => 'publish',
) );
$mailResult = false;
$mailResult = wp_mail( get_option('admin_email'), 'Your stock is running low', 'The stock of ' . $name . ' is running low. You have ' . $stock . ' piece(s) left.' );
if( $mailResult == true){
$mail_send = "Mail was send";
}else{
$mail_send = "Something went wrong en there was no mail send";
}
//error_log( $mail_send );
return $notification;
}
}
}
}
add_action( 'woocommerce_reduce_order_stock', 'boilerplate_custom_low_stock_notification', 10, 3 );
In this function i want to save the information.
/*
* Add values to column
*/
function woocommerce_shop_history_mail_column( $column, $post_id ) {
switch ( $column ) {
case 'mail' :
echo 'Is my mail send or not?';
break;
}
}
add_filter( 'manage_shop_history_posts_custom_column', 'woocommerce_shop_history_mail_column', 10, 2 );
Related
I'm trying to add product category to the email notification. The custom fields (Time and Date) work but the product category is displaying as an "Array".
function render_product_description($item_id, $item, $order){
$_product = $order->get_product_from_item( $item );
echo "<br>" . $_product->post->post_content;
echo "<br>";
echo '<p><strong>Time:</strong><br />';
echo get_post_meta($_product->id, 'time', true) .'</p>';
echo '<p><strong>Category:</strong><br />';
echo wp_get_post_terms($_product->id, 'product_cat', true) .'</p>';
echo '<p><strong>Date:</strong><br />';
echo get_post_meta($_product->id, 'date', true) .'</p>';
}
add_action('woocommerce_order_item_meta_end', 'render_product_description',10,3);
You can use implode() function that join array values in a string.
I also added an extra check for empty values
function render_product_description( $item_id, $item, $order, $plain_text ) {
// Get product id
$product_id = $item->get_product_id();
// Get product
$product = $item->get_product();
// Product content
$product_content = $product->post->post_content;
// NOT empty
if ( ! empty ( $product_content ) ) {
echo '<p>' . $product_content . '</p>';
}
// Get post meta
$time = get_post_meta( $product_id, 'time', true );
// NOT empty
if ( ! empty ( $time ) ) {
echo '<p><strong>Date:</strong><br />' . $time . '</p>';
}
// Get terms
$term_names = wp_get_post_terms( $product_id, 'product_cat', ['fields' => 'names'] );
// NOT empty
if ( ! empty ( $term_names ) ) {
echo '<p><strong>Categories:</strong><br />' . implode( ", ", $term_names ) . '</p>';
}
// Get post meta
$date = get_post_meta( $product_id, 'date', true );
// NOT empty
if ( ! empty ( $date ) ) {
echo '<p><strong>Date:</strong><br />' . $date . '</p>';
}
}
add_action( 'woocommerce_order_item_meta_end', 'render_product_description', 10, 4 );
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 just want to know if possible to change the email subject if the order have the specific category like (Preorder). I want to put PO at beginning (PO New customer order #0000) then all other order the customer receive the default email subject (New Customer Order #0000).
add_filter('woocommerce_email_subject_new_order', 'change_admin_email_subject', 1, 2);
function change_admin_email_subject( $subject, $order ) {
global $woocommerce;
global $product;
if ( has_term( 'preorder', $product->ID ) ) {
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$subject = sprintf( '[%s]New customer order (# %s) from %s %s', $blogname, $order->id, $order->billing_first_name, $order->billing_last_name );
}
return $subject;
}
Note: I just copy this code somewhere.
This can be done this way, making some small changes:
add_filter('woocommerce_email_subject_new_order', 'custom_admin_email_subject', 1, 2);
function custom_admin_email_subject( $subject, $order ) {
$backordered = false;
foreach($order->get_items() as $item_id => $item ){
if ( has_term( 'preorder', 'product_cat' , $item->get_product_id() ) ) {
$backordered = true;
break;
}
}
if ( $backordered ) {
$subject = sprintf( '[PO]New customer order (# %s) from %s %s', $order->get_id(), $order->get_billing_first_name(), $order->get_billing_last_name() );
}
return $subject;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
Or it can be done this way without a product category, checking that product is backordered:
add_filter('woocommerce_email_subject_new_order', 'custom_admin_email_subject', 1, 2);
function custom_admin_email_subject( $subject, $order ) {
$backordered = false;
foreach($order->get_items() as $item_id => $item ){
$product = $item->get_product();
if( $product->get_backorders() == 'yes' && $product->get_stock_quantity() < 0 ){
$backordered = true;
break;
}
}
if ( $backordered ) {
$subject = sprintf( '[PO]New customer order (# %s) from %s %s', $order->get_id(), $order->get_billing_first_name(), $order->get_billing_last_name() );
}
return $subject;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
Use this:
function change_admin_email_subject( $subject, $order ) {
// Get all order items
$items = $order->get_items();
$found = false;
// Loop through the items
foreach ( $items as $item ) {
$product_id = $item['product_id'];
// get the categories for current item
$terms = get_the_terms( $product_id, 'product_cat' );
// Loop through the categories to find if 'preorder' exist.
foreach ($terms as $term) {
if($term->slug == 'preorder'){
$subject = 'PO '. $subject;
$found = true;
break;
}
}
if($found == true){
break;
}
}
return $subject;
}
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.
I want to send a notification email to Author when a Custom Meta Field is added to their WordPress Post by add_post_meta or update_post_meta.
So far my code below is working successfully but it executes only when I use Save Post
function order_update_send_email( $post_id ) {
$email_sent = get_post_meta($post_id, 'email_sent', true);
$report = get_post_meta($post_id, 'report', true);
if ( $email_sent == 'Sent' ) {
return;
}
if ( $report ) {
$post_title = get_the_title( $post_id );
$post_url = get_permalink( $post_id );
$subject = 'Your report for: ' . $post_title;
$message = "Your order is completed\n\n";
$message .= "Report for: " . $post_title . "\n\n Link:" . $post_url;
$message .= "\n\n" . $report;
wp_mail( 'test#email.me', $subject, $message );
update_post_meta($post_id, 'email_sent', 'Sent');
}
}
add_action( 'save_post', 'order_update_send_email' );
In above code the Action hook save_post is working fine but I can't get add_post_meta or update_post_meta to work.
Anyone please advice, thanks.
you can use below sample code for this.
add_action( 'added_post_meta', 'wp_afterpostmeta', 10, 4 );
add_action( 'updated_post_meta', 'wp_afterpostmeta', 10, 4 );
function wp_afterpostmeta( $meta_id, $post_id, $meta_key, $meta_value )
{
if ( 'wp_meta_key' == $meta_key ) {
wp_do_something( $post_id, $meta_value );
}
}