Настроим пользовательское письмо для реализации какого-либо уведомления. Реализация будет в виде плагина.
Плагин пользовательского письма
Основной файл плагина 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]