/ Плагины / Пользовательское письмо Woocommerce

Пользовательское письмо Woocommerce

05.03.2021

285

Настроим пользовательское письмо для реализации какого-либо уведомления. Реализация будет в виде плагина.

Плагин пользовательского письма

Основной файл плагина custom-woocommerce-email.php в одноименной папке плагина custom-woocommerce-email

<?php
/**
 * Plugin Name: Custom WooCommerce Email
 */

if ( ! defined( 'ABSPATH' ) ) {
	return;
}


class Custom_WC_Email {

	/**
	 * Custom_WC_Email constructor.
	 */
	public function __construct() {
		// Filtering the emails and adding our own email.
		add_filter( 'woocommerce_email_classes', array( $this, 'register_email' ), 90, 1 );
		
		// Absolute path to the plugin folder.
		define( 'CUSTOM_WC_EMAIL_PATH', plugin_dir_path( __FILE__ ) );
	}

	/**
	 * @param array $emails
	 *
	 * @return array
	 */
	public function register_email( $emails ) {
		require_once 'emails/class-wc-customer-cancel-order.php';

		$emails['WC_Customer_Cancel_Order'] = new WC_Customer_Cancel_Order();

		return $emails;
	}
}

new Custom_WC_Email();

В папке custom-woocommerce-email создаем еще 2 папки: emails и templates. В папке emails будут содержаться вызовы и настройки пользовательских писем, а в templates шаблоны.

Настройки письма

Создаем в папке emails файл class-wc-customer-cancel-order.php с содержимым

<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

if ( ! class_exists( 'WC_Email' ) ) {
	return;
}

/**
 * Class WC_Customer_Cancel_Order
 */
class WC_Customer_Cancel_Order extends WC_Email {

	/**
	 * Create an instance of the class.
	 *
	 * @access public
	 * @return void
	 */
	function __construct() {
    // Email slug we can use to filter other data.
		$this->id          = 'wc_customer_cancelled_order';
		$this->title       = __( 'Cancelled Order to Customer', 'custom-wc-email' );
		$this->description = __( 'An email sent to the customer when an order is cancelled.', 'custom-wc-email' );
    // For admin area to let the user know we are sending this email to customers.
		$this->customer_email = true;
		$this->heading     = __( 'Order Cancelled', 'custom-wc-email' );
		// translators: placeholder is {blogname}, a variable that will be substituted when email is sent out
		$this->subject     = sprintf( _x( '[%s] Order Cancelled', 'default email subject for cancelled emails sent to the customer', 'custom-wc-email' ), '{blogname}' );
    
    // Template paths.
		$this->template_html  = 'emails/wc-customer-cancelled-order.php';
		$this->template_plain = 'emails/plain/wc-customer-cancelled-order.php';
		$this->template_base  = CUSTOM_WC_EMAIL_PATH . 'templates/';
    
    // Action to which we hook onto to send the email.
		add_action( 'woocommerce_order_status_pending_to_cancelled_notification', array( $this, 'trigger' ) );
		add_action( 'woocommerce_order_status_on-hold_to_cancelled_notification', array( $this, 'trigger' ) );

		parent::__construct();
	}
	
	
	
	/**
	 * Trigger Function that will send this email to the customer.
	 *
	 * @access public
	 * @return void
	 */
	function trigger( $order_id ) {
		$this->object = wc_get_order( $order_id );

		if ( version_compare( '3.0.0', WC()->version, '>' ) ) {
			$order_email = $this->object->billing_email;
		} else {
			$order_email = $this->object->get_billing_email();
		}

		$this->recipient = $order_email;


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

		$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
	}	
	
	

  /**
	 * Get content html.
	 *
	 * @access public
	 * @return string
	 */
	public function get_content_html() {
		return wc_get_template_html( $this->template_html, array(
			'order'         => $this->object,
			'email_heading' => $this->get_heading(),
			'sent_to_admin' => false,
			'plain_text'    => false,
			'email'			=> $this
		), '', $this->template_base );
	}

	/**
	 * Get content plain.
	 *
	 * @return string
	 */
	public function get_content_plain() {
		return wc_get_template_html( $this->template_plain, array(
			'order'         => $this->object,
			'email_heading' => $this->get_heading(),
			'sent_to_admin' => false,
			'plain_text'    => true,
			'email'			=> $this
		), '', $this->template_base );
	}	
	
	
	
}

