Skip to content

Commit 695a33a

Browse files
committed
[Mailer] Add support for multiple mailers
1 parent ef2b65a commit 695a33a

File tree

9 files changed

+108
-7
lines changed

9 files changed

+108
-7
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1555,8 +1555,17 @@ private function addMailerSection(ArrayNodeDefinition $rootNode)
15551555
->arrayNode('mailer')
15561556
->info('Mailer configuration')
15571557
->{!class_exists(FullStack::class) && class_exists(Mailer::class) ? 'canBeDisabled' : 'canBeEnabled'}()
1558+
->validate()
1559+
->ifTrue(function ($v) { return isset($v['dsn']) && \count($v['transports']); })
1560+
->thenInvalid('"dsn" and "transports" cannot be used together.')
1561+
->end()
1562+
->fixXmlConfig('transport')
15581563
->children()
1559-
->scalarNode('dsn')->defaultValue('smtp://null')->end()
1564+
->scalarNode('dsn')->defaultNull()->end()
1565+
->arrayNode('transports')
1566+
->useAttributeAsKey('name')
1567+
->prototype('scalar')->end()
1568+
->end()
15601569
->arrayNode('envelope')
15611570
->info('Mailer Envelope configuration')
15621571
->children()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1977,7 +1977,12 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
19771977

19781978
$loader->load('mailer.xml');
19791979
$loader->load('mailer_transports.xml');
1980-
$container->getDefinition('mailer.default_transport')->setArgument(0, $config['dsn']);
1980+
if (!\count($config['transports']) && null === $config['dsn']) {
1981+
$config['dsn'] = 'smtp://null';
1982+
}
1983+
$transports = $config['dsn'] ? ['main' => $config['dsn']] : $config['transports'];
1984+
$container->getDefinition('mailer.transports')->setArgument(0, $transports);
1985+
$container->getDefinition('mailer.default_transport')->setArgument(0, current($transports));
19811986

19821987
$classToServices = [
19831988
SesTransportFactory::class => 'mailer.transport_factory.amazon',

src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.xml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66

77
<services>
88
<service id="mailer.mailer" class="Symfony\Component\Mailer\Mailer">
9-
<argument type="service" id="mailer.default_transport" />
9+
<argument type="service" id="mailer.transports" />
1010
<argument type="service" id="messenger.default_bus" on-invalid="ignore" />
1111
<argument type="service" id="event_dispatcher" on-invalid="ignore" />
1212
</service>
1313
<service id="mailer" alias="mailer.mailer" />
1414
<service id="Symfony\Component\Mailer\MailerInterface" alias="mailer.mailer" />
1515

16+
<service id="mailer.transports" class="Symfony\Component\Mailer\Transports">
17+
<factory service="mailer.transport_factory" method="fromStrings" />
18+
<argument type="collection" /> <!-- transports -->
19+
</service>
20+
1621
<service id="mailer.transport_factory" class="Symfony\Component\Mailer\Transport">
1722
<argument type="tagged_iterator" tag="mailer.transport_factory" />
1823
</service>
@@ -24,7 +29,7 @@
2429
<service id="Symfony\Component\Mailer\Transport\TransportInterface" alias="mailer.default_transport" />
2530

2631
<service id="mailer.messenger.message_handler" class="Symfony\Component\Mailer\Messenger\MessageHandler">
27-
<argument type="service" id="mailer.default_transport" />
32+
<argument type="service" id="mailer.transports" />
2833
<tag name="messenger.message_handler" />
2934
</service>
3035

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
369369
'scoped_clients' => [],
370370
],
371371
'mailer' => [
372-
'dsn' => 'smtp://null',
372+
'dsn' => null,
373+
'transports' => [],
373374
'enabled' => !class_exists(FullStack::class) && class_exists(Mailer::class),
374375
],
375376
];

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/MailerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ protected function doSend(SentMessage $message): void
5555
}
5656
};
5757

58-
$mailer = new Mailer($testTransport, null);
58+
$mailer = new Mailer($testTransport);
5959

6060
$message = (new Email())
6161
->subject('Test subject')

src/Symfony/Component/Mailer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
4.4.0
55
-----
66

7+
* added support for multiple transports on a `Mailer` instance
78
* [BC BREAK] removed the `auth_mode` DSN option (it is now always determined automatically)
89
* STARTTLS cannot be enabled anymore (it is used automatically if TLS is disabled and the server supports STARTTLS)
910
* [BC BREAK] Removed the `encryption` DSN option (use `smtps` instead)

src/Symfony/Component/Mailer/Mailer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
/**
2323
* @author Fabien Potencier <fabien@symfony.com>
2424
*/
25-
class Mailer implements MailerInterface
25+
final class Mailer implements MailerInterface
2626
{
2727
private $transport;
2828
private $bus;

src/Symfony/Component/Mailer/Transport.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory;
2828
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
2929
use Symfony\Component\Mailer\Transport\TransportInterface;
30+
use Symfony\Component\Mailer\Transport\Transports;
3031
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
3132
use Symfony\Contracts\HttpClient\HttpClientInterface;
3233

@@ -62,6 +63,16 @@ public function __construct(iterable $factories)
6263
$this->factories = $factories;
6364
}
6465

66+
public function fromStrings(array $dsns): Transports
67+
{
68+
$transports = [];
69+
foreach ($dsns as $name => $dsn) {
70+
$transports[$name] = $this->fromString($dsn);
71+
}
72+
73+
return new Transports($transports);
74+
}
75+
6576
public function fromString(string $dsn): TransportInterface
6677
{
6778
$dsns = preg_split('/\s++\|\|\s++/', $dsn);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Mailer\Transport;
13+
14+
use Symfony\Component\Mailer\Exception\InvalidArgumentException;
15+
use Symfony\Component\Mailer\Exception\LogicException;
16+
use Symfony\Component\Mailer\SentMessage;
17+
use Symfony\Component\Mailer\SmtpEnvelope;
18+
use Symfony\Component\Mime\Message;
19+
use Symfony\Component\Mime\RawMessage;
20+
21+
/**
22+
* @author Fabien Potencier <fabien@symfony.com>
23+
*/
24+
class Transports implements TransportInterface
25+
{
26+
private $transports;
27+
private $default;
28+
29+
/**
30+
* @param TransportInterface[] $transports
31+
*/
32+
public function __construct(iterable $transports)
33+
{
34+
$this->transports = [];
35+
foreach ($transports as $name => $transport) {
36+
if (null === $this->default) {
37+
$this->default = $transport;
38+
}
39+
$this->transports[$name] = $transport;
40+
}
41+
42+
if (!$this->transports) {
43+
throw new LogicException(sprintf('"%s" must have at least one transport configured.', __CLASS__));
44+
}
45+
}
46+
47+
public function send(RawMessage $message, SmtpEnvelope $envelope = null): ?SentMessage
48+
{
49+
/** @var Message $message */
50+
if (RawMessage::class === \get_class($message) || !$message->getHeaders()->has('X-Transport')) {
51+
return $this->default->send($message, $envelope);
52+
}
53+
54+
$headers = $message->getHeaders();
55+
$transport = $headers->get('X-Transport');
56+
$headers->remove('X-Transport');
57+
58+
if (!isset($this->transports[$transport])) {
59+
throw new InvalidArgumentException(sprintf('The "%s" transport does not exist.', $transport));
60+
}
61+
62+
return $this->transports[$transport]->send($message, $envelope);
63+
}
64+
65+
public function __toString(): string
66+
{
67+
return 'all';
68+
}
69+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy