给WooCommerce创建一封自定义邮件,并在结账后发送,并没有想象的那么复杂。只要了解一些基本的php和html知识就可以做到,因为规律不受语言限制。

代码

源代码下载:WooCommerce 自定义邮件 已下载 229 次

为了简化过程,可以把所有代码浓缩成下面这段,使用了两个filter。

add_filter( 'woocommerce_email_classes',                 'cp_custom_woocommerce_email' );
add_filter( 'woocommerce_resend_order_emails_available', 'cp_custom_order_email_action' );

// 对应第一个filter,创建邮件
function cp_custom_woocommerce_email( $email_classes ) {   
    // include our custom email class
    require( 'class-custom-order-email.php' ); 
 
    // add the email class to the list of email classes that WooCommerce loads
    $email_classes['CP_Custom_Order_Email'] = new CP_Custom_Order_Email();
 
    return $email_classes; 
}    

// 对应第二个filter,让你能重新发送这封邮件
function cp_custom_order_email_action( $avai_emails ){
    $avai_emails[] = 'cp_custom_order';
    return $avai_emails;
}

第一个函数负责创建自定义的邮件,主要内容都在require进来的class-custom-order-email.php文件里,然而这个文件只是new order class的复制,改一下class名称就好,没有任何复杂的地方。实现的效果如下图所示

custom-email

第二个函数只是锦上添花,WooCommerce有重新发送邮件的功能,第二个函数将允许你重发自定义邮件,效果如下图所示

custom-order-action

这样自定义邮件就创建好了。现在说下看似最复杂的地方——名为CP_Custom_Order_Email的class,制作过程如下:

  1. 找到woocommerce/includes/emails/class-wc-email-new-order.php,拷贝一份并重命名为class-custom-order-email.php
  2. 把里面出现的“WC_Email_New_Order”字符串全部替换成“CP_Custom_Order_Email”
  3. 把$this->id的值改成“cp_custom_order”
  4. title、description之类的自己看着改改,over。

使用代码

把开头提到的代码拷贝到主题的functions.php里,将class-custom-order-email.php放在主题根目录就完成了。

问题

这封自定义邮件的模板在哪?

为了简化问题,偷懒使用了new order的模板,控制模板的代码如下

$this->template_html    = 'emails/admin-new-order.php';
$this->template_plain   = 'emails/plain/admin-new-order.php';

可以将模板放在其他位置吗,比如自己写的插件里?

是可以的,具体怎么放下回再说。

如何决定发送给管理员还是客户?

代码里有个参数叫sent_to_admin,设为true就是发给管理员。当然还有更省事的方法啊,换个文件copy,比如发给用户的class-wc-email-customer-processing-order.php。

