Woocommerce - Need to send email to specific address based on zip code - php

Basically, in woocommerce you have the option to input multiple email addresses (separated by commas) of who to send the completed order to, in WooCommerce -> Settings -> Emails -> New order. But I need a way to send to only one of these recipients based on the zip code of the customer who is ordering the product. Or completely overwrite woocommerce's way of handling this.
How can I tie into the function responsible for this, in order to send to the correct recipient? Basically, is there a hook defined for this, or does a plugin exist for something like this, or will I have to edit core WooCommerce files? If edits are needed to core files, can someone point me in the right direction as to which files will need edits?

I had a bit of trouble with helgatheviking's answer above and also a slightly different use case.
My problems/needs were:
I didn't quite understand the filter name as presented above.
The public function get_recipient() inside of class-wc-email.php expected a string but was getting an array.
A also wanted to conditionally add the extra recipient based on the payment method, rather than postcode.
Here's what I did instead:
Added full filter name, not just the suffix: woocommerce_email_recipient_new_order
Replaced explode() and array_push() with string concatenation $email .= ',' . $additional_email;.
Conditionally checked payment method: if( $order->get_payment_method() == "cod" ).
Full example:
add_filter( 'woocommerce_email_recipient_new_order' , 'so_26429482_add_recipient', 20, 2 );
function so_26429482_add_recipient( $email, $order ) {
// !empty($order) prevents a fatal error in WooCommerce Settings
// !empty($email) prevents the duplicate email from being sent in cases where the filter is run outside of when emails are normally sent. In my case, when using https://wordpress.org/plugins/woo-preview-emails/
if(!empty($order) && !empty($email)) {
$additional_email = "isf#domain.co";
if( $order->get_payment_method() == "cod" ) {
$email .= ',' . $additional_email;
} else {
$email .= ',another#domain.co';
}
}
return $email;
}

Each email has a filter that allows you to adjust the recipients of that email. The filter name is essentially woocommerce_email_recipient_{$email_id}.
So the following would filter the "to" addresses for the "new_order" email.
add_filter( 'new_order' , 'so_26429482_add_recipient', 20, 2 );
function so_26429482_add_recipient( $email, $order ) {
$additional_email = "somebody#somewhere.net";
if( $order->shipping_postcode == "90210" ){
$email = explode( ',', $email );
array_push( $email, $additional_email );
}
return $email;
}
I'm not 100% certain on the conditional logic, but I think that should check the shipping zip code and subsequently send to the additional email address.

Related

Change New Order email notification from name in Woocommerce

