Skip to content

Commit 5b9cded

Browse files
committed
Add transport factories (closes #31385, closes #32523)
1 parent af309b0 commit 5b9cded

32 files changed

+1660
-467
lines changed

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@
7777
use Symfony\Component\Lock\Store\FlockStore;
7878
use Symfony\Component\Lock\Store\StoreFactory;
7979
use Symfony\Component\Lock\StoreInterface;
80+
use Symfony\Component\Mailer\Bridge\Amazon\Factory\SesTransportFactory;
81+
use Symfony\Component\Mailer\Bridge\Google\Factory\GmailTransportFactory;
82+
use Symfony\Component\Mailer\Bridge\Mailchimp\Factory\MandrillTransportFactory;
83+
use Symfony\Component\Mailer\Bridge\Mailgun\Factory\MailgunTransportFactory;
84+
use Symfony\Component\Mailer\Bridge\Postmark\Factory\PostmarkTransportFactory;
85+
use Symfony\Component\Mailer\Bridge\Sendgrid\Factory\SendgridTransportFactory;
8086
use Symfony\Component\Mailer\Mailer;
8187
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
8288
use Symfony\Component\Messenger\MessageBus;
@@ -1955,8 +1961,24 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
19551961
}
19561962

19571963
$loader->load('mailer.xml');
1964+
$loader->load('mailer_transports.xml');
19581965
$container->getDefinition('mailer.default_transport')->setArgument(0, $config['dsn']);
19591966

