WooCommerce按品类年购限制代码故障排查求助
WooCommerce 品类年度购买限制代码修复
原代码存在的问题
- 语法错误:
$product_cat = 'regular'; 'special-promo';写法无效,无法同时指定两个品类,得用数组关联品类和对应限制。 - 时间计算错误:
time() - $time_in_years实际是减1秒而非1年,正确的一年前时间戳要用strtotime('-1 year')。 - 变量未定义:
$specific_product_id从未初始化,且原逻辑针对单个商品ID,不符合按品类限制的需求。 - 未区分品类限制:原代码只有一个
$limit值,没法实现regular限3次、special-promo限1次的差异化要求。 - 未统计当前购物车:原代码只计算历史订单购买量,没加入当前购物车的商品数量,会出现总量超标却不拦截的情况。
修复后的代码
function action_woocommerce_checkout_process() { // 获取客户邮箱 $customer_email = ''; if ( is_user_logged_in() ) { $user = wp_get_current_user(); $customer_email = $user->user_email; } elseif ( isset( $_POST['billing_email'] ) && ! empty( $_POST['billing_email'] ) ) { $customer_email = sanitize_email( $_POST['billing_email'] ); } elseif ( WC()->customer->get_billing_email() ) { $customer_email = WC()->customer->get_billing_email(); } if ( empty( $customer_email ) ) { return; } // 定义品类与对应年度购买限制(按购买总数量计算,如需按订单次数可调整统计逻辑) $category_limits = array( 'regular' => 3, 'special-promo' => 1 ); // 获取一年前的时间戳 $one_year_ago = strtotime( '-1 year' ); // 获取客户过去一年的有效订单(仅统计已完成/处理中的订单,排除取消、退款状态) $customer_orders = wc_get_orders( array( 'date_created' => '>' . $one_year_ago, 'customer' => $customer_email, 'status' => array( 'wc-completed', 'wc-processing' ), 'limit' => -1 // 拉取所有符合条件的订单 ) ); // 初始化各品类的历史购买总量 $category_purchase_counts = array_fill_keys( array_keys( $category_limits ), 0 ); // 统计历史订单中各品类的购买总量 foreach ( $customer_orders as $order ) { foreach ( $order->get_items() as $item ) { $product_id = $item->get_product_id(); // 检查商品所属目标品类 foreach ( $category_limits as $cat_slug => $limit ) { if ( has_term( $cat_slug, 'product_cat', $product_id ) ) { $category_purchase_counts[ $cat_slug ] += $item->get_quantity(); break; // 一个商品可能属于多个分类,匹配到目标分类后停止检查 } } } } // 统计当前购物车中各品类的购买量 foreach ( WC()->cart->get_cart() as $cart_item ) { $product_id = $cart_item['product_id']; foreach ( $category_limits as $cat_slug => $limit ) { if ( has_term( $cat_slug, 'product_cat', $product_id ) ) { $category_purchase_counts[ $cat_slug ] += $cart_item['quantity']; break; } } } // 检查是否超过限制并弹出错误提示 foreach ( $category_limits as $cat_slug => $limit ) { if ( $category_purchase_counts[ $cat_slug ] > $limit ) { $cat_name = get_term_by( 'slug', $cat_slug, 'product_cat' )->name; wc_add_notice( sprintf( '抱歉,您每年购买【%s】品类商品的上限为%d件,当前已选购%d件。', $cat_name, $limit, $category_purchase_counts[ $cat_slug ] ), 'error' ); } } } add_action( 'woocommerce_checkout_process', 'action_woocommerce_checkout_process', 10, 0 );
修复说明
- 用
$category_limits数组统一管理品类和对应限制,实现不同品类的差异化管控。 - 替换时间计算逻辑,确保只统计过去一年的订单。
- 新增订单状态筛选,避免将取消、退款的订单计入统计。
- 同时统计历史订单和当前购物车的商品数量,保证限制逻辑准确。
- 使用
has_term()检查商品所属品类,替换原无效的商品ID对比逻辑。 - 对邮箱参数做安全过滤,提升代码安全性。
内容的提问来源于stack exchange,提问作者Nat
相关产品推荐
相关产品推荐

