基于下单语言发送WooCommerce邮件通知的问题求助
问题场景
使用Polylang实现WooCommerce邮件按订单下单语言发送,但当前邮件会以触发邮件的用户(管理员、店铺经理)的语言发送。已确认map_language_to_locale()和get_locale_from_order_id()功能正常,问题出在set_email_locale_based_on_order()中$order_id = $email->object->id;的取值逻辑,手动指定$locale = 'pt_BR';时邮件可正常按目标语言发送。
问题原因
$email->object并非在所有邮件场景下都是标准的WC_Order对象,部分邮件类型的object可能缺少id属性,或者object本身不是订单实例,导致无法正确获取订单ID,最终$locale为空,语言切换失效。
修正方案
通过以下方式确保正确获取订单ID:
- 先验证
$email->object是否为WC_Order实例 - 若不是,尝试从邮件的
order_id属性直接获取 - 最后用
wc_get_order()验证订单的有效性,避免无效ID导致的错误
修正后的代码如下:
<?php add_filter('woocommerce_allow_switching_email_locale', 'set_email_locale_based_on_order', 10, 2); add_action('woocommerce_email_footer', 'restore_email_locale', 10, 1); function map_language_to_locale($language_slug) { $mapping = array( 'de' => 'de_DE', 'en' => 'en_US', 'pt' => 'pt_BR', ); return isset($mapping[$language_slug]) ? $mapping[$language_slug] : false; } function get_locale_from_order_id($order_id) { if (function_exists('pll_get_post_language')) { $order_language = pll_get_post_language($order_id, 'slug'); return map_language_to_locale($order_language); } return null; } function set_email_locale_based_on_order($email_locale, $email) { $order_id = null; // 优先从WC_Order对象获取ID if ($email->object instanceof WC_Order) { $order_id = $email->object->get_id(); // 使用WC_Order的标准方法get_id()替代直接取id属性 } // 尝试从邮件的order_id属性获取 elseif (isset($email->order_id)) { $order_id = $email->order_id; } // 验证订单ID有效性 if ($order_id && wc_get_order($order_id)) { $locale = get_locale_from_order_id($order_id); if ($locale) { switch_to_locale($locale); error_log("Switched to locale: " . $locale); add_filter('plugin_locale', fn () => $locale); } } return $email_locale; } function restore_email_locale() { restore_previous_locale(); } ?>
关键改进点
- 使用
$email->object instanceof WC_Order严格判断对象类型,避免非订单对象导致的错误 - 调用WC_Order的标准方法
get_id()替代直接访问id属性,符合WooCommerce开发规范 - 添加订单ID有效性验证,确保仅对有效订单执行语言切换
- 增加
$locale非空判断,避免无效的语言切换操作
内容的提问来源于stack exchange,提问作者roboes
相关产品推荐
相关产品推荐