Данное письмо будет отправляться клиенту при отмененном заказе. По умолчанию такого письма в системе нет. Событие по которому должно быть отправлено письмо определяется здесь (в данном примере при переходе со статуса В ожидании оплаты в Отменён, и из На удержании в Отменён):

// Action to which we hook onto to send the email.
add_action( 'woocommerce_order_status_pending_to_cancelled_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_on-hold_to_cancelled_notification', array( $this, 'trigger' ) );

$this->recipient = $order_email; — задается кому будет отправлено письмо. Можно заменить чтобы приходило администратору:

$this->recipient = get_option( 'admin_email' );

Шаблон письма

Далее создадим сам шаблон письма, для этого заводим внутри папки templates папку emails, а внутри неё папку plain.

В папке templates/emails/ создаем файл wc-customer-cancelled-order.php с содержимым шаблона:

<?php
/**
 * Cancelled Order sent to Customer.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * @hooked WC_Emails::email_header() Output the email header
 */
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>

	<p><?php printf( __( 'The order #%d has been cancelled. Order Details:', 'woocommerce' ), $order->get_order_number() ); ?></p>

<?php

/**
 * @hooked WC_Emails::order_details() Shows the order details table.
 * @hooked WC_Emails::order_schema_markup() Adds Schema.org markup.
 * @since 2.5.0
 */
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::order_meta() Shows order meta data.
 */
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::customer_details() Shows customer details
 * @hooked WC_Emails::email_address() Shows email address
 */
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::email_footer() Output the email footer
 */
do_action( 'woocommerce_email_footer', $email );

И в папке templates/emails/plain/ также создаем файл wc-customer-cancelled-order.php с содержимым шаблона (упрощенного, текстового):

<?php
/**
 * Admin cancelled order email (plain text)
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/admin-cancelled-order.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see 	    https://docs.woothemes.com/document/template-structure/
 * @author  	WooThemes
 * @package 	WooCommerce/Templates/Emails/Plain
 * @version 	2.5.0
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

echo "= " . $email_heading . " =\n\n";

echo sprintf( __( 'The order #%d has been cancelled. The order details:', 'woocommerce' ), $order->get_id() ) . "\n\n";

echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";

/**
 * @hooked WC_Emails::order_details() Shows the order details table.
 * @hooked WC_Emails::order_schema_markup() Adds Schema.org markup.
 * @since 2.5.0
 */
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );

echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";

/**
 * @hooked WC_Emails::order_meta() Shows order meta data.
 */
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );

/**
 * @hooked WC_Emails::customer_details() Shows customer details
 * @hooked WC_Emails::email_address() Shows email address
 */
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );

echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";

echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );

По материалам сайта: www.ibenic.com

Альтернативный способ

Структура папок и файлов та же как в предыдущем решении.

Создание плагина

<?php 
/**
 * Plugin Name: WooCommerce Custom Email 2
 */

if ( ! defined( 'ABSPATH' ) ) {
	return;
}


class Custom_Email_Manager {

	/**
	 * Constructor sets up actions
	 */
	public function __construct() {
	    
	    // template path
	    define( 'CUSTOM_TEMPLATE_PATH', untrailingslashit( plugin_dir_path( __FILE__ ) ) . '/templates/' );
	    // hook for when order status is changed
	    add_action( 'woocommerce_order_status_pending', array( &$this, 'custom_trigger_email_action' ), 10, 2 );
	    // include the email class files
	    add_filter( 'woocommerce_email_classes', array( &$this, 'custom_init_emails' ) );
		
	    // Email Actions - Triggers
	    $email_actions = array(
            
		    'custom_pending_email',
		    'custom_item_email',
	    );

	    foreach ( $email_actions as $action ) {
	        add_action( $action, array( 'WC_Emails', 'send_transactional_email' ), 10, 10 );
	    }
		
	    add_filter( 'woocommerce_template_directory', array( $this, 'custom_template_directory' ), 10, 2 );
		
	}
	
	public function custom_init_emails( $emails ) {
	    // Include the email class file if it's not included already
	    if ( ! isset( $emails[ 'Custom_Email' ] ) ) {
	        $emails[ 'Custom_Email' ] = include_once( 'emails/class-custom-email.php' );
	    }
	
	    return $emails;
	}
	
