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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:14:53