Today is another seemingly simple task that nevertheless could not be solved with either Stackoverflow or Chat-GPT 🙂
We need replace the customer shipping address in the email template for WooCommerce order notifications for some shipping method.

How to replace Woocommerce emails addresses section with custom data programmatically

The Stackoverflow solution

add_action( 'woocommerce_email_customer_details', 'sent_to_admin_custom_email_addresses', 5, 4 );
function sent_to_admin_custom_email_addresses( $order, $sent_to_admin, $plain_text, $email ){
    if( in_array( $email->id, array( 'new_order', 'cancelled_order', 'failed_order' ) ) ) {
        $mailer = WC()->mailer();
        remove_action( 'woocommerce_email_customer_details', array( $mailer, 'email_addresses' ), 20 );
        add_action( 'woocommerce_email_customer_details', 'custom_email_addresses', 20, 1 );
    }
}

function custom_email_addresses( $order ) {
    if ( is_a( $order, 'WC_Order' ) ) :

    $text_align = is_rtl() ? 'right' : 'left';
    $address    = $order->get_formatted_billing_address();

    ?><table id="addresses" cellspacing="0" cellpadding="0" style="width: 100%; vertical-align: top; margin-bottom: 40px; padding:0;" border="0">
        <tr>
            <td style="text-align:<?php echo esc_attr( $text_align ); ?>; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; border:0; padding:0;" valign="top" width="50%">
                <h2><?php esc_html_e( 'Billing address', 'woocommerce' ); ?></h2>
                <address class="address">
                    <?php echo wp_kses_post( $address ? $address : esc_html__( 'N/A', 'woocommerce' ) ); ?>
                </address>
            </td>
        </tr>
    </table>
    <?php
    endif;
}

For some reason this solution did not work for me, in fact – the second call to the hook add_action( ‘woocommerce_email_customer_details’) only duplicated the addresses in the letter twice.

Another solution

So first function OK, just revised to make make if condition based on shipping method:

add_action( 'woocommerce_email_customer_details', 'sent_to_admin_custom_email_addresses', 5, 4 );
function sent_to_admin_custom_email_addresses( $order, $sent_to_admin, $plain_text, $email ){
    foreach($order->get_shipping_methods() as $shipping_method ){
	if ( $shipping_method->get_method_id() === 'my_shipping_method_id' ){
	    $mailer = WC()->mailer();
            remove_action( 'woocommerce_email_customer_details', array( $mailer, 'email_addresses' ), 20 );
            add_action( 'woocommerce_email_customer_details', 'custom_email_addresses', 20, 1 );
        }
    }
}

And in the second part of code i just used a little CSS inline insertion to hide standard block with addresses:

function custom_email_addresses( $order ) {
    if ( is_a( $order, 'WC_Order' ) ) :

    $text_align = is_rtl() ? 'right' : 'left';
    $address    = $order->get_formatted_billing_address();
    
   // hide standard table with addresses via CSS
   ?>			
   <style>				
	table#addresses {
	    display:none !important;
	}
  </style>
  <table id="my-addresses-id" cellspacing="0" cellpadding="0" style="width: 100%; vertical-align: top; margin-bottom: 40px; padding:0;" border="0">
        <tr>
            <td style="text-align:<?php echo esc_attr( $text_align ); ?>; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; border:0; padding:0;" valign="top" width="50%">
                <h2><?php esc_html_e( 'Billing address', 'woocommerce' ); ?></h2>
                <address class="address">
                    <?php echo wp_kses_post( $address ? $address : esc_html__( 'N/A', 'woocommerce' ) ); ?>
                </address>
            </td>
        </tr>
    </table>
    <?php
    endif;
}

Don’t forget to change the <table id=”addresses” to some your HTML selector.


Leave a Reply

Your email address will not be published.