WooCommerce:如何按产品自定义分类法season筛选后台订单列表
问题原因
你现有的代码仅实现了后台订单列表筛选下拉框的渲染,没有添加对应的查询过滤逻辑,因此筛选参数提交后不会生效。
订单本身不直接关联产品的season自定义分类法,需要先匹配对应季节的产品,再查询包含这些产品的订单,最终将符合条件的订单ID注入到后台订单查询逻辑中。
完整可用代码
将原有代码替换为以下内容即可:
// 获取season分类法下的所有选项 function get_season_terms(){ $taxonomy = 'season'; $options = array(); foreach ( get_terms( array('taxonomy' => 'season', 'hide_empty' => true ) ) as $term ) { $options[$term->slug] = $term->name; } return $options; } // 在后台订单列表添加季节筛选下拉框 add_action( 'restrict_manage_posts', 'display_admin_shop_order_by_season_filter' ); function display_admin_shop_order_by_season_filter(){ global $pagenow, $typenow; if( 'shop_order' === $typenow && 'edit.php' === $pagenow ) { $domain = 'woocommerce'; $filter_id = 'by_season'; $current = isset($_GET[$filter_id])? $_GET[$filter_id] : ''; echo '<select name="'.$filter_id.'"> <option value="">' . __('Filter by Season…', $domain) . '</option>'; $options = get_season_terms(); foreach ( $options as $key => $label ) { printf( '<option value="%s"%s>%s</option>', $key, $key === $current ? ' selected="selected"' : '', $label ); } echo '</select>'; } } // 处理季节筛选的查询逻辑 add_action( 'pre_get_posts', 'filter_orders_by_season' ); function filter_orders_by_season( $query ) { global $pagenow, $typenow, $wpdb; // 仅在后台订单列表主查询触发 if ( 'shop_order' === $typenow && 'edit.php' === $pagenow && $query->is_main_query() && isset($_GET['by_season']) && !empty($_GET['by_season']) ) { $season_slug = sanitize_text_field($_GET['by_season']); // 第一步:查询所有属于当前季节的产品ID $product_ids = get_posts( array( 'post_type' => 'product', 'posts_per_page' => -1, 'post_status' => 'publish', 'fields' => 'ids', 'tax_query' => array( array( 'taxonomy' => 'season', 'field' => 'slug', 'terms' => $season_slug, ) ) ) ); if ( empty($product_ids) ) { // 没有对应季节的产品时不显示任何订单 $query->set( 'post__in', array(0) ); return; } // 第二步:查询所有包含以上产品的订单ID $order_ids = $wpdb->get_col( $wpdb->prepare( " SELECT DISTINCT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id IN ( SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE meta_key = '_product_id' AND meta_value IN (".implode(',', array_map('intval', $product_ids)).") ) " ) ); // 第三步:将符合条件的订单ID注入查询 if ( !empty($order_ids) ) { $query->set( 'post__in', $order_ids ); } else { $query->set( 'post__in', array(0) ); } } }
注意事项
- 如果站点有产品变体,且变体单独设置了season分类,需要自行调整产品ID查询逻辑,将变体ID也纳入查询范围
- 订单量极大的站点可酌情添加查询缓存,减少数据库查询压力
内容的提问来源于stack exchange,提问作者user3796291
相关产品推荐
相关产品推荐

