在WooCommerce邮件通知中显示多组自定义字段
问题描述
我已根据客户购买1件或2件特定商品的情况创建了自定义结账字段,字段包括:Voorletters(名字首字母)、Roepnaam(昵称)、Achternaam(姓氏)和Geboortedatum(出生日期)。目前代码可正常运行,数据已显示在WordPress后台对应订单下方,但希望将这些字段内容添加至两类邮件中:
- 客户支付成功后收到的订单完成邮件
- 管理员收到的新订单确认邮件
基于Stack Overflow相关方案,我的现有代码如下:
// 工具函数:获取特定商品的购物车总数量 function get_specific_cart_item_quantity() { $targeted_id = 5027; // <== 要检查的商品ID $item_qty = 0; // 初始化 // 遍历购物车商品 foreach ( WC()->cart->get_cart() as $item ) { if ( $item['product_id'] == $targeted_id ) { $item_qty += $item['quantity']; } } return $item_qty; } // 添加自定义结账字段 add_action('woocommerce_checkout_before_customer_details', 'add_custom_checkout_fields'); function add_custom_checkout_fields() { $item_qty = get_specific_cart_item_quantity(); if ( $item_qty ) { $domain = 'woocommerce'; echo '<div id="custom_checkout_fields"> <h3>' . __('<b>Persoonsgegevens BHV</b>', $domain) . '</h3> <p>' . __('Vul a.u.b. de persoonsgegevens van de BHV kandidaten in hieronder.', $domain) . '</p> <div class="custom-fields-container">'; $qty1 = $item_qty % 2 == 0 ? $item_qty / 2 : ( $item_qty == 1 ? 1 : ($item_qty + 1) / 2 ); $qty2 = $item_qty == 1 ? 1 : 2; // 根据商品数量,以两列布局显示自定义字段的多循环 for ( $k = 1; $k <= $qty1; $k++ ) { $qty2 = $item_qty % 2 != 0 && $k == $qty1 ? 1 : 2; // 第二层循环(字段类型) foreach ( array('Voorletters', 'Roepnaam', 'Achternaam', 'Geboortedatum') as $letter ) { $key = strtolower($letter); // 第三层循环(列) for ( $h = 1; $h <= $qty2; $h++ ) { $class = $item_qty > 1 ? (($h % 2 == 0) ? 'last' : 'first' ) : 'wide'; $class = $item_qty % 2 != 0 && $k == $qty1 ? 'wide' : $class; $index = $item_qty == 1 ? 1 : 2; $index = in_array($class, ['first', 'wide']) ? ($k*2)-1 : $k*2; $field = "custom_field_{$key}{$index}"; $label = sprintf('%s %d %s', __('Kandidaat', $domain), $index, $letter); woocommerce_form_field( $field, array( 'type' => 'text', 'label' => $label, 'placeholder' => '', 'class' => array('custom-field form-row-'.$class), 'required' => true, // 可改为false ), WC()->checkout->get_value( $field ) ); } } } echo '</div></div>'; } } // 验证自定义字段 add_action( 'woocommerce_after_checkout_validation', 'validate_custom_checkout_fields', 10, 2 ); function validate_custom_checkout_fields( $data, $errors ) { if ( did_action('woocommerce_checkout_process') >= 2 ) return; $item_qty = get_specific_cart_item_quantity(); if ( $item_qty ) { $domain = 'woocommerce'; $break = false; // 第一层循环(字段类型) foreach ( array('Voorletters', 'Roepnaam', 'Achternaam', 'Geboortedatum') as $letter ) { $key = strtolower($letter); // 第二层循环(候选人序号) for ( $i = 1; $i <= $item_qty; $i++ ) { $field = "custom_field_{$key}{$i}"; if ( isset($_POST[$field]) && empty($_POST[$field]) ) { $errors->add( 'validation', __('Vul a.u.b. de verplichte velden in.', $domain), 'error' ); $break = true; break; } } if ( $break ) break; } } } // 保存自定义字段数据为订单元数据 add_action( 'woocommerce_checkout_create_order', 'save_custom_checkout_fields', 10, 2 ); function save_custom_checkout_fields( $order, $data ) { $item_qty = get_specific_cart_item_quantity(); if ( $item_qty ) { // 第一层循环(字段类型) foreach ( array('Voorletters', 'Roepnaam', 'Achternaam', 'Geboortedatum') as $letter ) { $key = strtolower($letter); // 第二层循环(候选人序号) for ( $i = 1; $i <= $item_qty; $i++ ) { $field = "custom_field_{$key}{$i}"; if ( isset($_POST[$field]) && ! empty($_POST[$field]) ) { $order->update_meta_data( $field, sanitize_text_field($_POST[$field]) ); } } } } }
解决方案:添加自定义字段到邮件中
添加以下代码到你的主题functions.php文件或自定义插件中,即可将自定义字段内容插入到指定邮件的订单详情区域:
// 工具函数:获取订单中特定商品的总数量 function get_specific_order_item_quantity( $order ) { $targeted_id = 5027; // 对应之前的商品ID $item_qty = 0; // 遍历订单商品 foreach ( $order->get_items() as $item ) { if ( $item->get_product_id() == $targeted_id ) { $item_qty += $item->get_quantity(); } } return $item_qty; } // 将自定义字段添加到邮件订单详情中 add_action('woocommerce_email_order_details', 'add_custom_fields_to_woocommerce_emails', 20, 4); function add_custom_fields_to_woocommerce_emails( $order, $sent_to_admin, $plain_text, $email ) { // 仅针对目标邮件类型:新订单(管理员)和订单完成(客户) $targeted_emails = array('new_order', 'customer_completed_order'); if ( !in_array($email->id, $targeted_emails) ) return; $item_qty = get_specific_order_item_quantity( $order ); if ( !$item_qty ) return; $domain = 'woocommerce'; $fields = array( 'voorletters' => __('Voorletters', $domain), 'roepnaam' => __('Roepnaam', $domain), 'achternaam' => __('Achternaam', $domain), 'geboortedatum' => __('Geboortedatum', $domain) ); // 输出标题 echo '<h2>' . __('Persoonsgegevens BHV', $domain) . '</h2>'; echo '<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;">'; // 按候选人序号循环输出字段 for ( $i = 1; $i <= $item_qty; $i++ ) { echo '<tr><th colspan="2" style="text-align:left; font-size:16px; padding-top:15px;">' . sprintf(__('Kandidaat %d', $domain), $i) . '</th></tr>'; foreach ( $fields as $key => $label ) { $meta_key = "custom_field_{$key}{$i}"; $value = $order->get_meta($meta_key); if ( !empty($value) ) { echo '<tr> <th style="text-align:left; width: 30%;">' . $label . ':</th> <td style="text-align:left;">' . esc_html($value) . '</td> </tr>'; } } } echo '</table>'; }
说明
- 代码会先判断当前邮件类型是否为目标邮件(新订单/订单完成),再获取订单中对应商品的数量
- 以表格形式将每个候选人的四个字段有序展示在邮件中,兼容HTML邮件格式
- 仅当订单中存在目标商品时才会显示该部分内容
内容的提问来源于stack exchange,提问作者TvCasteren
相关产品推荐
相关产品推荐

