在WooCommerce商品搜索中启用product_tag与自定义分类book_author
WooCommerce商品搜索扩展至分类与标签的问题修复
问题描述
需要修改WooCommerce前端商品搜索,使其支持在商品名称、描述、product_tag标签和自定义分类book_author中检索。当前实现仅能匹配名称和描述,搜索标签或作者名称时结果不准确——例如搜索"murphy"仅返回2个商品,但对应作者归档页实际有5本关联书籍。
原实现代码(添加至主题functions.php):
add_filter('posts_search', 'woocommerce_search_product_tag_extended', 999, 2); function woocommerce_search_product_tag_extended($search, $query) { global $wpdb, $wp; $qvars = $wp->query_vars; if (is_admin() || empty($search) || !(isset($qvars['s']) && isset($qvars['post_type']) && !empty($qvars['s']) && $qvars['post_type'] === 'product')) { return $search; } $taxonomies = array('product_tag', 'book_author'); $tax_query = array('relation' => 'OR'); foreach($taxonomies as $taxonomy) { $tax_query[] = array( 'taxonomy' => $taxonomy, 'field' => 'name', 'terms' => esc_attr($qvars['s']), ); } $ids = get_posts(array( 'posts_per_page' => -1, 'post_type' => 'product', 'post_status' => 'publish', 'fields' => 'ids', 'tax_query' => $tax_query, )); if (sizeof($ids) > 0) { $search = str_replace('AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode( ',', $ids ) . ")) OR (", $search); } return $search; }
问题原因
原代码使用get_posts的tax_query时,terms参数默认是精确匹配分类名称,无法实现模糊匹配(比如无法通过"murphy"匹配"Abigail Murphy")。只有分类名称完全等于搜索词的商品才会被筛选,导致结果不全。
修复方案
直接通过SQL关联分类表实现模糊匹配,替换原代码为:
add_filter('posts_search', 'woocommerce_extend_search_to_taxonomies', 999, 2); function woocommerce_extend_search_to_taxonomies($search, $query) { global $wpdb; // 仅处理前端商品搜索请求 if (is_admin() || !$query->is_search() || $query->get('post_type') !== 'product' || empty($query->get('s'))) { return $search; } $search_term = $wpdb->esc_like($query->get('s')); $taxonomies = array('product_tag', 'book_author'); // 关联分类表,模糊匹配分类名称获取商品ID $tax_ids = $wpdb->get_col($wpdb->prepare(" SELECT DISTINCT tr.object_id FROM {$wpdb->term_relationships} tr JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id JOIN {$wpdb->terms} t ON tt.term_id = t.term_id WHERE tt.taxonomy IN ('" . implode("','", array_map('esc_sql', $taxonomies)) . "') AND t.name LIKE %s ", "%{$search_term}%")); if (!empty($tax_ids)) { // 将分类匹配的商品ID合并到原搜索条件中 $search = str_replace( 'AND (((', "AND ((({$wpdb->posts}.ID IN (" . implode(',', $tax_ids) . ")) OR (", $search ); } return $search; }
代码说明
- 模糊匹配处理:使用
$wpdb->esc_like安全处理搜索词,支持%通配符实现部分匹配。 - 分类表关联:通过JOIN WordPress核心分类表,直接查询所有匹配分类名称的商品ID,避免
tax_query的精确匹配限制。 - 条件合并:将分类匹配的商品ID作为OR条件加入原搜索逻辑,保留原有名称/描述搜索的同时,扩展至分类和标签维度。
内容的提问来源于stack exchange,提问作者Rob Tyrrell
相关产品推荐
相关产品推荐

