Skip to content

Commit 5e082de

Browse files
committed
[Mailer] Consume a PSR-14 event dispatcher
Signed-off-by: Alexander M. Turek <me@derrabus.de>
1 parent 2afcde7 commit 5e082de

File tree

12 files changed

+95
-17
lines changed

12 files changed

+95
-17
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.4
5+
---
6+
7+
* Enable the mailer to operate on any PSR-14-compatible event dispatcher
8+
49
5.3
510
---
611

Mailer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
namespace Symfony\Component\Mailer;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Symfony\Component\EventDispatcher\Event;
1516
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
1617
use Symfony\Component\Mailer\Event\MessageEvent;
1718
use Symfony\Component\Mailer\Messenger\SendEmailMessage;
1819
use Symfony\Component\Mailer\Transport\TransportInterface;
1920
use Symfony\Component\Messenger\MessageBusInterface;
2021
use Symfony\Component\Mime\RawMessage;
21-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
22+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as SymfonyEventDispatcherInterface;
2223

2324
/**
2425
* @author Fabien Potencier <fabien@symfony.com>
@@ -33,7 +34,7 @@ public function __construct(TransportInterface $transport, MessageBusInterface $
3334
{
3435
$this->transport = $transport;
3536
$this->bus = $bus;
36-
$this->dispatcher = class_exists(Event::class) ? LegacyEventDispatcherProxy::decorate($dispatcher) : $dispatcher;
37+
$this->dispatcher = class_exists(Event::class) && $dispatcher instanceof SymfonyEventDispatcherInterface ? LegacyEventDispatcherProxy::decorate($dispatcher) : $dispatcher;
3738
}
3839

3940
public function send(RawMessage $message, Envelope $envelope = null): void

Tests/EventListener/MessageListenerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\Mailer\Tests;
12+
namespace Symfony\Component\Mailer\Tests\EventListener;
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Mailer\Envelope;

Tests/MailerTest.php

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@
1212
namespace Symfony\Component\Mailer\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Psr\EventDispatcher\EventDispatcherInterface;
16+
use Symfony\Component\Mailer\Event\MessageEvent;
1517
use Symfony\Component\Mailer\Exception\LogicException;
1618
use Symfony\Component\Mailer\Mailer;
19+
use Symfony\Component\Mailer\Transport\NullTransport;
1720
use Symfony\Component\Mailer\Transport\TransportInterface;
21+
use Symfony\Component\Messenger\Envelope;
1822
use Symfony\Component\Messenger\MessageBusInterface;
23+
use Symfony\Component\Mime\Email;
1924
use Symfony\Component\Mime\RawMessage;
20-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2125

2226
class MailerTest extends TestCase
2327
{
@@ -28,4 +32,41 @@ public function testSendingRawMessages()
2832
$transport = new Mailer($this->createMock(TransportInterface::class), $this->createMock(MessageBusInterface::class), $this->createMock(EventDispatcherInterface::class));
2933
$transport->send(new RawMessage('Some raw email message'));
3034
}
35+
36+
public function testSendMessageToBus()
37+
{
38+
$bus = new class() implements MessageBusInterface {
39+
public $messages = [];
40+
41+
public function dispatch($message, array $stamps = []): Envelope
42+
{
43+
$this->messages[] = $message;
44+
45+
return new Envelope($message, $stamps);
46+
}
47+
};
48+
49+
$dispatcher = $this->createMock(EventDispatcherInterface::class);
50+
$dispatcher->expects($this->once())
51+
->method('dispatch')
52+
->with(self::callback(static function (MessageEvent $event) {
53+
return 'Time for Symfony Mailer!' === $event->getMessage()->getSubject();
54+
}))
55+
->willReturnArgument(0)
56+
;
57+
58+
$mailer = new Mailer(new NullTransport($dispatcher), $bus, $dispatcher);
59+
60+
$email = (new Email())
61+
->from('hello@example.com')
62+
->to('you@example.com')
63+
->subject('Time for Symfony Mailer!')
64+
->text('Sending emails is fun again!')
65+
->html('<p>See Twig integration for better HTML integration!</p>');
66+
67+
$mailer->send($email);
68+
69+
self::assertCount(1, $bus->messages);
70+
self::assertSame($email, $bus->messages[0]->getMessage());
71+
}
3172
}

Transport.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Mailer;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesTransportFactory;
1617
use Symfony\Component\Mailer\Bridge\Google\Transport\GmailTransportFactory;
@@ -32,12 +33,13 @@
3233
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
3334
use Symfony\Component\Mailer\Transport\TransportInterface;
3435
use Symfony\Component\Mailer\Transport\Transports;
35-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
3636
use Symfony\Contracts\HttpClient\HttpClientInterface;
3737

3838
/**
3939
* @author Fabien Potencier <fabien@symfony.com>
4040
* @author Konstantin Myakshin <molodchick@gmail.com>
41+
*
42+
* @final since Symfony 5.4
4143
*/
4244
class Transport
4345
{
@@ -54,15 +56,33 @@ class Transport
5456

5557
private $factories;
5658

57-
public static function fromDsn(string $dsn, EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null): TransportInterface
59+
/**
60+
* @param EventDispatcherInterface|null $dispatcher
61+
* @param HttpClientInterface|null $client
62+
* @param LoggerInterface|null $logger
63+
*/
64+
public static function fromDsn(string $dsn/*, EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null*/): TransportInterface
5865
{
66+
$dispatcher = 2 <= \func_num_args() ? func_get_arg(1) : null;
67+
$client = 3 <= \func_num_args() ? func_get_arg(2) : null;
68+
$logger = 4 <= \func_num_args() ? func_get_arg(3) : null;
69+
5970
$factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger)));
6071

