Search code examples
phpwoocommerceordersstatusemail-notifications

Woocommerce custom order status with customized email notification


I am using some custom order statuses that I have successfully added to WooCommerce. I have been able to customize the emails to be sent to the customer when certain types of products are ordered. works,

Now what I want is to change my code, so it only sends the customized email notifications and not the default WooCommerce processing mail.

Here is a working sample of my code:

// register a custom post status 'awaiting-delivery' for Orders
add_action( 'init', 'register_custom_post_status', 20 );
function register_custom_post_status() {
    register_post_status( 'wc-costum', array(
        'label'                     => _x( 'Instagram cursus', 'Order status', 'woocommerce' ),
        'public'                    => true,
        'exclude_from_search'       => false,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop( 'Instagram cursus <span class="count">(%s)</span>', 'Instagram cursus <span class="count">(%s)</span>', 'woocommerce' )
    ) );
}

// Adding custom status 'awaiting-delivery' to order edit pages dropdown
add_filter( 'wc_order_statuses', 'custom_wc_order_statuses' );
function custom_wc_order_statuses( $order_statuses ) {
    $order_statuses['wc-costum'] = _x( 'Instagram cursus', 'Order status', 'woocommerce' );
    return $order_statuses;
}


// Adding custom status 'awaiting-delivery' to admin order list bulk dropdown
add_filter( 'bulk_actions-edit-shop_order', 'custom_dropdown_bulk_actions_shop_order', 20, 1 );
function custom_dropdown_bulk_actions_shop_order( $actions ) {
    $actions['mark_costum'] = __( 'Instagram cursus', 'woocommerce' );
    return $actions;
}

// Adding action for 'awaiting-delivery'
add_filter( 'woocommerce_email_actions', 'custom_email_actions', 20, 1 );
function custom_email_actions( $actions ) {
    $actions[] = 'woocommerce_order_status_wc-costum';
    return $actions;
}

// Removing default email action for 'processing' status
remove_action( 'woocommerce_order_status_processing', array( WC(), 'send_transactional_email' ), 10, 1 );


// Adding action for 'awaiting-delivery'
add_action( 'woocommerce_order_status_changed', 'custom_email_notification', 10, 4 );
function custom_email_notification( $order_id, $old_status, $new_status, $order ) {
    $custom_statuses = array( 'costum', 'costum2', 'costum3' );

    if ( in_array( $new_status, $custom_statuses ) ) {
        // Your settings here
        $email_key = 'WC_Email_Customer_Processing_Order'; // The email notification type

        // Get specific WC_emails object
        $email_obj = WC()->mailer()->get_emails()[ $email_key ];

        // Triggering the customized email
        $email_obj->trigger( $order_id );
    }
}

// Customize email heading for this custom status email notification
add_filter( 'woocommerce_email_heading_customer_processing_order', 'email_heading_customer_awaiting_delivery_order', 10, 2 );
function email_heading_customer_awaiting_delivery_order( $heading, $order ){
    if ($order->has_status('costum')) {
        $email_key   = 'WC_Email_Customer_Processing_Order'; // The email notification type
        $email_obj   = WC()->mailer()->get_emails()[$email_key]; // Get specific WC_emails object
        $heading_txt = __('Bevestigingsmail:','woocommerce'); // New heading text
        return $email_obj->format_string( $heading_txt );
    } 
    return $heading;
}

// Customize email subject for this custom status email notification
add_filter( 'woocommerce_email_subject_customer_processing_order', 'email_subject_customer_awaiting_delivery_order', 10, 2 );
function email_subject_customer_awaiting_delivery_order( $subject, $order ){
    if ($order->has_status('costum')) {
        $email_key   = 'WC_Email_Customer_Processing_Order'; // The email notification type
        $email_obj   = WC()->mailer()->get_emails()[$email_key]; // Get specific WC_emails object
        $subject_txt = sprintf( __('[%s] Instagram cursus (%s) - %s', 'woocommerce'), '{site_title}', '{order_number}', '{order_date}' ); // New subject text
        return $email_obj->format_string( $subject_txt );
    } 
    return $subject;
}

// Remove content before woocommerce_email_before_order_table hook
add_action('woocommerce_email_order_details', 'remove_content_before_order_table', 1, 4);

function remove_content_before_order_table($order, $sent_to_admin, $plain_text, $email) {
    // Remove unwanted content here
    remove_action('woocommerce_email_before_order_table', array($email, 'order_details'), 10);
}