1967+
$classToServices = [
1968+
SesTransportFactory::class => 'mailer.transport_factory.amazon',
1969+
GmailTransportFactory::class => 'mailer.transport_factory.gmail',
1970+
MandrillTransportFactory::class => 'mailer.transport_factory.mailchimp',
1971+
MailgunTransportFactory::class => 'mailer.transport_factory.mailgun',
1972+
PostmarkTransportFactory::class => 'mailer.transport_factory.postmark',
1973+
SendgridTransportFactory::class => 'mailer.transport_factory.sendgrid',
1974+
];
1975+
1976+
foreach ($classToServices as $class => $service) {
1977+
if (!class_exists($class)) {
1978+
$container->removeDefinition($service);
1979+
}
1980+
}
1981+
19601982
$recipients = $config['envelope']['recipients'] ?? null;
19611983
$sender = $config['envelope']['sender'] ?? null;
19621984

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
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\Transport">
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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
<service id="mailer.transport_factory.abstract" class="Symfony\Component\Mailer\Transport\AbstractTransportFactory" abstract="true">
9+
<argument type="service" id="event_dispatcher" />
10+
<argument type="service" id="http_client" on-invalid="ignore" />
11+
<argument type="service" id="logger" on-invalid="ignore" />
12+
</service>
13+
14+
<service id="mailer.transport_factory.amazon" class="Symfony\Component\Mailer\Bridge\Amazon\Factory\SesTransportFactory" parent="mailer.transport_factory.abstract">
15+
<tag name="mailer.transport_factory" />
16+
</service>
17+
18+
<service id="mailer.transport_factory.gmail" class="Symfony\Component\Mailer\Bridge\Google\Factory\GmailTransportFactory" parent="mailer.transport_factory.abstract">
19+
<tag name="mailer.transport_factory" />
20+
</service>
21+
22+
<service id="mailer.transport_factory.mailchimp" class="Symfony\Component\Mailer\Bridge\Mailchimp\Factory\MandrillTransportFactory" parent="mailer.transport_factory.abstract">
23+
<tag name="mailer.transport_factory" />
24+
</service>
25+
26+
<service id="mailer.transport_factory.mailgun" class="Symfony\Component\Mailer\Bridge\Mailgun\Factory\MailgunTransportFactory" parent="mailer.transport_factory.abstract">
27+
<tag name="mailer.transport_factory" />
28+
</service>
29+
30+
<service id="mailer.transport_factory.postmark" class="Symfony\Component\Mailer\Bridge\Postmark\Factory\PostmarkTransportFactory" parent="mailer.transport_factory.abstract">
31+
<tag name="mailer.transport_factory" />
32+
</service>
33+
34+
<service id="mailer.transport_factory.sendgrid" class="Symfony\Component\Mailer\Bridge\Sendgrid\Factory\SendgridTransportFactory" parent="mailer.transport_factory.abstract">
35+
<tag name="mailer.transport_factory" />
36+
</service>
37+
38+
<service id="mailer.transport_factory.null" class="Symfony\Component\Mailer\Transport\NullTransportFactory" parent="mailer.transport_factory.abstract">
39+
<tag name="mailer.transport_factory" />
40+
</service>
41+
42+
<service id="mailer.transport_factory.sendmail" class="Symfony\Component\Mailer\Transport\SendmailTransportFactory" parent="mailer.transport_factory.abstract">
43+
<tag name="mailer.transport_factory" />
44+
</service>
45+
46+
<service id="mailer.transport_factory.smtp" class="Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory" parent="mailer.transport_factory.abstract">
47+
<tag name="mailer.transport_factory" priority="-100" />
48+
</service>
49+
</services>
50+
</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 = $this->getUser($dsn);
29+
$password = $this->getPassword($dsn);
30+
$region = $dsn->getOption('region');
31+
32+
if ('api' === $scheme) {
33+
return new Amazon\Http\Api\SesTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger);
34+
}
35+
36+
if ('http' === $scheme) {
37+
return new Amazon\Http\SesTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger);
38+
}
39+
40+
if ('smtp' === $scheme) {
41+
return new Amazon\Smtp\SesTransport($user, $password, $region, $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: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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\Factory;
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+
public function getFactory(): TransportFactoryInterface
23+
{
24+
return new SesTransportFactory($this->getDispatcher(), $this->getClient(), $this->getLogger());
25+
}
26+
27+
public function supportsProvider(): iterable
28+
{
29+
yield [
30+
new Dsn('api', 'ses'),
31+
true,
32+
];
33+
34+
yield [
35+
new Dsn('http', 'ses'),
36+
true,
37+
];
38+
39+
yield [
40+
new Dsn('smtp', 'ses'),
41+
true,
42+
];
43+
44+
yield [
45+
new Dsn('smtp', 'example.com'),
46+
false,
47+
];
48+
}
49+
50+
public function createProvider(): iterable
51+
{
52+
$client = $this->getClient();
53+
$dispatcher = $this->getDispatcher();
54+
$logger = $this->getLogger();
55+
56+
yield [
57+
new Dsn('api', 'ses', self::USER, self::PASSWORD),
58+
new Amazon\Http\Api\SesTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger),
59+
];
60+
61+
yield [
62+
new Dsn('api', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']),
63+
new Amazon\Http\Api\SesTransport(self::USER, self::PASSWORD, 'eu-west-1', $client, $dispatcher, $logger),
64+
];
65+
66+
yield [
67+
new Dsn('http', 'ses', self::USER, self::PASSWORD),
68+
new Amazon\Http\SesTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger),
69+
];
70+
71+
yield [
72+
new Dsn('http', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']),
73+
new Amazon\Http\SesTransport(self::USER, self::PASSWORD, 'eu-west-1', $client, $dispatcher, $logger),
74+
];
75+
76+
yield [
77+
new Dsn('smtp', 'ses', self::USER, self::PASSWORD),
78+
new Amazon\Smtp\SesTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger),
79+
];
80+
81+
yield [
82+
new Dsn('smtp', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']),
83+
new Amazon\Smtp\SesTransport(self::USER, self::PASSWORD, 'eu-west-1', $dispatcher, $logger),
84+
];
85+
}
86+
87+
public function unsupportedSchemeProvider(): iterable
88+
{
89+
yield [new Dsn('foo', 'ses', self::USER, self::PASSWORD)];
90+
}
91+
92+
public function incompleteDsnProvider(): iterable
93+
{
94+
yield [new Dsn('smtp', 'ses', self::USER)];
95+
96+
yield [new Dsn('smtp', 'ses', null, self::PASSWORD)];
97+
}
98+
}
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($this->getUser($dsn), $this->getPassword($dsn), $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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
namespace Symfony\Component\Mailer\Bridge\Google\Tests\Factory;
4+
5+
use Symfony\Component\Mailer\Bridge\Google\Factory\GmailTransportFactory;
6+
use Symfony\Component\Mailer\Bridge\Google\Smtp\GmailTransport;
7+
use Symfony\Component\Mailer\Tests\TransportFactoryTestCase;
8+
use Symfony\Component\Mailer\Transport\Dsn;
9+
use Symfony\Component\Mailer\Transport\TransportFactoryInterface;
10+
11+
class GmailTransportFactoryTest extends TransportFactoryTestCase
12+
{
13+
public function getFactory(): TransportFactoryInterface
14+
{
15+
return new GmailTransportFactory($this->getDispatcher(), $this->getClient(), $this->getLogger());
16+
}
17+
18+
public function supportsProvider(): iterable
19+
{
20+
yield [
21+
new Dsn('smtp', 'gmail'),
22+
true,
23+
];
24+
25+
yield [
26+
new Dsn('smtp', 'example.com'),
27+
false,
28+
];
29+
}
30+
31+
public function createProvider(): iterable
32+
{
33+
yield [
34+
new Dsn('smtp', 'gmail', self::USER, self::PASSWORD),
35+
new GmailTransport(self::USER, self::PASSWORD, $this->getDispatcher(), $this->getLogger()),
36+
];
37+
}
38+
39+
public function unsupportedSchemeProvider(): iterable
40+
{
41+
yield [new Dsn('http', 'gmail', self::USER, self::PASSWORD)];
42+
}
43+
44+
public function incompleteDsnProvider(): iterable
45+
{
46+
yield [new Dsn('smtp', 'gmail', self::USER)];
47+
48+
yield [new Dsn('smtp', 'gmail', null, self::PASSWORD)];
49+
}
50+
}
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\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 = $this->getUser($dsn);
29+
30+
if ('api' === $scheme) {
31+
return new Mailchimp\Http\Api\MandrillTransport($user, $this->client, $this->dispatcher, $this->logger);
32+
}
33+
34+
if ('http' === $scheme) {
35+
return new Mailchimp\Http\MandrillTransport($user, $this->client, $this->dispatcher, $this->logger);
36+
}
37+
38+
if ('smtp' === $scheme) {
39+
$password = $this->getPassword($dsn);
40+
41+
return new Mailchimp\Smtp\MandrillTransport($user, $password, $this->dispatcher, $this->logger);
42+
}
43+
44+
throw new UnsupportedSchemeException($dsn);
45+
}
46+
47+
public function supports(Dsn $dsn): bool
48+
{
49+
return 'mandrill' === $dsn->getHost();
50+
}
51+
}

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