Search code examples
wordpresswoocommercehook-woocommerceemail-notifications

Hide item meta data in certain WooCommerce email notifications


I've got this code snippet in my functions.php file:

add_action( 'woocommerce_checkout_create_order_line_item', 'add_custom_field_to_order_item_meta', 10, 4 );
function add_custom_field_to_order_item_meta( $item, $cart_item_key, $values, $order ) {
    $custom_field_value = get_post_meta( $item->get_product_id(), 'supplier_sku', true );
    if ( ! empty($custom_field_value) ){
            $item->update_meta_data( __('Supplier SKU', 'woocommerce'), $custom_field_value );
    }
}

It pulls in the custom field on products, called Supplier SKU and then adds it to the WooCommerce email notifications. Which is fine, but I want to exclude it from the customer email notification and only have it display in the admin email notification.

How can I achieve this?


Solution

  • You could use the woocommerce_display_item_meta hook and return an empty string

    function filter_woocommerce_display_item_meta ( $html, $item, $args ) {
        $html = '';
    
        return $html;
    }
    add_filter( 'woocommerce_display_item_meta', 'filter_woocommerce_display_item_meta', 10, 3 );
    

    While the above would work, there would be some issues, namely:

    • The hook doesn't run just for email notifications, so it wouldn't show up anywhere
    • Even if this hook would only be executed for email notifications, we would still need to specify that this should only be the case for certain email notifications. However, this hook does not offer a solution for it by default to make this distinction

    So a workaround will be needed, this can be done by creating a global variable through another hook that applies only to email notifications

    Step 1) creating and adding a global variable

    // Setting global variable
    function action_woocommerce_email_before_order_table( $order, $sent_to_admin, $plain_text, $email ) {
        $GLOBALS['email_id'] = $email->id;
    }
    add_action( 'woocommerce_email_before_order_table', 'action_woocommerce_email_before_order_table', 1, 4 );
    

    Step 2) In the hook woocommerce_display_item_meta, add and check for specific conditions

    • Only for email notifications
    • Only for specific meta data
    • Only for admin 'new order' email
    function filter_woocommerce_display_item_meta ( $html, $item, $args ) {
        // For email notifications and specific meta
        if ( ! is_wc_endpoint_url() && $item->is_type( 'line_item' ) && $item->get_meta( 'Supplier SKU' ) ) {
            // 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'] : '';
    
            // NOT empty and targeting specific email. Multiple statuses can be added, separated by a comma
            if ( ! empty ( $email_id ) && ! in_array( $email_id, array( 'new_order' ) ) ) {
                $html = '';
            }
        }
    
        return $html;
    }
    add_filter( 'woocommerce_display_item_meta', 'filter_woocommerce_display_item_meta', 10, 3 );