Собственное письмо
Стандартных писем хватает не всегда. В уроке о состояниях появилось состояние «Изготовлен» — о нём покупателю ничего не приходит. Своё письмо — это класс, наследующий WC_Email: он получает строку в настройках, тему, шаблон и оформление, общие со всеми письмами магазина.
Класс письма
Создайте файл includes/class-acme-email-ready.php:
// wp-content/plugins/acme-shop/includes/class-acme-email-ready.php
class Acme_Email_Ready extends WC_Email
{
public function __construct()
{
$this->id = 'acme_ready';
$this->customer_email = true;
$this->title = 'Заказ изготовлен';
$this->description = 'Отправляется покупателю, когда заказ изготовлен.';
$this->template_html = 'emails/acme-ready.php';
$this->template_base = dirname(__DIR__) . '/templates/';
$this->placeholders = ['{order_number}' => ''];
parent::__construct();
}
public function get_default_subject(): string
{
return 'Заказ №{order_number} изготовлен';
}
public function get_default_heading(): string
{
return 'Ваш заказ готов';
}
}Свойства задают идентификатор, название в панели и путь к шаблону. customer_email означает, что письмо уходит покупателю. Метка {order_number} в теме заменится номером заказа.
Отправка
Добавьте в класс два метода:
// wp-content/plugins/acme-shop/includes/class-acme-email-ready.php
public function trigger(int $orderId): void
{
$this->object = wc_get_order($orderId);
if (!$this->object || !$this->is_enabled()) {
return;
}
$this->recipient = $this->object->get_billing_email();
$this->placeholders['{order_number}'] = $this->object->get_order_number();
$this->send(
$this->get_recipient(),
$this->get_subject(),
$this->get_content(),
$this->get_headers(),
$this->get_attachments()
);
}
public function get_content_html(): string
{
return wc_get_template_html(
$this->template_html,
['order' => $this->object, 'email_heading' => $this->get_heading(), 'email' => $this],
'',
$this->template_base
);
}trigger() находит заказ, подставляет получателя и отправляет письмо. get_content_html() собирает тело письма из шаблона и передаёт в него переменные.
Шаблон
Создайте файл templates/emails/acme-ready.php:
<!-- wp-content/plugins/acme-shop/templates/emails/acme-ready.php -->
<?php do_action('woocommerce_email_header', $email_heading, $email); ?>
<p>Здравствуйте, <?php echo esc_html($order->get_billing_first_name()); ?>!</p>
<p>Заказ №<?php echo esc_html($order->get_order_number()); ?> изготовлен и завтра будет передан в доставку.</p>
<?php do_action('woocommerce_email_footer', $email); ?>Хуки шапки и подвала выводят общее оформление магазина: логотип, цвета, подпись. Настоящий файл начинается с <?php.
Регистрация
// wp-content/plugins/acme-shop/includes/emails.php
add_filter('woocommerce_email_classes', function (array $emails): array {
require_once __DIR__ . '/class-acme-email-ready.php';
$emails['Acme_Email_Ready'] = new Acme_Email_Ready();
return $emails;
});Файл класса подключается внутри фильтра: класс WC_Email загружается только к этому моменту. Откройте «WooCommerce → Настройки → Email» — в списке появилась строка «Заказ изготовлен», где письмо можно выключить или изменить тему.
Запуск по состоянию
// wp-content/plugins/acme-shop/includes/emails.php
add_action('woocommerce_order_status_ready', function (int $orderId) {
$emails = WC()->mailer()->get_emails();
if (isset($emails['Acme_Email_Ready'])) {
$emails['Acme_Email_Ready']->trigger($orderId);
}
});WC()->mailer() загружает все письма магазина. Переведите заказ в состояние «Изготовлен» в панели: покупателю придёт письмо с темой «Заказ №1024 изготовлен».
Из чего состоит письмо
| Часть | Где |
|---|---|
| Класс | includes/class-acme-email-ready.php |
| Шаблон | templates/emails/acme-ready.php |
| Регистрация | Фильтр woocommerce_email_classes |
| Запуск | Хук состояния заказа и метод trigger() |
Частая ошибка
Файл класса подключают в главном файле плагина рядом с остальными require. В этот момент класса WC_Email ещё нет, и сайт падает с ошибкой «класс не найден». Подключайте класс письма только внутри фильтра woocommerce_email_classes.