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

WooCommerce后台订单页自定义产品筛选下拉框筛选后消失问题

问题原因

问题出在pre_get_posts钩子的作用范围上——这个钩子会影响所有WP_Query查询,包括你用来获取产品列表的get_posts()调用。当执行订单筛选时,你的代码给查询设置了post__in = 订单ID数组,这会导致后续获取产品的查询也被强制使用这个post__in条件,自然查不到任何产品,下拉框也就消失了。

修复方案

有两种可靠的修复方式,任选其一即可:

方案1:限制pre_get_posts只修改主查询

修改筛选逻辑的函数,确保只对订单列表的主查询生效,不影响获取产品的次级查询:

function filter_orders_by_my_product($query) {
    global $pagenow, $typenow, $wpdb;

    // 增加判断:只针对订单页面的主查询生效
    if (
        $pagenow !== 'edit.php' ||
        $typenow !== 'shop_order' ||
        empty($_GET['my_product_filter']) ||
        !$query->is_main_query() || // 关键:只处理主查询
        $query->get('post_type') !== 'shop_order' // 额外确保查询对象是订单
    ) {
        return;
    }

    $product_id = intval($_GET['my_product_filter']);

    $order_ids = $wpdb->get_col($wpdb->prepare("
        SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items oi
        JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
        WHERE oim.meta_key = '_product_id' AND oim.meta_value = %d
    ", $product_id));

    if (!empty($order_ids)) {
        $query->query_vars['post__in'] = $order_ids;
    } else {
        $query->query_vars['post__in'] = array(0);
    }
}
add_action('pre_get_posts', 'filter_orders_by_my_product');

方案2:让产品查询跳过过滤器

在获取产品列表的get_posts()参数中添加suppress_filters => true,强制该查询不被pre_get_posts钩子干扰:

function add_my_product_filter_to_orders() {
    global $typenow;

    if ($typenow !== 'shop_order') return;

    if (!current_user_can('administrator')) { return; }

    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'tax_query'      => array(
            array(
                'taxonomy' => 'product_cat',
                'field'    => 'slug',
                'terms'    => 'test',
            ),
        ),
        'suppress_filters' => true, // 关键:禁止应用任何过滤器
    );

    $products = get_posts($args);
    if (!$products) return;

    $selected_product = isset($_GET['my_product_filter']) ? esc_attr($_GET['my_product_filter']) : '';

    echo '<select name="my_product_filter">';
    echo '<option value="">filter by product</option>';
    
    foreach ($products as $product) {
        echo '<option value="' . $product->ID . '" ' . selected($selected_product, $product->ID, false) . '>' . get_the_title($product->ID) . '</option>';
    }

    echo '</select>';
}
add_action('restrict_manage_posts', 'add_my_product_filter_to_orders', 25);
验证效果

修改后执行筛选操作,下拉框会保持显示,且$products = get_posts($args)能正常返回产品列表,筛选功能也能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:28:12