PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label email-notifications. Show all posts
Showing posts with label email-notifications. Show all posts

Monday, October 24, 2022

[FIXED] Which hook to use to save order meta data before email notifications are send in WooCommerce

 October 24, 2022     email-notifications, hook-woocommerce, orders, woocommerce, wordpress     No comments   

Issue

I'm looking for a Woocommerce action hook (or filter, I'm not sure) where I can update the shipping & billing address before the New Order email notification is sent.

Right now, I'm using the woocommerce_before_thankyou to update order meta.

The order is saved with correct address that I want to save, but the email is not displaying the correct address.

Here is the example code, similar with what I'm doing:

add_action( 'woocommerce_thankyou', 'checkout_save_user_meta');

function checkout_save_user_meta( $order_id ) {
    $order = wc_get_order( $order_id );
    $my_custom_address = 'My custom address';
    
    update_post_meta( $order_id, '_billing_address_1',  $my_custom_address );
    update_post_meta( $order_id, '_shipping_address_1',  $my_custom_address );
}

Any advice on which hook to use for this case?


Solution

You can use the woocommerce_checkout_create_order or the woocommerce_checkout_update_order_meta action hook.

So you would get:

/**
 * Action hook to adjust order before save.
 *
 * @since 3.0.0
 */
function action_woocommerce_checkout_create_order( $order, $data ) {    
    // Some value
    $my_custom_address = 'My custom address';

    // Update meta data
    $order->update_meta_data( '_billing_address_1', $my_custom_address );
    $order->update_meta_data( '_shipping_address_1', $my_custom_address );
}
add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );

OR

/**
 * Action hook fired after an order is created used to add custom meta to the order.
 *
 * @since 3.0.0
 */
function action_woocommerce_checkout_update_order_meta( $order_id, $data ) {    
    // Get an instance of the WC_Order object
    $order = wc_get_order( $order_id );
    
    // Is a WC_Order
    if ( is_a( $order, 'WC_Order' ) ) {     
        // Some value
        $my_custom_address = 'My custom address';

        // Update meta data
        $order->update_meta_data( '_billing_address_1', $my_custom_address );
        $order->update_meta_data( '_shipping_address_1', $my_custom_address );

        // Save
        $order->save();
    }
}   
add_action( 'woocommerce_checkout_update_order_meta', 'action_woocommerce_checkout_update_order_meta', 10, 2 );


Answered By - 7uc1f3r
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, May 15, 2022

[FIXED] How to pass "$email" to WooCommerce emails template files if not available by default

 May 15, 2022     email-notifications, parameters, woocommerce, wordpress     No comments   

Issue

I've checked many threads on the platform. But there is no thread which explains how to use the conditional $email>id parameter straight into a template.

This is what I have in email-header.php:

<div style="width:600px;" id="template_header_image">
    <?php
    if ( $img = get_option( 'woocommerce_email_header_image' ) ) {
        echo '<p style="margin-top:0;"><img width="80%" height="auto" src="' . esc_url( $img ) . '" alt="' . get_bloginfo( 'name', 'display' ) . '" /></p>';
    }
    if( $email->id == 'customer_processing_order'  ) {
        echo '<img alt="order in processing" src="https/example.com/image.png" />';
}
?>                          
</div>

The src is an example. The if( $email->id == 'customer_processing_order' ) is not working.

It seems that parameter $email is not being picked up. I tried to call it with global $email; but this also does not work.

Any advice?


Solution

In /includes/class-wc-emails.php we see that only $email_heading is passed via wc_get_template()

/**
 * Get the email header.
 *
 * @param mixed $email_heading Heading for the email.
 */
public function email_header( $email_heading ) {
    wc_get_template( 'emails/email-header.php', array( 'email_heading' => $email_heading ) );
}

So to pass the $email->id we have to use a workaround, first we will make the variable global available.


1) This can be done via different hooks but the woocommerce_email_header hook seems to be the most suitable in this specific case:

// Header - set global variable
function action_woocommerce_email_header( $email_heading, $email ) {
    $GLOBALS['email_id'] = $email->id;
} 
add_action( 'woocommerce_email_header', 'action_woocommerce_email_header', 10, 2 );

Code goes in functions.php file of the active child theme (or active theme).

2) Then in the desired template file you can use:

