首页 文章

当订单状态更改为自定义订单状态时,从WooCommerce发送电子邮件

提问于
浏览
10

我在我的WooCommerce安装中创建了一个名为Quote的自定义订单状态 .

/* 
* Change order status on new orders depending on order contents:
*  If any product in the order is availble for quote, return 'quote' status. 
*  Otherwise the order status will be set to processing.
*/
add_filter ('woocommerce_payment_complete_order_status', 'change_status_to_quote_if_applicable', 10, 2);
function change_status_to_quote_if_applicable($order_status, $order_id) { 
    $order = new WC_Order($order_id);
    $items = $order->get_items();
    foreach ($items as $item) {
        $product = get_product($item['product_id']);
        if(product_available_for_quote($product)){
            return 'quote';
        }
    }
    return $order_status;
}

现在,我想在收到已收到状态报价的订单时收到一封电子邮件 . 我根据这篇有用的文章创建了一个插件:http://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/

我的插件基本上都是从文章中复制过来的,我刚刚更改了电子邮件的内容 . 我想改变的是触发电子邮件的原因 .

文章中的插件有:

// Trigger on new paid orders
add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_processing_notification',  array( $this, 'trigger' ) );

我希望在订单获得状态“报价”时触发电子邮件 . 我这样做了:

// Trigger on new quote orders
add_action( 'woocommerce_order_status_pending_to_quote', array( $this, 'trigger' ) );

订单获得'quote'状态时没有任何反应 . 我检查了class-wc-order.php,特别是函数 update_status ,因为那是 woocommerce_order_status_.$this->status._to_.$new_status->slug 被触发的地方 . 我做了一个error_log来查看 woocommerce_order_status_pending_to_quote 操作是否存在,确实存在 . 但我的插件中的触发器功能永远不会运行 .

有任何想法吗?我已经尝试了很多不同的钩子,但我似乎无法运行触发器功能 .

非常感谢!

3 回答

  • 0

    我相信你可以使用你的自定义钩子,但首先你必须注册它 . 我有一个与WooThemes挂起的拉取请求,以允许过滤您在核心中发现的电子邮件操作 . 但是,如果/直到它被接受,这就应该如何做:

    /**
     * Register the "woocommerce_order_status_pending_to_quote" hook which is necessary to
     * allow automatic email notifications when the order is changed to refunded.
     * 
     * @modified from http://stackoverflow.com/a/26413223/2078474 to remove anonymous function
     */
    add_action( 'woocommerce_init', 'so_25353766_register_email' );
    function so_25353766_register_email(){
        add_action( 'woocommerce_order_status_pending_to_quote', array( WC(), 'send_transactional_email' ), 10, 10 );
    }
    

    WooCommerce 2.3.11的更新

    有了这个commit WooCommerce确实允许您过滤电子邮件操作 . 因此,理论上,您现在应该能够将操作注册为电子邮件触发器,并具有以下内容:

    /**
     * Register "woocommerce_order_status_pending_to_quote" as an email trigger
     */
    add_filter( 'woocommerce_email_actions', 'so_25353766_filter_actions' );
    function so_25353766_filter_actions( $actions ){
        $actions[] = "woocommerce_order_status_pending_to_quote";
        return $actions;
    }
    
  • 4

    我发现电子邮件操作在 woocommerce.phpinit 函数中定义 .

    // Email Actions
    $email_actions = array(
        'woocommerce_low_stock',
        'woocommerce_no_stock',
        'woocommerce_product_on_backorder',
        'woocommerce_order_status_pending_to_processing',
        'woocommerce_order_status_pending_to_completed',
        'woocommerce_order_status_pending_to_on-hold',
        'woocommerce_order_status_failed_to_processing',
        'woocommerce_order_status_failed_to_completed',
        'woocommerce_order_status_completed',
        'woocommerce_new_customer_note',
        'woocommerce_created_customer'
    );
    

    这就是为什么我的 woocommerce_order_status_pending_to_quote 动作钩子不起作用的原因 .

    我不想对核心woocommerce文件进行更改,所以我最终使用 woocommerce_order_status_pending_to_processing_notification 动作来挂钩我的触发器功能 . 我还更改了我的过滤器,以便订单始终处于待定状态并在我的自定义"quote"状态之前处理 . 我以前的解决方案给了订单"quote"状态而不是"processing",所以我不得不改变它 .

    add_filter ('woocommerce_order_status_pending_to_processing', 'change_status_to_quote_if_applicable', 10, 2);
    function change_status_to_quote_if_applicable($order_id) { 
        $order = new WC_Order($order_id);
        $items = $order->get_items();
        foreach ($items as $item) {
            $product = get_product($item['product_id']);
            if(product_available_for_quote($product)){
                $order->update_status('quote');
            }
        }
    }
    
  • 7

    感谢@helgatheviking现在有一个钩子,但我还要添加一个WC() - > mailer()的调用 . 所以上面的一些代码改为:

    if ( product_available_for_quote( $product ) ){
      $order->update_status('quote');
      // load email classes
      WC()->mailer();
      // send notification email
     do_action( 'woocommerce_order_status_pending_to_quote', $order_id );
      // no need to process any other products
      break;
     }
    

相关问题