Цель статьи - показать как просто можно реализовать отправку почтовых сообщений из консоли Yii 2.
Итак, у нас есть некая внутренняя система на базе Yii 2 Basic template, развернутая в следующем немного необычном окружении:
ОС - Windows 2008 R2
Веб-сервер - IIS 7.5
Сервер БД - MS SQL 2014
Почтовый сервер - MS Exchange 2013
Подготовительные работы завершены, переходим к созданию нашей собственной команды.
Создадим папку commands в корне проекта, т.к. она отсутствует в базовом шаблоне Yii, но по умолчанию она используется в качестве значения для controllerNamespace в config\console.php и создадим внутри новый файл с именем MailController.php (при создании файла не забывайте о правилах именования контроллеров)
Здесь всё организовано аналогично обычным контроллерам за исключением необходимости работы с представлением.
Разберем детально, что происходит:
На этом создание собственной консольной команды завершено и мы можем вызвать ее из консоли ОС - yii.bat mail, если всё прошло успешно, то осталось настроить задание в планировщике задач.
Итак, у нас есть некая внутренняя система на базе Yii 2 Basic template, развернутая в следующем немного необычном окружении:
ОС - Windows 2008 R2
Веб-сервер - IIS 7.5
Сервер БД - MS SQL 2014
Почтовый сервер - MS Exchange 2013
В БД есть таблица comment, содержащая комментарии, которые могу быть добавлены как через пользовательский интерфейс приложения, так и напрямую записаны в БД внешними приложениями. Поле sent является флагом отправки уведомления: 0 - уведомление не отправлено, 1 - отправлено.
Если с уведомлениями по комментариям, оставленными пользователями, все понятно: комментарий добавлен, обрабатываем POST, сохраняем данные, отправляем Email, то кто и когда должен обрабатывать комментарии, напрямую записанные внешним приложением в БД? (вопрос архитектуры мы оставим за рамками этой статьи).
На помощь нам приходит yii.bat, который находится в корне проекта и позволяет выполнять как стандартные команды, так и созданные собственными силами. Список стандартных команд можно посмотреть в Документации.
Создадим команду mail, которая будет осуществлять проверку таблицы comment на предмет неотправленных комментариев и рассылать уведомления пользователям.
Для начала нам потребуется настроить компонент для рассылки писем (я использую swiftmailer), для этого в конфигурационном файле config\console.php (аналог web.php для консольных приложений) добавим информацию:
'components' => [
...
'mailer' => [
'class' => 'yii\swiftmailer\Mailer',
'viewPath' => '@app/mail/',
'useFileTransport' => false,
'transport' => [
'class' => 'Swift_SmtpTransport',
'host' => '10.1.1.1', // Адрес вашего smtp сервера
'username' => '',
'password' => '',
'port' => '25', // Порт
'encryption' => '',
],
'messageConfig' => [
'from' => ['robot@example.ru' => 'Почтовый робот']
],
],
],
Как видно из параметров мой сервер не требует ни авторизации, ни шифрования.
Так как консольное приложение запускается вне корня сайта, необходимо явным образом его указать, для этого необходимо настроить компонент urlManager:
Так как консольное приложение запускается вне корня сайта, необходимо явным образом его указать, для этого необходимо настроить компонент urlManager:
'components' => [
...
'urlManager' => [
'class' => 'yii\web\UrlManager',
'scriptUrl' => 'http://yoursite/'
],
],
Подготовительные работы завершены, переходим к созданию нашей собственной команды.
Создадим папку commands в корне проекта, т.к. она отсутствует в базовом шаблоне Yii, но по умолчанию она используется в качестве значения для controllerNamespace в config\console.php и создадим внутри новый файл с именем MailController.php (при создании файла не забывайте о правилах именования контроллеров)
<?php
namespace app\commands;
use Yii;
use yii\console\Controller;
class MailController extends Controller
{
public function actionIndex()
{
$queryComments = Yii::$app->db->createCommand('select * from comment where sent = 0')
->queryAll();
foreach ($queryComments as $comment)
{
$this->PrepareMail($comment['id']);
Yii::$app->db->createCommand('update comment set sent=1 where id=:id')
->bindValue(':id',$comment['id'])
->query();
}
}
private function PrepareMail($comment_id)
{
...
Подготавливаем список получателей и данные для письма
...
if (is_array($emails)) {
$options = ['data' => $data];
$this->sendMail($subject, $layout_name, $emails, $options);
}
}
private function SendMail($subject, $layout_name, $emails, $options)
{
foreach ($emails as $email) {
\Yii::$app->mailer->compose($layout_name, $options)
->setTo($email)
->setSubject($subject)
->send();
}
}
Разберем детально, что происходит:
- В методе actionIndex получаем список всех неотправленных комментариев
- Последовательно для каждого в методе PrepareMail формируем письмо
- Отправляем с помощью метода SendMail, которому передаем тему письма, шаблон сообщения, список адресов и данные для подстановки в шаблон.
На этом создание собственной консольной команды завершено и мы можем вызвать ее из консоли ОС - yii.bat mail, если всё прошло успешно, то осталось настроить задание в планировщике задач.
Комментариев нет:
Отправить комментарий