	public function custom_trigger_email_action( $order_id, $posted ) {
	     // add an action for our email trigger if the order id is valid
	    if ( isset( $order_id ) && 0 != $order_id ) {
	        
	        new WC_Emails();
    		do_action( 'custom_pending_email_notification', $order_id );
	    
	    }
	}
	
	public function custom_template_directory( $directory, $template ) {
	   // ensure the directory name is correct
	    if ( false !== strpos( $template, '-custom' ) ) {
	      return 'my-custom-email';
	    }
	
	    return $directory;
	}
	
}// end of class
new Custom_Email_Manager();
?>

Создание шаблона письма (class-custom-email.php)

<?php 
/**
 * Custom Email
 *
 * An email sent to the admin when an order status is changed to Pending Payment.
 * 
 * @class       Custom_Email
 * @extends     WC_Email
 *
 */
class Custom_Email extends WC_Email {
    
    function __construct() {
        
        // Add email ID, title, description, heading, subject
        $this->id                   = 'custom_email';
        $this->title                = __( 'Custom Item Email', 'custom-email' );
        $this->description          = __( 'This email is received when an order status is changed to Pending.', 'custom-email' );
        
        $this->heading              = __( 'Custom Item Email', 'custom-email' );
        $this->subject              = __( '[{blogname}] Order for {product_title} (Order {order_number}) - {order_date}', 'custom-email' );
        
        // email template path
        $this->template_html    = 'emails/custom-item-email.php';
        $this->template_plain   = 'emails/plain/custom-item-email.php';
        
        // Triggers for this email
        add_action( 'custom_pending_email_notification', array( $this, 'queue_notification' ) );
        add_action( 'custom_item_email_notification', array( $this, 'trigger' ) );
        
        // Call parent constructor
        parent::__construct();
        
        // Other settings
        $this->template_base = CUSTOM_TEMPLATE_PATH;
        // default the email recipient to the admin's email address
        $this->recipient     = $this->get_option( 'recipient', get_option( 'admin_email' ) );
        
    }
    
    public function queue_notification( $order_id ) {
        
        $order = new WC_order( $order_id );
        $items = $order->get_items();
        // foreach item in the order
        foreach ( $items as $item_key => $item_value ) {
            // add an event for the item email, pass the item ID so other details can be collected as needed
            wp_schedule_single_event( time(), 'custom_item_email', array( 'item_id' => $item_key ) );
        }
    }
    
    // This function collects the data and sends the email
    function trigger( $item_id ) {
        
        $send_email = true;
        // validations
        if ( $item_id && $send_email ) {
            // create an object with item details like name, quantity etc.
            $this->object = $this->create_object( $item_id );
            
            // replace the merge tags with valid data
            $key = array_search( '{product_title}', $this->find );
            if ( false !== $key ) {
                unset( $this->find[ $key ] );
                unset( $this->replace[ $key ] );
            }
                
            $this->find[]    = '{product_title}';
            $this->replace[] = $this->object->product_title;
        
            if ( $this->object->order_id ) {
                
                $this->find[]    = '{order_date}';
                $this->replace[] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) );
        
                $this->find[]    = '{order_number}';
                $this->replace[] = $this->object->order_id;
            } else {
                    
                $this->find[]    = '{order_date}';
                $this->replace[] = __( 'N/A', 'custom-email' );
        
                $this->find[]    = '{order_number}';
                $this->replace[] = __( 'N/A', 'custom-email' );
            }
    
            // if no recipient is set, do not send the email
            if ( ! $this->get_recipient() ) {
                return;
            }
            // send the email
            $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers() );

        }
    }
    
    // Create an object with the data to be passed to the templates
    public static function create_object( $item_id ) {
    
        global $wpdb;
    
        $item_object = new stdClass();
        
        // order ID
        $query_order_id = "SELECT order_id FROM `". $wpdb->prefix."woocommerce_order_items`
                            WHERE order_item_id = %d";
        $get_order_id = $wpdb->get_results( $wpdb->prepare( $query_order_id, $item_id ) );
    
        $order_id = 0;
        if ( isset( $get_order_id ) && is_array( $get_order_id ) && count( $get_order_id ) > 0 ) {
            $order_id = $get_order_id[0]->order_id;
        } 
        $item_object->order_id = $order_id;
    
        $order = new WC_order( $order_id );
    
        // order date
        $post_data = get_post( $order_id );
        $item_object->order_date = $post_data->post_date;
    
        // product ID
        $item_object->product_id = wc_get_order_item_meta( $item_id, '_product_id' );
    
        // product name
        $_product = wc_get_product( $item_object->product_id );
        $item_object->product_title = $_product->get_title();    

        // qty
        $item_object->qty = wc_get_order_item_meta( $item_id, '_qty' );
        
        // total
        $item_object->total = wc_price( wc_get_order_item_meta( $item_id, '_line_total' ) );

        // email adress
        $item_object->billing_email = ( version_compare( WOOCOMMERCE_VERSION, "3.0.0" ) < 0 ) ? $order->billing_email : $order->get_billing_email();
    
        // customer ID
        $item_object->customer_id = ( version_compare( WOOCOMMERCE_VERSION, "3.0.0" ) < 0 ) ? $order->user_id : $order->get_user_id();
    
        return $item_object;
    
    }
    
    // return the html content
    function get_content_html() {
        ob_start();
        wc_get_template( $this->template_html, array(
        'item_data'       => $this->object,
        'email_heading' => $this->get_heading()
        ), 'my-custom-email/', $this->template_base );
        return ob_get_clean();
    }

    // return the plain content
    function get_content_plain() {
        ob_start();
        wc_get_template( $this->template_plain, array(
            'item_data'       => $this->object,
            'email_heading' => $this->get_heading()
            ), 'my-custom-email/', $this->template_base );
        return ob_get_clean();
    }
    
    // return the subject
    function get_subject() {
        
        $order = new WC_order( $this->object->order_id );
        return apply_filters( 'woocommerce_email_subject_' . $this->id, $this->format_string( $this->subject ), $this->object );
        
    }
    
    // return the email heading
    public function get_heading() {
        
        $order = new WC_order( $this->object->order_id );
        return apply_filters( 'woocommerce_email_heading_' . $this->id, $this->format_string( $this->heading ), $this->object );
        
    }
    
    // form fields that are displayed in WooCommerce->Settings->Emails
    function init_form_fields() {
        $this->form_fields = array(
            'enabled' => array(
                'title' 		=> __( 'Enable/Disable', 'custom-email' ),
                'type' 			=> 'checkbox',
                'label' 		=> __( 'Enable this email notification', 'custom-email' ),
                'default' 		=> 'yes'
            ),
            'recipient' => array(
                'title'         => __( 'Recipient', 'custom-email' ),
                'type'          => 'text',
                'description'   => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to %s', 'custom-email' ), get_option( 'admin_email' ) ),
                'default'       => get_option( 'admin_email' )
            ),
            'subject' => array(
                'title' 		=> __( 'Subject', 'custom-email' ),
                'type' 			=> 'text',
                'description' 	=> sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', 'custom-email' ), $this->subject ),
                'placeholder' 	=> '',
                'default' 		=> ''
            ),
            'heading' => array(
                'title' 		=> __( 'Email Heading', 'custom-email' ),
                'type' 			=> 'text',
                'description' 	=> sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.', 'custom-email' ), $this->heading ),
                'placeholder' 	=> '',
                'default' 		=> ''
            ),
            'email_type' => array(
                'title' 		=> __( 'Email type', 'custom-email' ),
                'type' 			=> 'select',
                'description' 	=> __( 'Choose which format of email to send.', 'custom-email' ),
                'default' 		=> 'html',
                'class'			=> 'email_type',
                'options'		=> array(
                    'plain'		 	=> __( 'Plain text', 'custom-email' ),
                    'html' 			=> __( 'HTML', 'custom-email' ),
                    'multipart' 	=> __( 'Multipart', 'custom-email' ),
                )
            )
        );
    }
    
}
return new Custom_Email();
?>

Создание шаблона HTML (custom-item-email-html.php)

<?php
/**
 * Admin new order email
 */
$order = new WC_order( $item_data->order_id );
$opening_paragraph = __( 'A new order has been made by %s. The details of the item are as follows:', 'custom-email' );

?>

<?php do_action( 'woocommerce_email_header', $email_heading ); ?>

