I would like to exclude added email attachments for customer reset password and customer new account emails, or limit adding some of attachment to Woocommerce order emails only (and exclude attachments for emails send to admin). Is it possible?
add_filter( 'woocommerce_email_attachments', 'doc_to_email', 10, 3);
function doc_to_email ( $attachments , $id, $object ) {
$attachments = array();
array_push($attachments, get_home_path() . '/doc/Zasady_ochrany_osobnich_udaju.pdf' );
if( !$id == array( 'customer_reset_password', 'customer_new_account') ) {
array_push($attachments, get_home_path() . '/doc/VOP.pdf' );
array_push($attachments, get_home_path() . '/doc/Reklamacni_rad.pdf' );
array_push($attachments, get_home_path() . '/doc/Reklamacni_protokol.pdf' );
array_push($attachments, get_home_path() . '/doc/Formular_pro_odstoupeni_od_smlouvy.pdf' );
}
return $attachments;
}
Thanks you
The following code will exclude email attachements from all admin email notifications and some attachements from specific email notifications:
add_filter( 'woocommerce_email_attachments', 'custom_email_attachments', 20, 3 );
function custom_email_attachments ( $attachments = [] , $email_id, $order ) {
// HERE define customer and admin excluded email Ids
$excluded_customer_email_ids = array( 'customer_reset_password', 'customer_new_account' );
$excluded_admin_email_ids = array( 'new_order', 'cancelled_order', 'failed_order' );
// Excluding attachements from admin email notifications
if( in_array( $email_id, $excluded_admin_email_ids ) )
return [];
$file_path = get_home_path() . '/doc/';
$attachments[] = $file_path . 'Zasady_ochrany_osobnich_udaju.pdf';
// Excluding some customer email notifications
if( ! in_array( $email_id, $excluded_customer_email_ids ) ) {
$attachments[] = $file_path . 'VOP.pdf';
$attachments[] = $file_path . 'Reklamacni_rad.pdf';
$attachments[] = $file_path . 'Reklamacni_protokol.pdf';
$attachments[] = $file_path . 'Formular_pro_odstoupeni_od_smlouvy.pdf';
}
return $attachments;
}
Code goes in function.php file of your active child theme (or active theme). It should works.
Related
I am trying to send an email to the customer after he has used a specific promo code 'FREECLASS' while checking out.
What I do is send the customer a code 'FREECLASS' after signing up. I want the customer to get an additional custom message after he uses that code.
Based on Send an email notification when a specific coupon code is applied in WooCommerce answer code, this is what I have done up until now but it is not working.
add_action( 'woocommerce_applied_coupon', 'custom_email_on_applied_coupon', 10, 1 );
function custom_email_on_applied_coupon( $coupon_code ){
if( $coupon_code == 'FREECLASS' ){
// Get user billing email
global $user_login;
$user = get_user_by('login', $user_login );
$email = $user->billing_email;
$to = "$email"; // Recipient
$subject = sprintf( __('Coupon "%s" has been applied'), $coupon_code );
$content = sprintf( __('The coupon code "%s" has been applied'), $coupon_code );
wp_mail( $to, $subject, $content );
}
}
This is my first WooCommerce project so some help would be really appreciated.
There is no need to use global variables, via $user_id you can get the WC_Customer instance Object and then the billing email address
wp_mail() - Sends an email, similar to PHP’s mail function
So you get:
function action_woocommerce_applied_coupon( $coupon_code ) {
// NOT logged in, return
if ( ! is_user_logged_in() ) return;
// Compare
if ( $coupon_code == 'freeclass' ) {
// Get user ID
$user_id = get_current_user_id();
// Get the WC_Customer instance Object
$customer = New WC_Customer( $user_id );
// Billing email
$email = $customer->get_billing_email();
// NOT empty
if ( ! empty ( $email ) ) {
// Recipient
$to = $email;
$subject = sprintf( __('Coupon "%s" has been applied', 'woocommerce' ), $coupon_code );
$content = sprintf( __('The coupon code "%s" has been applied by a customer', 'woocommerce' ), $coupon_code );
$headers = array( 'Content-Type: text/html; charset=UTF-8' );
wp_mail( $to, $subject, $content, $headers );
}
}
}
add_action( 'woocommerce_applied_coupon', 'action_woocommerce_applied_coupon', 10, 1 );
I am trying to send a custom WooCommerce mail with user credentials after an order with certain product. To explain further: Someone buys a product
I have to check if the order contains a certain product id
I have to check if the customer is registered as a user already, if not it should create a user
Then it should send a custom mail with those credentials to the customer
I am struggling to get the following code to work. Especially I dont know how I can add my custom email-message with the credentials and a custom login link. Do you know a solution?
add_action( 'woocommerce_thankyou', 'check_order_product_id' );
function check_order_product_id( $order_id ){
$order = wc_get_order( $order_id );
$items = $order->get_items();
$order_email = $order->billing_email;
//create custom mail
function get_custom_email_html( $order, $heading = false, $mailer ) {
$template = 'emails/my-custom-email-i-want-to-send.php';
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => false,
'plain_text' => false,
'email' => $mailer
) );
}
// load the mailer class
$mailer = WC()->mailer();
//format the email
$recipient = $order_email;
$subject = __("Deine Login-Daten für Geomap", 'theme_name');
$content = get_custom_email_html( $order, $subject, $mailer );
$headers = "Content-Type: text/html\r\n";
//send the email through wordpress
$mailer->send( $recipient, $subject, $content, $headers );
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === XYZ ) {
//get the user email from the order and check if registered already
function email_exists( $order_email ) {
$user = get_user_by( 'email', $order_email );
if ( $user ) {
return $wp_new_user_notification_email;
}
else {
// random password with 12 chars
$random_password = wp_generate_password();
// create new user with email as username & newly created pw
$user_id = wp_create_user( $order_email, $random_password, $order_email );
return $wp_new_user_notification_email;
}
}
}
}
}
Because you mentioned low barrier to entry being very important...
I'd recommend linking to your thank you page and having the registration link there too. You can use SSO (Google/Amazon/etc.) options so that users don't need to register directly through WordPress.
I'm assuming the product ID has some kind of activation code? You can send that, encrypted, as a parameter to the registration page so that it's registered in their session. Once logged in, you have attached their activation code to the user account, and you're done.
Steps:
Customer buys
If they have an account: send them the link, and they're done.
If they don't:
a. Send them an email with a link with the encrypted activation code.
b. They will have to register (through SSO or through WordPress directly).
c. Once registered, you attach their product to their user account, and redirect them to the page they care about.
Hey for the question "how I can add my custom email-message with the credentials and a custom login link",
In your code, there is this line
$template = 'emails/my-custom-email-i-want-to-send.php';
you could add the credentials there, you may pass other arguments as the second parameter of this functionwc_get_template_html
second, the code order will not work for what you are trying to achieve
in this line, you are sending the email
$mailer->send( $recipient, $subject, $content, $headers );
And after that, there is a foreach loop for all the items in the order and creates a function looking if the user exists.
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === XYZ ) {
//get the user email from the order and check if registered already
function email_exists( $order_email ) {
This function is not been called.
I will suggest to take out that function from the foreach loop and call it inside if your goal is to check only if the product XYZ exists
and all of it before the email
function check_order_product_id( $order_id ){
$order = wc_get_order( $order_id );
$items = $order->get_items();
$order_email = $order->billing_email;
//create custom mail
function get_custom_email_html( $order, $heading = false, $mailer ) {
$template = 'emails/my-custom-email-i-want-to-send.php';
return wc_get_template_html( $template, array(
'order' => $order,
'email_heading' => $heading,
'sent_to_admin' => false,
'plain_text' => false,
'email' => $mailer
) );
}
function send_custom_email($order_email, $order){
// load the mailer class
$mailer = WC()->mailer();
//format the email
$recipient = $order_email;
$subject = __("Deine Login-Daten für Geomap", 'theme_name');
$content = get_custom_email_html( $order, $subject, $mailer );
$headers = "Content-Type: text/html\r\n";
//send the email through wordpress
$mailer->send( $recipient, $subject, $content, $headers );
}
function email_exists( $order_email ) {
$user = get_user_by( 'email', $order_email );
if ( $user ) {
send_custom_email($order_email, $order);
//not sure where this variable was comming from
return $wp_new_user_notification_email;
}
else {
// random password with 12 chars
$random_password = wp_generate_password();
// create new user with email as username & newly created pw
$user_id = wp_create_user( $order_email, $random_password, $order_email );
//not sure where this variable was comming from
return $wp_new_user_notification_email;
}
}
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $product_id === XYZ ) {
//get the user email from the order and check if registered already
email_exists( $order_email );
}
}
}
Now as a conclusion, WP_user class doesn't give access to the password for security reasons, and they don't send it by email, you should not either is a very bad practice.
I will suggest you create the account and let WP send the default email and then you send another email with the link to your custom page, but not with the credentials.
That way they will receive two emails one secure and one with the special conditions.
Is it possible to amend the content of the Activation email that is sent to users when they sign up for an account on a WordPress site?
I am looking to change the subject and the body of the email to read something a little more in line with my website's information.
I have tried to added the following into a custom plugin found inside mu-plugins, but it seems to have no affect at all:
<?php
/*
Plugin Name: Disable Username and Password Notification
Description: Disables the Username and Password email
*/
// Start changing email body
function myprefix_change_activation_email_body ($old_body, $domain, $path, $title, $user, $user_email, $key, $meta) {
$my_message = "Hi! This is my new email! ";
$my_message .= "Your site {$title} is almost ready. We probably also want to include the activation key: {$key} ";
$my_message .= "Activate your site here : http://{$domain}{$path}wp-activate.php?key=$key";
// ... other stuff
return $my_message;
}
add_filter('wpmu_signup_blog_notification_email', 'myprefix_change_activation_email_body', 10, 8);
// End changing email body
// Start changing email subject
function myprefix_change_activation_email_subject ($old_subject, $domain, $path, $title, $user, $user_email, $key, $meta) {
$my_subject = "Hi! You just registered on my site!";
return $my_subject;
}
add_filter('wpmu_signup_blog_notification_subject', 'myprefix_change_activation_email_subject', 10, 8);
// End changing email subject
From what I can tell, the issue is that the filter being used is most likely for MultiSite setups which my site is not. It is just a standard WordPress site.
Cheers
The function that you're looking for is wp_new_user_notification it's a pluggable function. Pluggable functions are function that let you override Wordpress Core functionalities.
You can override, simply by:
Create a file in mu-plugins folder, you can call whatever you want, but you should give a meaningful name, like custom-new-user-notification.php
Copy the default function and wrapping it in a if statement checking if the function doesn't exist. (it's a best practice if not it can produce errors)
Change the message and subject ( or whatever you want to change)
Example:
<?php
/*
Plugin Name: Custom User Notification
Plugin URI: http://www.example.com
Description: Pligin description
Version: 1.0
Author: Your Name
Author URI: http://www.authorurl.com
*/
if( !function_exists( 'wp_new_user_notification' ) ){
function wp_new_user_notification( $user_id, $deprecated = null, $notify = '' ) {
if ( $deprecated !== null ) {
_deprecated_argument( __FUNCTION__, '4.3.1' );
}
global $wpdb, $wp_hasher;
$user = get_userdata( $user_id );
// The blogname option is escaped with esc_html on the way into the database in sanitize_option
// we want to reverse this for the plain text arena of emails.
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
if ( 'user' !== $notify ) {
$switched_locale = switch_to_locale( get_locale() );
$message = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
$message .= sprintf( __( 'Username: %s' ), $user->user_login ) . "\r\n\r\n";
$message .= sprintf( __( 'Email: %s' ), $user->user_email ) . "\r\n";
#wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] New User Registration' ), $blogname ), $message );
if ( $switched_locale ) {
restore_previous_locale();
}
}
// `$deprecated was pre-4.3 `$plaintext_pass`. An empty `$plaintext_pass` didn't sent a user notification.
if ( 'admin' === $notify || ( empty( $deprecated ) && empty( $notify ) ) ) {
return;
}
// Generate something random for a password reset key.
$key = wp_generate_password( 20, false );
/** This action is documented in wp-login.php */
do_action( 'retrieve_password_key', $user->user_login, $key );
// Now insert the key, hashed, into the DB.
if ( empty( $wp_hasher ) ) {
require_once ABSPATH . WPINC . '/class-phpass.php';
$wp_hasher = new PasswordHash( 8, true );
}
$hashed = time() . ':' . $wp_hasher->HashPassword( $key );
$wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user->user_login ) );
$switched_locale = switch_to_locale( get_user_locale( $user ) );
$message = sprintf(__('Username: %s'), $user->user_login) . "\r\n\r\n";
$message .= __('To set your password, visit the following address:') . "\r\n\r\n";
$message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user->user_login), 'login') . ">\r\n\r\n";
$message .= wp_login_url() . "\r\n";
wp_mail($user->user_email, sprintf(__('[%s] Your username and password info'), $blogname), $message);
if ( $switched_locale ) {
restore_previous_locale();
}
}
}
I am creating a plugin which makes an API call to a book keeping service and I am integrating it with WooCommerce.
After the order is created I am using woocommerce_email_order_details hook to execute my API call using $response = wp_remote_post( $post_url );, where $post_url is modified so that it all works with the API.
Within this response is also a pdf which I am saving to a folder in the uploads folder using WP_Filesystem() API. This part looks like this:
$response = wp_remote_post( $post_url );
if ( is_wp_error( $response ) ) {
$error_code = wp_remote_retrieve_response_code( $response );
$error_message = wp_remote_retrieve_response_message( $response );
return new WP_Error( $error_code, $error_message );
}
$body = json_decode( $response['body'] );
$pdf_link = esc_url( $body->order->pdf );
$pdf_name = esc_html( $body->order->order_number );
$pdf_get = wp_remote_get( $pdf_link );
if ( is_wp_error( $pdf_get ) ) {
$error_code = wp_remote_retrieve_response_code( $pdf_get );
$error_message = wp_remote_retrieve_response_message( $pdf_get );
return new WP_Error( $error_code, $error_message );
}
$pdf_contents = $pdf_get['body'];
$pdf_name = 'order-' . $pdf_name . '.pdf';
$upload_dir = wp_upload_dir();
$new_dir = $upload_dir['basedir'] . '/orders/' . date( 'Y' ) . '/' . date( 'm' );
if ( ! file_exists( $new_dir ) ) {
wp_mkdir_p( $new_dir );
}
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once( ABSPATH . '/wp-admin/includes/file.php' );
WP_Filesystem();
}
$wp_filesystem->put_contents(
$new_dir . '/' . $pdf_name,
$pdf_contents,
FS_CHMOD_FILE // predefined mode settings for WP files.
);
I've tested this with a live link on my local server and it all works.
One thing I don't think I can do is escape the contents of a pdf before saving it because that would break it. Even though this is something that the API of the book keeping service sends me, I don't want to assume anything and take it for granted.
What I am most interested in is: is this safe? Are there any possible vectors of attack here, because I wouldn't want to put my client at a risk.
I have managed to send email on new posting but I am trying to send email when other users edit any posts, pages and custom post types. Still no luck.
Any help would be appreciated. Thanks in advance.
Below is the code, I am using to send email, when someone add new post. I need some piece of code when someone update.
function wpse_19040_notify_admin_on_publish( $new_status, $old_status, $post ) {
if ( $new_status !== 'publish' || $old_status === 'publish' )
return;
if ( ! $post_type = get_post_type_object( $post->post_type ) )
return;
// Recipient, in this case the administrator email
$emailto = get_option( 'admin_email' );
// Email subject, "New {post_type_label}"
$subject = 'New ' . $post_type->labels->singular_name. " added: ";
// Email body
$message = "There has been new post. Please check below:";
$message .= 'View it: ' . get_permalink( $post->ID );
wp_mail( $emailto, $subject, $message );
}
add_action( 'transition_post_status', 'wpse_19040_notify_admin_on_publish', 10, 3 );