woocommerce_order_item_meta_start钩子如何仅在订单完成邮件生效
问题原因
你之前的修改失效核心有两点:
woocommerce_order_item_meta_start钩子在邮件场景下会传递4个参数,你原来的add_action只声明接收3个参数,函数内部无法获取到$email邮件实例对象,直接调用未定义的$email变量会触发PHP错误,导致逻辑完全不执行。- 条件判断没有做非目标场景的提前拦截,多层嵌套下变量不存在时会直接中断运行。
正确实现代码
将原有代码替换为以下版本即可,核心调整是修改钩子接收的参数数量,拿到$email实例后做精准场景判断:
// 最后一个参数设置为4,声明接收钩子传递的全部4个参数 add_action( 'woocommerce_order_item_meta_start', 'email_confirmation_display_order_items', 10, 4 ); function email_confirmation_display_order_items( $item_id, $item, $order, $email ) { // 非订单完成客户通知邮件直接退出,不输出内容 if ( $email->id !== 'customer_completed_order' ) { return; } // 仅在邮件场景下处理商品行 if ( ! is_wc_endpoint_url() && $item->is_type('line_item') ) { $ot_address = get_post_meta( $item->get_product_id(), 'ot_address', true ); if ( ! empty($ot_address) ) { printf( '<div>' . __("Terms: %s", "woocommerce") . '</div>', $ot_address ); } } }
扩展说明
- 如果你需要同时在管理员的新订单通知邮件中展示该内容,只需要把邮件ID判断改为
if ( ! in_array( $email->id, ['customer_completed_order', 'new_order'] ) ) return;即可 - 采用提前return的写法替代多层if嵌套,代码可读性更高,也能避免不必要的逻辑执行
内容的提问来源于stack exchange,提问作者Bára Vlášková
相关产品推荐
相关产品推荐

