phpsqlwordpresswoocommercewoocommerce-bookings

Custom email subject placeholders for WooCommerce order related bookings


Woocommerce gives the option to add placeholders to the subject of an email. I'd like to expand on that ability by creating a custom placeholder that pulls information from woocommerce gravity forms product addons and woocommerce bookings.

I've tried Create additional variables/placeholders for Woocommerce email notifications subject code making some changes to see if I could make it work. Also, I tried getting the woocommerce meta fields but that didn't work either.

On this code I am not able to get the booking related to the order:

// For woocommerce versions up to 3.2
add_filter( 'woocommerce_email_format_string' , 'filter_email_format_string', 20, 2 );
function filter_email_format_string( $string, $email ) {
    // Get the instance of the WC_Order object
    $booking = $get_order;

    // Additional wanted placeholders in the array (find / replace pairs)
    $additional_placeholders = array(
        '{custom_one}'      => $booking->get_start_date(),
    );

    // return the clean string with new replacements
    return str_replace( array_keys( $additional_placeholders ), array_values( $additional_placeholders ), $string );
}

Solution

  • First of all your main problem is:

    How to get the booking Id(s) from an order (Id)?

    As an order can have many bookings (items), you can get the booking Id(s) targeting the post parent (which is the order ID) with a very simple and light SQL query Using WordPress WPDB Class and available methods.

    Then you will be able to get the start date from one booking of this order and set it as a custom placeholder for email notification subject:

    // Custom function to get the booking Ids from an order Id (with an SQL query)
    function wc_get_booking_ids( $order_id ){
        global $wpdb;
    
        return $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'wc_booking' AND post_parent =  %d", $order_id ) );
    }
    
    // For woocommerce versions up to 3.2
    add_filter( 'woocommerce_email_format_string' , 'filter_email_format_string', 20, 2 );
    function filter_email_format_string( $string, $email ) {
        if( ! is_a($email->object, 'WC_Order') ) return; // Exit
    
        $booking_ids = wc_get_booking_ids( $email->object->get_id() );
    
        if( ! empty($booking_ids) ) {
            // Get the instance of the WC_Booking object from one booking Id
            $booking = new WC_Booking( reset($booking_ids) );
    
            if( is_a($booking, 'WC_Booking') && method_exists($booking, 'get_start_date') ) {
                // Additional placeholders array (one by line)
                $custom_placeholders = array(
                    '{start_date}' => $start_date = $booking->get_start_date(),
                );
                $string = str_replace( array_keys( $custom_placeholders ), array_values( $custom_placeholders ), $string );
            }
        }
        return $string;
    }
    

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