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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:41:52