WooCommerce:仅显示指定库存状态的多属性可用变体
WooCommerce 按指定有库存变体筛选产品解决方案
原代码问题分析
- 直接针对主产品(可变产品)的元数据进行筛选,但主产品的元数据并不存储变体的属性和库存信息,无法实现精准匹配
- 使用
_variation_description字段匹配尺寸参数,不符合WooCommerce变体属性的存储逻辑——变体的尺寸属性值实际存储在attribute_{属性slug}格式的元字段中(如attribute_pa_size、attribute_pa_0_one_size等) - 逻辑关系使用
OR,导致筛选条件失效,无法确保筛选出「存在指定尺寸且有库存的变体」的主产品
解决方案代码
/** * 按指定尺寸且有库存的变体筛选产品 */ function vm_woocommerce_product_query( $q, $instance ) { // 仅在前台产品主查询、且filter_size参数存在时执行 if ( ! is_admin() && isset( $_GET['filter_size'] ) && $q->is_main_query() ) { $filter_size = sanitize_text_field( $_GET['filter_size'] ); global $wpdb; // 构建元查询:筛选存在符合条件变体的可变产品 $q->set( 'meta_query', array( array( 'relation' => 'AND', // 限定主产品为可变产品类型 array( 'key' => '_product_type', 'value' => 'variable', 'compare' => '=' ), // 子查询:获取所有包含指定尺寸且有库存变体的父产品ID array( 'key' => 'ID', 'value' => $wpdb->prepare( "SELECT post_parent FROM {$wpdb->posts} p JOIN {$wpdb->postmeta} pm_attr ON p.ID = pm_attr.post_id JOIN {$wpdb->postmeta} pm_stock ON p.ID = pm_stock.post_id WHERE p.post_type = 'product_variation' AND pm_attr.meta_key IN ('attribute_pa_size', 'attribute_pa_0_one_size', 'attribute_pa_1_36_t_m_42_eu', 'attribute_pa_3_36_t_m_42_us', 'attribute_pa_4_39_t_m_48_us') AND pm_attr.meta_value = %s AND pm_stock.meta_key = '_stock_status' AND pm_stock.meta_value = 'instock'", $filter_size ), 'compare' => 'IN' ) ) ) ); } } add_action( 'woocommerce_product_query', 'vm_woocommerce_product_query', 10, 2 );
代码说明
- 执行条件限制:仅在前台的产品主查询中生效,避免影响后台操作
- 可变产品限定:先筛选出类型为
variable的主产品,排除简单产品等无需变体的类型 - 子查询逻辑:
- 关联变体帖子表(
product_variation类型)和元数据表 - 匹配所有可能的尺寸属性字段(你提供的
pa_*系列属性),确保参数值能匹配到对应变体 - 同时验证变体的库存状态为
instock - 最终返回所有符合条件的变体的父产品ID,主查询只保留这些ID的产品
- 关联变体帖子表(
- 安全处理:使用
$wpdb->prepare对URL参数进行转义,防止SQL注入风险
内容的提问来源于stack exchange,提问作者Jari Rengeling
相关产品推荐
相关产品推荐

