10000 Add NativeTransportFactory · symfony/symfony@f81c0a6 · GitHub
[go: up one dir, main page]

Skip to content

Commit f81c0a6

Browse files
committed
Add NativeTransportFactory
1 parent 7d3ba72 commit f81c0a6

File tree

8 files changed

+226
-31
lines changed

8 files changed

+226
-31
lines changed

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

7-
<parameters>
8-
<parameter key="mailer.sendmail_default_command">/usr/sbin/sendmail -bs</parameter>
9-
</parameters>
10-
117
<services>
128
<service id="mailer.transport_factory.abstract" class="Symfony\Component\Mailer\Transport\AbstractTransportFactory" abstract="true">
139
<argument type="service" id="event_dispatcher" />
@@ -45,11 +41,14 @@
4541

4642
<service id="mailer.transport_factory.sendmail" class="Symfony\Component\Mailer\Transport\SendmailTransportFactory" parent="mailer.transport_factory.abstract">
4743
<tag name="mailer.transport_factory" />
48-
<argument type="string">%mailer.sendmail_default_command%</argument>
4944
</service>
5045

5146
<service id="mailer.transport_factory.smtp" class="Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory" parent="mailer.transport_factory.abstract">
5247
<tag name="mailer.transport_factory" priority="-100" />
5348
</service>
49+
50+
<service id="mailer.transport_factory.native" class="Symfony\Component\Mailer\Transport\NativeTransportFactory" parent="mailer.transport_factory.abstract">
51+
<tag name="mailer.transport_factory" />
52+
</service>
5453
</services>
5554
</container>

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"symfony/expression-language": "^4.4|^5.0",
4646
"symfony/http-client": "^4.4|^5.0",
4747
"symfony/lock": "^4.4|^5.0",
48-
"symfony/mailer": "^4.4|^5.0",
48+
"symfony/mailer": "^4.4|^5.2",
4949
"symfony/messenger": "^4.4|^5.0",
5050
"symfony/mime": "^4.4|^5.0",
5151
"symfony/process": "^4.4|^5.0",
@@ -79,7 +79,7 @@
7979
"symfony/http-client": "<4.4",
8080
"symfony/form": "<4.4",
8181
"symfony/lock": "<4.4",
82-
"symfony/mailer": "<4.4",
82+
"symfony/mailer": "<5.2",
8383
"symfony/messenger": "<4.4",
8484
"symfony/mime": "<4.4",
8585
"symfony/property-info": "<4.4",
@@ -111,7 +111,7 @@
111111
"minimum-stability": "dev",
112112
"extra": {
113113
"branch-alias": {
114-
"dev-master": "5.1-dev"
114+
"dev-master": "5.2-dev"
115115
}
116116
}
117117
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
3+
namespace Symfony\Component\Mailer\Tests\Transport;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
7+
use Symfony\Component\Mailer\Transport\Dsn;
8+
use Symfony\Component\Mailer\Transport\NativeTransportFactory;
9+
use Symfony\Component\Mailer\Transport\SendmailTransport;
10+
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport;
11+
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream;
12+
use Symfony\Component\Mailer\Transport\TransportInterface;
13+
14+
final class NativeTransportFactoryTest extends TestCase
15+
{
16+
public static $fakeConfiguration = [];
17+
18+
public static function setUpBeforeClass(): void
19+
{
20+
parent::setUpBeforeClass();
21+
22+
$namespace = str_replace('\\Tests\\', '\\', __NAMESPACE__);
23+
24+
$current = \get_called_class();
25+
26+
$eval = <<<EOT
27+
namespace $namespace;
28+
29+
function ini_get(\$key)
30+
{
31+
\$vals = \\$current::\$fakeConfiguration;
32+
return \$vals[\$key] ?? '';
33+
}
34+
EOT;
35+
eval($eval);
36+
}
37+
38+
public function provideCreateWithNotSupportedScheme(): \Generator
39+
{
40+
yield ['sendmail://default'];
41+
42+
if (PHP_OS_FAMILY != 'Windows') {
43+
yield ['native+smtp://default'];
44+
}
45+
}
46+
47+
/**
48+
* @dataProvider provideCreateWithNotSupportedScheme
49+
*/
50+
public function testCreateWithNotSupportedScheme(string $dsn)
51+
{
52+
$this->expectException(UnsupportedSchemeException::class);
53+
$this->expectExceptionMessageRegExp('#The ".*" scheme is not supported#');
54+
55+
$sut = new NativeTransportFactory();
56+
$sut->create(Dsn::fromString($dsn));
57+
}
58+
59+
public function provideCreateSendmailWithNoSendmailPath(): \Generator
60+
{
61+
if ('Linux' === PHP_OS_FAMILY) {
62+
yield ['native://default'];
63+
}
64+
65+
yield ['native+sendmail://default'];
66+
}
67+
68+
/**
69+
* @dataProvider provideCreateSendmailWithNoSendmailPath
70+
*/
71+
public function testCreateSendmailWithNoSendmailPath(string $dsn)
72+
{
73+
$this->expectException(\Exception::class);
74+
$this->expectExceptionMessage('sendmail_path is not configured');
75+
76+
$sut = new NativeTransportFactory();
77+
$sut->create(Dsn::fromString($dsn));
78+
}
79+
80+
public function provideCreateSendmailWithNoHostOrNoPort(): array
81+
{
82+
return [
83+
['native://default', '', ''],
84+
['native+smtp://default', '/usr/sbin/sendmail -t -i', ''],
85+
['native://default', '', 'localhost'],
86+
];
87+
}
88+
89+
/**
90+
* @requires OSFAMILY Windows
91+
*
92+
* @dataProvider provideCreateSendmailWithNoHostOrNoPort
93+
*/
94+
public function testCreateSendmailWithNoHostOrNoPort(string $dsn, string $sendmaiPath, string $smtp)
95+
{
96+
$this->expectException(\Exception::class);
97+
$this->expectExceptionMessage('smtp or smtp_port is not configured');
98+
99+
self::$fakeConfiguration = [
100+
'sendmail_path' => $sendmaiPath,
101+
'smtp' => $smtp,
102+
];
103+
104+
$sut = new NativeTransportFactory();
105+
$sut->create(Dsn::fromString($dsn));
106+
}
107+
108+
public function provideCreate(): \Generator
109+
{
110+
yield ['native://default', '/usr/sbin/sendmail -t -i', '', '', new SendmailTransport('/usr/sbin/sendmail -t -i')];
111+
yield ['native+sendmail://default', '/usr/sbin/sendmail -t -i', '', '', new SendmailTransport('/usr/sbin/sendmail -t -i')];
112+
113+
if ('Windows' === PHP_OS_FAMILY) {
114+
$socketStream = new SocketStream();
115+
$socketStream->setHost('myhost.tld');
116+
$socketStream->setPort(25);
117+
$socketStream->disableTls();
118+
yield ['native://default', '', 'myhost.tld', '25', new SmtpTransport($socketStream)];
119+
yield ['native+smtp://default', '/usr/sbin/sendmail -t -i', 'myhost.tld', '25', new SmtpTransport($socketStream)];
120+
121+
$socketStreamTls = new SocketStream();
122+
$socketStreamTls->setHost('myhost.tld');
123+
$socketStreamTls->setPort(465);
124+
yield ['native://default', '', 'myhost.tld', '465', new SmtpTransport($socketStreamTls)];
125+
}
126+
}
127+
128+
/**
129+
* @dataProvider provideCreate
130+
*/
131+
public function testCreate(string $dsn, string $sendmailPath, string $smtp, string $smtpPort, TransportInterface $expectedTransport)
132+
{
133+
self::$fakeConfiguration = [
134+
'sendmail_path' => $sendmailPath,
135+
'smtp' => $smtp,
136+
'smtp_port' => $smtpPort,
137+
];
138+
139+
$sut = new NativeTransportFactory();
140+
$transport = $sut->create(Dsn::fromString($dsn));
141+
142+
$this->assertEquals($expectedTransport, $transport);
143+
}
144+
}

