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

基于WooCommerce购物车商品及数量的嵌套循环改造需求

按商品变体分组生成WooCommerce结账参与者字段

需求说明

原代码根据购物车总数量生成统一的参与者信息字段,现需改造为按商品变体分组:例如购物车中有2份Day1活动票、1份Day2活动票时,分别生成Day1组(2个参与者字段)和Day2组(1个参与者字段)。


修改后的完整代码

1. 生成分组的参与者字段

// 按商品变体分组生成WooCommerce结账参与者字段
add_action( 'woocommerce_before_order_notes', 'person_details_by_variant' );

function person_details_by_variant($checkout) {
    global $woocommerce;
    $cart_items = $woocommerce->cart->get_cart();
    $global_attendee_num = 1; // 全局参与者序号,确保表单字段唯一

    foreach ($cart_items as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $variant_name = $product->get_name(); // 获取商品变体名称(如Day1、Day2)
        $quantity = $cart_item['quantity']; // 当前变体的购买数量

        // 输出分组标题
        echo '<h3>'.$variant_name.' 参与者信息 (共'.$quantity.'人)</h3>';

        // 内层循环:为当前变体的每个数量生成字段组
        for ($j = 1; $j <= $quantity; $j++) {
            $field_suffix = $variant_name . '_' . $global_attendee_num;

            // 学年选择字段
            woocommerce_form_field( 'school_year_' . $field_suffix, array(
                'type'        => 'radio',
                'required'    => true,
                'class'       => array('my-field-class form-row-wide'),
                'label'       => __('学年'),
                'options'     => array(
                    'Reception' => 'Reception',
                    'Year 1'    => 'Year 1',
                    'Year 2'    => 'Year 2',
                    'Year 3'    => 'Year 3',
                    'Year 4'    => 'Year 4',
                    'Year 5'    => 'Year 5',
                    'Year 6'    => 'Year 6',
                    'Year 7'    => 'Year 7',
                ),
            ), $checkout->get_value( 'school_year_' . $field_suffix ));

            // 孩子全名字段
            woocommerce_form_field( 'cstm_full_name_' . $field_suffix, array(
                'type'        => 'text',
                'required'    => true,
                'class'       => array('my-field-class form-row-wide'),
                'label'       => __('孩子全名'),
                'placeholder' => __('输入全名'),
            ), $checkout->get_value( 'cstm_full_name_' . $field_suffix ));

            echo '<div class="clear"></div>';

            // 紧急联系电话字段
            woocommerce_form_field( 'cstm_phone_' . $field_suffix, array(
                'type'        => 'tel',
                'required'    => true,
                'class'       => array('my-field-class form-row-first'),
                'label'       => __('紧急联系电话'),
                'placeholder' => __('输入电话号码'),
            ), $checkout->get_value( 'cstm_phone_' . $field_suffix ));

            echo '<div class="clear"></div>';

            // 照片授权字段
            woocommerce_form_field( 'photo_consent_' . $field_suffix, array(
                'type'        => 'radio',
                'required'    => true,
                'class'       => array('my-field-class form-row-wide'),
                'label'       => __('照片授权同意?'),
                'options'     => array(
                    'Yes' => '同意',
                    'No'  => '不同意',
                ),
            ), $checkout->get_value( 'photo_consent_' . $field_suffix ));

            $global_attendee_num++;
        }
    }
}

2. 保存分组字段的订单元数据

// 保存分组参与者字段到订单元数据
add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta_by_variant');

function customise_checkout_field_update_order_meta_by_variant($order_id) {
    global $woocommerce;
    $cart_items = $woocommerce->cart->get_cart();
    $global_attendee_num = 1;

    foreach ($cart_items as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $variant_name = $product->get_name();
        $quantity = $cart_item['quantity'];

        for ($j = 1; $j <= $quantity; $j++) {
            $field_suffix = $variant_name . '_' . $global_attendee_num;
            $attendee_label = $variant_name . ' 参与者 ' . $j;

            // 保存学年信息
            if (!empty($_POST['school_year_' . $field_suffix])) {
                update_post_meta($order_id, $attendee_label . ' - 学年', sanitize_text_field($_POST['school_year_' . $field_suffix]));
            }
            // 保存姓名信息
            if (!empty($_POST['cstm_full_name_' . $field_suffix])) {
                update_post_meta($order_id, $attendee_label . ' - 姓名', sanitize_text_field($_POST['cstm_full_name_' . $field_suffix]));
            }
            // 保存紧急联系电话
            if (!empty($_POST['cstm_phone_' . $field_suffix])) {
                update_post_meta($order_id, $attendee_label . ' - 紧急联系电话', sanitize_text_field($_POST['cstm_phone_' . $field_suffix]));
            }
            // 保存照片授权状态
            if (!empty($_POST['photo_consent_' . $field_suffix])) {
                update_post_meta($order_id, $attendee_label . ' - 照片授权', sanitize_text_field($_POST['photo_consent_' . $field_suffix]));
            }

            $global_attendee_num++;
        }
    }
}

3. 在订单邮件中显示分组字段

// 在订单邮件中显示分组参与者字段
add_filter('woocommerce_email_order_meta_fields', 'my_custom_checkout_field_order_meta_fields_by_variant', 10, 3);

function my_custom_checkout_field_order_meta_fields_by_variant( $fields, $sent_to_admin, $order ) {
    $order_meta = get_post_meta($order->get_id());
    $variant_attendee_fields = array();

    // 筛选出所有参与者相关的元数据
    foreach ($order_meta as $key => $value) {
        if (strpos($key, '参与者') !== false) {
            $variant_attendee_fields[$key] = $value[0];
        }
    }

    // 按变体分组排序后添加到邮件字段
    if (!empty($variant_attendee_fields)) {
        ksort($variant_attendee_fields);
        foreach ($variant_attendee_fields as $key => $value) {
            $fields[$key] = array(
                'label' => $key,
                'value' => $value,
            );
        }
    }

    return $fields;
}

关键改动说明

  • 嵌套循环结构:外层遍历购物车中的每个商品变体,内层根据变体购买数量生成对应字段组
  • 字段唯一标识:字段名加入变体名称+全局序号,避免不同变体的字段冲突
  • 分组可视化:结账页面按变体名称分组展示,用户能清晰区分不同场次的参与者信息
  • 元数据优化:订单元数据加入变体标识,便于后台查看和管理
  • 邮件动态适配:不再硬编码固定数量字段,而是动态读取订单中已保存的参与者数据,适配任意数量的变体和购票数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:14:56