根据产品变体术语将收件人添加到 Woocommerce 电子邮件通知

2024-05-27

我创建了一个 Woocommerce 插件并要求它做两件事:

  1. 根据购物车中的产品变体,向特定电子邮件地址发送通知消息。

  2. 电子邮件必须仅包含相关产品,不得包含其他属性的产品。

例如:

产品 A 具有名为 Chef 的属性,其中 Chef-one 和 Chef-two 作为变量术语。用户可以从厨师一或厨师二中选择产品A。

如果用户从 Chef-one 选择产品 A,则必须将通知电子邮件发送至[电子邮件受保护] /cdn-cgi/l/email-protection包含所订购产品的名称(因为它会显示在常规 Woocommerce 通知电子邮件中)。

如果用户从厨师一中选择产品 A,从厨师二中选择产品 B,则必须向厨师一发送一封仅包含产品 A 的通知电子邮件,并且必须向厨师二发送一封仅包含产品 B 的通知电子邮件。

我已经使用上找到的教程创建了该插件https://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/ https://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/并对其进行了调整以适应上述目的。

我还修改了代码找到了以下解决方案:根据产品属性添加自定义 woocommerce 电子邮件 https://stackoverflow.com/questions/40633541/adding-a-custom-woocommerce-email-based-on-the-product-attribute Woocommerce - 需要根据邮政编码将电子邮件发送到特定地址 https://stackoverflow.com/questions/26429482/woocommerce-need-to-send-email-to-specific-address-based-on-zip-code

这是我的插件类文件中的代码:

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

/**
 * A custom WAKIKI Order WooCommerce Email class
 *
 * @since 0.1
 * @extends \WC_Email
 */

class WC_Wakiki_Order_Email extends WC_Email {


/**
 * Set email defaults
 *
 * @since 0.1
 */
public function __construct() {

    // set ID, this simply needs to be a unique name
    $this->id = 'wc_wakiki_order';

    // this is the title in WooCommerce Email settings
    $this->title = 'WAKIKI Order';

    // this is the description in WooCommerce email settings
    $this->description = 'WAKIKI Order Notification emails are sent when a customer places an order on the website';

    // these are the default heading and subject lines that can be overridden using the settings
    $this->heading = 'WAKIKI Delivery Order';
    $this->subject = 'WAKIKI Delivery Order';

    // these define the locations of the templates that this email should use, we'll just use the new order template since this email is similar
    $this->template_html  = 'emails/admin-new-order.php';
    $this->template_plain = 'emails/plain/admin-new-order.php';

    // Trigger on new paid orders
    add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
    add_action( 'woocommerce_order_status_failed_to_processing_notification',  array( $this, 'trigger' ) );

    // Call parent constructor to load any other defaults not explicity defined here
    parent::__construct();

    // this sets the recipient to the settings defined below in init_form_fields()
    $this->recipient = $this->get_option( 'recipient' );

    // if none was entered, just use the WP admin email as a fallback
    if ( ! $this->recipient )
        $this->recipient = get_option( 'admin_email' );
}


/**
 * Determine if the email should actually be sent and setup email merge variables
 *
 * @since 0.1
 * @param int $order_id
 */
public function trigger( $order_id ) {

    // Bail if no order ID is present
    if ( ! $order_id )
        return;

      $order = new WC_Order( $order_id );

      // Find the product_id
      $items = $order->get_items();
      foreach ( $items as $item ) {
          $product_id = $item['product_id'];
      }
            // From the product_id get the product attribute
            $product = new WC_Product( $product_id );  // create an object of WC_Product class

            $patt = $product->get_attributes();  // call get_attributes method

            // Condition valid to send the email (if the attributes is chef)
            if ( array_key_exists('pa_chef', $patt) ) 

            // Determine which email address to send to, based on Product Attribute Term)
            add_filter( 'new_order' , 'add_recipient', 20, 2 );

            function add_recipient( $email, $order ) {
                $additional_email = "[email protected] /cdn-cgi/l/email-protection";
                $terms = get_terms("pa_chef");
                if( $order->$term->name == "pa_chef-one" ){
                 $email = explode( ',', $email );
                 array_push( $email, $additional_email );
}
return $email;
}



    {
            // Send the email
            // Setup order object
            $this->object = new WC_Order( $order_id );
            $this->recipient    = $this->object->billing_email;

            // Replace variables in the subject/headings
            $this->find[] = '{order_date}';
            $this->replace[] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );

            $this->find[] = '{order_number}';
            $this->replace[] = $this->object->get_order_number();

            if ( ! $this->is_enabled() || ! $this->get_recipient() )
                return;

            // Send the email!
            $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );

        }

        else
        {
            return; //do nothing if there is not chef attribute
        }
}


/**
 * get_content_plain function
 *
 * @since 0.1
 * @return string
 */
public function get_content_plain() {
    ob_start();
    woocommerce_get_template( $this->template_plain, array(
        'order'         => $this->object,
        'email_heading' => $this->get_heading()
    ) );
    return ob_get_clean();
}


