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

如何统计WooCommerce中指定用户对指定产品的有效订阅数量?

统计用户针对特定产品的有效订阅数量(WooCommerce Subscriptions)

好问题!WooCommerce Subscriptions 确实支持用户购买同一产品的多份订阅,但WC_Subscriptions_Manager::user_has_subscription()只能返回布尔值,没法统计具体数量。这里有两种实用的实现方案,你可以根据场景选择:

方法一:使用官方API遍历订阅(推荐,兼容性好)

这种方法依赖WooCommerce Subscriptions提供的官方函数,代码更易维护,也能处理各种边缘情况(比如变体产品、订单项数量):

function get_user_active_subscription_count( $user_id, $product_id ) {
    $subscription_count = 0;
    // 获取用户名下所有订阅
    $subscriptions = wcs_get_users_subscriptions( $user_id );
    
    if ( empty( $subscriptions ) ) {
        return $subscription_count;
    }
    
    // 定义你认为"有效"的订阅状态,可按需调整
    $valid_statuses = array( 'active', 'pending', 'on-hold' );
    
    foreach ( $subscriptions as $subscription ) {
        // 跳过无效状态的订阅
        if ( ! in_array( $subscription->get_status(), $valid_statuses ) ) {
            continue;
        }
        
        // 遍历订阅内的所有商品项
        foreach ( $subscription->get_items() as $item ) {
            // 处理变体产品:如果是变体,用父产品ID匹配;否则直接用产品ID
            $item_product_id = $item->get_product_id();
            $item_variation_id = $item->get_variation_id();
            $target_match_id = $item_variation_id > 0 ? wc_get_product_parent_id( $item_variation_id ) : $item_product_id;
            
            if ( $target_match_id == $product_id ) {
                // 累加该商品项的数量(支持用户一次购买多份订阅)
                $subscription_count += $item->get_quantity();
            }
        }
    }
    
    return $subscription_count;
}

// 使用示例
$current_user_id = get_current_user_id();
$target_product_id = 123; // 替换成你的目标产品ID
$total_subs = get_user_active_subscription_count( $current_user_id, $target_product_id );
echo "用户拥有该产品的有效订阅总数:{$total_subs}";

关键细节说明:

  • 兼容变体产品:自动识别订阅中的变体,匹配其父产品ID
  • 支持多份购买:累加每个订单项的quantity值,而非仅统计订阅订单数
  • 可自定义有效状态:你可以根据业务需求添加/移除状态(比如去掉pending)

方法二:直接数据库查询(性能优先)

如果你的站点用户订阅量极大,遍历所有订阅可能会有性能损耗,这时可以用自定义SQL直接查询数据库,效率更高:

function get_user_active_subscription_count_sql( $user_id, $product_id ) {
    global $wpdb;
    
    // 定义有效订阅状态
    $valid_statuses = array( 'active', 'pending', 'on-hold' );
    $statuses_clause = "'" . implode( "','", $valid_statuses ) . "'";
    
    // 获取目标产品的所有变体ID(如果有)
    $variation_ids = $wpdb->get_col( $wpdb->prepare( "
        SELECT ID FROM {$wpdb->posts} 
        WHERE post_parent = %d AND post_type = 'product_variation'
    ", $product_id ) );
    
    // 合并主产品ID和变体ID,确保都能匹配到
    $product_ids = array_merge( array( $product_id ), $variation_ids );
    $product_ids_clause = "'" . implode( "','", $product_ids ) . "'";
    
    // 查询总订阅数量
    $total_count = $wpdb->get_var( $wpdb->prepare( "
        SELECT SUM(oi.quantity) 
        FROM {$wpdb->prefix}posts AS p
        JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
        JOIN {$wpdb->prefix}woocommerce_order_items AS oi ON p.ID = oi.order_id
        JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS oim ON oi.order_item_id = oim.order_item_id
        WHERE pm.meta_key = '_customer_user' 
          AND pm.meta_value = %d 
          AND p.post_type = 'shop_subscription' 
          AND p.post_status IN ($statuses_clause)
          AND oim.meta_key IN ('_product_id', '_variation_id')
          AND oim.meta_value IN ($product_ids_clause)
    ", $user_id ) );
    
    // 如果查询结果为空,返回0
    return $total_count ? (int)$total_count : 0;
}

// 使用示例
$current_user_id = get_current_user_id();
$target_product_id = 123;
$total_subs = get_user_active_subscription_count_sql( $current_user_id, $target_product_id );
echo "用户拥有该产品的有效订阅总数:{$total_subs}";

注意事项:

  • 确保数据库前缀正确:{$wpdb->prefix}会自动适配你的站点配置
  • 状态和产品ID的处理和方法一保持一致,确保统计准确
  • 这种方法跳过了WooCommerce的对象层,性能更好,但需要对数据库结构有一定了解

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:39:19