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

WooCommerce可变产品库存与尺码过滤异常问题求助

WooCommerce 筛选属性时仅显示对应属性有库存产品的解决方案

问题背景

在WooCommerce中同时筛选「有库存」和产品属性(如尺码L)时,默认逻辑仅检查产品是否包含该属性的变体,不验证该变体是否有库存,导致筛选属性后产品列表无变化。现有代码仅隐藏缺货变体,但无法实现"筛选属性时仅显示该属性有库存的产品"的需求,同时需保留缺货产品的自然搜索可见性。

解决方案代码

以下代码会修改产品查询逻辑,仅在存在属性筛选时,过滤出包含对应属性且该属性变体有库存的产品;无属性筛选时,保持原有逻辑,缺货产品仍可被搜索到:

// 保留原有隐藏缺货变体的逻辑
function check_variation_is_active( $active, $variation ) {
    if ( ! $variation->is_in_stock() ) {
        return false;
    }
    return $active;
}
add_filter( 'woocommerce_variation_is_active','check_variation_is_active', 10, 2 );

// 修改产品查询,实现属性+库存联合筛选
function filter_product_query_for_in_stock_variations( $query ) {
    if ( ! is_admin() && $query->is_main_query() && ( is_post_type_archive( 'product' ) || is_tax( array_filter( get_object_taxonomies( 'product' ), function( $tax ) {
        return str_starts_with( $tax, 'pa_' );
    } ) ) ) ) {
        
        $tax_query = $query->get( 'tax_query' );
        $has_product_attribute = false;
        $target_taxonomy = '';
        $target_terms = array();
        
        // 检查是否存在产品属性筛选(pa_开头的分类)
        if ( is_array( $tax_query ) ) {
            foreach ( $tax_query as $group ) {
                if ( isset( $group['taxonomy'] ) && str_starts_with( $group['taxonomy'], 'pa_' ) ) {
                    $has_product_attribute = true;
                    $target_taxonomy = $group['taxonomy'];
                    $target_terms = $group['terms'];
                    break;
                }
            }
        }
        
        if ( $has_product_attribute ) {
            global $wpdb;
            
            // 关联变体表,筛选出有对应属性且库存可用的变体的父产品ID
            $parent_product_ids = $wpdb->get_col( $wpdb->prepare( "
                SELECT DISTINCT p.post_parent
                FROM {$wpdb->posts} p
                INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
                INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
                INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
                WHERE p.post_type = 'product_variation'
                AND pm.meta_key = '_stock_status'
                AND pm.meta_value = 'instock'
                AND tt.taxonomy = %s
                AND tt.term_id IN (" . implode( ',', array_fill( 0, count( $target_terms ), '%d' ) ) . ")
            ", array_merge( array( $target_taxonomy ), $target_terms ) ) );
            
            // 限制查询仅返回这些父产品
            if ( ! empty( $parent_product_ids ) ) {
                $query->set( 'post__in', $parent_product_ids );
            } else {
                // 如果没有符合条件的产品,返回空结果
                $query->set( 'post__in', array( 0 ) );
            }
        }
    }
}
add_action( 'pre_get_posts', 'filter_product_query_for_in_stock_variations' );

代码说明

  1. 原有逻辑保留:继续使用check_variation_is_active函数隐藏缺货的变体选项,避免用户选择不可用的变体。
  2. 查询修改逻辑:
    • 通过pre_get_posts钩子拦截产品查询,仅在前台产品归档页或属性分类页生效。
    • 自动检测是否存在产品属性筛选(如尺码、颜色等,以pa_开头的自定义属性)。
    • 通过数据库查询,获取所有包含对应属性且该属性变体处于「有库存」状态的父产品ID。
    • 将查询结果限制为这些父产品,实现"筛选属性时仅显示该属性有库存的产品"的需求。
  3. 兼容自然搜索:当没有属性筛选时,查询逻辑不改变,缺货产品依然可以被自然搜索到,保留原有流量。

使用注意事项

  • 将代码添加到当前主题的functions.php文件,或自定义功能插件中。
  • 代码会自动识别所有以pa_开头的产品属性,无需手动修改属性标识。
  • 测试前请清空网站缓存,确保查询逻辑生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:27:04