Как использовать PHPmailer в функции WordPress
У меня есть функция в файле functions.php WordPress, которая ищет определенное условие в метаданных пользователя и отправляет email пользователю на основе найденного. Сейчас я использую wp_mail() для отправки писем, и это работает. Однако я хочу использовать встроенный класс PHPMailer, чтобы отправлять сообщения через SMTP.
Я думал, что нашел решение здесь: https://codex.wordpress.org/Plugin_API/Action_Reference/phpmailer_init, однако это, похоже, применимо только к системным сообщениям, а не к пользовательским.
На данный момент я просто предполагаю, но попробовал следующее, безуспешно (WordPress перестает загружаться в этой точке, без сообщения об ошибке):
function my_function() {
// если что-то найдено, отправляем email
global $phpmailer;
$phpmailer->IsSMTP();
$phpmailer->Host = 'smtp.google.com';
$phpmailer->Port = '587';
$phpmailer->SMTPSecure = 'tls';
$phpmailer->SMTPAuth = true;
$phpmailer->Username = 'something@gmail.com';
$phpmailer->Password = '11111111';
$phpmailer->addAddress('joe@example.com', 'Joe User');
$phpmailer->setFrom('from@example.com', 'Mailer');
$phpmailer->addReplyTo('info@example.com', 'Information');
$phpmailer->isHTML(true);
$phpmailer->Subject = 'Here is the subject';
$phpmailer->Body = 'This is the HTML message body <b>in bold!</b>';
$phpmailer->send();
// Email отправлен; функция завершена
}
Для информации: я вызываю эту функцию в header. Я не добавляю её как действие (action), потому что хочу контролировать, где она используется.
Есть ли способ получить прямой доступ к классу PHPMailer из моей функции? Я мог бы загрузить PHPMailer отдельно, но это кажется неразумным.
Нет необходимости использовать класс PHPMailer вместо функции wp_mail()
. wp_mail()
по сути является оберткой для этого класса. Она просто предоставляет более удобный способ упаковки и отправки сообщения.
Вы можете получить доступ к элементам PHPMailer во время его инициализации, чтобы wp_mail()
отправляла письма через SMTP вместо веб-сервера.
Вы сказали, что не добавляете это как действие для контроля места использования, но именно для этого и нужны хуки действий — они позволяют подключить ваш код именно там и тогда, где и когда вам нужно.
В данном случае все эти параметры PHPMailer должны быть установлены при его инициализации. Для этого существует хук действия — phpmailer_init
.
Вы можете определить свои настройки при инициализации PHPMailer, используя этот хук:
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = 'smtp.google.com';
$phpmailer->Port = '587';
$phpmailer->SMTPSecure = 'tls';
$phpmailer->SMTPAuth = true;
$phpmailer->Username = 'something@gmail.com';
$phpmailer->Password = '11111111';
$phpmailer->From = 'from@example.com';
$phpmailer->FromName = 'From Name';
$phpmailer->addReplyTo('info@example.com', 'Information');
}
Вы хотите, чтобы ваше сообщение было в HTML. Вы могли бы установить это в аргументе заголовка wp_mail()
, но лучше использовать фильтр wp_mail_content_type
:
add_filter( 'wp_mail_content_type','set_my_mail_content_type' );
function set_my_mail_content_type() {
return "text/html";
}
После правильной настройки вы можете использовать wp_mail()
для отправки сообщения в любом месте. Я рекомендую привязать эту функцию к чему-то осмысленному, например, к 'template_redirect', чтобы выполнить отправку до отправки заголовков:
function my_function() {
$to = 'joe@example.com';
$subject = 'Here is the subject';
$message = 'This is the HTML message body <b>in bold!</b>';
wp_mail( $to, $subject, $message );
}
Обновление: Альтернативный (изолированный) метод:
Расширяя описанное выше, предположим, что некоторые из этих настроек не являются стандартными для каждого вызова wp_mail()
, и вы хотите использовать их только для конкретного письма.
Вам все равно придется вынести настройки и подключить их соответствующим образом (иначе они не будут обработаны в нужное время). Учитывая, что хуки phpmailer_init
и wp_mail_content_type
срабатывают во время выполнения wp_mail()
, вы можете установить эти хуки внутри вашей основной функции, отправить письмо, а затем удалить их, чтобы вернуться к настройкам по умолчанию.
function send_smtp_email( $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = 'smtp.google.com';
$phpmailer->Port = '587';
$phpmailer->SMTPSecure = 'tls';
$phpmailer->SMTPAuth = true;
$phpmailer->Username = 'something@gmail.com';
$phpmailer->Password = '11111111';
$phpmailer->From = 'from@example.com';
$phpmailer->FromName = 'From Name';
$phpmailer->addReplyTo('info@example.com', 'Information');
}
function set_my_mail_content_type() {
return "text/html";
}
function my_function() {
$to = 'joe@example.com';
$subject = 'Here is the subject';
$message = 'This is the HTML message body <b>in bold!</b>';
add_filter( 'wp_mail_content_type','set_my_mail_content_type' );
add_action( 'phpmailer_init', 'send_smtp_email' );
wp_mail( $to, $subject, $message );
remove_filter( 'wp_mail_content_type','set_my_mail_content_type' )
remove_action( 'phpmailer_init', 'send_smtp_email' );
}

Использование вызова к файлу ядра WP не всегда является лучшим решением. Это работает сейчас, но что если что-то изменится в будущей версии? Всегда лучше использовать существующие действия ядра, как это должным образом задокументировано, чтобы сохранить совместимость в будущих обновлениях.
