自定义代码致WooCommerce设置邮件标签崩溃的原因与修复
WooCommerce新订单邮件自定义代码引发的致命错误解决
问题描述
我使用以下自定义代码控制WooCommerce新订单邮件的收件人,代码在订单提交时功能正常,但提交首单后访问「WooCommerce > 设置」的「邮件」标签时,网站会触发致命错误:
add_filter( 'woocommerce_email_recipient_new_order', 'custom_wc_email_recipient_new_order', 10, 2 ); function custom_wc_email_recipient_new_order( $recipient, $order ) { // 获取订单创建者的用户ID $user_id = $order->get_user_id(); // 获取用户角色 $user = get_userdata( $user_id ); $user_role = $user->roles[0]; // 仅当用户是指定角色时,给管理员邮箱抄送新订单邮件 if ( $user_role == 'role1' ) { return $recipient .= ', admin@website.com'; } // 其他角色返回原收件人 return $recipient; }
错误日志显示数据库查询异常,核心报错示例:
[20-Dec-2022 17:12:00 UTC] WordPress database error Unknown column 'wp_postmeta.post_id' in 'where clause' for query SELECT meta_id FROM wp_8hkq051x71_postmeta, (SELECT DISTINCT post_id FROM wp_8hkq051x71_postmeta WHERE (meta_key = '_billing_country' OR meta_key='_shipping_country') AND meta_value='UA') AS states_in_country WHERE (meta_key='_billing_state' OR meta_key='_shipping_state') AND meta_value='CV' AND wp_postmeta.post_id = states_in_country.post_id LIMIT 100 made by do_action_ref_array('action_scheduler_run_queue'), WP_Hook->do_action, WP_Hook->apply_filters, ActionScheduler_QueueRunner->run, ActionScheduler_QueueRunner->do_batch, ActionScheduler_Abstract_QueueRunner->process_action, ActionScheduler_Action->execute, do_action_ref_array('woocommerce_run_update_callback'), WP_Hook->do_action, WP_Hook->apply_filters, WC_Install::run_update_callback, wc_update_721_adjust_ukraine_states, Automattic\WooCommerce\Database\Migrations\MigrationHelper::migrate_country_states, Automattic\WooCommerce\Database\Migrations\MigrationHelper::migrate_country_states_for_orders
类似日志中meta_value的值会变化为CH、CK、KS等。
错误原因
- WooCommerce官方Bug:报错来自WooCommerce 7.2.1版本的乌克兰州数据迁移脚本,查询语句未给主表指定别名,导致引用
wp_postmeta.post_id时找不到对应列,属于官方数据库迁移逻辑漏洞。 - 自定义代码逻辑缺陷:原代码未判断
$order对象是否有效,访问邮件设置页面时,WooCommerce会调用该过滤器但不会传入有效订单对象,直接执行$order->get_user_id()会触发致命错误。
修复方案
- 修复官方Bug:将WooCommerce更新至7.2.2及以上版本,官方已在后续版本中修复了该数据库迁移问题。
- 调整自定义代码:增加
$order对象的有效性判断,避免无有效订单时执行对象方法,修改后的代码如下:
add_filter( 'woocommerce_email_recipient_new_order', 'custom_wc_email_recipient_new_order', 10, 2 ); function custom_wc_email_recipient_new_order( $recipient, $order ) { if ( $order ) { // 获取订单创建者的用户ID $user_id = $order->get_user_id(); // 获取用户角色 $user = get_userdata( $user_id ); $user_role = $user->roles[0]; // 仅当用户是指定角色时,给管理员邮箱抄送新订单邮件 if ( $user_role == 'role1' ) { return $recipient .= ', admin@website.com'; } // 其他角色返回原收件人 return $recipient; } return $recipient; }
这段代码会在$order对象存在时才执行角色判断逻辑,既保证邮件设置页面正常加载,又保留原有的收件人控制功能。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