// Customize email content for this custom status email notification
add_action( 'woocommerce_email_before_order_table', 'custom_content_for_customer_processing_order_email', 10, 4 );
function custom_content_for_customer_processing_order_email( $order, $sent_to_admin, $plain_text, $email ) {
    // Check if it's the "Customer Processing Order" email triggered by 'awaiting-delivery' status
    if ( $email->id === 'customer_processing_order' && $order->has_status( 'costum' ) ) {
        echo '<h4>Bedankt voor het aanmelden voor de Instagram cursus.</h4>';
        echo '<p>Bij het aanmelden heb je je Instagram gebruikersnaam moeten invullen. Als je dit niet hebt gedaan, stuur deze dan zo snel als mogelijk naar ons toe als reactie op de deze e-mail, zodoende weten wij welke Instagram gebruiker wij moeten accepteren.</p>
        <p>Je gaat een online cursus doen die volledig via Instagram te volgen is. Je krijgt één jaar lang toegang tot deze Instagram cursus.</p>
        <p>Om de cursus te kunnen volgen vragen we je het volgende te doen:</p>
        <ol>
            <li>Volg onze cursuspagina op Instagram: <a href="https://instagram.com/ehboviva.online?igshid=NzZlODBkYWE4Ng==">ehboviva.online</a></li>
            <li>Wij accepteren je verzoek binnen 48 uur</li>
            <li>Vanaf nu heb je één jaar lang toegang tot ons Instagram account en kan je dus op elk moment de cursus openen en doornemen</li>
        </ol>
        <p>Veel lees en kijk plezier, succes!</p>';
    }
}

Right now my code is made so it sends with the processing mail. But I want to only send the custom email. Or maybe change the recipient of the processing mail to something else than the customer mail. But when I turn off the processing mail it does not send either. And when I change the mail of the recipient it sends both mails to that adress.

What should I change?

P.S. I have removed a lot of code otherwise I could not post this because of spam detection. So if someone misses something please notify me.


