本文介绍如何修改 woocommerce 评论统计图表代码,使其仅统计当前 wpml 激活语言下的商品评论,避免跨语言混计,核心在于用 `wp_comment_query` 替代原始 sql 查询并自动集成 wp

在使用 WPML 构建多语言 WooCommerce 站点时,一个常见痛点是:默认的评论统计逻辑(如星级分布直方图)会汇总全站所有语言的商品评论,导致当前语言页面显示的数据失真。例如,英文页面可能错误地包含大量中文或西班牙语评论的评分数据。
问题根源在于原始代码中硬编码的 SQL 查询:
$review_ratings = $wpdb->get_results("
SELECT meta_value
FROM {$wpdb->prefix}commentmeta as commentmeta
JOIN {$wpdb->prefix}comments as comments ON comments.comment_id = commentmeta.comment_id
WHERE commentmeta.meta_key = 'rating' AND comments.comment_approved = 1
ORDER BY commentmeta.meta_value
", ARRAY_A);该查询绕过了 WordPress 的评论查询机制,完全忽略 WPML 的语言过滤逻辑(如 wpml_language 元数据、wpml_translations 表关联等),因此无法感知当前活动语言。
✅ 正确解法:改用 WP_Comment_Query 并配合 WPML 标准实践
WP_Comment_Query 是 WordPress 原生、可扩展且与多语言插件(包括 WPML)深度兼容的评论查询接口。WPML 会在其钩子中自动为 WP_Comment_Query 注入语言上下文(例如通过 'language' => ICL_LANGUAGE_CODE 过滤),前提是查询未显式禁用该行为。
以下是推荐的重构版 get_all_product_review_ratings() 函数:
function get_all_product_review_ratings() {
global $wpdb;
// 使用带语言标识的 transient key,避免不同语言共用缓存
$lang_code = defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : 'all';
$transient_key = 'all_product_review_ratings_' . $lang_code;
if (false === ($review_ratings = get_transient($transient_key))) {
$args = array(
'status' => 'approve', // 只取已审核评论
'type' => 'review', // 限定为 product review 类型
'number' => 0, // 获取全部(无分页)
'meta_query' => array(
array(
'key' => 'rating',
'compare' => 'EXISTS'
)
),
// ✅ 关键:不手动指定 language,交由 WPML 自动处理
// WPML 会通过 'wpml_language' meta 或关联逻辑自动过滤当前语言评论
);
$comments_query = new WP_Comment_Query();
$comments = $comments_query->query($args);
$review_ratings = array();
foreach ($comments as $comment) {
$rating = get_comment_meta($comment->comment_ID, 'rating', true);
if (is_numeric($rating)) {
$review_ratings[] = array('meta_value' => $rating);
}
}
// 缓存按语言隔离,5 分钟过期
set_transient($transient_key, $review_ratings, 5 * MINUTE_IN_SECONDS);
}
return $review_ratings;
}? 关键优化说明:
⚠️ 注意事项:
完成上述修改后,display_all_product_review_histogram() 及其依赖函数将自动按当前 WPML 语言环境输出精准的星级分布图表——真正实现“所见即所得”的多语言评论可视化。