/**
 * Initialize Settings Form Fields
 *
 * @since 2.0
 */
public function init_form_fields() {

    $this->form_fields = array(
        'enabled'    => array(
            'title'   => 'Enable/Disable',
            'type'    => 'checkbox',
            'label'   => 'Enable this email notification',
            'default' => 'yes'
        ),
        'recipient'  => array(
            'title'       => 'Recipient(s)',
            'type'        => 'text',
            'description' => sprintf( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', esc_attr( get_option( 'admin_email' ) ) ),
            'placeholder' => '',
            'default'     => ''
        ),
        'subject'    => array(
            'title'       => 'Subject',
            'type'        => 'text',
            'description' => sprintf( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', $this->subject ),
            'placeholder' => '',
            'default'     => ''
        ),
        'heading'    => array(
            'title'       => 'Email Heading',
            'type'        => 'text',
            'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.' ), $this->heading ),
            'placeholder' => '',
            'default'     => ''
        ),
        'email_type' => array(
            'title'       => 'Email type',
            'type'        => 'select',
            'description' => 'Choose which format of email to send.',
            'default'     => 'html',
            'class'       => 'email_type',
            'options'     => array(
                'plain'     => __( 'Plain text', 'woocommerce' ),
                'html'      => __( 'HTML', 'woocommerce' ),
                'multipart' => __( 'Multipart', 'woocommerce' ),
            )
        )
    );
}

这是我所能得到的最接近的结果,但它不起作用。我怀疑问题出在“根据产品属性术语确定要发送到哪个电子邮件地址”这一行。该插件一直在加载,直到我添加该部分。

该函数应该位于单独的插件文件中吗?

我还需要帮助让电子邮件仅包含与其发送到的供应商相关的信息。

任何使该插件正常工作的帮助将不胜感激。


过滤器new_order WooCommerce 中不存在 (或者在你的代码中)

正确的过滤钩(位于WC_Email https://docs.woocommerce.com/wc-apidocs/source-class-WC_Email.html#269类核心代码,第 269 行)是这个吗:

$recipient  = apply_filters( 'woocommerce_email_recipient_' . $this->id, $this->recipient, $this->object );

在这个钩子中,$this->id is 'new_order' 为你。

您的代码中有很大的错误:

  • 术语名称应该类似于"one" or "chef-one", 但绝对不是 "pa_chef-one", as "pa_chef"是您的属性“Chef”的分类别名。
  • 多个电子邮件收件人不在数组中,而是在逗号分隔的字符串中。

所以正确的代码应该是这样的:

add_filter( 'woocommerce_email_recipient_new_order', 'add_recipient', 10, 2 );
function add_recipient( $recipient, $order )
{
    if ( ! is_a( $order, 'WC_Order' ) ) return $recipient;

    // Additional email recipient
    $additional_email = "[email protected] /cdn-cgi/l/email-protection";

    // The term name "pa_chef-one" is very strange … It should be "one" or "chef-one" (may be)
    $term_slug = "one";

    $has_term = false;

    // Iterating through each order item
    foreach ($order->get_items() as $item_id => $item_obj) {
        $variation_id = $item_obj->get_variation_id();
        $variation_obj = wc_get_product($variation_id);
        $variation_attributes = $variation_obj->get_attributes();
        foreach( $variation_attributes as $taxonomy_key => $term_value ){

            if( $taxonomy_key == "pa_chef" && $term_value == $term_slug ){
                $recipient .= ','. $additional_email;
                $has_term = true;
                break; // stop the 2nd loop
            }
        }
        if( $has_term ) break; // stop the 1st loop
    }
    return $recipient;
}

代码位于活动子主题(或主题)的 function.php 文件中或任何插件文件中。

专为 WooCommerce 版本 3+ 打造


类似的答案:

将新订单电子邮件通知附件添加到供应商电子邮件中 https://stackoverflow.com/questions/43367686/add-the-new-order-email-notification-attachment-to-the-vendor-email/43368342#43368342

根据自定义字段有条件地发送 Woocommerce 电子邮件通知收件人 https://stackoverflow.com/questions/45124313/woocommerce-email-notification-recipient-conditionally-based-on-custom-field/45124434#45124434

WooCommerce 电子邮件通知:不同城市的不同电子邮件收件人 https://stackoverflow.com/questions/41940348/woocommerce-email-notifications-different-email-recipient-for-different-cities/41948372#41948372

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据产品变体术语将收件人添加到 Woocommerce 电子邮件通知 的相关文章

  • Laravel $request->file() 返回 null

    尝试在后端使用 Laravel 上传文件时遇到问题 Issue Laravel request gt file 方法返回 null Setup 我使用以下方法构建了一个 AJAX 请求超级代理人 https github com visio
  • 免费 PHP 登录库 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • setcookie with expire=0 浏览器关闭后不会过期

    我使用setcookie来制作一个过期 0的cookie 从 PHP 文档来看 link http php net manual en function setcookie php cookie 过期的时间 这是一个 Unix 时间戳 所以
  • 用户可以更改 PHP 中 $_SESSION 的值吗?

    这是我的想法 我想知道是否可能 将信息存储在 PHP 的 SESSION 变量中有多安全 在 SESSION 变量中存储变量有两个潜在的 不安全 风险 另一个答案所描述的第一个称为 会话固定 这里的想法是 由于会话 ID 存储在 cooki
  • 在服务器上找不到本地主机或 phpMyAdmin:如何修复?

    我按照安装说明进行操作PHP MySQL and PHPMyAdmin 但是当我尝试访问时http localhost phpmyadmin 我收到此错误 未找到 在此找不到请求的 URL phpmyadmin 服务器 然后我尝试访问loc
  • 如何使用 PHP 构建正确的 SOAP 请求

    我需要格式化 构建此 SOAP 服务 的请求 http api notificationmessaging com NMSOAP NotificationService wsdl http api notificationmessaging
  • CakePHP 视图包括其他视图

    我有一个 CakePHP 应用程序 在某些时候会显示带有产品媒体 图片或视频 的视图 我想知道是否有某种方式可以包含另一个威胁视频或威胁图片的视图 具体取决于标志 我想将这些 小视图 用于其他几个目的 所以它应该 像 蛋糕组件一样 以便重用
  • Xdebug V3 不会停止 VSCode 中的断点

    我正在尝试使用 VSCode 在 XAMPP 上进行调试 但没有成功 我知道有很多关于这个的问题 我已经尽了一切努力 但仍然行不通 我的 xdebug 扩展确实有一件奇怪的事情 我目前使用 PHP v7 4 12 和 Xdebug 版本 3
  • 如何从网站网址中隐藏 .html 扩展名

    我知道这个问题以前曾被问过 但有人知道隐藏 html 扩展名的好方法吗 我已经尝试了许多代码和许多答案https stackoverflow com https stackoverflow com 但我没有看到结果 那是我再问你一次 我有一
  • 如何在 PHP 的 HTML 页面中显示错误消息?

    我有以下登录表单 login php 其中要求输入用户名和密码
  • 分页显示所有其他页面上第 1 页的相同帖子

    我最近在创建即将发生的事件列表时得到了很多帮助 请参阅此处显示即将举行的活动 包括今天的活动 https stackoverflow com questions 17343615 showing upcoming events includ
  • PHP 中标头的使用

    非常简单的问题 这两个 PHP 版本 5 标头调用中哪一个是 最好的 header Not Modified true 304 header HTTP 1 1 304 Not Modified 我很确定第一个是最多价的 但只是好奇如果在 H
  • 通过互联网IP地址从一台计算机访问xampp到另一台计算机

    我试图从另一台计算机访问我的 xampp 它显示为禁止错误 然后我在 google 上搜索答案 因为他们告诉在 apache 文件夹中的 httpd conf 文件中更改一些设置 如下所示 Order Deny Allow Deny fro
  • PHP 编码风格回归;在开关/外壳中

    我们正在尝试为我们的团队实施新的编码风格指南 当未找到 break 时 php codeniffer 会在 switch case 语句上打印警告 如下所示 switch foo case 1 return 1 case 2 return
  • 如何处理 REST api 中的 php 通知、警告和错误?

    在 REST API 中 200 响应表明操作成功 PHP 默认情况下直接在响应正文中输出错误消息 而不更改响应代码 在 SPA 中 用户无法直接看到响应文本 因此 当应用程序未按预期工作时 我通过 FireBug 检查响应正文 以检查可能
  • 字符串相似度的算法(比Levenshtein和similar_text更好)? php, Js

    在哪里可以找到比 levenshtein 和 phpimilar text 方法更准确地评估错误字符的拼写的算法 Example similar text jonas xxjon similar echo similar returns 6
  • PHP session_regenerate_id 和黑莓浏览器

    问候 我正在开发一个登录系统 并陷入了黑莓浏览器身份验证的困境 他们似乎对 PHP 的 session regenerate id 有问题 有人可以建议替代方案吗 以下是身份验证和登录脚本 UPDATE看来会话一般都不起作用 拿出 sess
  • 在本地 SDK 服务器上工作时,实时 Google App Engine 上出现 404

    我已经在GAE标准环境上部署了几个PHP应用程序 一切正常 现在我正在部署一个新应用程序 该应用程序位于由gcloudSDK按预期工作 终端命令 dev appserver py log level warning app yaml 问题是
  • 联系表格 7 自动添加 p 标签

    我在联系表单 7 编辑器中有下一个代码 div class row div class col sm 8 col sm offset 2 div class row div class col sm 4 text name class bo
  • PHP更改小数点分隔符

    在某些情况下 PHP 会在操作后更改小数点分隔符 下面是一个示例 为什么小数点分隔符变成 这是一个多语言网站 在西班牙语版本中 区域设置设置为西班牙语 es ES 小数点分隔符为 这就是为什么正在改变 解决方案是强制 LC NUMERIC

随机推荐