Email notification of New order process has 'My Blog' title.
I look into Woocommerce setting but could not find it.
Any Idea how to change 'My Blog' to 'X Company'
red underline text in attached images.
Plateform: Wordpress + Woocommerce
Update:
What you want to change is the "From name" and it can be changed using:
add_filter('woocommerce_email_from_name', 'change_new_order_email_from_name', 10, 2 );
function change_new_order_email_from_name( $from_name, $email ){
if( $email->id === 'new_order' )
$from_name = __("ACME corp");
return $from_name;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Addition: To add custom placeholders for the email subject (for woocommerce 3.2+):
// Only for woocommerce versions 3.2 + (up to 3.2)
add_filter( 'woocommerce_email_format_string' , 'custom_email_format_string', 20, 2 );
function custom_email_format_string( $string, $email ) {
// Get the instance of the WC_Order object
$order = $email->object;
// Additional wanted placeholders in the array of find / relace pairs
$additional_placeholders = array(
'{shop_company}' => __("ACME corp"),
);
// return the clean string with new replacements
return str_replace( array_keys( $additional_placeholders ), array_values( $additional_placeholders ), $string );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Then in your email settings, on the Subject field of an email notification you will be able to replace for example:
Your {site_title} order receipt from {order_date}
by
Your {shop_company} order receipt from {order_date}
Please use this WooCommerce hook woocommerce_email_subject_new_order to change new order email title.
add_filter( 'woocommerce_email_subject_new_order', 'customizing_new_order_subject', 10, 2 );
function customizing_new_order_subject( $formated_subject, $order ){
// Get an instance of the WC_Email_New_Order object
$email = WC()->mailer->get_emails()['WC_Email_New_Order'];
// Get unformatted subject from settings
$subject = $email->get_option( 'subject', $email->get_default_subject() );
// Loop through order line items
$product_names = array();
foreach( $order->get_items() as $item )
$product_names[] = $item->get_name(); // Set product names in an array
// Set product names in a string with separators (when more than one item)
$product_names = implode( ' - ', $product_names );
// Replace "{product_name}" by the product name
$subject = str_replace( '{product_name}', $product_names, $subject );
// format and return the custom formatted subject
return $email->format_string( $subject );
}
For more details see this link
Go to
WooCommerce > Settings > Emails > Processing Orders.
Here you will find a field called "Email Subject". Here, change {site_title} to whatever you want it to appear.
Alternatively, if you want to change the value of {site_title} itself, then head over to Settings > General.
Here you will find the field called Site Title. Change it to whatever you want it to appear.
Let me know if it works!
I found the solution after digging, its very easy.
WooCommerce>Setting>Emails
At the bottom, there is section where you can header and footer text.
Simple.
Really appreciate your help #LoicTheAztec

WooCommerce: Add additional e-mail recipient (new order) depending on post-code

I'd like to add additional e-mail recipients depending on the customers post-code. We have different suppliers for different provinces (e.g. 4614 - Supplier 1, 3314 - Supplier 2) and it is necessary to direct the orders to the responsible suppliers. For accounting we need to direct the new orders to the responsible department (currently set in the WooCommerce backend).
I already tried to use the WooCommerce filter for the e-mail recipient to add the e-mails based on the post-code. For this purpose i set up two arrays and tried to get the shipping post-code (or the billing post-code) to use in this if-function.
This is the code i tried to use on our website:
add_filter( 'woocommerce_email_recipient_new_order', 'cond_recipients_email_notifications', 10, 2 );
function cond_recipients_email_notifications( $recipient, $order ) {
if ( ! is_a( $order, 'WC_Order' ) ) return $recipient;
// TARGET-ZIP-CODE
$zip_zone1 = array( '4614', '4072', '4615', '4064', '4062', '4611' );
$zip_zone2 = array( '3314', '3353', '3313', '3312', '3350', '3322', '3354' );
// User ZIP-CODE
$user_zip_zone = $order->get_shipping_postcode();
if(empty($user_shipping_postcode))
$user_zip_zone = $order->get_billing_postcode();
// ADD EMAIL IF ZIP-CODE MATCHES TARGET-ZIP-CODE
if ( in_array( $user_zip_zone, $zip_zone1)) {
$recipient .= ', e-mail-supplier1#e-mail.at';
} elseif ( in_array( $user_zip_zone, $zip_zone2) ) {
$recipient .= ', e-mail-supplier2#e-mail.at';
}
return $recipient;
}
I tried to implement this snippet in the functions.php of my child theme but it doesn't work as expected. I'm obviously missing something but i have no clue what my mistake could be. Unfortunately i have little experience with php so my understanding of this matter is limited.
Does anybody know a way to implement the needed function in WooCommerce or how to make this code-snippet work? What is wrong with my code?
Help is very appreciated!
I got the information that this code is working correctly. Upon getting this info i checked my server settings and there were some wrong settings.
The code works as it was supposed to be! Thank you for your help!
Feel free to use my code, maybe someone else needs to implement the same function.

Email validation with Ultimate Member Plugin

I need help modifying the code below. I'm using the Ultimate Member plugin on my Wordpress site for membership. I only want those people within my organization to be able to register for the site (my departments use different domains for their email addresses, it's a headache and I don't want to get into that). Right now, it will automatically validate emails from #company1.com, but I need to add up to 10 more email addresses to that code to perform automatic validation. Basically, anyone that doesn't have an email address listed, is automatically denied membership to the site.
add_action('um_before_new_user_register', 'require_google_email_for_signup');
function require_google_email_for_signup( $args ) {
extract($args);
if ( !strstr( $user_email, '#company1.com' ) )
exit( wp_redirect( add_query_arg('err', 'you_must_have_googlemail') ) );
}
"um_before_new_user_register" has been removed from the 2.x version. You can use the below working code for complete form validation not just a single field.
add_action('um_submit_form_errors_hook_','um_custom_validate_form', 999, 1);
function um_custom_validate_form( $args ) {
global $ultimatemember;
$user_email = $args['user_email'];
if ( !strstr( $user_email, '#domain1.com' )){
$ultimatemember->classes['form']->add_error( 'user_email', 'You must register with a valid email address.' );
}
}
strstr() is more memory intensive compared to strpos(), so I will recommend using the latter. When dealing with an array, you can use the following iterative logic:
Set a variable, say $check, to false
Iterate through each allowed domain in a for loop
Whenever a match is found (by using strpos()), we set $check to true and break out of the loop. This ensures that we do not traverse the entire array when a match is already found
Evaluate $check, and decide whether to throw an error / exit
Hint: I would recommend converting your user-email to lowercase when using strpos (or you can use stripos()), because some users may enter emails that are of mixed cases.
With that in mind, here is an example:
<?php
add_action('um_before_new_user_register', 'require_google_email_for_signup');
function require_google_email_for_signup( $args ) {
extract($args);
// Store allowed domains in an array
$allowed_domains = ['#company1.com', '#company2.com', '#company3.com'];
// Set flag to false (fail-safe)
$check = false;
// Iterate through all allowed domains
foreach( $allowed_domains as $domain ) {
// If a match is found (remember to use lowercase emails!)
// Update flag and break out of for loop
if ( strpos( strtolower( $user_email ), $domain ) !== false ) {
$check = true;
break;
}
}
if ( !$check )
exit( wp_redirect( add_query_arg('err', 'you_must_have_googlemail') ) );
}
Use this code:
<?php
add_action('um_before_new_user_register', 'require_google_email_for_signup');
function require_google_email_for_signup( $args ) {
extract($args);
/* add multiple domains name here */
$allow_domains = ['company1.com', 'company2.com', 'company3.com'];
/* get domain name from user email */
$domain_name = substr(strrchr($user_email, "#"), 1);
if (!in_array($domain_name, $allow_domains)){
exit( wp_redirect( add_query_arg('err', 'you_must_have_googlemail') ) );
}
}
?>
This custom code no longer works in the latest version 2 update to ultimate member. The hook was removed, so it’s no longer possible to do email address blocking with this code. Does anyone have any suggestions on how to get this to work again? Here is the code I'm using:
/* ULTIMATE MEMBER PLUGIN DOMAIN WHITELISTING CODE SNIPPET
enter code here`The following code will require a domain name to be
whitelisted for user `enter code here`registrations.
It forces a user email to match one included in this code at registration.
You can add any provider you want by copying and pasting a new line as per
instructions.*/
add_action('um_before_new_user_register', 'force_google_email_for_avnw_signup');
function force_google_email_for_avnw_signup( $args ) {
extract($args);
if ( !strstr( $user_email, '#anydomain.com' ) )
exit( wp_redirect( add_query_arg('err', 'whitelisted_email_required') ) );
}

Add a new field to woocommerce_email_customer_details or any other part of emails

Ok so I am building a woocommerce site for a client and they love it but the only issue is they need a customer number to come through with the email for all new orders. They are willing to go in and fill in this info for each user, but I cannot find out how to get this info to automatically send with the new order email.
I am using WP - Members plugin to add custom information to the users profile, and have created a field there called Customer # (option name: customer_number) I cannot figure how to get woocommerce to add this number to the email that is sent when they place the order (to the admin)
I have tried many different things, it seems like it should just be a hook but I dont know how to get the values or have not been able to figure this out yet in any way.
I have looked and looked and this is my last resort, my minimal understanding of php and hooks is probably my downfall here, so please be very clear if instructing me in that way.
I will not give up on this issue, so I hope someone can help!
We can adapt from my tutorial on customizing the checkout fields to display some extra info in the email:
function kia_display_email_order_user_meta( $order, $sent_to_admin, $plain_text ) {
$user_id = $order->customer_user;
if( ! empty( $user_id ) && ( $data = get_user_meta( $user_id, '_some_user_meta', true ) ) != '' ){
if( $plain_text ){
echo 'The user data for some field is ' . $data;
} else {
echo '<p>The user data for <strong>some field</strong> is ' . $data . '</p>';
}
}
}
add_action('woocommerce_email_customer_details', 'kia_display_email_order_user_meta', 30, 3 );
In this case we'll replace the get_post_meta() of my tutorial with get_user_meta().... and knowing that the user Id is stored in the $order->customer_id property of the $order object.

woocommerce custom fields included in product email

I'm trying to include a custom field in the email that is sent to customers upon purchase. I added a custom field "Phone_number" into the all of the product pages.
I've tried including
<?php
$orderidno = $order->id;
$prodmetaa = get_post_meta($orderidno, "Phone_number" , True);
echo $prodmetaa;
?>
In the order email template, but haven't had any success. Has anyone done anything like this before or have any Idea how I could accomplish this .
Plugin URL - https://wordpress.org/plugins/woocommerce/
You can use hooks/actions/filters to do so. Here is documentation on doing something like you want http://docs.woothemes.com/document/add-a-custom-field-in-an-order-to-the-emails/
/**
* Add the field to order emails
**/
add_filter('woocommerce_email_order_meta_keys', 'my_woocommerce_email_order_meta_keys');
function my_woocommerce_email_order_meta_keys( $keys ) {
$keys['How did you hear about us?'] = 'hear_about_us';
return $keys;
}
To expand upon the above tutorial and now taking advantage of the improved email template hooks that I added and I think were released in WC 2.3.0
function so_229971110_add_meta_to_email( $order, $sent_to_admin, $plain_text ){
$prodmetaa = get_post_meta($order->id, "Phone_number" , True);
echo "Phone Number: " . $prodmetaa;
}
add_action( 'woocommerce_email_customer_details', 'so_229971110_add_meta_to_email', 20, 3 );

Categories