woocommerce_order_status_completed 挂钩:在操作之后强制发送电子邮件(而不是之前)

woocommerce_order_status_completed hook: force email AFTER action (instead of before)

我写了一个附加到 woocommerce_order_status_completed 的操作,它工作正常,向订单添加了一些元数据。但是订单完成后发出的电子邮件似乎在 运行s 之前发出,因此不会发送有问题的元数据(如果我再次 运行 完成的订单它会发送,但是那是因为此数据现在已经在数据库中)。所以我正在寻找的是:

有什么想法或建议吗?我查看了 Woocommerce API 参考资料,但找不到任何适合的内容。

更新: 找到了一个较早的钩子并尝试将其连接到

add_action( 'woocommerce_order_status_completed_notification','mysite_woocommerce_order_status_completed',5,1 );

应该 运行 更快,但电子邮件仍然先发出(在元数据进入数据库并可以读取之前。如果我 "recomplete" 订单(将其重新处理状态然后再次完成),它将发送元数据(同样,这是因为它现在在数据库中)

经过多次纠缠,我想出了一个看起来有点丑陋的解决方法,但希望它能帮助其他人。

  1. 我验证了我的挂钩在主邮件之前是正确的 运行。 (使用 add_action( 'woocommerce_order_status_completed_notification','mysite_woocommerce_order_status_completed',5,1 ); )
  2. 我确认我的元数据在电子邮件发出前已正确插入数据库

不幸的是,它仍然拒绝在第一次发送时获取我的元数据。所以我做了以下事情:

我将 woocommerce/templates/emails/email-order-items.php 模板复制到我的主题中并进行了以下更改:

// Variation
if ( ! empty( $item_meta->meta ) ) {
echo '<br/><small>' . nl2br( $item_meta->display( true, true, '_', "\n" ) ) . '</small>';

  // following 5 lines are MY extra code (checking for my meta field 'signup_code')
  if (!array_key_exists('signup_code',$item_meta->meta)) {
  $suc = wc_get_order_item_meta( $item_id, 'signup_code' );
  if ($suc) {
  echo '<br/><small>signup_code: ' . $suc . '</small>';
  }}
}

它将检查元数组中的重复项,如果它已经存在则不输出。它需要这样做以防止它显示两次(否则它会在第二次发送时显示)。我无法相信这是所有必要的,但我找不到任何其他可以解决这个问题的指针。

更新: 这显然是由 woo 内部缓存问题引起的。我在这里与其中一位求爱者进行了长时间的讨论:

https://wordpress.org/support/topic/hook-an-action-before-transactional-woocommerce-emails-are-triggeredsent-out/page/2?replies=40#post-8379725

结果是,它将在未来的版本中修复,但您可以在此处查看更改:

https://github.com/woothemes/woocommerce/commit/3db3f3796eb28fb79983f605a5a70d61ca114c6d