Skip to content

Commit 02aa069

Browse files
committed
Add transport factories (closes #31385)
1 parent 64eaf7e commit 02aa069

26 files changed

+1160
-261
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@
7373
use Symfony\Component\Lock\Store\FlockStore;
7474
use Symfony\Component\Lock\Store\StoreFactory;
7575
use Symfony\Component\Lock\StoreInterface;
76+
use Symfony\Component\Mailer\Bridge\Amazon\Factory\SesTransportFactory;
77+
use Symfony\Component\Mailer\Bridge\Google\Factory\GmailTransportFactory;
78+
use Symfony\Component\Mailer\Bridge\Mailchimp\Factory\MandrillTransportFactory;
79+
use Symfony\Component\Mailer\Bridge\Mailgun\Factory\MailgunTransportFactory;
80+
use Symfony\Component\Mailer\Bridge\Postmark\Factory\PostmarkTransportFactory;
81+
use Symfony\Component\Mailer\Bridge\Sendgrid\Factory\SendgridTransportFactory;
7682
use Symfony\Component\Mailer\Mailer;
7783
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
7884
use Symfony\Component\Messenger\MessageBus;
@@ -1927,6 +1933,21 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
19271933

19281934
$loader->load('mailer.xml');
19291935
$container->getDefinition('mailer.default_transport')->setArgument(0, $config['dsn']);
1936+
1937+
$classToServices = [
1938+
SesTransportFactory::class => 'mailer.transport_factory.amazon',
1939+
GmailTransportFactory::class => 'mailer.transport_factory.gmail',
1940+
MandrillTransportFactory::class => 'mailer.transport_factory.mailchimp',
1941+
MailgunTransportFactory::class => 'mailer.transport_factory.mailgun',
1942+
PostmarkTransportFactory::class => 'mailer.transport_factory.postmark',
1943+
SendgridTransportFactory::class => 'mailer.transport_factory.sendgrid',
1944+
];
1945+
1946+
foreach ($classToServices as $class => $service) {
1947+
if (!class_exists($class)) {
1948+
$container->removeDefinition($service);
1949+
}
1950+
}
19301951
}
19311952

