WooCommerce邮件:基于学员数量发送个性化独立邮件
解决WooCommerce课程订单给每位学员发送个性化独立邮件的问题
我明白你的痛点:之前的方案要么把所有学员塞进同一封邮件(存在隐私问题),要么循环时重复给第一个学员发多封,没法做到每人一封带自己姓名和邮箱的专属邮件。核心问题在于你之前的逻辑是试图在邮件类内部循环发送,而正确的做法应该是遍历每个学员,单独触发邮件发送,并为每封邮件注入对应的个人信息。
下面是完整的解决方案,分步骤实现:
1. 重构自定义邮件类,支持动态替换学员变量
首先修改你插件里的自定义邮件代码,去掉内部的while循环,让它专注处理单封邮件,同时新增支持替换学员姓名和邮箱的变量:
class WC_Course_Order_Email extends WC_Email { // 保留你原有的构造函数等基础代码... public function trigger( $order_id, $order = false ) { $this->setup_locale(); if ( $order_id && ! is_a( $order, 'WC_Order' ) ) { $order = wc_get_order( $order_id ); } if ( is_a( $order, 'WC_Order' ) ) { $this->object = $order; $this->recipient = $this->get_recipient(); // 收件人将在外部动态设置 // 基础订单变量替换 $this->find[] = '{order_date}'; $this->replace[] = date_i18n( woocommerce_date_format(), strtotime( $this->object->get_date_created() ) ); $this->find[] = '{order_number}'; $this->replace[] = $this->object->get_order_number(); // 新增学员变量占位(后续动态替换) $this->find[] = '{student_name}'; $this->replace[] = ''; $this->find[] = '{student_email}'; $this->replace[] = ''; } if ( ! $this->is_enabled() || ! $this->get_recipient() ) { return; } $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); $this->restore_locale(); } // 新增方法:动态设置学员信息,用于替换模板变量 public function set_student_info( $name, $email ) { // 更新姓名变量 $name_key = array_search('{student_name}', $this->find); if ( false !== $name_key ) { $this->replace[$name_key] = $name; } // 更新邮箱变量并设置收件人 $email_key = array_search('{student_email}', $this->find); if ( false !== $email_key ) { $this->replace[$email_key] = $email; } $this->recipient = $email; } }
2. 修改functions.php中的钩子逻辑,遍历学员并单独发送邮件
去掉之前批量添加CC/BCC的代码,换成以下逻辑:拦截默认邮件触发,手动遍历每个学员,调用自定义邮件类的方法发送个性化邮件:
// 禁用默认的课程邮件自动触发,避免重复发送 add_filter( 'woocommerce_email_enabled_wc_course_order', '__return_false' ); // 在订单完成(或你需要的状态节点)时,手动发送每个学员的专属邮件 add_action( 'woocommerce_order_status_completed', 'send_individual_student_course_emails', 20, 1 ); function send_individual_student_course_emails( $order_id ) { $order = wc_get_order( $order_id ); if ( ! $order ) return; // 遍历订单中的商品,只处理目标课程(示例产品ID为1164) foreach ( $order->get_items() as $item_id => $item_data ) { $product_id = $item_data->get_product_id(); if ( $product_id != 1164 ) continue; $course_qty = $item_data->get_quantity(); // 遍历每个报名名额,按序号读取对应学员信息 for ( $q = 1; $q <= $course_qty; $q++ ) { $first_name = wc_get_order_item_meta( $item_id, "First Name - {$q}", true ); $last_name = wc_get_order_item_meta( $item_id, "Last Name - {$q}", true ); $student_name = trim( "{$first_name} {$last_name}" ); $student_email = wc_get_order_item_meta( $item_id, "Student Email - {$q}", true ); // 跳过信息不完整的条目 if ( empty( $student_email ) || empty( $student_name ) ) continue; // 获取自定义邮件实例,注入学员信息并发送 $email_instance = WC()->mailer()->get_emails()['WC_Course_Order_Email']; $email_instance->set_student_info( $student_name, $student_email ); $email_instance->trigger( $order_id, $order ); } } }
3. 更新邮件模板,添加个性化变量
在你的自定义邮件模板(比如wc-course-order.php)中,替换成包含学员变量的内容,示例:
<p>亲爱的{student_name},感谢您报名。请使用邮箱{student_email}登录。</p> <p>您的订单号:{order_number},下单日期:{order_date}</p>
方案核心优势
- 不再批量发送,为每个学员单独生成邮件,完全隔离隐私信息;
- 通过
set_student_info动态注入专属数据,确保每封邮件的变量替换准确; - 按购买序号读取对应学员字段,不会出现重复读取第一个学员数据的问题。
内容的提问来源于stack exchange,提问作者calwex718
相关产品推荐
相关产品推荐

