Adding recipients to Woocommerce email notifications based on product variation term

旧街凉风 提交于 2021-02-08 07:32:34

问题


I have created a Woocommerce plugin and require it to do two things:

  1. Send a notification message to a specific email address, based on which product variation is in the cart.

  2. The email must contain only the relevant product, and not products that contain other attributes.

For example:

Product A has an Attribute named Chef, with chef-one and chef-two as variable Terms. The user may select Product A from chef-one or chef-two.

If the user selects Product A from chef-one, a notification email must be sent to chefone@email.com containing the name of the product ordered (as it would show up in a regular Woocommerce notification email).

If the user selects Product A from chef-one and Product B from chef-two, a notification email must be sent to chef-one containing only Product A, and a notification email must be sent to chef-two containing only Product B.

I have created the plugin using the tutorial found on https://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/ and have adapted it to suit the above purpose.

I have also adapted code found the following solutions: Adding a custom woocommerce email based on the product attribute Woocommerce - Need to send email to specific address based on zip code

Here is the code from my plugin's class file:

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' ),
            )
        )
    );
}

This is as close as I am able to get it, but it is not working. I suspect the problem lies somewhere around the line that says "Determine which email address to send to, based on Product Attribute Term". The plugin was loading until I added that section.

Is the function supposed to be in a separate plugin file?

I also need help in getting the email to contain only the information relevant to the vendor it is being sent to.

Any assistance in getting this plugin to work would be greatly appreciated.


回答1:


The filter new_order doesn't exist in WooCommerce (or in your code)

The correct filter hook (located in WC_Email class core code, line 269) is this one:

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

In this hook, $this->id is 'new_order' for you.

There is big errors in your code:

  • The term name should be something like "one" or "chef-one", but absolutely not "pa_chef-one", as "pa_chef" is the taxonomy slug for your attribute "Chef".
  • The multiple email recipients are not in an array, but in a coma separated string.

So the correct code should be something like:

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;
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Made for WooCommerce version 3+


Similar answers:

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



来源:https://stackoverflow.com/questions/45673781/adding-recipients-to-woocommerce-email-notifications-based-on-product-variation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!