src/Symfony/Component/Mailer/Tests/Transport/SendmailTransportFactoryTest.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,6 @@ public function createProvider(): iterable
4040
];
4141
}
4242

43-
public function testCreateWithCustomCommand()
44-
{
45-
$factory = new SendmailTransportFactory($this->getDispatcher(), $this->getClient(), $this->getLogger(), '/usr/sbin/sendmail -t');
46-
$dsn = new Dsn('sendmail+smtp', 'default');
47-
$this->assertEquals(new SendmailTransport('/usr/sbin/sendmail -t', $this->getDispatcher(), $this->getLogger()), $factory->create($dsn));
48-
}
49-
5043
public function unsupportedSchemeProvider(): iterable
5144
{
5245
yield [

src/Symfony/Component/Mailer/Transport.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
2323
use Symfony\Component\Mailer\Transport\Dsn;
2424
use Symfony\Component\Mailer\Transport\FailoverTransport;
25+
use Symfony\Component\Mailer\Transport\NativeTransportFactory;
2526
use Symfony\Component\Mailer\Transport\NullTransportFactory;
2627
use Symfony\Component\Mailer\Transport\RoundRobinTransport;
2728
use Symfony\Component\Mailer\Transport\SendmailTransportFactory;
@@ -162,5 +163,7 @@ public static function getDefaultFactories(EventDispatcherInterface $dispatcher
162163
yield new SendmailTransportFactory($dispatcher, $client, $logger);
163164

164165
yield new EsmtpTransportFactory($dispatcher, $client, $logger);
166+
167+
yield new NativeTransportFactory($dispatcher, $client, $logger);
165168
}
166169
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Mailer\Transport;
13+
14+
use Symfony\Component\Mailer\Exception\TransportException;
15+
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
16+
use Symfony\Component\Mailer\Transport\Smtp\SmtpTransport;
17+
use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream;
18+
19+
/**
20+
* @author Laurent VOULLEMIER <laurent.voullemier@gmail.com>
21+
*/
22+
final class NativeTransportFactory extends AbstractTransportFactory
23+
{
24+
public function create(Dsn $dsn): TransportInterface
25+
{
26+
if (!\in_array($dsn->getScheme(), $this->getSupportedSchemes(), true)) {
27+
throw new UnsupportedSchemeException($dsn, 'native', $this->getSupportedSchemes());
28+
}
29+
30+
$isWindows = 'WIN' === strtoupper(substr(PHP_OS, 0, 3));
31+
if ($sendMailPath = ini_get('sendmail_path')) {
32+
if (!$isWindows || 'native+sendmail' === $dsn->getScheme() || 'native' === $dsn->getScheme()) {
33+
return new SendmailTransport($sendMailPath, $this->dispatcher, $this->logger);
34+
}
35+
}
36+
37+
if (!$isWindows || 'native+sendmail' === $dsn->getScheme()) {
38+
throw new TransportException('sendmail_path is not configured in php.ini.');
39+
}
40+
41+
// Only for windows hosts; at this point non-windows
42+
// host have already thrown an exception or returned a transport
43+
$host = ini_get('smtp');
44+
$port = (int) ini_get('smtp_port');
45+
46+
if (!$host || !$port) {
47+
throw new TransportException('smtp or smtp_port is not configured in php.ini.');
48+
}
49+
50+
$socketStream = new SocketStream();
51+
$socketStream->setHost($host);
52+
$socketStream->setPort($port);
53+
if (465 !== $port) {
54+
$socketStream->disableTls();
55+
}
56+
57+
return new SmtpTransport($socketStream, $this->dispatcher, $this->logger);
58+
}
59+
60+
protected function getSupportedSchemes(): array
61+
{
62+
$supportedShemes = ['native', 'native+sendmail'];
63+
64+
if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
65+
$supportedShemes[] = 'native+smtp';
66+
}
67+
68+
return $supportedShemes;
69+
}
70+
}

src/Symfony/Component/Mailer/Transport/SendmailTransportFactory.php

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,17 @@
1111

1212
namespace Symfony\Component\Mailer\Transport;
1313

14-
use Psr\Log\LoggerInterface;
1514
use Symfony\Component\Mailer\Exception\UnsupportedSchemeException;
16-
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
17-
use Symfony\Contracts\HttpClient\HttpClientInterface;
1815

1916
/**
2017
* @author Konstantin Myakshin <molodchick@gmail.com>
2118
*/
2219
final class SendmailTransportFactory extends AbstractTransportFactory
2320
{
24-
/**
25-
* @var string
26-
*/
27-
private $command;
28-
29-
public function __construct(EventDispatcherInterface $dispatcher = null, HttpClientInterface $client = null, LoggerInterface $logger = null, ?string $command = null)
30-
{
31-
parent::__construct($dispatcher, $client, $logger);
32-
$this->command = $command;
33-
}
34-
3521
public function create(Dsn $dsn): TransportInterface
3622
{
3723
if ('sendmail+smtp' === $dsn->getScheme() || 'sendmail' === $dsn->getScheme()) {
38-
return new SendmailTransport($this->command, $this->dispatcher, $this->logger);
24+
return new SendmailTransport(null, $this->dispatcher, $this->logger);
3925
}
4026

4127
throw new UnsupportedSchemeException($dsn, 'sendmail', $this->getSupportedSchemes());

src/Symfony/Component/Mailer/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"minimum-stability": "dev",
4747
"extra": {
4848
"branch-alias": {
49-
"dev-master": "5.1-dev"
49+
"dev-master": "5.2-dev"
5050
}
5151
}
5252
}

0 commit comments

Comments
 (0)
0