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

11

我在我的WooCommerce安装中创建了一个自定义订单状态,称为“报价”。

/* 
* 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' ) );

当订单达到“报价”状态时,没有任何反应。我已经检查了class-wc-order.php文件,特别是函数update_status,因为这里触发了woocommerce_order_status_.$this->status._to_.$new_status->slug。我使用了error_log函数来查看woocommerce_order_status_pending_to_quote操作是否存在,确实存在。但是我的插件中的触发函数从未运行。

有什么想法吗?我尝试了很多不同的钩子,但似乎无法使触发函数运行。

非常感谢!

3个回答

7

我相信你可以使用自定义钩子,但首先你需要注册它。我已经向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 https://dev59.com/OILba4cB1Zd3GeqPkuRm#26413223 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+

通过这个提交,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.php 文件中的 init 函数中定义的。
// 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动作来挂载我的触发功能。我还更改了我的过滤器,以便订单始终在自定义“报价”状态之前获得“待处理”和“处理中”的状态。我的原始解决方案给订单分配了“报价”状态,而不��“处理中”,所以我必须进行更改。
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');
        }
    }
}

我已经添加了一个答案,所以代码被正确格式化了。 - Gabriel Reguly

0
感谢@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;
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接