6172
return $factory->fromString($dsn);
6273
}
6374

64-
public static function fromDsns(array $dsns, EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null): TransportInterface
75+
/**
76+
* @param EventDispatcherInterface|null $dispatcher
77+
* @param HttpClientInterface|null $client
78+
* @param LoggerInterface|null $logger
79+
*/
80+
public static function fromDsns(array $dsns/*, EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null*/): TransportInterface
6581
{
82+
$dispatcher = 2 <= \func_num_args() ? func_get_arg(1) : null;
83+
$client = 3 <= \func_num_args() ? func_get_arg(2) : null;
84+
$logger = 4 <= \func_num_args() ? func_get_arg(3) : null;
85+
6686
$factory = new self(iterator_to_array(self::getDefaultFactories($dispatcher, $client, $logger)));
6787

6888
return $factory->fromStrings($dsns);
@@ -154,8 +174,19 @@ public function fromDsnObject(Dsn $dsn): TransportInterface
154174
throw new UnsupportedSchemeException($dsn);
155175
}
156176

157-
public static function getDefaultFactories(EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null): iterable
177+
/**
178+
* @param EventDispatcherInterface|null $dispatcher
179+
* @param HttpClientInterface|null $client
180+
* @param LoggerInterface|null $logger
181+
*
182+
* @return \Traversable<int, TransportFactoryInterface>
183+
*/
184+
public static function getDefaultFactories(/*EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null*/): iterable
158185
{
186+
$dispatcher = 1 <= \func_num_args() ? func_get_arg(0) : null;
187+
$client = 2 <= \func_num_args() ? func_get_arg(1) : null;
188+
$logger = 3 <= \func_num_args() ? func_get_arg(2) : null;
189+
159190
foreach (self::FACTORY_CLASSES as $factoryClass) {
160191
if (class_exists($factoryClass)) {
161192
yield new $factoryClass($dispatcher, $client, $logger);

Transport/AbstractHttpTransport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
namespace Symfony\Component\Mailer\Transport;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\HttpClient\HttpClient;
1617
use Symfony\Component\Mailer\Exception\HttpTransportException;
1718
use Symfony\Component\Mailer\SentMessage;
18-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
1919
use Symfony\Contracts\HttpClient\HttpClientInterface;
2020
use Symfony\Contracts\HttpClient\ResponseInterface;
2121

Transport/AbstractTransport.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Mailer\Transport;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Psr\Log\NullLogger;
1617
use Symfony\Component\EventDispatcher\Event;
@@ -20,7 +21,7 @@
2021
use Symfony\Component\Mailer\SentMessage;
2122
use Symfony\Component\Mime\Address;
2223
use Symfony\Component\Mime\RawMessage;
23-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
24+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as SymfonyEventDispatcherInterface;
2425

2526
/**
2627
* @author Fabien Potencier <fabien@symfony.com>
@@ -34,7 +35,7 @@ abstract class AbstractTransport implements TransportInterface
3435

3536
public function __construct(EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
3637
{
37-
$this->dispatcher = class_exists(Event::class) ? LegacyEventDispatcherProxy::decorate($dispatcher) : $dispatcher;
38+
$this->dispatcher = class_exists(Event::class) && $dispatcher instanceof SymfonyEventDispatcherInterface ? LegacyEventDispatcherProxy::decorate($dispatcher) : $dispatcher;
3839
$this->logger = $logger ?? new NullLogger();
3940
}
4041

Transport/AbstractTransportFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
namespace Symfony\Component\Mailer\Transport;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\Mailer\Exception\IncompleteDsnException;
16-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
1717
use Symfony\Contracts\HttpClient\HttpClientInterface;
1818

1919
/**

Transport/SendmailTransport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
namespace Symfony\Component\Mailer\Transport;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\Mailer\Envelope;
1617
use Symfony\Component\Mailer\SentMessage;
1718
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport;
1819
use Symfony\Component\Mailer\Transport\Smtp\Stream\AbstractStream;
1920
use Symfony\Component\Mailer\Transport\Smtp\Stream\ProcessStream;
2021
use Symfony\Component\Mime\RawMessage;
21-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2222

2323
/**
2424
* SendmailTransport for sending mail through a Sendmail/Postfix (etc..) binary.

Transport/Smtp/EsmtpTransport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111

1212
namespace Symfony\Component\Mailer\Transport\Smtp;
1313

14+
use Psr\EventDispatcher\EventDispatcherInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\Mailer\Exception\TransportException;
1617
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
1718
use Symfony\Component\Mailer\Transport\Smtp\Auth\AuthenticatorInterface;
1819
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream;
19-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2020

2121
/**
2222
* Sends Emails over SMTP with ESMTP support.

0 commit comments

Comments
 (0)