如何统计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
相关产品推荐
相关产品推荐

