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

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

HIT

05.03.2021

1787

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

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

Основной файл плагина 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' ) );
[site-socialshare]
  • Похожие записи
  • Комментарии
  • Вложения
Watermark для изображений товаров (обзор плагинов)

Watermark для изображений товаров (обзор плагинов)

Рассмотрим различные плагины по добавлению водяного знака (watermark) на изображения товаров. WooCommerce Products Image Watermark (BeRocket) Плагин не понравился. Логотип добавляется только одним способом, с указанием положения. Можно перезагрузить загруженные Читать далее »

WooCommerce and 1C:Enterprise

WooCommerce and 1C:Enterprise

Разбираем на элементы плагин WooCommerce and 1C:Enterprise/1С:Предприятие Data Exchange. Плагин дает функционал обмена данными между сайтом и программой 1С: Предприятие. Некоторые моменты синхронизации сайта с 1С описаны в статье Интеграция Читать далее »

Доработка функционала Woocommerce

Доработка функционала Woocommerce

Продолжаем дорабатывать различные аспекты модуля Woocommerce. Общий вес заказа Чтобы выводить общий вес заказа, нужно в шаблонах cart-totals.php (в корзине) и/или review-order.php (в заказе) добавить следующий код (перед закрывающим тегом Читать далее »

/ /

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

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

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