Solution

  • There are some mistakes and missing things in your code…

    I have revised your code.

    I have renamed your "costum" status to something more explicit ("instacursus") and added a 2nd custom status "custom", this way you can see how to add multiple status keeping a compact code…

    I have added a hooked function to disable default "processing" notification.

    Try the following:

    // register a custom post status for WooCommerce Orders
    add_action( 'init', 'register_custom_post_status', 20 );
    function register_custom_post_status() {
        register_post_status( 'wc-instacursus', array(
            'label'                     => _x( 'Instagram cursus', 'Order status', 'woocommerce' ),
            'public'                    => true,
            'exclude_from_search'       => false,
            'show_in_admin_all_list'    => true,
            'show_in_admin_status_list' => true,
            'label_count'               => _n_noop( 'Instagram cursus <span class="count">(%s)</span>', 'Instagram cursus <span class="count">(%s)</span>', 'woocommerce' )
        ) );
    
        register_post_status( 'wc-custom', array(
            'label'                     => _x( 'Custom', 'Order status', 'woocommerce' ),
            'public'                    => true,
            'exclude_from_search'       => false,
            'show_in_admin_all_list'    => true,
            'show_in_admin_status_list' => true,
            'label_count'               => _n_noop( 'Customs <span class="count">(%s)</span>', 'Custom <span class="count">(%s)</span>', 'woocommerce' )
        ) );
    }
    
    // Adding custom statuses to order edit pages dropdown
    add_filter( 'wc_order_statuses', 'custom_wc_order_statuses' );
    function custom_wc_order_statuses( $order_statuses ) {
        $order_statuses['wc-instacursus'] = _x( 'Instagram cursus', 'Order status', 'woocommerce' );
        $order_statuses['wc-custom']      = _x( 'Custom', 'Order status', 'woocommerce' );
        return $order_statuses;
    }
    
    
    // Adding custom statuses to admin order list bulk dropdown
    add_filter( 'bulk_actions-edit-shop_order', 'custom_dropdown_bulk_actions_shop_order', 20, 1 );
    function custom_dropdown_bulk_actions_shop_order( $actions ) {
        $actions['mark_instacursus'] = __( 'Change status to Instagram cursus', 'woocommerce' );
        $actions['mark_custom'] = __( 'Change status to Custom', 'woocommerce' );
        return $actions;
    }
    
    // Adding action for custom statuses
    add_filter( 'woocommerce_email_actions', 'custom_email_actions', 20, 1 );
    function custom_email_actions( $actions ) {
        $actions[] = 'woocommerce_order_status_wc-instacursus';
        $actions[] = 'woocommerce_order_status_wc-custom';
        return $actions;
    }
    
    // Removing default email notification for 'processing' status (from pending)
    add_action( 'woocommerce_email', 'unhook_pending_to_processing_email_notification' );
    function unhook_pending_to_processing_email_notification( $email_class ) {
        remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class->emails['WC_Email_New_Order'], 'trigger' ) );
        remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class->emails['WC_Email_Customer_Processing_Order'], 'trigger' ) );
    }
    
    // Remove transactional email notifications for custom order statuses
    remove_action( 'woocommerce_order_status_processing', array( 'WC_Emails', 'send_transactional_email' ), 10, 1 );
    
    // Add transactional email notifications for custom order statuses
    add_action( 'woocommerce_order_status_wc-instacursus', array( 'WC_Emails', 'send_transactional_email' ), 10, 1 );
    add_action( 'woocommerce_order_status_wc-custom', array( 'WC_Emails', 'send_transactional_email' ), 10, 1 );
    
    // Send email on status change
    add_action('woocommerce_order_status_instacursus', 'custom_status_trigger_email_notification', 10, 2 );
    add_action('woocommerce_order_status_custom', 'custom_status_trigger_email_notification', 10, 2 );
    function custom_status_trigger_email_notification( $order_id, $order ) {
        WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order']->trigger( $order_id );
    }
    
    // Customize email heading for this custom status email notification
    add_filter( 'woocommerce_email_heading_customer_processing_order', 'email_heading_customer_awaiting_delivery_order', 10, 2 );
    function email_heading_customer_awaiting_delivery_order( $heading, $order ){
        if ( $order->has_status( array('instacursus', 'custom') ) ) {
            if ($order->has_status('instacursus')) {
                $heading_txt = __('Bevestigingsmail:','woocommerce');
            } elseif ($order->has_status('custom')) {
                $heading_txt = __('Custom email:','woocommerce');
            }
            $heading = WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order']->format_string( $heading_txt );
        } 
        return $heading;
    }
    
    // Customize email subject for this custom status email notification
    add_filter( 'woocommerce_email_subject_customer_processing_order', 'email_subject_customer_awaiting_delivery_order', 10, 2 );
    function email_subject_customer_awaiting_delivery_order( $subject, $order ){
        if ( $order->has_status( array('instacursus', 'custom') ) ) {
            if ($order->has_status('instacursus')) {
                $subject_txt = sprintf( __('[%s] Instagram cursus (%s) - %s', 'woocommerce'), '{site_title}', '{order_number}', '{order_date}' );
            } elseif ($order->has_status('custom')) {
                $subject_txt = sprintf( __('[%s] Custom (%s) - %s', 'woocommerce'), '{site_title}', '{order_number}', '{order_date}' );
            }
            $subject = WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order']->format_string( $subject_txt );
        } 
        return $subject;
    }
    
    // Remove content before woocommerce_email_before_order_table hook
    add_action('woocommerce_email_order_details', 'remove_content_before_order_table', 1, 4);
    function remove_content_before_order_table($order, $sent_to_admin, $plain_text, $email) {
        // Remove unwanted content here
        remove_action('woocommerce_email_before_order_table', array($email, 'order_details'), 10);
    }
    
    // Customize email content for this custom status email notification
    add_action( 'woocommerce_email_before_order_table', 'custom_content_for_customer_processing_order_email', 10, 4 );
    function custom_content_for_customer_processing_order_email( $order, $sent_to_admin, $plain_text, $email ) {
        // Check if it's the "Customer Processing Order" email triggered by 'awaiting-delivery' status
        if ( $email->id === 'customer_processing_order' && $order->has_status(  array('instacursus', 'custom') ) ) {
            if ( $order->has_status('instacursus') ) {
                echo '<h4>Bedankt voor het aanmelden voor de Instagram cursus.</h4>';
                echo '<p>Bij het aanmelden heb je je Instagram gebruikersnaam moeten invullen. Als je dit niet hebt gedaan, stuur deze dan zo snel als mogelijk naar ons toe als reactie op de deze e-mail, zodoende weten wij welke Instagram gebruiker wij moeten accepteren.</p>
                <p>Je gaat een online cursus doen die volledig via Instagram te volgen is. Je krijgt één jaar lang toegang tot deze Instagram cursus.</p>
                <p>Om de cursus te kunnen volgen vragen we je het volgende te doen:</p>
                <ol>
                    <li>Volg onze cursuspagina op Instagram: <a href="https://instagram.com/ehboviva.online?igshid=NzZlODBkYWE4Ng==">ehboviva.online</a></li>
                    <li>Wij accepteren je verzoek binnen 48 uur</li>
                    <li>Vanaf nu heb je één jaar lang toegang tot ons Instagram account en kan je dus op elk moment de cursus openen en doornemen</li>
                </ol>
                <p>Veel lees en kijk plezier, succes!</p>';
            } elseif ( $order->has_status('custom') ) {
                echo '<h4>Bedankt voor het aanmelden voor de Custom.</h4>';
                echo '<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pretium quam vulputate dignissim suspendisse in. Est ultricies integer quis auctor elit sed vulputate.</p>
                <p>Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Mi quis hendrerit dolor magna eget est. Mauris in aliquam sem fringilla ut morbi.</p>
                <p>Om de cursus te kunnen volgen vragen we je het volgende te doen:</p>';
            }
        }
    }
    

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

    Related: WooCommerce: Add Custom order statuses with custom email notifications