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
相关产品推荐
相关产品推荐

