diff --git a/src/Symfony/Component/Mailer/Event/MessageEvent.php b/src/Symfony/Component/Mailer/Event/MessageEvent.php index b068f7e78d64..ad0f5574af24 100644 --- a/src/Symfony/Component/Mailer/Event/MessageEvent.php +++ b/src/Symfony/Component/Mailer/Event/MessageEvent.php @@ -20,7 +20,7 @@ * * @author Fabien Potencier */ -final class MessageEvent extends Event +class MessageEvent extends Event { private RawMessage $message; private Envelope $envelope; diff --git a/src/Symfony/Component/Mailer/Event/QueuingMessageEvent.php b/src/Symfony/Component/Mailer/Event/QueuingMessageEvent.php new file mode 100644 index 000000000000..250f58e95e13 --- /dev/null +++ b/src/Symfony/Component/Mailer/Event/QueuingMessageEvent.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Event; + +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Messenger\Stamp\StampInterface; +use Symfony\Component\Mime\RawMessage; + +/** + * Allows the transformation of a Message, the Envelope, and the Messenger stamps before the email is sent to the Messenger bus. + * + * @author Fabien Potencier + */ +final class QueuingMessageEvent extends MessageEvent +{ + /** @var StampInterface[] */ + private array $stamps = []; + + public function __construct(RawMessage $message, Envelope $envelope, string $transport) + { + parent::__construct($message, $envelope, $transport, true); + } + + public function addStamp(StampInterface $stamp): void + { + $this->stamps[] = $stamp; + } + + /** + * @return StampInterface[] + */ + public function getStamps(): array + { + return $this->stamps; + } +} diff --git a/src/Symfony/Component/Mailer/Mailer.php b/src/Symfony/Component/Mailer/Mailer.php index daa62fe19688..70339a44d378 100644 --- a/src/Symfony/Component/Mailer/Mailer.php +++ b/src/Symfony/Component/Mailer/Mailer.php @@ -13,6 +13,7 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Event\QueuingMessageEvent; use Symfony\Component\Mailer\Exception\TransportExceptionInterface; use Symfony\Component\Mailer\Messenger\SendEmailMessage; use Symfony\Component\Mailer\Transport\TransportInterface; @@ -44,6 +45,7 @@ public function send(RawMessage $message, Envelope $envelope = null): void return; } + $stamps = []; if (null !== $this->dispatcher) { // The dispatched event here has `queued` set to `true`; the goal is NOT to render the message, but to let // listeners do something before a message is sent to the queue. @@ -52,12 +54,13 @@ public function send(RawMessage $message, Envelope $envelope = null): void // Listeners should act depending on the `$queued` argument of the `MessageEvent` instance. $clonedMessage = clone $message; $clonedEnvelope = null !== $envelope ? clone $envelope : Envelope::create($clonedMessage); - $event = new MessageEvent($clonedMessage, $clonedEnvelope, (string) $this->transport, true); + $event = new QueuingMessageEvent($clonedMessage, $clonedEnvelope, (string) $this->transport); $this->dispatcher->dispatch($event); + $stamps = $event->getStamps(); } try { - $this->bus->dispatch(new SendEmailMessage($message, $envelope)); + $this->bus->dispatch(new SendEmailMessage($message, $envelope), $stamps); } catch (HandlerFailedException $e) { foreach ($e->getNestedExceptions() as $nested) { if ($nested instanceof TransportExceptionInterface) { diff --git a/src/Symfony/Component/Mailer/Tests/MailerTest.php b/src/Symfony/Component/Mailer/Tests/MailerTest.php index 6c86b415167b..6339f87e31b1 100644 --- a/src/Symfony/Component/Mailer/Tests/MailerTest.php +++ b/src/Symfony/Component/Mailer/Tests/MailerTest.php @@ -13,13 +13,14 @@ use PHPUnit\Framework\TestCase; use Psr\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\Mailer\Event\MessageEvent; +use Symfony\Component\Mailer\Event\QueuingMessageEvent; use Symfony\Component\Mailer\Exception\LogicException; use Symfony\Component\Mailer\Mailer; use Symfony\Component\Mailer\Transport\NullTransport; use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Messenger\Stamp\StampInterface; use Symfony\Component\Mime\Email; use Symfony\Component\Mime\RawMessage; @@ -37,19 +38,25 @@ public function testSendMessageToBus() { $bus = new class() implements MessageBusInterface { public $messages = []; + public $stamps = []; public function dispatch($message, array $stamps = []): Envelope { $this->messages[] = $message; + $this->stamps = $stamps; return new Envelope($message, $stamps); } }; + $stamp = $this->createMock(StampInterface::class); + $dispatcher = $this->createMock(EventDispatcherInterface::class); $dispatcher->expects($this->once()) ->method('dispatch') - ->with(self::callback(static function (MessageEvent $event) { + ->with(self::callback(static function (QueuingMessageEvent $event) use ($stamp) { + $event->addStamp($stamp); + return 'Time for Symfony Mailer!' === $event->getMessage()->getSubject(); })) ->willReturnArgument(0) @@ -68,5 +75,7 @@ public function dispatch($message, array $stamps = []): Envelope self::assertCount(1, $bus->messages); self::assertSame($email, $bus->messages[0]->getMessage()); + self::assertCount(1, $bus->stamps); + self::assertSame([$stamp], $bus->stamps); } }