修改WordPress主查询:限制特定客户仅查看指定WooCommerce产品
解决WooCommerce特定客户仅查看指定产品的查询问题
问题分析
你在pre_get_posts钩子中设置的post__in参数被fill_query_vars重置,核心原因是WooCommerce在产品分类页面会基于当前分类重新处理查询参数,覆盖了自定义的post__in设置。
解决方案
通过提高钩子优先级、结合分类筛选与产品ID限制、处理边界情况,确保查询修改生效:
完整代码实现
add_action( 'pre_get_posts', 'customprefix_pre_get_posts', 99 ); function customprefix_pre_get_posts( $query ) { // 仅处理前台主查询、产品分类页面,且用户已登录 if ( !is_admin() && $query->is_main_query() && is_product_category() && is_user_logged_in() ) { $user = wp_get_current_user(); $allowed = customprefix_get_allowed_products_per_user( $user ); // 确保$allowed为有效数组 $allowed = is_array( $allowed ) ? $allowed : []; if ( !empty( $allowed ) ) { // 保留当前分类的筛选条件,同时限制仅显示允许的产品 $tax_query = $query->get( 'tax_query', [] ); $tax_query[] = [ 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => get_queried_object_id(), 'operator' => 'IN' ]; $query->set( 'tax_query', $tax_query ); $query->set( 'post__in', $allowed ); $query->set( 'post_type', 'product' ); } else { // 无允许产品时返回空结果 $query->set( 'post__in', [-1] ); } } } // 辅助函数:获取用户允许查看的产品ID数组 function customprefix_get_allowed_products_per_user( $user ) { // 替换为你存储用户允许产品ID的元数据字段名 $allowed_ids = get_user_meta( $user->ID, 'allowed_product_ids', true ); // 处理元数据为序列化数组的情况 if ( is_serialized( $allowed_ids ) ) { $allowed_ids = unserialize( $allowed_ids ); } // 处理元数据为逗号分隔字符串的情况(如果你的存储格式是字符串) elseif ( is_string( $allowed_ids ) && !empty( $allowed_ids ) ) { $allowed_ids = array_map( 'intval', explode( ',', $allowed_ids ) ); } return is_array( $allowed_ids ) ? $allowed_ids : []; }
关键修改说明
- 提高钩子优先级:将钩子优先级设为99,确保自定义修改在WooCommerce默认查询处理之后执行,避免被覆盖。
- 结合分类筛选与产品ID限制:手动保留当前产品分类的
tax_query条件,同时添加post__in限制,确保仅显示分类内用户允许的产品。 - 边界情况处理:
- 当
$allowed为空时,设置post__in为[-1],确保返回空结果(WordPress会忽略空数组的post__in)。 - 确保
$allowed始终为有效数组,避免查询报错。
- 当
- 限制前台查询:添加
!is_admin()判断,避免后台查询被意外修改。
内容的提问来源于stack exchange,提问作者Abe
相关产品推荐
相关产品推荐