2.1) put this just after if ( ! defined( 'ABSPATH' ) ) {..}

// Getting the email ID global variable
$ref_name_globals_var = isset( $GLOBALS ) ? $GLOBALS : '';
$email_id = isset( $ref_name_globals_var['email_id'] ) ? $ref_name_globals_var['email_id'] : '';

2.2) and at the desired location, towards the output

// Targeting specific email. Multiple statuses can be added, separated by a comma
if ( in_array( $email_id, array( 'new_order', 'customer_processing_order' ) ) ) {
    // Desired output
    echo '<p style="color: red; font-size: 20px;">Your output</p>';
}


Answered By - 7uc1f3r
Answer Checked By - Terry (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, March 13, 2022

[FIXED] Send email notification to user when on WooCommerce checkout page and has products in cart

 March 13, 2022     checkout, email-notifications, php, woocommerce, wordpress     No comments   

Issue

I need to be able to send an email to the user when he is in the checkout, basically when is about to make the purchase.

I added this code to my functions.php but, it happens that it sends the mail more than 1 time in an erratic way, I think it is due to the conditionals i declared but i'm not too sure.

Here is the code:

if (is_user_logged_in() && !WC()->cart->is_empty()) {

        /*the current user data*/
        $current_user = wp_get_current_user();
        $email = $current_user->user_email;
        $name = $current_user->user_firstname;

        /*the mail structure*/
        $to = $email;
        $subject = "¡Hola - " . $name . "!, tu compra está casi lista.";
        $body = '
                    //the mail body
        ';

        $headers = array('Content-Type: text/html; charset=UTF-8');
        wp_mail($to, $subject, $body, $headers);
    } /*endif*/
}

add_action('woocommerce_after_shop_loop_item', 'send_mail_when_is_in_checkout');

Solution

The woocommerce_after_shop_loop_item hook has nothing to do with the checkout page but is executed on the shop page, you should instead use a hook that only applies to the checkout page, e.g. woocommerce_before_checkout_form

To avoid error messages, it is best to check whether WC->cart is actually available before using it

So you get:

function action_woocommerce_before_checkout_form() {
    // Only logged in users
    if ( ! is_user_logged_in() ) return;

    // WC Cart
    if ( WC()->cart ) {
        // Cart NOT empty
        if ( ! WC()->cart->is_empty() ) {
            // The current user
            $current_user = wp_get_current_user();
            $email = $current_user->user_email;
            $name = $current_user->user_firstname;

            // NOT empty
            if ( ! empty ( $email ) && ! empty ( $name ) ) {
                // The mail structure
                $to = $email;
                $subject = sprintf( __( 'Hello %s, your message', 'woocommerce' ), $name );
                $body = __( 'The mail body', 'woocommerce' );

                // Headers
                $headers = array( 'Content-Type: text/html; charset=UTF-8' );

                // Sends an email, similar to PHP’s mail function
                wp_mail( $to, $subject, $body, $headers );
            }
        }
    }
}
add_action( 'woocommerce_before_checkout_form', 'action_woocommerce_before_checkout_form' );

Optional: to send email notifications with the same layout of the other WooCommerce email notifications

Replace

// NOT empty
if ( ! empty ( $email ) && ! empty ( $name ) ) {
    // The mail structure
    $to = $email;
    $subject = sprintf( __( 'Hello %s, your message', 'woocommerce' ), $name );
    $body = __( 'The mail body', 'woocommerce' );

    // Headers   
    $headers = array( 'Content-Type: text/html; charset=UTF-8' );

    // Sends an email, similar to PHP’s mail function
    wp_mail( $to, $subject, $body, $headers );
}

With

// NOT empty
if ( ! empty ( $email ) && ! empty ( $name ) ) {
    // Mailer
    $mailer = WC()->mailer();
    
    // To, subject, message
    $to = $email;
    $subject = __( 'My subject', 'woocommerce' );
    $message_body = __( 'My message', 'woocommerce' );

    // Message head and message body
    $message = $mailer->wrap_message( sprintf( __( 'Hello %s', 'woocommerce' ), $name ), $message_body );
    
    // Headers
    $headers = 'Content-Type: text/html\r\n';

    // Send an email
    $mailer->send( $to, $subject, $message, $headers );
}


Answered By - 7uc1f3r
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Display a custom field in WooCommerce email notifications for admin

 March 13, 2022     custom-fields, email-notifications, php, woocommerce, wordpress     No comments   

