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

WooCommerce自定义代码实现按地理位置显示租赁产品问题

WooCommerce 租赁产品地理位置可见性修正方案

原代码存在的问题

  • 全局$product误用:woocommerce_product_query是修改产品列表查询的钩子,此时尚未生成单个产品对象,直接调用$product->get_id()属于逻辑错误,还会引发未定义变量报错。
  • 变量未定义:$product_id未初始化就调用get_id(),属于语法错误。
  • 自定义字段取值错误:get_post_meta默认返回数组,导致后续与字符串类型的用户账单地址对比失效,需传入第三个参数true获取单个值。
  • 查询参数使用错误:post__not_in用于排除指定产品ID,而非分类slug,原代码传入array('rentals')完全无效。
  • 逻辑颠倒:需求是显示匹配条件的产品,原代码却试图排除分类,逻辑完全错误。

修正后的代码

add_action( 'woocommerce_product_query', 'myshop_restrict_rental_products_by_location', 9999, 2 );
 
function myshop_restrict_rental_products_by_location( $q, $query ) {
    // 仅对前台主产品查询生效,不影响后台管理
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    $user = wp_get_current_user();
    $rental_category_slug = 'rentals';

    // 未登录用户:隐藏所有租赁类产品
    if ( empty( $user->ID ) ) {
        $tax_query = $q->get( 'tax_query', array() );
        $tax_query[] = array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => $rental_category_slug,
            'operator' => 'NOT IN',
        );
        $q->set( 'tax_query', $tax_query );
        return;
    }

    // 获取用户账单地址的州/城市
    $customer_state = get_user_meta( $user->ID, 'billing_state', true );
    
    // 用户未填写账单地址:隐藏租赁类产品
    if ( empty( $customer_state ) ) {
        $tax_query = $q->get( 'tax_query', array() );
        $tax_query[] = array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => $rental_category_slug,
            'operator' => 'NOT IN',
        );
        $q->set( 'tax_query', $tax_query );
        return;
    }

    // 筛选条件:属于租赁分类 + 产品位置匹配用户账单地址
    $tax_query = $q->get( 'tax_query', array() );
    $tax_query[] = array(
        'taxonomy' => 'product_cat',
        'field'    => 'slug',
        'terms'    => $rental_category_slug,
        'operator' => 'IN',
    );

    $meta_query = $q->get( 'meta_query', array() );
    $meta_query[] = array(
        'key'     => 'custom_product_location',
        'value'   => $customer_state,
        'compare' => '=',
    );

    $q->set( 'tax_query', $tax_query );
    $q->set( 'meta_query', $meta_query );
}

代码说明

  • 后台过滤:通过is_admin()判断,避免修改后台产品列表的查询逻辑,只影响前台商店页面。
  • 分层逻辑:
    1. 未登录用户直接隐藏所有租赁类产品;
    2. 登录但未填写账单地址的用户,同样隐藏租赁类产品;
    3. 登录且有账单地址的用户,仅显示属于租赁分类且custom_product_location与用户billing_state匹配的产品。
  • 高效查询:通过tax_query和meta_query直接在数据库查询阶段筛选产品,比单个产品循环判断效率更高,也避免了页面加载后再隐藏产品的闪烁问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:15:47