Search code examples
woocommercewoocommerce-email

How to add Product names on the Email subject in Woocommerce


I have found many PHP codes shared on this platform for adding product name in the subject field in Woocommerce emails.

But when I add the snippets, Checkout is not working "Error processing checkout. Please try again."

Here is the code

add_filter( 'woocommerce_email_format_string' , 'add_custom_email_format_string', 10, 2 );
    function add_custom_email_format_string( $string, $email ) {
        $order          = $email->object; // Get the instance of the WC_Order OBJECT
        $products_names = array();

        // Loop through order items
        foreach( $order->get_items() as $item ) {
            $products_names[] = $item->get_name();
        };

        // Replace placeholders with their respective values
        $string = str_replace( '{biller_fname}', $order->billing_first_name(), $string );
        $string = str_replace( '{biller_lname}', $order->billing_last_name(), $string );
        $string = str_replace( '{biller_email}', $order->billing_email(), $string );
        $string = str_replace( '{product_name}', implode(' ', $products_names), $string );
        $string = str_replace( '{blog_name}', get_bloginfo('name'), $string );

        return $string;
    }

Any updated code that works? Please share it

Also, mention the tag which I can add it on the email settings... Like "{product_name}


Solution

  • First, here is a utility function to get the formatted product names string from an order (that we will use in both ways after):

    function get_formatted_product_names_string( $order ) {
        $placeholder_data = array();
    
        // Loop through order items
        foreach( $order->get_items() as $item ) {
            $product  = $item->get_product();
            $quantity = $item->get_quantity();
            $placeholder_data[] = $quantity . ' × ' . $product->get_name();
        };
    
        return implode(', ', $placeholder_data);
    }
    

    Code goes in functions.php file of your child theme (or in a plugin).


    Now, there are 2 ways to add product names to the email subject…

    1) Using placeholders:

    Add The following code additionally:

    // REQUIRES get_formatted_product_names_string() custom utility function
    
    add_filter( 'woocommerce_email_format_string' , 'custom_email_format_string_placeholder', 10, 2 );
    function custom_email_format_string_placeholder( $string, $email ) {
        $order          = $email->object; // Get the instance of the WC_Order OBJECT
        if ( is_a($order, 'WC_Order') ) {
            // Replace placeholders with their respective values
            $string = str_replace( '{products}', get_formatted_product_names_string( $order ), $string );
        }
        return $string;
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

    Then go to WooCommerce Settings > Emails, and for each desired email notification, you will have to add the placeholder {products} to the email subject (see the example below).

    Here we start for "New Order" notification (click on "manage" button).
    Add [{site_title}]: New order #{order_number} | Products: {products} text to the Email subject field and "save Changes".

    enter image description here


    2) Editing each email type using a filter hook:

    Here we will use the composite filter hook 'woocommerce_email_subject_' . $email_id.

    For email IDs see: Target a specific email notification with the email id in WooCommerce

    Here below, we will handle the New Order email notification:

    // REQUIRES get_formatted_product_names_string() function
    
    add_filter( 'woocommerce_email_subject_new_order', 'custom_new_order_email_subject', 20, 2 );
    function custom_new_order_email_subject( $formated_subject, $order ){
        return sprintf( __('[%s] New order #%s | Products: %s', 'woocommerce'), 
            get_bloginfo('name'), // Site name
            $order->get_order_number(), // Order number (or order ID)
            get_formatted_product_names_string( $order )
        );
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.