You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce品牌筛选插件异常:筛选结果不符问题求助

WooCommerce品牌筛选异常的修复方案

核心问题分析

  • 表单参数与查询参数不匹配:表单中品牌选择框的name属性是filter_brand,但查询时错误使用$_GET['brand']接收值,导致无法获取正确的筛选条件。
  • 分类法名称错误:注册的自定义分类法是brand,但查询时误用了WooCommerce产品属性前缀pa_brand,导致筛选目标分类错误。
  • 条件判断逻辑漏洞:原代码中is_admin()与后续页面判断的逻辑优先级错误,可能导致非商品页面也执行筛选逻辑,干扰正常查询。

修复后的完整代码

<?php
/*
Plugin Name: My WooCommerce Filter Plugin
Description: A simple product filter plugin for WooCommerce, including filters for price, brand, and color.
Version: 1.0
Author: Your Name
*/

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

/**
 * Register Custom Taxonomies for Brand and Color
 */
add_action('init', 'register_custom_taxonomies_for_products');
function register_custom_taxonomies_for_products() 
{
    // Brand taxonomy
    $labels = array(
        'name'                       => _x('Brands', 'Taxonomy General Name', 'text_domain'),
        'singular_name'              => _x('Brand', 'Taxonomy Singular Name', 'text_domain'),
        // Further labels omitted for brevity
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
    );
    register_taxonomy('brand', array('product'), $args);

    // Color taxonomy
    $labels = array(
        'name'                       => _x('Colors', 'Taxonomy General Name', 'text_domain'),
        'singular_name'              => _x('Color', 'Taxonomy Singular Name', 'text_domain'),
        // Further labels omitted for brevity
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => false,
        'public'                     => true,
        'show_ui'                    => true,
    );
    register_taxonomy('color', array('product'), $args);
}

/**
 * Display the filter form.
 */
add_action('woocommerce_before_shop_loop', 'my_wc_filter_form', 10);
function my_wc_filter_form() {
    $brands = get_terms(['taxonomy' => 'brand', 'hide_empty' => true]);
    $colors = get_terms(['taxonomy' => 'color', 'hide_empty' => true]);
    ?>
    <form role="filter" method="get" class="woocommerce-product-filter" action="<?php echo esc_url(home_url('/shop/')); ?>">
        <!-- Price Filter -->
        <input type="number" name="min_price" placeholder="Min price" style="width: 100px;" value="<?php echo isset($_GET['min_price']) ? esc_attr($_GET['min_price']) : ''; ?>">
        <input type="number" name="max_price" placeholder="Max price" style="width: 100px;" value="<?php echo isset($_GET['max_price']) ? esc_attr($_GET['max_price']) : ''; ?>">

        <!-- Brand Filter -->
        <select name="filter_brand">
            <option value="">Select a Brand</option>
            <?php foreach ($brands as $brand): ?>
                <option value="<?php echo esc_attr($brand->slug); ?>" <?php echo isset($_GET['filter_brand']) && $_GET['filter_brand'] === $brand->slug ? 'selected' : ''; ?>><?php echo esc_html($brand->name); ?></option>
            <?php endforeach; ?>
        </select>

        <!-- Color Filter -->
        <select name="filter_color">
            <option value="">Select a Color</option>
            <?php foreach ($colors as $color): ?>
                <option value="<?php echo esc_attr($color->slug); ?>" <?php echo isset($_GET['filter_color']) && $_GET['filter_color'] === $color->slug ? 'selected' : ''; ?>><?php echo esc_html($color->name); ?></option>
            <?php endforeach; ?>
        </select>

        <!-- 保留原有查询参数,避免筛选后丢失分页等信息 -->
        <?php
        foreach ($_GET as $key => $value) {
            if (!in_array($key, ['min_price', 'max_price', 'filter_brand', 'filter_color', 'paged'])) {
                echo '<input type="hidden" name="' . esc_attr($key) . '" value="' . esc_attr($value) . '">';
            }
        }
        ?>

        <button type="submit">Apply Filters</button>
    </form>
    <?php
}

/**
 * Adjust the product query based on filters.
 */
add_action( 'woocommerce_product_query', 'custom_product_query' );
function custom_product_query( $query ) {
    // 修正条件判断,确保仅在前台商品相关页面执行筛选
    if ( ! is_admin() && ( is_shop() || is_product_category() || is_product_taxonomy() ) ) {
        // 获取对应表单参数
        $brand = isset($_GET['filter_brand']) ? sanitize_text_field($_GET['filter_brand']) : '';
        $color = isset($_GET['filter_color']) ? sanitize_text_field($_GET['filter_color']) : '';
        $min_price = isset($_GET['min_price']) ? floatval($_GET['min_price']) : 0;
        $max_price = isset($_GET['max_price']) ? floatval($_GET['max_price']) : PHP_INT_MAX;

        $tax_query = $query->get('tax_query') ?: [];
        $meta_query = $query->get('meta_query') ?: [];

        // 品牌筛选:使用正确的自定义分类法名称
        if ( $brand ) {
            $tax_query[] = [
                'taxonomy' => 'brand',
                'field' => 'slug',
                'terms' => $brand
            ];
        }

        // 颜色筛选逻辑
        if ( $color ) {
            $tax_query[] = [
                'taxonomy' => 'color',
                'field' => 'slug',
                'terms' => $color
            ];
        }

        // 价格筛选逻辑
        if ( $min_price > 0 || $max_price < PHP_INT_MAX ) {
            $meta_query[] = [
                'key' => '_price',
                'value' => [$min_price, $max_price],
                'type' => 'numeric',
                'compare' => 'BETWEEN'
            ];
        }

        // 更新查询参数
        if ( !empty($tax_query) ) {
            $query->set('tax_query', $tax_query);
        }
        if ( !empty($meta_query) ) {
            $query->set('meta_query', $meta_query);
        }
    }
}

额外优化说明

  • 给筛选控件添加了回显值逻辑,提交后保持用户选择状态,提升体验。
  • 保留了分页等原有查询参数,避免筛选后页面状态丢失。
  • 补充了颜色和价格的完整筛选逻辑,让插件功能更完善。

内容的提问来源于stack exchange,提问作者maztt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:44:52