28条留言

  1. 发送自定义邮件的按钮是否可以直接提到 WC 的「订单」这个页面来呢?那样会方便很多,不用每次点进每个订单详情中去。也就是在「订单」页面增加一个自定义的栏目?这样也可以把一些自定义字段直接显示,会不会更方便些?

    1. 发送邮件的按钮应该说原本就在订单页面里,你看看order actions里,不是有所有邮件的发送选项吗,如下图所示

      1. 谢谢…我的意思是,它的上一层级的那个订单列表的页面。因为左侧菜单中那个页面叫「订单」页面,你截图的这个叫订单详情页…那个列表是否能增加一个栏目,显示自定义字段呢,以及增加一个栏目,可以直接发邮件的…

        1. 好吧,「订单」这个页面就是订单列表页,我记住了。

          你说的当然可以,custom post type列表页显示自定义字段,谷歌搜,文章很多。

          直接发送邮件,把woocommerce订单详情页面发送邮件的代码读懂,移植到订单列表页面就行了,用ajax+php实现。你可以搜索下有没有相关插件。

  2. 你好,我前几个小时的那个评论,是问「能否在用户购买后发送一封邮件,此邮件包含两个变量,手动输入」。

    后来我想到,用户订单详情中有一个「订单 提示」(Order Notes)模块,能否将这个模块复制一下,修改生成另一个「发送账号信息」的模块。每次在此输入不同的账号,发送出去后,别的内容是固定的,比如包含「如何使用此账号」的说明链接等?

    因为你的模板发送出去的数据,都是固定的,只是自己修改邮件主题什么的。

    或者,通过添加「自定义项目」(Custom Fields)的方式发送?
    比如 Custom Fields「账号」「密码」,然后执行一个「自定义模板」的动作,发送新邮件呢?如何在模板中只显示这两个元数据,订单详情不显示呢?

    1. 你说的是WooCommerce吗?如果是的话,你可以创建一封新的邮件模板,包含你要在QQ企业邮箱HTML模式下编辑的信息,在客户结账后发送给你自己,然后手动输入对方的账号和密码,转发给对方。

      或者这封邮件不自动发送给你,而是在订单产生后,到订单详情里填写账号密码,再用order actions发送这个邮件,当然也要你手动操作,除非你能让填写账号密码这步自动化。

      给WooCommerce创建新邮件不难

      1. 谢谢!第一种方法很机智。

        已在「订单」类型中添加 4 个自定义字段,能在订单管理页呈现一个填写字段值的模块。希望在填写后执行一个动作发送信息邮件。
        1、现在不知如何在邮件中 PHP 呈现当前 POST 的指定字段值;
        2、选用了 processing 模板,导致一下单就触发了邮件,如何修改触发机制呢?
        3、准备在「新订单」邮件中加一个指向当前订单管理页的地址,发现是 …/wp-admin/post.php?post=1991&action=edit
        动态修改的话是这样吗:
        ……/wp-admin/post.php?post=get_order_number(); ?>&action=edit

        1. 第一点,如果是自定义字段的话,保存订单后直接从数据库读取就行了,应该跟POST没什么关系。
          二三点我没有试过,我想控制触发条件的代码就在email class的construct里

          // Triggers for this email
          		add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
          		add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
          

          模板里$order变量记录了订单的信息,通过这个变量可以获取订单号。

          1. 1、删除了两行 add_action,还是会触发发送。如果一同删除下方的 parent::__construct(); 就不会自动触发了,但是执行动作也不能发送邮件了。

            2、PHP 如何将字段值显示出来呢?搜了好久都没找到。

        2. var_dump和get_post_meta没什么关系,而且var_dump仅在调试时使用,前者是php基本函数,后者是WordPress基于php定义的函数。

          很抱歉这样说,但如果你弄不清这两个东西,改动代码是非常困难的,建议先学习php的基础知识。

          你说的border是1的问题没那么简单,邮件大部分样式都不是在模板里定义的,而是通过css和一个将css转换为内联样式的php库来写的。改动这个需要你懂php和css。

          1. 哈哈,其实你说的我都懂。get_post_meta 很明显 post 就是 WordPress 定义的概念,本身不属于 php 语法中的函数。CSS 我懂。只是改了这么久有点累了,还得找找在哪里- –

    2. 去读一下parent::__construct()的代码可能就明白了,这个class不是extend的一个class吗
      php显示字段值种类太多了,如果你是说custom field,可以用get_post_meta()

      1. 如果要打印在屏幕上,是不是这样:

        username 是字段名。

        后来我用了 invoice 收据的模板,是必须手动发送的。只是它有支付和未支付,感觉有点累赘,但不太敢乱改。

        1. 你确定删除trigger代码不管用吗?parent constructor里并没有发送邮件的代码,我本地用admin-new-order模板试了下,删除trigger就不会发送了。

          1. 我也觉得,至少理论上是不会的。可能当时由于缓存之类的问题导致的吧,我只试了一次。

            刚才我发送了一个 php 代码,但是没有显示出来,可能作为代码执行了,而你这里没有那个字段,因此是空的。
            我在前后加了几个星号,看看这回能否显示~

          2. php 中输入 echo get_post_meta ( get_the_ID(), ‘username’, true );

        2. 如果你想让一个变量显示,无论有没有值,可以用var_dump

          1. 用我那条成功了~ var_dump 和 get_post_meta 是一样的效果?

            然后就是发现我模板做出来的表格,右侧和下放有较深的细边线,但是其他的邮件是正常的,灰色的粗线。border 没动过,值是默认的”1″,我改成 solid 之后还是一样的。

    3. 确实,给woocommerce加新邮件很简单,难度全在定制化那个模板上,邮件模板本来就很罗嗦,如果再需要显示与默认数据不同的东西更麻烦。
      其实这篇文章记录的东西正是我给一个客户写的插件,但我只写了最简单的部分。如果要写后面咋改的模板,估计我就要跟你一样的心情了。
      要自己改的话恐怕必须把WooCommerce模板原理搞明白。

      1. 恩,辛苦。
        我已经搞定了,主要是表格中的字段值是动态的,别的部分都是固定的。
        现在就差那个框线了,虽然可以忽略,但是看着怪怪的。我去找找相关的 CSS 在哪里好了。
        疑点是表格的样式竟然没动也会产生差异。不知道是不是我删了 tbody 和 tfoot 标记的缘故。

        1. 关于修改woocommerce样式,可以看这篇文章http://www.solagirl.net/woocommerce-2-3-email-customization.html

      2. 还有一个问题就是,要保护商店的经营数据,避免被回头客知晓他回访期间我们的销量,需要将订单号变一种样式。比如在前面加上 年份+月份。看起来就像是这个月的第几单,而不是从一开始的第几单。或者其他的算法,来保护这个数值不被联想。

        1. 这个没改过,不过order就是custom post type,搜下custom post type permalink之类的应该有解决方案。

      3. 因为发的货是帐号,有使用期限的。有一个字段就是时间,yymmdd。

        在这一天需要发送一封邮件,说到期了。

        那么再新建一个邮件模板,能否设置一个 trigger,在那天的 15:00 触发,自动发送提醒邮件呢?

        如果不行,记得有个定时任务的插件叫 WP-Cron,如果要在那时候执行任务,「让 WC 发送某封邮件」的函数是什么?

        1. 每个class里的trigger()函数就是发送邮件的,至于定时发送,自己写吧。
          如果不需要显示订单详情之类的,不需要用WooCommerce的邮件写法。

  3. sola, 你现在仍然用的是 Hostgator的主机吗? 最近有看到一个帖子,说HG支持成人/赌博站,影响SEO之类的。你觉得有这回事吗?

发表评论

电子邮件地址不会被公开。 必填项已用*标注