Выполнение отправки почты через Symfony Messenger - PullRequest
2 голосов
/ 02 августа 2020

Я ищу большую помощь с моим кодом. Я пробовал все, что было в моих силах, чтобы подключить некоторые Symfony функции, и я думаю, что куда-то собираюсь ..

Я использую Symfony 4.2 и платформу API и пытаюсь добавить процесс, который отправляет сообщение электронной почты для асинхронного использования.

У меня есть объект комментария, который запускает его при сохранении объекта. Это вызывает мою функцию __invoke, но есть проблема. Я не совсем понимаю, что мне делать дальше.

Как сказано в документации здесь , сначала мне нужно настроить Data Persister:

<?php

namespace App\DataPersister;

use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use App\Entity\Comment;

final class EmailNotificationDataPersister implements ContextAwareDataPersisterInterface
{
private $decorated;
private $mailer;

public function __construct(ContextAwareDataPersisterInterface $decorated, \Swift_Mailer $mailer)
{
    $this->decorated = $decorated;
    $this->mailer = $mailer;
}

public function supports($data, array $context = []): bool
{
    return $this->decorated->supports($data, $context);
}

public function persist($data, array $context = [])
{
    $result = $this->decorated->persist($data, $context);

    if (
        $data instanceof Comment && (
            ($context['collection_operation_name'] ?? null) === 'post')
    ) {
        $this->sendWelcomeEmail($data);
    }

    return $result;
}

public function remove($data, array $context = [])
{
    return $this->decorated->remove($data, $context);
}

private function sendWelcomeEmail(Comment $comment)
{
    // Your welcome email logic...
    // $this->mailer->send(...);
}
}

Я используя Symfony 4.2, поэтому я установил почтовый клиент быстрой рассылки.

Также я определил EmailSubscriber:

<?php

namespace App\EventSubscriber;

use ApiPlatform\Core\EventListener\EventPriorities;
use App\Entity\Comment;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\Messenger\MessageBusInterface;

final class EmailNotificationSubscriber implements EventSubscriberInterface

{

private $messageBus;

public function __construct(MessageBusInterface $messageBus)
{
    $this->messageBus = $messageBus;
}

public static function getSubscribedEvents()
{
    return [
        KernelEvents::VIEW => [ 'sendMail', EventPriorities::POST_WRITE],
    ];
}

public function sendMail(GetResponseForControllerResultEvent $event)
{
    $comment = $event->getControllerResult();
    $method = $event->getRequest()->getMethod();


    if (!$comment instanceof Comment || Request::METHOD_POST !== $method) {
        return;
    }

    $this->messageBus->dispatch(new Comment());
}
}

И, наконец, я реализовал обработчик:

<?php

namespace App\Handler;

use App\Entity\Comment;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

final class EmailNotificationHandler implements MessageHandlerInterface
{
    public function __invoke(Comment $comment)
    {
        // do something with the resource
    }
}

Когда я запускаю объект persist на своей платформе api, перехватывается функция var_dump () из invoke.

Я понятия не имею, если что-то не так и что мне делать дальше. Мне нужно, чтобы отправка электронной почты выполнялась асинхронно с использованием Symfony Messenger.

В моем файле .env:

MESSENGER_TRANSPORT_DSN=amqp://127.0.0.1:8000/api/messages

И framework .yaml

messenger:
    transports:
        amqp: "%env(MESSENGER_TRANSPORT_DSN)%"

    routing:
        'App\Entity\Comment': amqp

А также есть ли способ отправить электронное письмо на любое случайное письмо, указанное в таблице пользователя? Я хочу установить для этого конфигурацию почтовой программы.

1 Ответ

0 голосов
/ 03 августа 2020

Для асинхронного запуска вам необходимо transport . Для локального тестирования symfony сервер и docker работают нормально.

#config/packages/messenger.yaml
transports:
    async: '%env(RABBITMQ_DSN)%'

Поместите docker-compose.yaml в проект root.

rabbitmq:
    image: rabbitmq:3-management
    ports: [5672, 15672]

Запуск в консоли

docker-compose up -d
symfony server:start -d

Для использования сообщения, запускаемого в консоли

symfony console messenger:consume async -vv

При производстве вам нужно добавить RABBITMQ_DSN (или MESSENGER_TRANSPORT_DSN) с реальными учетными данными для RabbitMQ, Amazon SQS et c и, возможно, использовать Супервизор для приема сообщений.

...