Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
voodooism
Сообщения: 48
Зарегистрирован: 2018.11.12, 10:29

Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Сообщение voodooism »

В проекте есть функционал отправки почты. Нужно настроить мэйлер таким образом, что бы в случае если константа YII_ENV_PROD имеет ложное значение вся отправляемая почта перехватывалась и отправлялась на заданные в проекте адреса.

В данный момент это реализовано через прослойку на этапе конфигурации DI контейнера.
В тестовой конфигурации мы из параметров приложения дергаем значения test_notifierTo и test_notifierCC и подменяем любые адреса на те что указаны в этих переменных.

Код: Выделить всё

        $container->setSingleton(NotifierInterface::class, function () use ($app) {
            return YII_ENV_PROD ? new Notifier($app->params['notifierFrom']) :
                new TestNotifier($app->params['notifierFrom'], $app->params['test_notifierTo'],
                    $app->params['test_notifierCC']);
        });
Но такой подход обязывает везде в проекте использовать NotifierInterface для отправки почты. Учитывая что проект достаточно большой и поддерживается несколькими людьми, нет гарантии что всё время будет дергаться именно этот интерфейс. Да и переписывать все места отправки почты нет возможности. Поэтому хотелось бы каким то образом сконфигурировать мэйлер на этапе конфигурирования приложения или DI. Что-то вроде этого:

Код: Выделить всё

$container->setSingleton(MailerInterface::class, function () use ($app) {
            return YII_ENV_PROD ? $app->mailer : $app->testMailer;
        });
А в настройках тестового мэйлера:

Код: Выделить всё

 'testMailer' => [
            //...
            'messageConfig' => [
                'from' => ['test@email.from' => 'Тестовая рассылка'],
                'to' => $params['test_notifierTo']
            ],
           //...
        ],
Но к сожалению это не работает, и приоритетным адресом считается тот который задается при конфигурации письма методом ->setTo($email)
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Сообщение yiiliveext »

voodooism писал(а): 2019.08.13, 08:31 В проекте есть функционал отправки почты. Нужно настроить мэйлер таким образом, что бы в случае если константа YII_ENV_PROD имеет ложное значение вся отправляемая почта перехватывалась и отправлялась на заданные в проекте адреса.

Поэтому хотелось бы каким то образом сконфигурировать мэйлер на этапе конфигурирования приложения или DI. Что-то вроде этого:

Код: Выделить всё

$container->setSingleton(MailerInterface::class, function () use ($app) {
            return YII_ENV_PROD ? $app->mailer : $app->testMailer;
        });
А в настройках тестового мэйлера:

Код: Выделить всё

 'testMailer' => [
            //...
            'messageConfig' => [
                'from' => ['test@email.from' => 'Тестовая рассылка'],
                'to' => $params['test_notifierTo']
            ],
           //...
        ],
Но к сожалению это не работает, и приоритетным адресом считается тот который задается при конфигурации письма методом ->setTo($email)
Используйте события

Код: Выделить всё

     
     Event::on(
         'yii\swiftmailer\Mailer',
         \yii\swiftmailer\Mailer::EVENT_BEFORE_SEND,
         function ($event) {
             $testTo =  Yii::$app->params['test_notifierTo'];
             $testFrom = ['test@email.from' => 'Тестовая рассылка'];
             $message = $event->message;
             $from = $message->getFrom();
                 if ($from !==  $testFrom && YII_ENV_DEV) {
                     $event->isValid = false;
                     $message->setFrom($testFrom);
                     $message->setTo($testTo);
                     Yii::$app->mailer->send($message);
                 }
         }
    );
voodooism
Сообщения: 48
Зарегистрирован: 2018.11.12, 10:29

Re: Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Сообщение voodooism »

Решил проблему на этапе настройки DI следующим образом:

Код: Выделить всё

        if (!YII_ENV_PROD) {
            $container->set(TestMessage::class, static function (Container $container, $params, $config) use ($app) {
                return new TestMessage($app->params['test_notifierTo'], $app->params['test_notifierCC'], $config);
            });
        }

      $container->setSingleton(MailerInterface::class, static function () use ($app) {
            return YII_ENV_PROD ? $app->mailer : $app->testMailer;
        });
Класс TestMessage выглядит так:

Код: Выделить всё

<?php

namespace app\components\mailer;

use yii\swiftmailer\Message;

class TestMessage extends Message
{
    private $to;
    private $cc;

    public function __construct(string $to, string $cc, $config = [])
    {
        $this->to = explode(',', $to);
        if ($cc) {
            $this->cc = explode(',', $cc);
        }
        parent::__construct($config);
    }

    public function setTo($to)
    {
        $this->getSwiftMessage()->setTo($this->to ?? $to);

        return $this;
    }

    public function setCc($cc)
    {
        $this->getSwiftMessage()->setCc($this->cc ?? $cc);

        return $this;
    }
}
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Сообщение yiiliveext »

voodooism писал(а): 2019.08.13, 12:47 Решил проблему на этапе настройки DI следующим образом:

Код: Выделить всё

        if (!YII_ENV_PROD) {
            $container->set(TestMessage::class, static function (Container $container, $params, $config) use ($app) {
                return new TestMessage($app->params['test_notifierTo'], $app->params['test_notifierCC'], $config);
            });
        }

      $container->setSingleton(MailerInterface::class, static function () use ($app) {
            return YII_ENV_PROD ? $app->mailer : $app->testMailer;
        });
А зачем вам два мейлера?

Код: Выделить всё

'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            'viewPath' => '@app/mail',
            'messageConfig' => [
                'charset' => 'UTF-8',
                'class' => 'app\components\mailer\TestMessage'
            ],
            //...........
],

Код: Выделить всё

$container->set(TestMessage::class, [ 
'to' => !YII_ENV_PROD ? $app->params['test_notifierTo'] : null,
'cc' => !YII_ENV_PROD ? $app->params['test_notifierCC'] : null,
]);

Код: Выделить всё

use yii\swiftmailer\Message;

class TestMessage extends Message
{
    public $to;
    public $cc;

    public function setTo($to)
    {
        $this->getSwiftMessage()->setTo($this->to ?? $to);

        return $this;
    }

    public function setCc($cc)
    {
        $this->getSwiftMessage()->setCc($this->cc ?? $cc);

        return $this;
    }
}
voodooism
Сообщения: 48
Зарегистрирован: 2018.11.12, 10:29

Re: Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Сообщение voodooism »

Ну это уже внутренняя логика. В мэйлерах могут быть разные конфигурации для теста и для прода. Например конфигурация транспорта.
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Тестовая конфигурация swiftmailer для отправки почты на заданные адреса

Сообщение yiiliveext »

voodooism писал(а): 2019.08.13, 14:31 Ну это уже внутренняя логика. В мэйлерах могут быть разные конфигурации для теста и для прода. Например конфигурация транспорта.
Тогда да, согласен. Но я все же предпочитаю в таком случат делать через события, это более универсально. В вашем случае, если кто-то создаст свой мейлер в модуле, то ваши настройки не будут иметь силы.
Ответить