skip to Main Content

I’m sure this is something stupid since everything works EXCEPT the email is not actually sent. I think something is wrong with the hook since the error_log message doesn’t show. The hook itself is valid, since I was able to add_action within the WC_Custom_Order_Status class and in an another file outside a class with no problem.

File ready-pickup-status.php:

class WC_Custom_Order_Status {
    public function __construct() {
        // Hook into WordPress actions and filters
        add_action('init', array($this, 'register_ready_order_status'));
        add_filter('wc_order_statuses', array($this, 'add_ready_order_status'));
        add_filter('bulk_actions-edit-shop_order', array($this, 'ready_to_bulk_actions_order'));
        add_action('admin_head', array($this, 'add_ready_actions_button_css'));
        add_filter( 'woocommerce_email_classes', array( $this, 'add_customer_ready_order_email' ) );
    }

    // Register custom order status
    public function register_ready_order_status() {
        register_post_status( 'wc-ready', array(
            'label'                     => 'Ready for pick-up',
            'public'                    => true,
            'exclude_from_search'       => false,
            'show_in_admin_all_list'    => true,
            'show_in_admin_status_list' => true,
            'label_count'               => _n_noop( 'Ready for pick-up <span class="count">(%s)</span>', 'Ready for pick-up <span class="count">(%s)</span>' )
        ) );
    }

    // Add ready for pick-up message to order status
    public function add_ready_order_status( $order_statuses ) {
        $order_statuses['wc-ready'] = 'Ready for pick-up';
        return $order_statuses;
    }

    // Adding this custom status to admin order list bulk dropdown
    public function ready_to_bulk_actions_order( $actions ) {
        $actions['mark_ready'] = __( 'Change status to ready for pick-up', 'woocommerce' );
        return $actions;
    }

    // Set styling for custom order status action button icon and list icon
    public function add_ready_actions_button_css() {
        ?>
        <style>
            .order-status.status-wc-ready {
                color: #78321f !important;
                background: #bfd471 !important;
            }
        </style>
        <?php
    }

    public function add_customer_ready_order_email( $email_classes ) {
        require_once LCLPC_ADMIN_TEMPLATES_DIR . 'emails/class-wc-ready-for-pickup-email.php';
        $email_classes['WC_Ready_For_Pickup_Email'] = new WC_Ready_For_Pickup_Email();
        return $email_classes;
    }

}

// Initialize the class
new WC_Custom_Order_Status();

class-wc-ready-for-pickup-email.php

<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}


class WC_Ready_For_Pickup_Email extends WC_Email {
    public function __construct() {
        $this->id             = 'wc_ready_for_pickup';
        $this->customer_email = true;
        $this->title          = __( 'Ready for Pick-up', 'lockoloop-customizer' );
        $this->description    = __( 'Ready for Pick-up emails are sent to customers when their orders are marked ready for pick-up.', 'lockoloop-customizer' );
        $this->template_base  = LCLPC_ADMIN_TEMPLATES_DIR;
        $this->template_html  = 'emails/customer-ready-for-pickup.php';
        $this->template_plain = 'emails/plain/customer-ready-for-pickup.php';
        $this->recipient = '{customer_email}';
        $this->placeholders   = array(
            '{order_date}'   => '',
            '{order_number}' => '',
        );

        parent::__construct();

    }


    add_action( 'woocommerce_order_status_ready', array( $this, 'trigger' ), 10, 2 );
    add_action( 'woocommerce_order_status_changed', array( $this, 'taf' ), 10, 2 );

    public function taf() {
        error_log('Taf');
    }

    public function trigger( $order_id, $order = false ) {
        error_log('Yo');
        $this->setup_locale();

        if ( $order_id && ! is_a( $order, 'WC_Order' ) ) {
            $order = wc_get_order( $order_id );
        }

        if ( is_a( $order, 'WC_Order' ) ) {
            $this->object                         = $order;
            $this->recipient                      = $this->object->get_billing_email();
            $this->placeholders['{order_date}']   = wc_format_datetime( $this->object->get_date_created() );
            $this->placeholders['{order_number}'] = $this->object->get_order_number();
        }

        if ( $this->is_enabled() && $this->get_recipient() ) {
            $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
        }

        $this->restore_locale();
    }

    /**
     * Get email subject.
     *
     * @return string
     */
    public function get_default_subject() {
        return __( 'Your {site_title} order is ready for pick-up', 'lockoloop-customizer' );
    }

    /**
     * Get email heading.
     *
     * @return string
     */
    public function get_default_heading() {
        return __( 'Your order is ready for pick-up', 'lockoloop-customizer' );
    }

    /**
     * Get content html.
     *
     * @return string
     */
    public function get_content_html() {
        return wc_get_template_html(
            $this->template_html,
            array(
                'order'              => $this->object,
                'email_heading'      => $this->get_heading(),
                'additional_content' => $this->get_additional_content(),
                'sent_to_admin'      => false,
                'plain_text'         => false,
                'email'              => $this,
            ),
            '',
            $this->template_base
        );
    }

    /**
     * Get content plain.
     *
     * @return string
     */
    public function get_content_plain() {
        return wc_get_template_html(
            $this->template_plain,
            array(
                'order'              => $this->object,
                'email_heading'      => $this->get_heading(),
                'additional_content' => $this->get_additional_content(),
                'sent_to_admin'      => false,
                'plain_text'         => true,
                'email'              => $this,
            ),
            '',
            $this->template_base
        );
    }

    /**
     * Default content to show below main email content.
     *
     * @return string
     */
    public function get_default_additional_content() {
        return __( 'Thanks for shopping with us.', 'woocommerce' );
    }
}

return new WC_Ready_For_Pickup_Email();

2

Answers


  1. Chosen as BEST ANSWER

    So the trick lies in registering the action hook as an email action, and then use the hook with the suffix _notification in the email class:

    class WC_Custom_Order_Status {
            [...]
            add_filter( 'woocommerce_email_actions', array( $this, 'add_email_actions') );
            }
    
    public function add_email_actions( $actions ) {
            $actions[] = 'woocommerce_order_status_ready';
            return $actions;
        }
    

    Then:

    class WC_Ready_For_Pickup_Email extends WC_Email {
            [...]
            add_action( 'woocommerce_order_status_ready_notification', array( $this, 'trigger' ), 10, 2 );
            }
    

  2. I think you are missing one piece. You need to register a new woocommerce_email_actions so that you can then use that to trigger the transactional email.

    For example:

    function so78610089_email_actions( $actions ) {
        $actions[] = 'woocommerce_order_status_ready';
        return $actions;
    }
    add_filter( 'woocommerce_email_actions', 'so78610089_email_actions' );
    

    Then in your ready for pickup email class you’d have the following as the trigger (hook generated/defined here):

    add_action( 'woocommerce_order_status_ready_notification', array( $this, 'trigger' ), 10, 2 );
    

    The thing I am not 100% certain of is if woocommerce_order_status_ready is ever fired or if you need something like woocommerce_order_status_pending_to_ready or woocommerce_order_status_processing_to_ready.

    Oh nevermind, it does look like the former is triggered here but would be fired Every time it’s changed to that and so the _to_ statuses can help refine/limit when the email is triggered.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search