如何获取WooCommerce订单及客户邮件中选择字段的order_meta详情
WooCommerce 动态数量自定义结账字段显示解决方案
问题说明
已根据商品购买数量创建额外自定义结账字段,购买N件商品需填写N组对应字段,字段包含下拉选择项,需要在WooCommerce后台订单概览页、客户通知邮件中正常展示这些字段的meta数据。
原有代码问题梳理
- 循环生成字段时,下拉选择类字段(性别、T恤尺码、夏令营经验)未加序号后缀,多件商品提交时后填写的数据会覆盖前序数据
- 字段保存逻辑缺失下拉类字段的保存代码,且存在重复保存的冗余逻辑
- 邮件字段调用逻辑硬写50组字段不合理,且调用的meta key与实际保存的key不匹配,部分下划线前缀的key不存在
- 缺少后台订单页展示自定义字段的逻辑
修正后完整代码
// 根据购物车商品数量生成自定义结账字段 add_action( 'woocommerce_before_order_notes', 'person_details' ); function person_details($checkout) { global $woocommerce; $count = $woocommerce->cart->cart_contents_count; for($i=1; $i<= $count; $i++) { print ('第'.$i.'位参与人信息'); // 姓名 woocommerce_form_field( 'cstm_full_name'.$i, array( 'type' => 'text', 'class' => array('my-field-class form-row-wide'), 'label' => __('全名'), 'required' => true, ), $checkout->get_value( 'cstm_full_name'.$i )); echo '<div class="clear"></div>'; // 性别 woocommerce_form_field( 'cstm_gender'.$i, array( 'type' => 'select', 'required' => true, 'class' => array( 'my-field-class form-row-wide' ), 'label' => __( '性别' ), 'options' => array( 'blank' => __( '请选择', 'njengah' ), 'jongen' => __( '男', 'njengah' ), 'meisje' => __( '女', 'njengah' ), 'genderneutraal' => __( '其他', 'njengah' ) )), $checkout->get_value( 'cstm_gender'.$i )); // 年龄 woocommerce_form_field( 'cstm_leeftijd'.$i, array( 'type' => 'text', 'class' => array('my-field-class form-row-first'), 'label' => __('开营时年龄'), 'required' => true, ), $checkout->get_value( 'cstm_leeftijd'.$i )); // 当前所在组别 woocommerce_form_field( 'cstm_groep'.$i, array( 'type' => 'text', 'class' => array('my-field-class form-row-last'), 'label' => __('当前所属组别'), 'required' => true, ), $checkout->get_value( 'cstm_groep'.$i )); // T恤尺码 woocommerce_form_field( 'cstm_shirt'.$i, array( 'type' => 'select', 'required' => true, 'class' => array( 'my-field-class form-row-first' ), 'label' => __( 'T恤尺码' ), 'options' => array( 'blank' => __( '请选择', 'njengah' ), 'Maat S' => __( 'S', 'njengah' ), 'Maat M' => __( 'M', 'njengah' ), 'Maat L' => __( 'L', 'njengah' ) )), $checkout->get_value( 'cstm_shirt'.$i )); // 夏令营参与经验 woocommerce_form_field( 'cstm_ervaring'.$i, array( 'type' => 'select', 'required' => true, 'class' => array( 'my-field-class form-row-last' ), 'label' => __( '夏令营参与经验' ), 'options' => array( 'blank' => __( '请选择', 'njengah' ), '1e keer Summer Camp' => __( '第一次参与', 'njengah' ), '2e keer Summer Camp' => __( '第二次参与', 'njengah' ), '3e keer Summer Camp' => __( '第三次参与', 'njengah' ), '4e keer Summer Camp' => __( '第四次及以上参与', 'njengah' ) )), $checkout->get_value( 'cstm_ervaring'.$i )); echo '<div class="clearbox"></div>'; } } // 保存自定义字段值到订单meta add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta'); function customise_checkout_field_update_order_meta($order_id) { global $woocommerce; $count = $woocommerce->cart->cart_contents_count; for($i=1; $i<= $count; $i++) { // 保存姓名 if (!empty($_POST['cstm_full_name'.$i])) { update_post_meta($order_id, '第'.$i.'位参与人姓名', sanitize_text_field($_POST['cstm_full_name'.$i])); } // 保存性别 if (!empty($_POST['cstm_gender'.$i])) { update_post_meta($order_id, '第'.$i.'位参与人性别', sanitize_text_field($_POST['cstm_gender'.$i])); } // 保存年龄 if (!empty($_POST['cstm_leeftijd'.$i])) { update_post_meta($order_id, '第'.$i.'位参与人开营年龄', sanitize_text_field($_POST['cstm_leeftijd'.$i])); } // 保存组别 if (!empty($_POST['cstm_groep'.$i])) { update_post_meta($order_id, '第'.$i.'位参与人当前组别', sanitize_text_field($_POST['cstm_groep'.$i])); } // 保存T恤尺码 if (!empty($_POST['cstm_shirt'.$i])) { update_post_meta($order_id, '第'.$i.'位参与人T恤尺码', sanitize_text_field($_POST['cstm_shirt'.$i])); } // 保存参与经验 if (!empty($_POST['cstm_ervaring'.$i])) { update_post_meta($order_id, '第'.$i.'位参与人夏令营参与经验', sanitize_text_field($_POST['cstm_ervaring'.$i])); } } } // 自定义字段添加到订单邮件 add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys', 10, 1); function my_custom_checkout_field_order_meta_keys( $keys ) { // 获取订单商品数量动态生成字段 $order = wc_get_order( get_the_ID() ); if(!$order) return $keys; $count = $order->get_item_count(); for($i=1; $i<= $count; $i++) { $keys[] = '第'.$i.'位参与人姓名'; $keys[] = '第'.$i.'位参与人性别'; $keys[] = '第'.$i.'位参与人开营年龄'; $keys[] = '第'.$i.'位参与人当前组别'; $keys[] = '第'.$i.'位参与人T恤尺码'; $keys[] = '第'.$i.'位参与人夏令营参与经验'; } return $keys; } // 自定义字段显示到后台订单详情页 add_action( 'woocommerce_admin_order_data_after_billing_address', 'show_custom_fields_in_admin_order', 10, 1 ); function show_custom_fields_in_admin_order( $order ){ $count = $order->get_item_count(); for($i=1; $i<= $count; $i++) { echo '<p><strong>第'.$i.'位参与人信息:</strong></p>'; echo '<p>姓名:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人姓名', true ) . '</p>'; echo '<p>性别:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人性别', true ) . '</p>'; echo '<p>开营年龄:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人开营年龄', true ) . '</p>'; echo '<p>当前组别:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人当前组别', true ) . '</p>'; echo '<p>T恤尺码:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人T恤尺码', true ) . '</p>'; echo '<p>参与经验:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人夏令营参与经验', true ) . '</p>'; } }
生效说明
将上述代码添加到主题的functions.php文件或者自定义代码片段插件中即可生效,所有字段会自动适配购物车商品数量,提交后的数据会同步展示在后台订单页和客户通知邮件中。
内容的提问来源于stack exchange,提问作者Broxys
相关产品推荐
相关产品推荐