<?php
$billing_first_name = ( version_compare( WOOCOMMERCE_VERSION, "3.0.0" ) < 0 ) ? $order->billing_first_name : $order->get_billing_first_name();
$billing_last_name = ( version_compare( WOOCOMMERCE_VERSION, "3.0.0" ) < 0 ) ? $order->billing_last_name : $order->get_billing_last_name(); 
if ( $order && $billing_first_name && $billing_last_name ) : ?>
	<p><?php printf( $opening_paragraph, $billing_first_name . ' ' . $billing_last_name ); ?></p>
<?php endif; ?>

<table cellspacing="0" cellpadding="6" style="width: 100%; border: 1px solid #eee;" border="1" bordercolor="#eee">
	<tbody>
		<tr>
			<th scope="row" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Ordered Product', 'custom-email' ); ?></th>
			<td style="text-align:left; border: 1px solid #eee;"><?php echo $item_data->product_title; ?></td>
		</tr>
		<tr>
			<th scope="row" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Quantity', 'custom-email' ); ?></th>
			<td style="text-align:left; border: 1px solid #eee;"><?php echo $item_data->qty; ?></td>
		</tr>
		<tr>
			<th scope="row" style="text-align:left; border: 1px solid #eee;"><?php _e( 'Total', 'custom-email' ); ?></th>
			<td style="text-align:left; border: 1px solid #eee;"><?php echo $item_data->total; ?></td>
		</tr>
	</tbody>
</table>

<p><?php _e( 'This is a custom email sent as the order status has been changed to Pending Payment.', 'custom-email' ); ?></p>

<p><?php echo make_clickable( sprintf( __( 'You can view and edit this order in the dashboard here: %s', 'custom-email' ), admin_url( 'post.php?post=' . $item_data->order_id . '&action=edit' ) ) ); ?></p>

<?php do_action( 'woocommerce_email_footer' ); ?>

Создание текстового шаблона (custom-item-email-plain.php)

<?php
/**
 * Admin new order email
 */
$order = new WC_order( $item_data->order_id );

echo "= " . $email_heading . " =\n\n";

$opening_paragraph = __( 'A new order has been made by %s. The details of the item are as follows:', 'custom-email' );

$billing_first_name = ( version_compare( WOOCOMMERCE_VERSION, "3.0.0" ) < 0 ) ? $order->billing_first_name : $order->get_billing_first_name();
$billing_last_name = ( version_compare( WOOCOMMERCE_VERSION, "3.0.0" ) < 0 ) ? $order->billing_last_name : $order->get_billing_last_name(); 
if ( $order && $billing_first_name && $billing_last_name ) {
	echo sprintf( $opening_paragraph, $billing_first_name . ' ' . $billing_last_name ) . "\n\n";
}

echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";

echo sprintf( __( 'Ordered Product: %s', 'custom-email' ), $item_data->product_title ) . "\n";

echo sprintf( __( 'Quantity: %s', 'custom-email' ), $item_data->qty ) . "\n";

echo sprintf( __( 'Total: %s', 'custom-email' ), $item_data->total ) . "\n";

echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";

echo __( 'This is a custom email sent as the order status has been changed to Pending Payment.', 'custom-email' ) . "\n\n";

echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Разбираем woocommerce на молекулы

Разбираем woocommerce на молекулы

В данном материале разбираем некоторые хуки woocommerce, их последовательность, а также в структуру шаблонов WC и их проверку. Добавляем стандартные хлебные крошки WC <?php woocommerce_breadcrumb(); ?> Файлы шаблона: archive-product.php — Читать далее »

Акция 20% на каждый второй и 30% на каждый 3 товар

Акция 20% на каждый второй и 30% на каждый 3 товар

Немного измененный и доработанный вариант акции (20% на 3 товар, 30% на 4 товар). В данном случае немного изменен принцип применения акции. Если в предыдущем примере акция применялась буквально к Читать далее »

Различные наработки по Woocommerce

Различные наработки по Woocommerce

Очередной сборник различных наработок для плагина Woocommerce. Изменить вывод заголовка товара Выведем вместо заголовка краткий заголовок, созданный в виде дополнительного поля. Создание поля Выводы в каталоге и карточке товара. Если Читать далее »

Добавить комментарий

Пока нет комментариев. Будь первым!

Пользовательское письмо Woocommerce
Цены в зависимости от группы пользователей
Рекомендации для васЦены в зависимости от группы пользователейOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.