Issue

I installed Checkout Field Editor on my wordpress site. I created the custom field. However, using the following code, the pcustomer field appears both in the "new order" email that arrives to me and to the customer. Instead I want it to come exclusively to me. I tried to edit the code, but it still doesn't work.

add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
    $fields['meta_key'] = array(
        'label' => __( 'Label' ),
        'value' => get_post_meta( $order->id, 'meta_key', true ),
    );
    return $fields;
}

Solution

Since WooCommerce 3, your code is a bit outdated, with some mistakes Try the following:

add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
    $meta_key = '_meta_key1'; // <= Here define the correct meta key
    $meta_value = $order->get_meta( $meta_key1 );
    
    if ( ! empty( $meta_value1 ) ) {
        $fields[ $meta_key1 ] = array(
            'label' => __( 'My label 1', "text-domain' ),
            'value' => $meta_value1,
        );
    }
    return $fields;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.


Now to restrict the code only to admin email notifications, you will use $sent_to_admin argument variable as follows:

add_filter( 'woocommerce_email_order_meta_fields', 'custom_woocommerce_email_order_meta_fields', 10, 3 );
function custom_woocommerce_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
    if ( $sent_to_admin ) {
        $meta_key1 = '_meta_key1'; // <= Here define the correct meta key
        $meta_value1 = $order->get_meta( $meta_key1 );
        
        if ( ! empty( $meta_value1 ) ) {
            $fields[ $meta_key1 ] = array(
                'label' => __( 'My label 1', "text-domain' ),
                'value' => $meta_value1,
            );
        }
    }
    return $fields;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

This time this custom field will not be displayed on customer email notifications.

Note:

  • $order->idis uncorrect since WooCommerce 3. use instead $order->get_id().
  • WordPress get_post_meta() function can be replace by WooCommerce WC_Data get_meta() method.


Answered By - LoicTheAztec
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, February 10, 2022

[FIXED] Change currency symbol in WooCommerce emails notifications

 February 10, 2022     email-notifications, php, woocommerce, wordpress     No comments   

Issue

I am struggeling by changing the currency symbol in WooCommerce email notifications.

Everywhere you can see the € currency, but as far as you open the emails, you find, that the currency there is £.

I tried to add this function using Snipets:

/**
* change currency symbol to €
*/

add_filter( 'woocommerce_currency_symbol', 'wc_change_uae_currency_symbol', 10, 2 );

function wc_change_uae_currency_symbol( $currency_symbol, $currency ) {
switch ( $currency ) {
case '€':
$currency_symbol = '€';
break;
}

return $currency_symbol;
}

But nothing has changed. Any advice?


Here is a simple image for that also describe the situation:

enter image description here


Solution

This should fix the issue:

function filter_woocommerce_currency_symbol( $currency_symbol, $currency ) {    
    // Compare
    switch( $currency ) {
        case 'GBP': $currency_symbol = '&euro;';
        break;
    }
    
    return $currency_symbol;
}
add_filter( 'woocommerce_currency_symbol', 'filter_woocommerce_currency_symbol', 1, 2 );

The difference is that you are currently converting € symbol into the € symbol


Tested in WordPress 5.8.3 and WooCommerce 6.0.0



Answered By - 7uc1f3r
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, January 28, 2022

[FIXED] Email notification to a particular address if a specific product is purchased in Woocommerce

 January 28, 2022     email-notifications, hook-woocommerce, orders, woocommerce, wordpress     No comments   

Issue

I am using the woocommerce plugin in my Wordpress website. I am wondering how can I send an email notification to a specific address email if product A is purchased by customer.

How to send an email notification to a specific address when a specific product is purchased in Woocommerce?


Solution

The code below will add a custom defined email recipient to New Email Notification When a specific defined product Id is found in order items:

add_filter( 'woocommerce_email_recipient_new_order', 'conditional_recipient_new_email_notification', 15, 2 );
function conditional_recipient_new_email_notification( $recipient, $order ) {
    if( is_admin() ) return $recipient; // (Mandatory to avoid backend errors)

    ## --- YOUR SETTINGS (below) --- ##

    $targeted_id = 37; // HERE define your targeted product ID
    $addr_email  = 'name@domain.com'; // Here the additional recipient

    // Loop through orders items
    foreach ($order->get_items() as $item_id => $item ) {
        if( $item->get_variation_id() == $targeted_id || $item->get_product_id() == $targeted_id ){
            $recipient .= ', ' . $addr_email; 
            break; // Found and added - We stop the loop
        }
    }

    return $recipient;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.



Answered By - LoicTheAztec
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, January 27, 2022

[FIXED] Add coupon names and percentage to WooCommerce view order details and email notifications

 January 27, 2022     coupon, email-notifications, orders, woocommerce, wordpress     No comments   

Issue

I used Add the Coupon Code names to Woocommerce View Order details and email notifications to inspire my snippet.

I'm trying to expand the snippet to also include the coupon percentage amount in brackets, if the coupon type is a percentage discount.

This is what it should look like:

enter image description here

Here is my attempt. Any ideas if this is correct:

add_filter( 'woocommerce_get_order_item_totals', 'add_coupons_codes_line_to_order_totals_lines', 10, 3 );
function add_coupons_codes_line_to_order_totals_lines( $total_rows, $order, $tax_display ) {
    // Exit if there is no coupons applied
    if( sizeof( $order->get_used_coupons() ) == 0 )
        return $total_rows;

    $new_total_rows = []; // Initializing

    foreach($total_rows as $key => $total ){
        $new_total_rows[$key] = $total;

        if( $key == 'discount' ){
            // Get applied coupons
            $applied_coupons = $order->get_used_coupons();
            
        if( $applied_coupons->discount_type == 'percent'){
             // Get applied coupon percentge
            $applied_coupons_percentage = $applied_coupons->coupon_amount;
            }

            // Insert applied coupon codes in total lines after discount line
            $new_total_rows['coupon_codes'] = array(
                'label' => __('Applied coupons:', 'woocommerce'),
                'value' => implode( ', ', $applied_coupons '<p> ({$applied_coupons_percentage}%)</p>' ),
            );
        }
    }

    return $new_total_rows;
}

I use this to display the coupon percentage on the cart page. I tried to incorporate this into my snippet above:

function my_coupon_percentage_cart($value, $coupon)
{
    if($coupon->discount_type == 'percent' && !empty($coupon->coupon_amount))
    {
        $amt = "<br><br><p><em><strong>{$coupon->coupon_amount}% OFF on Your Order</strong></em></p>";   
    }

    return $value.$amt;
}
add_filter('woocommerce_cart_totals_coupon_html','my_coupon_percentage_cart',10,2);


Solution

Besides the fact that your code contains mistakes, it also contains some outdated code

  • get_used_coupons() is deprecated since 3.7.0 - Replaced with better named method to reflect the actual data being returned.
  • $coupon->discount_type has been replaced with $coupon->get_discount_type()
  • $coupon->coupon_amount has been replaced with $coupon->get_amount()

So you get:

function filter_woocommerce_get_order_item_totals( $total_rows, $order, $tax_display ) {
    // Exit if there is no coupons applied
    if ( sizeof( $order->get_coupon_codes() ) == 0 ) return $total_rows;

    $new_total_rows = []; // Initializing

    foreach( $total_rows as $key => $total ) {
        $new_total_rows[$key] = $total;

        if ( $key == 'discount' ) {
            // Get used coupon codes only
            $coupon_codes = $order->get_coupon_codes();
            
            // Loop through WC_Order_Item_Coupon objects
            foreach ( $coupon_codes as $index => $coupon_code ) {
                // Get an instance of the WC_Coupon Object
                $coupon = new WC_Coupon( $coupon_code );

                // Discount type = percent & amount NOT empty
                if ( $coupon->get_discount_type() == 'percent' && ! empty ( $coupon->get_amount() ) ) {
                    $coupon_codes[$index] = $coupon_code . ' (' . $coupon->get_amount() . '%)';
                }
            }
            

            // Insert applied coupon codes in total lines after discount line
            $new_total_rows['coupon_codes'] = array(
                'label' => __( 'Applied coupons:', 'woocommerce' ),
                'value' => implode( ', ', $coupon_codes ),
            );
        }
    }

    return $new_total_rows;
}
add_filter( 'woocommerce_get_order_item_totals', 'filter_woocommerce_get_order_item_totals', 10, 3 );


Answered By - 7uc1f3r
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing