首页 文章

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

提问于
浏览
1

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

  • 根据购物车中的产品差异,向特定的电子邮件地址发送通知消息 .

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

For example:

产品A有一个名为Chef的属性,其中chef-one和chef-two为变量Terms . 用户可以从Chef-one或chef-two中选择产品A.

如果用户从chef-one中选择产品A,则必须向chefone@email.com发送通知电子邮件,其中包含所订购产品的名称(因为它将显示在常规的Woocommerce通知电子邮件中) .

如果用户从chef-one选择产品A,从chef-two选择产品B,则必须向仅包含产品A的chef-one发送通知电子邮件,并且必须向仅包含产品B的chef-two发送通知电子邮件 .

我使用https://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/上的教程创建了插件,并根据上述目的对其进行了调整 .

我也改编了代码,发现了以下解决方案:Adding a custom woocommerce email based on the product attribute 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 = "info@email.com";
                $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' ),
            )
        )
    );
}

这是我能够得到的尽可能接近,但它无法正常工作 . 我怀疑问题出在“确定要发送到哪个电子邮件地址,基于产品属性术语”这一行的某处 . 该插件正在加载,直到我添加该部分 .

该函数应该在一个单独的插件文件中吗?

我还需要帮助,使电子邮件只包含与发送给它的供应商相关的信息 .

任何帮助使这个插件工作将不胜感激 .

1 回答

  • 0

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

    正确的过滤器钩子(位于WC_Email类核心代码,第269行)是这样的:

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

    在这个钩子中, $this->id 对你来说是' new_order ' .

    您的代码中存在很大错误:

    • 术语名称应该类似于 "one""chef-one"but absolutely not "pa_chef-one" ,因为 "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 = "info@email.com";
    
        // 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制作


    类似的答案:

    Add the New order email notification attachment to the vendor email

    Woocommerce email notification recipient conditionally based on custom field

    WooCommerce email notifications: different email recipient for different cities

相关问题