19321953
/**

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

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,62 @@
1212
<service id="mailer" alias="mailer.mailer" />
1313
<service id="Symfony\Component\Mailer\MailerInterface" alias="mailer.mailer" />
1414

15+
<service id="mailer.transport_factory" class="Symfony\Component\Mailer\TransportFactory">
16+
<argument type="tagged_iterator" tag="mailer.transport_factory" />
17+
</service>
18+
1519
<service id="mailer.default_transport" class="Symfony\Component\Mailer\Transport\TransportInterface">
16-
<factory class="Symfony\Component\Mailer\Transport" method="fromDsn" />
20+
<factory service="mailer.transport_factory" method="fromString" />
1721
<argument /> <!-- env(MAILER_DSN) -->
18-
<argument type="service" id="event_dispatcher" />
19-
<argument type="service" id="http_client" on-invalid="ignore" />
20-
<argument type="service" id="logger" on-invalid="ignore" />
2122
</service>
2223
<service id="Symfony\Component\Mailer\Transport\TransportInterface" alias="mailer.default_transport" />
2324

2425
<service id="mailer.messenger.message_handler" class="Symfony\Component\Mailer\Messenger\MessageHandler">
2526
<argument type="service" id="mailer.default_transport" />
2627
<tag name="messenger.message_handler" />
2728
</service>
29+
30+
<!-- transports -->
31+
<service id="mailer.transport_factory.abstract" class="Symfony\Component\Mailer\Transport\AbstractTransportFactory" abstract="true">
32+
<argument type="service" id="event_dispatcher" />
33+
<argument type="service" id="http_client" on-invalid="ignore" />
34+
<argument type="service" id="logger" on-invalid="ignore" />
35+
</service>
36+
37+
<service id="mailer.transport_factory.amazon" class="Symfony\Component\Mailer\Bridge\Amazon\Factory\SesTransportFactory" parent="mailer.transport_factory.abstract">
38+
<tag name="mailer.transport_factory" />
39+
</service>
40+
41+
<service id="mailer.transport_factory.gmail" class="Symfony\Component\Mailer\Bridge\Google\Factory\GmailTransportFactory" parent="mailer.transport_factory.abstract">
42+
<tag name="mailer.transport_factory" />
43+
</service>
44+
45+
<service id="mailer.transport_factory.mailchimp" class="Symfony\Component\Mailer\Bridge\Mailchimp\Factory\MandrillTransportFactory" parent="mailer.transport_factory.abstract">
46+
<tag name="mailer.transport_factory" />
47+
</service>
48+
49+
<service id="mailer.transport_factory.mailgun" class="Symfony\Component\Mailer\Bridge\Mailgun\Factory\MailgunTransportFactory" parent="mailer.transport_factory.abstract">
50+
<tag name="mailer.transport_factory" />
51+
</service>
52+
53+
<service id="mailer.transport_factory.postmark" class="Symfony\Component\Mailer\Bridge\Postmark\Factory\PostmarkTransportFactory" parent="mailer.transport_factory.abstract">
54+
<tag name="mailer.transport_factory" />
55+
</service>
56+
57+
<service id="mailer.transport_factory.sendgrid" class="Symfony\Component\Mailer\Bridge\Sendgrid\Factory\SendgridTransportFactory" parent="mailer.transport_factory.abstract">
58+
<tag name="mailer.transport_factory" />
59+
</service>
60+
61+
<service id="mailer.transport_factory.null" class="Symfony\Component\Mailer\Transport\NullTransportFactory" parent="mailer.transport_factory.abstract">
62+
<tag name="mailer.transport_factory" />
63+
</service>
64+
65+
<service id="mailer.transport_factory.sendmail" class="Symfony\Component\Mailer\Transport\SendmailTransportFactory" parent="mailer.transport_factory.abstract">
66+
<tag name="mailer.transport_factory" />
67+
</service>
68+
69+
<service id="mailer.transport_factory.smtp" class="Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory" parent="mailer.transport_factory.abstract">
70+
<tag name="mailer.transport_factory" priority="-100" />
71+
</service>
2872
</services>
2973
</container>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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\Bridge\Amazon\Factory;
13+
14+
use Symfony\Component\Mailer\Bridge\Amazon;
15+
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
16+
use Symfony\Component\Mailer\Transport\AbstractTransportFactory;
17+
use Symfony\Component\Mailer\Transport\Dsn;
18+
use Symfony\Component\Mailer\Transport\TransportInterface;
19+
20+
/**
21+
* @author Konstantin Myakshin <molodchick@gmail.com>
22+
*/
23+
final class SesTransportFactory extends AbstractTransportFactory
24+
{
25+
public function create(Dsn $dsn): TransportInterface
26+
{
27+
$scheme = $dsn->getScheme();
28+
$user = $dsn->getUser();
29+
$pass = $dsn->getPass();
30+
$region = $dsn->getOption('region');
31+
32+
if ('smtp' === $scheme) {
33+
return new Amazon\Smtp\SesTransport($user, $pass, $region, $this->dispatcher, $this->logger);
34+
}
35+
36+
if ('api' === $scheme) {
37+
return new Amazon\Http\Api\SesTransport($user, $pass, $region, $this->client, $this->dispatcher, $this->logger);
38+
}
39+
40+
if ('http' === $scheme) {
41+
return new Amazon\Http\SesTransport($user, $pass, $region, $this->client, $this->dispatcher, $this->logger);
42+
}
43+
44+
throw new UnsupportedSchemeException($dsn);
45+
}
46+
47+
public function supports(Dsn $dsn): bool
48+
{
49+
return 'ses' === $dsn->getHost();
50+
}
51+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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\Bridge\Amazon\Tests;
13+
14+
use Symfony\Component\Mailer\Bridge\Amazon;
15+
use Symfony\Component\Mailer\Bridge\Amazon\Factory\SesTransportFactory;
16+
use Symfony\Component\Mailer\Tests\TransportFactoryTestCase;
17+
use Symfony\Component\Mailer\Transport\Dsn;
18+
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
19+
20+
class SesTransportFactoryTest extends TransportFactoryTestCase
21+
{
22+
private const USER = 'u$ser';
23+
private const PASS = 'pa$ss';
24+
25+
public function getFactory(): TransportFactoryInterface
26+
{
27+
return new SesTransportFactory($this->eventDispatcher, $this->httpClient, $this->logger);
28+
}
29+
30+
public function supportsProvider(): iterable
31+
{
32+
yield [
33+
new Dsn('smtp', 'ses', null, self::USER, self::PASS),
34+
true,
35+
];
36+
37+
yield [
38+
new Dsn('api', 'ses', null, self::USER, self::PASS),
39+
true,
40+
];
41+
42+
yield [
43+
new Dsn('http', 'ses', null, self::USER, self::PASS),
44+
true,
45+
];
46+
47+
yield [
48+
new Dsn('smtp', 'dummy', null, self::USER, self::PASS),
49+
true,
50+
];
51+
}
52+
53+
public function createProvider(): iterable
54+
{
55+
yield [
56+
new Dsn('smtp', 'ses', null, self::USER, self::PASS),
57+
new Amazon\Smtp\SesTransport(self::USER, self::PASS, null, $this->eventDispatcher, $this->logger),
58+
];
59+
60+
yield [
61+
new Dsn('api', 'ses', null, self::USER, self::PASS),
62+
new Amazon\Http\Api\SesTransport(self::USER, self::PASS, null, $this->httpClient, $this->eventDispatcher, $this->logger),
63+
];
64+
65+
yield [
66+
new Dsn('http', 'ses', null, self::USER, self::PASS),
67+
new Amazon\Http\SesTransport(self::USER, self::PASS, null, $this->httpClient, $this->eventDispatcher, $this->logger),
68+
];
69+
//TODO: region /eu-west-1
70+
}
71+
72+
public function unsupportedSchemeProvider(): iterable
73+
{
74+
yield new Dsn('foo', 'ses', null, self::USER, self::PASS);
75+
}
76+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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\Bridge\Google\Factory;
13+
14+
use Symfony\Component\Mailer\Bridge\Google\Smtp\GmailTransport;
15+
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
16+
use Symfony\Component\Mailer\Transport\AbstractTransportFactory;
17+
use Symfony\Component\Mailer\Transport\Dsn;
18+
use Symfony\Component\Mailer\Transport\TransportInterface;
19+
20+
/**
21+
* @author Konstantin Myakshin <molodchick@gmail.com>
22+
*/
23+
final class GmailTransportFactory extends AbstractTransportFactory
24+
{
25+
public function create(Dsn $dsn): TransportInterface
26+
{
27+
if ('smtp' === $dsn->getScheme()) {
28+
return new GmailTransport($dsn->getUser(), $dsn->getPass(), $this->dispatcher, $this->logger);
29+
}
30+
31+
throw new UnsupportedSchemeException($dsn);
32+
}
33+
34+
public function supports(Dsn $dsn): bool
35+
{
36+
return 'gmail' === $dsn->getHost();
37+
}
38+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace Symfony\Component\Mailer\Bridge\Google\Tests;
4+
5+
use Symfony\Component\Mailer\Tests\TransportFactoryTestCase;
6+
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
7+
8+
class GmailTransportFactoryTest extends TransportFactoryTestCase
9+
{
10+
public function getFactory(): TransportFactoryInterface
11+
{
12+
// TODO: Implement getFactory() method.
13+
}
14+
15+
public function supportsProvider(): iterable
16+
{
17+
// TODO: Implement supportsProvider() method.
18+
}
19+
20+
public function createProvider(): iterable
21+
{
22+
// TODO: Implement createProvider() method.
23+
}
24+
25+
public function unsupportedSchemeProvider(): iterable
26+
{
27+
// TODO: Implement unsupportedSchemeProvider() method.
28+
}
29+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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\Bridge\Mailchimp\Factory;
13+
14+
use Symfony\Component\Mailer\Bridge\Mailchimp;
15+
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
16+
use Symfony\Component\Mailer\Transport\AbstractTransportFactory;
17+
use Symfony\Component\Mailer\Transport\Dsn;
18+
use Symfony\Component\Mailer\Transport\TransportInterface;
19+
20+
/**
21+
* @author Konstantin Myakshin <molodchick@gmail.com>
22+
*/
23+
final class MandrillTransportFactory extends AbstractTransportFactory
24+
{
25+
public function create(Dsn $dsn): TransportInterface
26+
{
27+
$scheme = $dsn->getScheme();
28+
$user = $dsn->getUser();
29+
30+
if ('smtp' === $scheme) {
31+
return new Mailchimp\Smtp\MandrillTransport($user, $dsn->getPass(), $this->dispatcher, $this->logger);
32+
}
33+
34+
if ('api' === $scheme) {
35+
return new Mailchimp\Http\Api\MandrillTransport($user, $this->client, $this->dispatcher, $this->logger);
36+
}
37+
38+
if ('http' === $scheme) {
39+
return new Mailchimp\Http\MandrillTransport($user, $this->client, $this->dispatcher, $this->logger);
40+
}
41+
42+
throw new UnsupportedSchemeException($dsn);
43+
}
44+
45+
public function supports(Dsn $dsn): bool
46+
{
47+
return 'mandrill' === $dsn->getHost();
48+
}
49+
}

0 commit comments

Comments
 (0)