Добавление получателей в уведомления по электронной почте Woocommerce в зависимости от срока изменения продукта

Я создал плагин Woocommerce и требую, чтобы он выполнял две вещи:

  1. Отправьте сообщение с уведомлением на определенный адрес электронной почты, в зависимости от того, какой вариант продукта находится в корзине.

  2. В электронном письме должен быть указан только соответствующий товар, а не товары, содержащие другие атрибуты.

Например:

У продукта A есть Атрибут Chef с переменными Условиями chef-one и chef-two. Пользователь может выбрать продукт A из одного или двух шеф-поваров.

Если пользователь выбирает продукт A у chef-one, на адрес [email protected] должно быть отправлено электронное письмо с уведомлением, содержащее название заказанного продукта (как оно будет отображаться в обычном электронном письме с уведомлением Woocommerce).

Если пользователь выбирает продукт A из chef-one и продукт B из chef-two, необходимо отправить электронное письмо с уведомлением для chef-one, содержащее только продукт A, а уведомление по электронной почте должно быть отправлено шеф-повару-two, содержащее только продукт B.

Я создал плагин, используя руководство, которое можно найти на https://www.skyverge.com/blog/how-to-add-a-custom-woocommerce-email/ и адаптировали его для вышеуказанной цели.

Я также адаптировал код и нашел следующие решения: Добавление настраиваемая электронная почта woocommerce на основе атрибута продукта Woocommerce - необходимо отправить электронное письмо на конкретный адрес в соответствии с почтовым индексом

Вот код из файла класса моего плагина:

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

Это настолько близко, насколько я могу понять, но это не работает. Я подозреваю, что проблема кроется где-то в строке, которая гласит: «Определите, на какой адрес электронной почты отправлять сообщения, на основе термина атрибута продукта». Плагин загружался, пока я не добавил этот раздел.

Должна ли функция быть в отдельном файле плагина?

Мне также нужна помощь в получении электронного письма, содержащего только ту информацию, которая имеет отношение к поставщику, которому оно отправляется.

Мы будем очень благодарны за любую помощь в настройке этого плагина.


person Craig de Gouveia    schedule 14.08.2017    source источник
comment
Я обновил код в своем ответе…   -  person LoicTheAztec    schedule 14.08.2017


Ответы (1)


Фильтр new_order не существует в WooCommerce (или в вашем коде)

Правильный обработчик фильтра (находится в WC_Email основной код класса, строка 269):

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

В этом крючке $this->id для вас означает "new_order".

В вашем коде есть большие ошибки:

  • Название термина должно быть примерно таким, как "one" или "chef-one", но ни в коем случае не "pa_chef-one", поскольку "pa_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]";

    // 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+


Подобные ответы:

Добавить уведомление по электронной почте о новом заказе вложение к электронному письму поставщика

< / а>

Уведомления по электронной почте WooCommerce: разные получатели электронной почты для разных городов

person LoicTheAztec    schedule 14.08.2017
comment
Спасибо @LoicTheAztec за ваш отзыв и за улучшения в коде. Я добавил приведенный выше фрагмент в файл класса подключаемого модуля под строкой, в которой говорится: «Определить, на какой адрес электронной почты отправлять и выше» return $ email; - все еще получаю ошибку, когда я активирую плагин. Возвращает получателя $; заменить функцию $ email? Это мой первый плагин, поэтому с моей стороны может потребоваться некоторое количество проб и ошибок. - person Craig de Gouveia; 14.08.2017
comment
@CraigdeGouveia Я не совсем уверен в своем коде на 100%, но ловушка правильная. Аргументы в функции верны. (Я добавил несколько рабочих ссылок на старые ответы с помощью этого крючка в ответ в конце…). Я протестировал весь код цикла foreach, и он тоже работает. Теперь проблема может заключаться в именах терминов или заголовках, которые вы зададите в этой функции. Проблема может быть и в другом месте. Я надеюсь, ты найдешь способ. Но главный вопрос здесь касался крючка, и этот крючок для этого предназначен. - person LoicTheAztec; 14.08.2017