From 469c9896979994da7e601224611d7d7ed3fc40cd Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 2 Sep 2019 13:54:07 +0200 Subject: [PATCH] [Mailer] Change the DSN semantics --- .../Tests/Functional/app/Mailer/config.yml | 2 +- .../Tests/Transport/SesApiTransportTest.php | 48 +++++++++++++++++ .../Tests/Transport/SesHttpTransportTest.php | 48 +++++++++++++++++ .../Transport/SesTransportFactoryTest.php | 54 +++++++++++++------ .../Amazon/Transport/SesApiTransport.php | 12 +++-- .../Amazon/Transport/SesHttpTransport.php | 12 +++-- .../Amazon/Transport/SesTransportFactory.php | 18 ++++--- .../Transport/GmailTransportFactoryTest.php | 30 +++++++---- .../Transport/GmailTransportFactory.php | 8 +-- .../Transport/MandrillApiTransportTest.php | 44 +++++++++++++++ .../Transport/MandrillHttpTransportTest.php | 44 +++++++++++++++ .../MandrillTransportFactoryTest.php | 48 ++++++++++++----- .../Transport/MandrillApiTransport.php | 11 ++-- .../Transport/MandrillHttpTransport.php | 11 ++-- .../Transport/MandrillTransportFactory.php | 18 ++++--- .../Transport/MailgunApiTransportTest.php | 48 +++++++++++++++++ .../Transport/MailgunHttpTransportTest.php | 48 +++++++++++++++++ .../Transport/MailgunTransportFactoryTest.php | 50 +++++++++++------ .../Mailgun/Transport/MailgunApiTransport.php | 15 ++++-- .../Transport/MailgunHttpTransport.php | 17 ++++-- .../Transport/MailgunTransportFactory.php | 18 ++++--- .../Transport/PostmarkApiTransportTest.php | 44 +++++++++++++++ .../PostmarkTransportFactoryTest.php | 37 +++++++++---- .../Transport/PostmarkApiTransport.php | 11 ++-- .../Transport/PostmarkTransportFactory.php | 15 +++--- .../Transport/SendgridApiTransportTest.php | 26 +++++++++ .../SendgridTransportFactoryTest.php | 37 +++++++++---- .../Transport/SendgridApiTransport.php | 11 ++-- .../Transport/SendgridTransportFactory.php | 15 +++--- .../Exception/UnsupportedSchemeException.php | 4 +- .../Mailer/Test/TransportFactoryTestCase.php | 2 +- .../Transport/NullTransportFactoryTest.php | 17 +----- .../Tests/Transport/NullTransportTest.php | 2 +- .../SendmailTransportFactoryTest.php | 13 ++--- .../Smtp/EsmtpTransportFactoryTest.php | 2 +- .../Transport/AbstractHttpTransport.php | 22 ++++++++ .../Transport/AbstractTransportFactory.php | 7 +++ .../Mailer/Transport/NullTransport.php | 2 +- .../Mailer/Transport/NullTransportFactory.php | 8 +-- .../Transport/SendmailTransportFactory.php | 8 +-- .../Transport/Smtp/EsmtpTransportFactory.php | 4 +- 41 files changed, 704 insertions(+), 187 deletions(-) create mode 100644 src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesHttpTransportTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillHttpTransportTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunHttpTransportTest.php create mode 100644 src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Mailer/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Mailer/config.yml index 7cb290dc24d51..c2c3ace06f179 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Mailer/config.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Mailer/config.yml @@ -4,7 +4,7 @@ imports: framework: mailer: - dsn: 'smtp://null' + dsn: 'null://null' envelope: sender: sender@example.org recipients: diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php new file mode 100644 index 0000000000000..a1b0ae7f1a81e --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesApiTransportTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Amazon\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesApiTransport; + +class SesApiTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(SesApiTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new SesApiTransport('ACCESS_KEY', 'SECRET_KEY'), + 'ses+api://ACCESS_KEY@email.eu-west-1.amazonaws.com', + ], + [ + new SesApiTransport('ACCESS_KEY', 'SECRET_KEY', 'us-east-1'), + 'ses+api://ACCESS_KEY@email.us-east-1.amazonaws.com', + ], + [ + (new SesApiTransport('ACCESS_KEY', 'SECRET_KEY'))->setHost('example.com'), + 'ses+api://ACCESS_KEY@example.com', + ], + [ + (new SesApiTransport('ACCESS_KEY', 'SECRET_KEY'))->setHost('example.com')->setPort(99), + 'ses+api://ACCESS_KEY@example.com:99', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesHttpTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesHttpTransportTest.php new file mode 100644 index 0000000000000..4e7cbd66aa15b --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesHttpTransportTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Amazon\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesHttpTransport; + +class SesHttpTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(SesHttpTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new SesHttpTransport('ACCESS_KEY', 'SECRET_KEY'), + 'ses+https://ACCESS_KEY@email.eu-west-1.amazonaws.com', + ], + [ + new SesHttpTransport('ACCESS_KEY', 'SECRET_KEY', 'us-east-1'), + 'ses+https://ACCESS_KEY@email.us-east-1.amazonaws.com', + ], + [ + (new SesHttpTransport('ACCESS_KEY', 'SECRET_KEY'))->setHost('example.com'), + 'ses+https://ACCESS_KEY@example.com', + ], + [ + (new SesHttpTransport('ACCESS_KEY', 'SECRET_KEY'))->setHost('example.com')->setPort(99), + 'ses+https://ACCESS_KEY@example.com:99', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesTransportFactoryTest.php index 8e21f56f50441..7fada879ddc69 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Tests/Transport/SesTransportFactoryTest.php @@ -29,28 +29,33 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('api', 'ses'), + new Dsn('ses+api', 'default'), true, ]; yield [ - new Dsn('http', 'ses'), + new Dsn('ses+https', 'default'), true, ]; yield [ - new Dsn('smtp', 'ses'), + new Dsn('ses', 'default'), true, ]; yield [ - new Dsn('smtps', 'ses'), + new Dsn('ses+smtp', 'default'), true, ]; yield [ - new Dsn('smtp', 'example.com'), - false, + new Dsn('ses+smtps', 'default'), + true, + ]; + + yield [ + new Dsn('ses+smtp', 'example.com'), + true, ]; } @@ -61,37 +66,52 @@ public function createProvider(): iterable $logger = $this->getLogger(); yield [ - new Dsn('api', 'ses', self::USER, self::PASSWORD), + new Dsn('ses+api', 'default', self::USER, self::PASSWORD), new SesApiTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger), ]; yield [ - new Dsn('api', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), + new Dsn('ses+api', 'default', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), new SesApiTransport(self::USER, self::PASSWORD, 'eu-west-1', $client, $dispatcher, $logger), ]; yield [ - new Dsn('http', 'ses', self::USER, self::PASSWORD), + new Dsn('ses+api', 'example.com', self::USER, self::PASSWORD, 8080), + (new SesApiTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('ses+https', 'default', self::USER, self::PASSWORD), new SesHttpTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger), ]; yield [ - new Dsn('http', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), + new Dsn('ses', 'default', self::USER, self::PASSWORD), + new SesHttpTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger), + ]; + + yield [ + new Dsn('ses+https', 'example.com', self::USER, self::PASSWORD, 8080), + (new SesHttpTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('ses+https', 'default', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), new SesHttpTransport(self::USER, self::PASSWORD, 'eu-west-1', $client, $dispatcher, $logger), ]; yield [ - new Dsn('smtp', 'ses', self::USER, self::PASSWORD), + new Dsn('ses+smtp', 'default', self::USER, self::PASSWORD), new SesSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger), ]; yield [ - new Dsn('smtp', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), + new Dsn('ses+smtp', 'default', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), new SesSmtpTransport(self::USER, self::PASSWORD, 'eu-west-1', $dispatcher, $logger), ]; yield [ - new Dsn('smtps', 'ses', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), + new Dsn('ses+smtps', 'default', self::USER, self::PASSWORD, null, ['region' => 'eu-west-1']), new SesSmtpTransport(self::USER, self::PASSWORD, 'eu-west-1', $dispatcher, $logger), ]; } @@ -99,15 +119,15 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('foo', 'ses', self::USER, self::PASSWORD), - 'The "foo" scheme is not supported for mailer "ses". Supported schemes are: "api", "http", "smtp", "smtps".', + new Dsn('ses+foo', 'default', self::USER, self::PASSWORD), + 'The "ses+foo" scheme is not supported. Supported schemes for mailer "ses" are: "ses", "ses+api", "ses+https", "ses+smtp", "ses+smtps".', ]; } public function incompleteDsnProvider(): iterable { - yield [new Dsn('smtp', 'ses', self::USER)]; + yield [new Dsn('ses+smtp', 'default', self::USER)]; - yield [new Dsn('smtp', 'ses', null, self::PASSWORD)]; + yield [new Dsn('ses+smtp', 'default', null, self::PASSWORD)]; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php index 6bd2b2cb9a008..1bfa9db341d29 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesApiTransport.php @@ -25,7 +25,7 @@ */ class SesApiTransport extends AbstractApiTransport { - private const ENDPOINT = 'https://email.%region%.amazonaws.com'; + private const HOST = 'email.%region%.amazonaws.com'; private $accessKey; private $secretKey; @@ -45,7 +45,7 @@ public function __construct(string $accessKey, string $secretKey, string $region public function __toString(): string { - return sprintf('api://%s@ses?region=%s', $this->accessKey, $this->region); + return sprintf('ses+api://%s@%s', $this->accessKey, $this->getEndpoint()); } protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface @@ -53,8 +53,7 @@ protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInte $date = gmdate('D, d M Y H:i:s e'); $auth = sprintf('AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s', $this->accessKey, $this->getSignature($date)); - $endpoint = str_replace('%region%', $this->region, self::ENDPOINT); - $response = $this->client->request('POST', $endpoint, [ + $response = $this->client->request('POST', 'https://'.$this->getEndpoint(), [ 'headers' => [ 'X-Amzn-Authorization' => $auth, 'Date' => $date, @@ -72,6 +71,11 @@ protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInte return $response; } + private function getEndpoint(): ?string + { + return ($this->host ?: str_replace('%region%', $this->region, self::HOST)).($this->port ? ':'.$this->port : ''); + } + private function getSignature(string $string): string { return base64_encode(hash_hmac('sha256', $string, $this->secretKey, true)); diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php index 202aef7baa1f6..be828b0dfc9e8 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesHttpTransport.php @@ -24,7 +24,7 @@ */ class SesHttpTransport extends AbstractHttpTransport { - private const ENDPOINT = 'https://email.%region%.amazonaws.com'; + private const HOST = 'email.%region%.amazonaws.com'; private $accessKey; private $secretKey; @@ -44,7 +44,7 @@ public function __construct(string $accessKey, string $secretKey, string $region public function __toString(): string { - return sprintf('http://%s@ses?region=%s', $this->accessKey, $this->region); + return sprintf('ses+https://%s@%s', $this->accessKey, $this->getEndpoint()); } protected function doSendHttp(SentMessage $message): ResponseInterface @@ -52,8 +52,7 @@ protected function doSendHttp(SentMessage $message): ResponseInterface $date = gmdate('D, d M Y H:i:s e'); $auth = sprintf('AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s', $this->accessKey, $this->getSignature($date)); - $endpoint = str_replace('%region%', $this->region, self::ENDPOINT); - $response = $this->client->request('POST', $endpoint, [ + $response = $this->client->request('POST', 'https://'.$this->getEndpoint(), [ 'headers' => [ 'X-Amzn-Authorization' => $auth, 'Date' => $date, @@ -73,6 +72,11 @@ protected function doSendHttp(SentMessage $message): ResponseInterface return $response; } + private function getEndpoint(): ?string + { + return ($this->host ?: str_replace('%region%', $this->region, self::HOST)).($this->port ? ':'.$this->port : ''); + } + private function getSignature(string $string): string { return base64_encode(hash_hmac('sha256', $string, $this->secretKey, true)); diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesTransportFactory.php index 0dba1d998b465..5977d2f376826 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesTransportFactory.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Transport/SesTransportFactory.php @@ -27,24 +27,26 @@ public function create(Dsn $dsn): TransportInterface $user = $this->getUser($dsn); $password = $this->getPassword($dsn); $region = $dsn->getOption('region'); + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); - if ('api' === $scheme) { - return new SesApiTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger); + if ('ses+api' === $scheme) { + return (new SesApiTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('http' === $scheme) { - return new SesHttpTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger); + if ('ses+https' === $scheme || 'ses' === $scheme) { + return (new SesHttpTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('smtp' === $scheme || 'smtps' === $scheme) { + if ('ses+smtp' === $scheme || 'ses+smtps' === $scheme) { return new SesSmtpTransport($user, $password, $region, $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['api', 'http', 'smtp', 'smtps']); + throw new UnsupportedSchemeException($dsn, 'ses', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'ses' === $dsn->getHost(); + return ['ses', 'ses+api', 'ses+https', 'ses+smtp', 'ses+smtps']; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Google/Tests/Transport/GmailTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Google/Tests/Transport/GmailTransportFactoryTest.php index 803b3b4e2473a..456be78483066 100644 --- a/src/Symfony/Component/Mailer/Bridge/Google/Tests/Transport/GmailTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Google/Tests/Transport/GmailTransportFactoryTest.php @@ -18,30 +18,40 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('smtp', 'gmail'), + new Dsn('gmail', 'default'), true, ]; yield [ - new Dsn('smtps', 'gmail'), + new Dsn('gmail+smtp', 'default'), true, ]; yield [ - new Dsn('smtp', 'example.com'), - false, + new Dsn('gmail+smtps', 'default'), + true, + ]; + + yield [ + new Dsn('gmail+smtp', 'example.com'), + true, ]; } public function createProvider(): iterable { yield [ - new Dsn('smtp', 'gmail', self::USER, self::PASSWORD), + new Dsn('gmail', 'default', self::USER, self::PASSWORD), + new GmailSmtpTransport(self::USER, self::PASSWORD, $this->getDispatcher(), $this->getLogger()), + ]; + + yield [ + new Dsn('gmail+smtp', 'default', self::USER, self::PASSWORD), new GmailSmtpTransport(self::USER, self::PASSWORD, $this->getDispatcher(), $this->getLogger()), ]; yield [ - new Dsn('smtps', 'gmail', self::USER, self::PASSWORD), + new Dsn('gmail+smtps', 'default', self::USER, self::PASSWORD), new GmailSmtpTransport(self::USER, self::PASSWORD, $this->getDispatcher(), $this->getLogger()), ]; } @@ -49,15 +59,15 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('foo', 'gmail', self::USER, self::PASSWORD), - 'The "foo" scheme is not supported for mailer "gmail". Supported schemes are: "smtp", "smtps".', + new Dsn('gmail+foo', 'default', self::USER, self::PASSWORD), + 'The "gmail+foo" scheme is not supported. Supported schemes for mailer "gmail" are: "gmail", "gmail+smtp", "gmail+smtps".', ]; } public function incompleteDsnProvider(): iterable { - yield [new Dsn('smtp', 'gmail', self::USER)]; + yield [new Dsn('gmail+smtp', 'default', self::USER)]; - yield [new Dsn('smtp', 'gmail', null, self::PASSWORD)]; + yield [new Dsn('gmail+smtp', 'default', null, self::PASSWORD)]; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Google/Transport/GmailTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/Google/Transport/GmailTransportFactory.php index 346a2a7e93a48..8a0bd5626699e 100644 --- a/src/Symfony/Component/Mailer/Bridge/Google/Transport/GmailTransportFactory.php +++ b/src/Symfony/Component/Mailer/Bridge/Google/Transport/GmailTransportFactory.php @@ -23,15 +23,15 @@ final class GmailTransportFactory extends AbstractTransportFactory { public function create(Dsn $dsn): TransportInterface { - if ('smtp' === $dsn->getScheme() || 'smtps' === $dsn->getScheme()) { + if (\in_array($dsn->getScheme(), $this->getSupportedSchemes())) { return new GmailSmtpTransport($this->getUser($dsn), $this->getPassword($dsn), $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['smtp', 'smtps']); + throw new UnsupportedSchemeException($dsn, 'gmail', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'gmail' === $dsn->getHost(); + return ['gmail', 'gmail+smtp', 'gmail+smtps']; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php new file mode 100644 index 0000000000000..2bec482818421 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillApiTransportTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Mailchimp\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillApiTransport; + +class MandrillApiTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(MandrillApiTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new MandrillApiTransport('KEY'), + 'mandrill+api://mandrillapp.com', + ], + [ + (new MandrillApiTransport('KEY'))->setHost('example.com'), + 'mandrill+api://example.com', + ], + [ + (new MandrillApiTransport('KEY'))->setHost('example.com')->setPort(99), + 'mandrill+api://example.com:99', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillHttpTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillHttpTransportTest.php new file mode 100644 index 0000000000000..dd72c848f14fe --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillHttpTransportTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Mailchimp\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Mailchimp\Transport\MandrillHttpTransport; + +class MandrillHttpTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(MandrillHttpTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new MandrillHttpTransport('KEY'), + 'mandrill+https://mandrillapp.com', + ], + [ + (new MandrillHttpTransport('KEY'))->setHost('example.com'), + 'mandrill+https://example.com', + ], + [ + (new MandrillHttpTransport('KEY'))->setHost('example.com')->setPort(99), + 'mandrill+https://example.com:99', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillTransportFactoryTest.php index 2e8e2c0c0cc76..317cbb35cdcf7 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Tests/Transport/MandrillTransportFactoryTest.php @@ -29,28 +29,33 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('api', 'mandrill'), + new Dsn('mandrill', 'default'), true, ]; yield [ - new Dsn('http', 'mandrill'), + new Dsn('mandrill+api', 'default'), true, ]; yield [ - new Dsn('smtp', 'mandrill'), + new Dsn('mandrill+https', 'default'), true, ]; yield [ - new Dsn('smtps', 'mandrill'), + new Dsn('mandrill+smtp', 'default'), true, ]; yield [ - new Dsn('smtp', 'example.com'), - false, + new Dsn('mandrill+smtps', 'default'), + true, + ]; + + yield [ + new Dsn('mandrill+smtp', 'example.com'), + true, ]; } @@ -61,22 +66,37 @@ public function createProvider(): iterable $logger = $this->getLogger(); yield [ - new Dsn('api', 'mandrill', self::USER), + new Dsn('mandrill+api', 'default', self::USER), new MandrillApiTransport(self::USER, $client, $dispatcher, $logger), ]; yield [ - new Dsn('http', 'mandrill', self::USER), + new Dsn('mandrill+api', 'example.com', self::USER, '', 8080), + (new MandrillApiTransport(self::USER, $client, $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('mandrill', 'default', self::USER), new MandrillHttpTransport(self::USER, $client, $dispatcher, $logger), ]; yield [ - new Dsn('smtp', 'mandrill', self::USER, self::PASSWORD), + new Dsn('mandrill+https', 'default', self::USER), + new MandrillHttpTransport(self::USER, $client, $dispatcher, $logger), + ]; + + yield [ + new Dsn('mandrill+https', 'example.com', self::USER, '', 8080), + (new MandrillHttpTransport(self::USER, $client, $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('mandrill+smtp', 'default', self::USER, self::PASSWORD), new MandrillSmtpTransport(self::USER, self::PASSWORD, $dispatcher, $logger), ]; yield [ - new Dsn('smtps', 'mandrill', self::USER, self::PASSWORD), + new Dsn('mandrill+smtps', 'default', self::USER, self::PASSWORD), new MandrillSmtpTransport(self::USER, self::PASSWORD, $dispatcher, $logger), ]; } @@ -84,15 +104,15 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('foo', 'mandrill', self::USER), - 'The "foo" scheme is not supported for mailer "mandrill". Supported schemes are: "api", "http", "smtp", "smtps".', + new Dsn('mandrill+foo', 'default', self::USER), + 'The "mandrill+foo" scheme is not supported. Supported schemes for mailer "mandrill" are: "mandrill", "mandrill+api", "mandrill+https", "mandrill+smtp", "mandrill+smtps".', ]; } public function incompleteDsnProvider(): iterable { - yield [new Dsn('api', 'mandrill')]; + yield [new Dsn('mandrill+api', 'default')]; - yield [new Dsn('smtp', 'mandrill', self::USER)]; + yield [new Dsn('mandrill+smtp', 'default', self::USER)]; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php index 879611b88484e..904f66994c580 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillApiTransport.php @@ -25,7 +25,7 @@ */ class MandrillApiTransport extends AbstractApiTransport { - private const ENDPOINT = 'https://mandrillapp.com/api/1.0/messages/send.json'; + private const HOST = 'mandrillapp.com'; private $key; @@ -38,12 +38,12 @@ public function __construct(string $key, HttpClientInterface $client = null, Eve public function __toString(): string { - return sprintf('api://mandrill'); + return sprintf('mandrill+api://%s', $this->getEndpoint()); } protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { - $response = $this->client->request('POST', self::ENDPOINT, [ + $response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/api/1.0/messages/send.json', [ 'json' => $this->getPayload($email, $envelope), ]); @@ -59,6 +59,11 @@ protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInte return $response; } + private function getEndpoint(): ?string + { + return ($this->host ?: self::HOST).($this->port ? ':'.$this->port : ''); + } + private function getPayload(Email $email, SmtpEnvelope $envelope): array { $payload = [ diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php index a24afa86a8e93..cec26aaf03d0b 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillHttpTransport.php @@ -24,7 +24,7 @@ */ class MandrillHttpTransport extends AbstractHttpTransport { - private const ENDPOINT = 'https://mandrillapp.com/api/1.0/messages/send-raw.json'; + private const HOST = 'mandrillapp.com'; private $key; public function __construct(string $key, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) @@ -36,13 +36,13 @@ public function __construct(string $key, HttpClientInterface $client = null, Eve public function __toString(): string { - return sprintf('http://mandrill'); + return sprintf('mandrill+https://%s', $this->getEndpoint()); } protected function doSendHttp(SentMessage $message): ResponseInterface { $envelope = $message->getEnvelope(); - $response = $this->client->request('POST', self::ENDPOINT, [ + $response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/api/1.0/messages/send-raw.json', [ 'json' => [ 'key' => $this->key, 'to' => $this->stringifyAddresses($envelope->getRecipients()), @@ -62,4 +62,9 @@ protected function doSendHttp(SentMessage $message): ResponseInterface return $response; } + + private function getEndpoint(): ?string + { + return ($this->host ?: self::HOST).($this->port ? ':'.$this->port : ''); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillTransportFactory.php index b00b2bee748e8..1ba963e00d7d3 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillTransportFactory.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Transport/MandrillTransportFactory.php @@ -25,26 +25,28 @@ public function create(Dsn $dsn): TransportInterface { $scheme = $dsn->getScheme(); $user = $this->getUser($dsn); + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); - if ('api' === $scheme) { - return new MandrillApiTransport($user, $this->client, $this->dispatcher, $this->logger); + if ('mandrill+api' === $scheme) { + return (new MandrillApiTransport($user, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('http' === $scheme) { - return new MandrillHttpTransport($user, $this->client, $this->dispatcher, $this->logger); + if ('mandrill+https' === $scheme || 'mandrill' === $scheme) { + return (new MandrillHttpTransport($user, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('smtp' === $scheme || 'smtps' === $scheme) { + if ('mandrill+smtp' === $scheme || 'mandrill+smtps' === $scheme) { $password = $this->getPassword($dsn); return new MandrillSmtpTransport($user, $password, $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['api', 'http', 'smtp', 'smtps']); + throw new UnsupportedSchemeException($dsn, 'mandrill', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'mandrill' === $dsn->getHost(); + return ['mandrill', 'mandrill+api', 'mandrill+https', 'mandrill+smtp', 'mandrill+smtps']; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php new file mode 100644 index 0000000000000..eb9838390aed8 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunApiTransportTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Mailgun\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunApiTransport; + +class MailgunApiTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(MailgunApiTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new MailgunApiTransport('ACCESS_KEY', 'DOMAIN'), + 'mailgun+api://api.mailgun.net?domain=DOMAIN', + ], + [ + new MailgunApiTransport('ACCESS_KEY', 'DOMAIN', 'us-east-1'), + 'mailgun+api://api.us-east-1.mailgun.net?domain=DOMAIN', + ], + [ + (new MailgunApiTransport('ACCESS_KEY', 'DOMAIN'))->setHost('example.com'), + 'mailgun+api://example.com?domain=DOMAIN', + ], + [ + (new MailgunApiTransport('ACCESS_KEY', 'DOMAIN'))->setHost('example.com')->setPort(99), + 'mailgun+api://example.com:99?domain=DOMAIN', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunHttpTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunHttpTransportTest.php new file mode 100644 index 0000000000000..9b57b2b35e770 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunHttpTransportTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Mailgun\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunHttpTransport; + +class MailgunHttpTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(MailgunHttpTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new MailgunHttpTransport('ACCESS_KEY', 'DOMAIN'), + 'mailgun+https://api.mailgun.net?domain=DOMAIN', + ], + [ + new MailgunHttpTransport('ACCESS_KEY', 'DOMAIN', 'us-east-1'), + 'mailgun+https://api.us-east-1.mailgun.net?domain=DOMAIN', + ], + [ + (new MailgunHttpTransport('ACCESS_KEY', 'DOMAIN'))->setHost('example.com'), + 'mailgun+https://example.com?domain=DOMAIN', + ], + [ + (new MailgunHttpTransport('ACCESS_KEY', 'DOMAIN'))->setHost('example.com')->setPort(99), + 'mailgun+https://example.com:99?domain=DOMAIN', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunTransportFactoryTest.php index 829d880fca624..67a3ed51c4291 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Tests/Transport/MailgunTransportFactoryTest.php @@ -29,28 +29,33 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('api', 'mailgun'), + new Dsn('mailgun+api', 'default'), true, ]; yield [ - new Dsn('http', 'mailgun'), + new Dsn('mailgun', 'default'), true, ]; yield [ - new Dsn('smtp', 'mailgun'), + new Dsn('mailgun+https', 'default'), true, ]; yield [ - new Dsn('smtps', 'mailgun'), + new Dsn('mailgun+smtp', 'default'), true, ]; yield [ - new Dsn('smtp', 'example.com'), - false, + new Dsn('mailgun+smtps', 'default'), + true, + ]; + + yield [ + new Dsn('mailgun+smtp', 'example.com'), + true, ]; } @@ -61,27 +66,42 @@ public function createProvider(): iterable $logger = $this->getLogger(); yield [ - new Dsn('api', 'mailgun', self::USER, self::PASSWORD), + new Dsn('mailgun+api', 'default', self::USER, self::PASSWORD), new MailgunApiTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger), ]; yield [ - new Dsn('api', 'mailgun', self::USER, self::PASSWORD, null, ['region' => 'eu']), + new Dsn('mailgun+api', 'default', self::USER, self::PASSWORD, null, ['region' => 'eu']), new MailgunApiTransport(self::USER, self::PASSWORD, 'eu', $client, $dispatcher, $logger), ]; yield [ - new Dsn('http', 'mailgun', self::USER, self::PASSWORD), + new Dsn('mailgun+api', 'example.com', self::USER, self::PASSWORD, 8080), + (new MailgunApiTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('mailgun', 'default', self::USER, self::PASSWORD), new MailgunHttpTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger), ]; yield [ - new Dsn('smtp', 'mailgun', self::USER, self::PASSWORD), + new Dsn('mailgun+https', 'default', self::USER, self::PASSWORD), + new MailgunHttpTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger), + ]; + + yield [ + new Dsn('mailgun+https', 'example.com', self::USER, self::PASSWORD, 8080), + (new MailgunHttpTransport(self::USER, self::PASSWORD, null, $client, $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('mailgun+smtp', 'default', self::USER, self::PASSWORD), new MailgunSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger), ]; yield [ - new Dsn('smtps', 'mailgun', self::USER, self::PASSWORD), + new Dsn('mailgun+smtps', 'default', self::USER, self::PASSWORD), new MailgunSmtpTransport(self::USER, self::PASSWORD, null, $dispatcher, $logger), ]; } @@ -89,15 +109,15 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('foo', 'mailgun', self::USER, self::PASSWORD), - 'The "foo" scheme is not supported for mailer "mailgun". Supported schemes are: "api", "http", "smtp", "smtps".', + new Dsn('mailgun+foo', 'default', self::USER, self::PASSWORD), + 'The "mailgun+foo" scheme is not supported. Supported schemes for mailer "mailgun" are: "mailgun", "mailgun+api", "mailgun+https", "mailgun+smtp", "mailgun+smtps".', ]; } public function incompleteDsnProvider(): iterable { - yield [new Dsn('api', 'mailgun', self::USER)]; + yield [new Dsn('mailgun+api', 'default', self::USER)]; - yield [new Dsn('api', 'mailgun', null, self::PASSWORD)]; + yield [new Dsn('mailgun+api', 'default', null, self::PASSWORD)]; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php index f58e183736885..1838a01061502 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunApiTransport.php @@ -26,7 +26,7 @@ */ class MailgunApiTransport extends AbstractApiTransport { - private const ENDPOINT = 'https://api.%region_dot%mailgun.net/v3/%domain%/messages'; + private const HOST = 'api.%region_dot%mailgun.net'; private $key; private $domain; @@ -43,7 +43,7 @@ public function __construct(string $key, string $domain, string $region = null, public function __toString(): string { - return sprintf('api://%s@mailgun?region=%s', $this->domain, $this->region); + return sprintf('mailgun+api://%s?domain=%s', $this->getEndpoint(), $this->domain); } protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface @@ -54,8 +54,8 @@ protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInte $headers[] = $header->toString(); } - $endpoint = str_replace(['%domain%', '%region_dot%'], [urlencode($this->domain), 'us' !== ($this->region ?: 'us') ? $this->region.'.' : ''], self::ENDPOINT); - $response = $this->client->request('POST', $endpoint, [ + $endpoint = str_replace('%domain%', urlencode($this->domain), $this->getEndpoint()).'/v3/%domain%/messages'; + $response = $this->client->request('POST', 'https://'.$endpoint, [ 'auth_basic' => 'api:'.$this->key, 'headers' => $headers, 'body' => $body->bodyToIterable(), @@ -137,4 +137,11 @@ private function prepareAttachments(Email $email, ?string $html): array return [$attachments, $inlines, $html]; } + + private function getEndpoint(): ?string + { + $host = $this->host ?: str_replace('%region_dot%', 'us' !== ($this->region ?: 'us') ? $this->region.'.' : '', self::HOST); + + return $host.($this->port ? ':'.$this->port : ''); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php index ad77efea6be7f..b5c9db3ba72b6 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunHttpTransport.php @@ -26,7 +26,8 @@ */ class MailgunHttpTransport extends AbstractHttpTransport { - private const ENDPOINT = 'https://api.%region_dot%mailgun.net/v3/%domain%/messages.mime'; + private const HOST = 'api.%region_dot%mailgun.net'; + private $key; private $domain; private $region; @@ -42,7 +43,7 @@ public function __construct(string $key, string $domain, string $region = null, public function __toString(): string { - return sprintf('http://%s@mailgun?region=%s', $this->domain, $this->region); + return sprintf('mailgun+https://%s?domain=%s', $this->getEndpoint(), $this->domain); } protected function doSendHttp(SentMessage $message): ResponseInterface @@ -55,8 +56,9 @@ protected function doSendHttp(SentMessage $message): ResponseInterface foreach ($body->getPreparedHeaders()->all() as $header) { $headers[] = $header->toString(); } - $endpoint = str_replace(['%domain%', '%region_dot%'], [urlencode($this->domain), 'us' !== ($this->region ?: 'us') ? $this->region.'.' : ''], self::ENDPOINT); - $response = $this->client->request('POST', $endpoint, [ + + $endpoint = str_replace('%domain%', urlencode($this->domain), $this->getEndpoint()).'/v3/%domain%/messages.mime'; + $response = $this->client->request('POST', 'https://'.$endpoint, [ 'auth_basic' => 'api:'.$this->key, 'headers' => $headers, 'body' => $body->bodyToIterable(), @@ -70,4 +72,11 @@ protected function doSendHttp(SentMessage $message): ResponseInterface return $response; } + + private function getEndpoint(): ?string + { + $host = $this->host ?: str_replace('%region_dot%', 'us' !== ($this->region ?: 'us') ? $this->region.'.' : '', self::HOST); + + return $host.($this->port ? ':'.$this->port : ''); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunTransportFactory.php index 486dd6661935f..c238f832fae89 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunTransportFactory.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Transport/MailgunTransportFactory.php @@ -27,24 +27,26 @@ public function create(Dsn $dsn): TransportInterface $user = $this->getUser($dsn); $password = $this->getPassword($dsn); $region = $dsn->getOption('region'); + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); - if ('api' === $scheme) { - return new MailgunApiTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger); + if ('mailgun+api' === $scheme) { + return (new MailgunApiTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('http' === $scheme) { - return new MailgunHttpTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger); + if ('mailgun+https' === $scheme || 'mailgun' === $scheme) { + return (new MailgunHttpTransport($user, $password, $region, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('smtp' === $scheme || 'smtps' === $scheme) { + if ('mailgun+smtp' === $scheme || 'mailgun+smtps' === $scheme) { return new MailgunSmtpTransport($user, $password, $region, $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['api', 'http', 'smtp', 'smtps']); + throw new UnsupportedSchemeException($dsn, 'mailgun', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'mailgun' === $dsn->getHost(); + return ['mailgun', 'mailgun+api', 'mailgun+https', 'mailgun+smtp', 'mailgun+smtps']; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php new file mode 100644 index 0000000000000..b6568706f8306 --- /dev/null +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkApiTransportTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Mailer\Bridge\Postmark\Tests\Transport; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkApiTransport; + +class PostmarkApiTransportTest extends TestCase +{ + /** + * @dataProvider getTransportData + */ + public function testToString(PostmarkApiTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new PostmarkApiTransport('KEY'), + 'postmark+api://api.postmarkapp.com', + ], + [ + (new PostmarkApiTransport('KEY'))->setHost('example.com'), + 'postmark+api://example.com', + ], + [ + (new PostmarkApiTransport('KEY'))->setHost('example.com')->setPort(99), + 'postmark+api://example.com:99', + ], + ]; + } +} diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkTransportFactoryTest.php index 721af087a74db..d93a1a2081bb1 100644 --- a/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Tests/Transport/PostmarkTransportFactoryTest.php @@ -28,23 +28,28 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('api', 'postmark'), + new Dsn('postmark+api', 'default'), true, ]; yield [ - new Dsn('smtp', 'postmark'), + new Dsn('postmark', 'default'), true, ]; yield [ - new Dsn('smtps', 'postmark'), + new Dsn('postmark+smtp', 'default'), true, ]; yield [ - new Dsn('smtp', 'example.com'), - false, + new Dsn('postmark+smtps', 'default'), + true, + ]; + + yield [ + new Dsn('postmark+smtp', 'example.com'), + true, ]; } @@ -54,17 +59,27 @@ public function createProvider(): iterable $logger = $this->getLogger(); yield [ - new Dsn('api', 'postmark', self::USER), + new Dsn('postmark+api', 'default', self::USER), new PostmarkApiTransport(self::USER, $this->getClient(), $dispatcher, $logger), ]; yield [ - new Dsn('smtp', 'postmark', self::USER), + new Dsn('postmark+api', 'example.com', self::USER, '', 8080), + (new PostmarkApiTransport(self::USER, $this->getClient(), $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('postmark', 'default', self::USER), + new PostmarkSmtpTransport(self::USER, $dispatcher, $logger), + ]; + + yield [ + new Dsn('postmark+smtp', 'default', self::USER), new PostmarkSmtpTransport(self::USER, $dispatcher, $logger), ]; yield [ - new Dsn('smtps', 'postmark', self::USER), + new Dsn('postmark+smtps', 'default', self::USER), new PostmarkSmtpTransport(self::USER, $dispatcher, $logger), ]; } @@ -72,13 +87,13 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('foo', 'postmark', self::USER), - 'The "foo" scheme is not supported for mailer "postmark". Supported schemes are: "api", "smtp", "smtps".', + new Dsn('postmark+foo', 'default', self::USER), + 'The "postmark+foo" scheme is not supported. Supported schemes for mailer "postmark" are: "postmark", "postmark+api", "postmark+smtp", "postmark+smtps".', ]; } public function incompleteDsnProvider(): iterable { - yield [new Dsn('api', 'postmark')]; + yield [new Dsn('postmark+api', 'default')]; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php index a13e8ae7300c0..d7b8344c6b683 100644 --- a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkApiTransport.php @@ -25,7 +25,7 @@ */ class PostmarkApiTransport extends AbstractApiTransport { - private const ENDPOINT = 'http://api.postmarkapp.com/email'; + private const HOST = 'api.postmarkapp.com'; private $key; @@ -38,12 +38,12 @@ public function __construct(string $key, HttpClientInterface $client = null, Eve public function __toString(): string { - return sprintf('api://postmark'); + return sprintf('postmark+api://%s', $this->getEndpoint()); } protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { - $response = $this->client->request('POST', self::ENDPOINT, [ + $response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/email', [ 'headers' => [ 'Accept' => 'application/json', 'X-Postmark-Server-Token' => $this->key, @@ -111,4 +111,9 @@ private function getAttachments(Email $email): array return $attachments; } + + private function getEndpoint(): ?string + { + return ($this->host ?: self::HOST).($this->port ? ':'.$this->port : ''); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkTransportFactory.php index fbe6add0c2871..983f41a4503e8 100644 --- a/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkTransportFactory.php +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Transport/PostmarkTransportFactory.php @@ -26,19 +26,22 @@ public function create(Dsn $dsn): TransportInterface $scheme = $dsn->getScheme(); $user = $this->getUser($dsn); - if ('api' === $scheme) { - return new PostmarkApiTransport($user, $this->client, $this->dispatcher, $this->logger); + if ('postmark+api' === $scheme) { + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); + + return (new PostmarkApiTransport($user, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('smtp' === $scheme || 'smtps' === $scheme) { + if ('postmark+smtp' === $scheme || 'postmark+smtps' === $scheme || 'postmark' === $scheme) { return new PostmarkSmtpTransport($user, $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['api', 'smtp', 'smtps']); + throw new UnsupportedSchemeException($dsn, 'postmark', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'postmark' === $dsn->getHost(); + return ['postmark', 'postmark+api', 'postmark+smtp', 'postmark+smtps']; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php index 083c04d3173de..ea5e91af1a947 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridApiTransportTest.php @@ -19,6 +19,32 @@ class SendgridApiTransportTest extends TestCase { + /** + * @dataProvider getTransportData + */ + public function testToString(SendgridApiTransport $transport, string $expected) + { + $this->assertSame($expected, (string) $transport); + } + + public function getTransportData() + { + return [ + [ + new SendgridApiTransport('KEY'), + 'sendgrid+api://api.sendgrid.com', + ], + [ + (new SendgridApiTransport('KEY'))->setHost('example.com'), + 'sendgrid+api://example.com', + ], + [ + (new SendgridApiTransport('KEY'))->setHost('example.com')->setPort(99), + 'sendgrid+api://example.com:99', + ], + ]; + } + public function testSend() { $email = new Email(); diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridTransportFactoryTest.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridTransportFactoryTest.php index e6494649cda69..b32c37e0c8b48 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Tests/Transport/SendgridTransportFactoryTest.php @@ -28,23 +28,28 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('api', 'sendgrid'), + new Dsn('sendgrid+api', 'default'), true, ]; yield [ - new Dsn('smtp', 'sendgrid'), + new Dsn('sendgrid', 'default'), true, ]; yield [ - new Dsn('smtps', 'sendgrid'), + new Dsn('sendgrid+smtp', 'default'), true, ]; yield [ - new Dsn('smtp', 'example.com'), - false, + new Dsn('sendgrid+smtps', 'default'), + true, + ]; + + yield [ + new Dsn('sendgrid+smtp', 'example.com'), + true, ]; } @@ -54,17 +59,27 @@ public function createProvider(): iterable $logger = $this->getLogger(); yield [ - new Dsn('api', 'sendgrid', self::USER), + new Dsn('sendgrid+api', 'default', self::USER), new SendgridApiTransport(self::USER, $this->getClient(), $dispatcher, $logger), ]; yield [ - new Dsn('smtp', 'sendgrid', self::USER), + new Dsn('sendgrid+api', 'example.com', self::USER, '', 8080), + (new SendgridApiTransport(self::USER, $this->getClient(), $dispatcher, $logger))->setHost('example.com')->setPort(8080), + ]; + + yield [ + new Dsn('sendgrid', 'default', self::USER), + new SendgridSmtpTransport(self::USER, $dispatcher, $logger), + ]; + + yield [ + new Dsn('sendgrid+smtp', 'default', self::USER), new SendgridSmtpTransport(self::USER, $dispatcher, $logger), ]; yield [ - new Dsn('smtps', 'sendgrid', self::USER), + new Dsn('sendgrid+smtps', 'default', self::USER), new SendgridSmtpTransport(self::USER, $dispatcher, $logger), ]; } @@ -72,13 +87,13 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('foo', 'sendgrid', self::USER), - 'The "foo" scheme is not supported for mailer "sendgrid". Supported schemes are: "api", "smtp", "smtps".', + new Dsn('sendgrid+foo', 'sendgrid', self::USER), + 'The "sendgrid+foo" scheme is not supported. Supported schemes for mailer "sendgrid" are: "sendgrid", "sendgrid+api", "sendgrid+smtp", "sendgrid+smtps".', ]; } public function incompleteDsnProvider(): iterable { - yield [new Dsn('api', 'sendgrid')]; + yield [new Dsn('sendgrid+api', 'default')]; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php index 8536b8eb6ce46..c945d96de9af5 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridApiTransport.php @@ -26,7 +26,7 @@ */ class SendgridApiTransport extends AbstractApiTransport { - private const ENDPOINT = 'https://api.sendgrid.com/v3/mail/send'; + private const HOST = 'api.sendgrid.com'; private $key; @@ -39,12 +39,12 @@ public function __construct(string $key, HttpClientInterface $client = null, Eve public function __toString(): string { - return sprintf('api://sendgrid'); + return sprintf('sendgrid+api://%s', $this->getEndpoint()); } protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { - $response = $this->client->request('POST', self::ENDPOINT, [ + $response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/v3/mail/send', [ 'json' => $this->getPayload($email, $envelope), 'auth_bearer' => $this->key, ]); @@ -136,4 +136,9 @@ private function getAttachments(Email $email): array return $attachments; } + + private function getEndpoint(): ?string + { + return ($this->host ?: self::HOST).($this->port ? ':'.$this->port : ''); + } } diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridTransportFactory.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridTransportFactory.php index 70d87a08dabff..a4734c7213d77 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridTransportFactory.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Transport/SendgridTransportFactory.php @@ -25,19 +25,22 @@ public function create(Dsn $dsn): TransportInterface { $key = $this->getUser($dsn); - if ('api' === $dsn->getScheme()) { - return new SendgridApiTransport($key, $this->client, $this->dispatcher, $this->logger); + if ('sendgrid+api' === $dsn->getScheme()) { + $host = 'default' === $dsn->getHost() ? null : $dsn->getHost(); + $port = $dsn->getPort(); + + return (new SendgridApiTransport($key, $this->client, $this->dispatcher, $this->logger))->setHost($host)->setPort($port); } - if ('smtp' === $dsn->getScheme() || 'smtps' === $dsn->getScheme()) { + if ('sendgrid+smtp' === $dsn->getScheme() || 'sendgrid+smtps' === $dsn->getScheme() || 'sendgrid' === $dsn->getScheme()) { return new SendgridSmtpTransport($key, $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['api', 'smtp', 'smtps']); + throw new UnsupportedSchemeException($dsn, 'sendgrid', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'sendgrid' === $dsn->getHost(); + return ['sendgrid', 'sendgrid+api', 'sendgrid+smtp', 'sendgrid+smtps']; } } diff --git a/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php b/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php index e67733630cea1..165d644cb301e 100644 --- a/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php +++ b/src/Symfony/Component/Mailer/Exception/UnsupportedSchemeException.php @@ -18,8 +18,8 @@ */ class UnsupportedSchemeException extends LogicException { - public function __construct(Dsn $dsn, array $supported) + public function __construct(Dsn $dsn, string $name, array $supported) { - parent::__construct(sprintf('The "%s" scheme is not supported for mailer "%s". Supported schemes are: "%s".', $dsn->getScheme(), $dsn->getHost(), implode('", "', $supported))); + parent::__construct(sprintf('The "%s" scheme is not supported. Supported schemes for mailer "%s" are: "%s".', $dsn->getScheme(), $name, implode('", "', $supported))); } } diff --git a/src/Symfony/Component/Mailer/Test/TransportFactoryTestCase.php b/src/Symfony/Component/Mailer/Test/TransportFactoryTestCase.php index 6c73354bb3853..34a264be7d6bc 100644 --- a/src/Symfony/Component/Mailer/Test/TransportFactoryTestCase.php +++ b/src/Symfony/Component/Mailer/Test/TransportFactoryTestCase.php @@ -69,7 +69,7 @@ public function testCreate(Dsn $dsn, TransportInterface $transport): void $factory = $this->getFactory(); $this->assertEquals($transport, $factory->create($dsn)); - if ('smtp' !== $dsn->getScheme() && 'smtps' !== $dsn->getScheme()) { + if (false !== strpos('smtp', $dsn->getScheme())) { $this->assertStringMatchesFormat($dsn->getScheme().'://%S'.$dsn->getHost().'%S', (string) $transport); } } diff --git a/src/Symfony/Component/Mailer/Tests/Transport/NullTransportFactoryTest.php b/src/Symfony/Component/Mailer/Tests/Transport/NullTransportFactoryTest.php index 06248f34b51c5..9b39a6140b6c3 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/NullTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/NullTransportFactoryTest.php @@ -27,29 +27,16 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('smtp', 'null'), + new Dsn('null', ''), true, ]; - - yield [ - new Dsn('smtp', 'example.com'), - false, - ]; } public function createProvider(): iterable { yield [ - new Dsn('smtp', 'null'), + new Dsn('null', 'null'), new NullTransport($this->getDispatcher(), $this->getLogger()), ]; } - - public function unsupportedSchemeProvider(): iterable - { - yield [ - new Dsn('foo', 'null'), - 'The "foo" scheme is not supported for mailer "null". Supported schemes are: "smtp".', - ]; - } } diff --git a/src/Symfony/Component/Mailer/Tests/Transport/NullTransportTest.php b/src/Symfony/Component/Mailer/Tests/Transport/NullTransportTest.php index c43bf90f9951c..34c2a41392b1e 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/NullTransportTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/NullTransportTest.php @@ -19,6 +19,6 @@ class NullTransportTest extends TestCase public function testToString() { $t = new NullTransport(); - $this->assertEquals('smtp://null', (string) $t); + $this->assertEquals('null://', (string) $t); } } diff --git a/src/Symfony/Component/Mailer/Tests/Transport/SendmailTransportFactoryTest.php b/src/Symfony/Component/Mailer/Tests/Transport/SendmailTransportFactoryTest.php index 84d8d92ca74ab..078b00b6f5b54 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/SendmailTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/SendmailTransportFactoryTest.php @@ -27,20 +27,15 @@ public function getFactory(): TransportFactoryInterface public function supportsProvider(): iterable { yield [ - new Dsn('smtp', 'sendmail'), + new Dsn('sendmail+smtp', 'default'), true, ]; - - yield [ - new Dsn('smtp', 'example.com'), - false, - ]; } public function createProvider(): iterable { yield [ - new Dsn('smtp', 'sendmail'), + new Dsn('sendmail+smtp', 'default'), new SendmailTransport(null, $this->getDispatcher(), $this->getLogger()), ]; } @@ -48,8 +43,8 @@ public function createProvider(): iterable public function unsupportedSchemeProvider(): iterable { yield [ - new Dsn('http', 'sendmail'), - 'The "http" scheme is not supported for mailer "sendmail". Supported schemes are: "smtp".', + new Dsn('sendmail+http', 'default'), + 'The "sendmail+http" scheme is not supported. Supported schemes for mailer "sendmail" are: "sendmail", "sendmail+smtp".', ]; } } diff --git a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/EsmtpTransportFactoryTest.php b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/EsmtpTransportFactoryTest.php index a3b13b624c42f..7dcea33e9648f 100644 --- a/src/Symfony/Component/Mailer/Tests/Transport/Smtp/EsmtpTransportFactoryTest.php +++ b/src/Symfony/Component/Mailer/Tests/Transport/Smtp/EsmtpTransportFactoryTest.php @@ -64,7 +64,7 @@ public function createProvider(): iterable $transport = new EsmtpTransport('example.com', 465, true, $eventDispatcher, $logger); yield [ - new Dsn('smtp', 'example.com', '', '', 465), + new Dsn('smtps', 'example.com', '', '', 465), $transport, ]; } diff --git a/src/Symfony/Component/Mailer/Transport/AbstractHttpTransport.php b/src/Symfony/Component/Mailer/Transport/AbstractHttpTransport.php index 17deb9fe614c3..5480810b0d375 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractHttpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractHttpTransport.php @@ -24,6 +24,8 @@ */ abstract class AbstractHttpTransport extends AbstractTransport { + protected $host; + protected $port; protected $client; public function __construct(HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) @@ -40,6 +42,26 @@ public function __construct(HttpClientInterface $client = null, EventDispatcherI parent::__construct($dispatcher, $logger); } + /** + * @return $this + */ + public function setHost(?string $host) + { + $this->host = $host; + + return $this; + } + + /** + * @return $this + */ + public function setPort(?int $port) + { + $this->port = $port; + + return $this; + } + abstract protected function doSendHttp(SentMessage $message): ResponseInterface; protected function doSend(SentMessage $message): void diff --git a/src/Symfony/Component/Mailer/Transport/AbstractTransportFactory.php b/src/Symfony/Component/Mailer/Transport/AbstractTransportFactory.php index 959fca5746609..17c87224df4a6 100644 --- a/src/Symfony/Component/Mailer/Transport/AbstractTransportFactory.php +++ b/src/Symfony/Component/Mailer/Transport/AbstractTransportFactory.php @@ -32,6 +32,13 @@ public function __construct(EventDispatcherInterface $dispatcher = null, HttpCli $this->logger = $logger; } + public function supports(Dsn $dsn): bool + { + return \in_array($dsn->getScheme(), $this->getSupportedSchemes()); + } + + abstract protected function getSupportedSchemes(): array; + protected function getUser(Dsn $dsn): string { $user = $dsn->getUser(); diff --git a/src/Symfony/Component/Mailer/Transport/NullTransport.php b/src/Symfony/Component/Mailer/Transport/NullTransport.php index 71a0958b53d6b..92fb82a478cbd 100644 --- a/src/Symfony/Component/Mailer/Transport/NullTransport.php +++ b/src/Symfony/Component/Mailer/Transport/NullTransport.php @@ -26,6 +26,6 @@ protected function doSend(SentMessage $message): void public function __toString(): string { - return 'smtp://null'; + return 'null://'; } } diff --git a/src/Symfony/Component/Mailer/Transport/NullTransportFactory.php b/src/Symfony/Component/Mailer/Transport/NullTransportFactory.php index d874e5b583c4e..4c45f39e11978 100644 --- a/src/Symfony/Component/Mailer/Transport/NullTransportFactory.php +++ b/src/Symfony/Component/Mailer/Transport/NullTransportFactory.php @@ -20,15 +20,15 @@ final class NullTransportFactory extends AbstractTransportFactory { public function create(Dsn $dsn): TransportInterface { - if ('smtp' === $dsn->getScheme()) { + if ('null' === $dsn->getScheme()) { return new NullTransport($this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['smtp']); + throw new UnsupportedSchemeException($dsn, 'null', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'null' === $dsn->getHost(); + return ['null']; } } diff --git a/src/Symfony/Component/Mailer/Transport/SendmailTransportFactory.php b/src/Symfony/Component/Mailer/Transport/SendmailTransportFactory.php index 5e89a2070e06c..77d6d49a4a461 100644 --- a/src/Symfony/Component/Mailer/Transport/SendmailTransportFactory.php +++ b/src/Symfony/Component/Mailer/Transport/SendmailTransportFactory.php @@ -20,15 +20,15 @@ final class SendmailTransportFactory extends AbstractTransportFactory { public function create(Dsn $dsn): TransportInterface { - if ('smtp' === $dsn->getScheme()) { + if ('sendmail+smtp' === $dsn->getScheme() || 'sendmail' === $dsn->getScheme()) { return new SendmailTransport(null, $this->dispatcher, $this->logger); } - throw new UnsupportedSchemeException($dsn, ['smtp']); + throw new UnsupportedSchemeException($dsn, 'sendmail', $this->getSupportedSchemes()); } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'sendmail' === $dsn->getHost(); + return ['sendmail', 'sendmail+smtp']; } } diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransportFactory.php b/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransportFactory.php index a1438f91f49f6..6613145f68f81 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransportFactory.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/EsmtpTransportFactory.php @@ -39,8 +39,8 @@ public function create(Dsn $dsn): TransportInterface return $transport; } - public function supports(Dsn $dsn): bool + protected function getSupportedSchemes(): array { - return 'smtp' === $dsn->getScheme() || 'smtps' === $dsn->getScheme(); + return ['smtp', 'smtps']; } } 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