Skip to content
This repository was archived by the owner on Feb 6, 2022. It is now read-only.

Commit b39da7a

Browse files
committed
allow using env variables in transport configuration
1 parent ad75109 commit b39da7a

File tree

2 files changed

+181
-59
lines changed

2 files changed

+181
-59
lines changed

DependencyInjection/SwiftmailerExtension.php

Lines changed: 40 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
1515
use Symfony\Component\DependencyInjection\ContainerInterface;
1616
use Symfony\Component\DependencyInjection\ChildDefinition;
17+
use Symfony\Component\DependencyInjection\Definition;
1718
use Symfony\Component\DependencyInjection\DefinitionDecorator;
1819
use Symfony\Component\DependencyInjection\Reference;
1920
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
@@ -66,68 +67,57 @@ public function load(array $configs, ContainerBuilder $container)
6667

6768
protected function configureMailer($name, array $mailer, ContainerBuilder $container, $isDefaultMailer = false)
6869
{
69-
if (null === $mailer['transport']) {
70-
$transport = 'null';
71-
} elseif ('gmail' === $mailer['transport']) {
72-
$mailer['encryption'] = 'ssl';
73-
$mailer['auth_mode'] = 'login';
74-
$mailer['host'] = 'smtp.gmail.com';
75-
$transport = 'smtp';
76-
} else {
77-
$transport = $mailer['transport'];
78-
}
79-
80-
if (null !== $mailer['url']) {
81-
$parts = parse_url($mailer['url']);
82-
if (!empty($parts['scheme'])) {
83-
$transport = $parts['scheme'];
84-
}
70+
$definitionDecorator = $this->createChildDefinition('swiftmailer.transport.eventdispatcher.abstract');
71+
$container
72+
->setDefinition(sprintf('swiftmailer.mailer.%s.transport.eventdispatcher', $name), $definitionDecorator)
73+
;
8574

86-
if (!empty($parts['user'])) {
87-
$mailer['username'] = $parts['user'];
88-
}
89-
if (!empty($parts['pass'])) {
90-
$mailer['password'] = $parts['pass'];
91-
}
92-
if (!empty($parts['host'])) {
93-
$mailer['host'] = $parts['host'];
94-
}
95-
if (!empty($parts['port'])) {
96-
$mailer['port'] = $parts['port'];
97-
}
98-
if (!empty($parts['query'])) {
99-
$query = array();
100-
parse_str($parts['query'], $query);
101-
if (!empty($query['encryption'])) {
102-
$mailer['encryption'] = $query['encryption'];
103-
}
104-
if (!empty($query['auth_mode'])) {
105-
$mailer['auth_mode'] = $query['auth_mode'];
106-
}
107-
}
75+
$options = array();
76+
$envVariablesAllowed = array('transport', 'url', 'username', 'password', 'host', 'port', 'timeout', 'source_ip', 'local_domain', 'encryption', 'auth_mode');
77+
foreach ($envVariablesAllowed as $key) {
78+
$container->resolveEnvPlaceholders($mailer[$key], null, $userEnvs);
79+
$options[$key] = $mailer[$key];
10880
}
109-
unset($mailer['url']);
11081

111-
$container->setParameter(sprintf('swiftmailer.mailer.%s.transport.name', $name), $transport);
82+
if ($userEnvs) {
83+
$transportId = sprintf('swiftmailer.mailer.%s.transport.dynamic', $name);
84+
$definitionDecorator = (new Definition(\Swift_Transport::class))
85+
->setFactory(array(SwiftmailerTransportFactory::class, 'createTransport'))
86+
->setArguments(array(
87+
$options,
88+
new Reference('router.request_context'),
89+
new Reference(sprintf('swiftmailer.mailer.%s.transport.eventdispatcher', $name)),
90+
));
91+
$container->setDefinition(sprintf('swiftmailer.mailer.%s.transport.dynamic', $name), $definitionDecorator);
92+
$container->setAlias(sprintf('swiftmailer.mailer.%s.transport', $name), $transportId);
93+
94+
$definitionDecorator = $this->createChildDefinition('swiftmailer.mailer.abstract');
95+
$container
96+
->setDefinition(sprintf('swiftmailer.mailer.%s', $name), $definitionDecorator)
97+
->replaceArgument(0, new Reference(sprintf('swiftmailer.mailer.%s.transport', $name)))
98+
;
11299

113-
if (isset($mailer['disable_delivery']) && $mailer['disable_delivery']) {
114-
$transport = 'null';
115-
$container->setParameter(sprintf('swiftmailer.mailer.%s.delivery.enabled', $name), false);
100+
$container->setParameter(sprintf('swiftmailer.mailer.%s.transport.name', $name), 'dynamic');
116101
} else {
117-
$container->setParameter(sprintf('swiftmailer.mailer.%s.delivery.enabled', $name), true);
118-
}
102+
$mailer = SwiftmailerTransportFactory::resolveOptions($mailer);
103+
$transport = $mailer['transport'];
119104

120-
if (empty($mailer['port'])) {
121-
$mailer['port'] = 'ssl' === $mailer['encryption'] ? 465 : 25;
122-
}
105+
$container->setParameter(sprintf('swiftmailer.mailer.%s.transport.name', $name), $transport);
106+
107+
$transportId = in_array($transport, array('smtp', 'mail', 'sendmail', 'null'))
108+
? sprintf('swiftmailer.mailer.%s.transport.%s', $name, $transport)
109+
: $transport;
123110

124-
$this->configureMailerTransport($name, $mailer, $container, $transport, $isDefaultMailer);
125-
$this->configureMailerSpool($name, $mailer, $container, $transport, $isDefaultMailer);
111+
$this->configureMailerTransport($name, $mailer, $container, $transport, $isDefaultMailer);
112+
}
113+
$this->configureMailerSpool($name, $mailer, $container, $transportId, $isDefaultMailer);
126114
$this->configureMailerSenderAddress($name, $mailer, $container, $isDefaultMailer);
127115
$this->configureMailerAntiFlood($name, $mailer, $container, $isDefaultMailer);
128116
$this->configureMailerDeliveryAddress($name, $mailer, $container, $isDefaultMailer);
129117
$this->configureMailerLogging($name, $mailer, $container, $isDefaultMailer);
130118

119+
$container->setParameter(sprintf('swiftmailer.mailer.%s.delivery.enabled', $name), empty($mailer['disable_delivery']));
120+
131121
// alias
132122
if ($isDefaultMailer) {
133123
$container->setAlias('swiftmailer.mailer', sprintf('swiftmailer.mailer.%s', $name));
@@ -144,11 +134,6 @@ protected function configureMailerTransport($name, array $mailer, ContainerBuild
144134
$container->setParameter(sprintf('swiftmailer.mailer.%s.transport.smtp.%s', $name, $key), $mailer[$key]);
145135
}
146136

147-
$definitionDecorator = $this->createChildDefinition('swiftmailer.transport.eventdispatcher.abstract');
148-
$container
149-
->setDefinition(sprintf('swiftmailer.mailer.%s.transport.eventdispatcher', $name), $definitionDecorator)
150-
;
151-
152137
if ('smtp' === $transport) {
153138
$authDecorator = $this->createChildDefinition('swiftmailer.transport.authhandler.abstract');
154139
$container
@@ -278,10 +263,6 @@ protected function configureMailerSpool($name, array $mailer, ContainerBuilder $
278263
))
279264
;
280265

281-
if (in_array($transport, array('smtp', 'mail', 'sendmail', 'null'))) {
282-
// built-in transport
283-
$transport = sprintf('swiftmailer.mailer.%s.transport.%s', $name, $transport);
284-
}
285266
$container->setAlias(sprintf('swiftmailer.mailer.%s.transport.real', $name), $transport);
286267
$container->setAlias(sprintf('swiftmailer.mailer.%s.transport', $name), sprintf('swiftmailer.mailer.%s.transport.spool', $name));
287268
$container->setParameter(sprintf('swiftmailer.mailer.%s.spool.enabled', $name), true);
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Bundle\SwiftmailerBundle\DependencyInjection;
13+
14+
use Symfony\Component\Routing\RequestContext;
15+
16+
/**
17+
* Factory to create a \Swift_Transport object.
18+
*
19+
* @author Romain Gautier <[email protected]>
20+
*/
21+
class SwiftmailerTransportFactory
22+
{
23+
/**
24+
* @param array $options
25+
* @param RequestContext $requestContext
26+
* @param \Swift_Events_EventDispatcher $eventDispatcher
27+
*
28+
* @return \Swift_Transport
29+
*
30+
* @throws \InvalidArgumentException if the scheme is not a built-in Swiftmailer transport
31+
*/
32+
public static function createTransport(array $options, RequestContext $requestContext, \Swift_Events_EventDispatcher $eventDispatcher)
33+
{
34+
$options = static::resolveOptions($options);
35+
36+
if ('smtp' === $options['transport']) {
37+
$smtpAuthHandler = new \Swift_Transport_Esmtp_AuthHandler([
38+
new \Swift_Transport_Esmtp_Auth_CramMd5Authenticator(),
39+
new \Swift_Transport_Esmtp_Auth_LoginAuthenticator(),
40+
new \Swift_Transport_Esmtp_Auth_PlainAuthenticator(),
41+
]);
42+
$smtpAuthHandler->setUsername($options['username']);
43+
$smtpAuthHandler->setPassword($options['password']);
44+
$smtpAuthHandler->setAuthMode($options['auth_mode']);
45+
46+
$transport = new \Swift_Transport_EsmtpTransport(
47+
new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()),
48+
array($smtpAuthHandler),
49+
$eventDispatcher
50+
);
51+
$transport->setHost($options['host']);
52+
$transport->setPort($options['port']);
53+
$transport->setEncryption($options['encryption']);
54+
$transport->setTimeout($options['timeout']);
55+
$transport->setSourceIp($options['source_ip']);
56+
57+
(new SmtpTransportConfigurator(null, $requestContext))->configure($transport);
58+
} elseif ('sendmail' === $options['transport']) {
59+
$transport = new \Swift_Transport_SendmailTransport(
60+
new \Swift_Transport_StreamBuffer(new \Swift_StreamFilters_StringReplacementFilterFactory()),
61+
$eventDispatcher
62+
);
63+
64+
(new SmtpTransportConfigurator(null, $requestContext))->configure($transport);
65+
} elseif ('mail' === $options['transport']) {
66+
$transport = new \Swift_Transport_MailTransport(
67+
new \Swift_Transport_SimpleMailInvoker(),
68+
$eventDispatcher
69+
);
70+
} elseif ('null' === $options['transport']) {
71+
$transport = new \Swift_Transport_NullTransport($eventDispatcher);
72+
} else {
73+
throw new \InvalidArgumentException(sprintf('Not a built-in Swiftmailer transport: %s.', $options['transport']));
74+
}
75+
76+
return $transport;
77+
}
78+
79+
/**
80+
* @param array $options
81+
*
82+
* @return array options
83+
*/
84+
public static function resolveOptions(array $options)
85+
{
86+
$options += array(
87+
'transport' => null,
88+
'username' => null,
89+
'password' => null,
90+
'host' => null,
91+
'port' => null,
92+
'timeout' => null,
93+
'source_ip' => null,
94+
'local_domain' => null,
95+
'encryption' => null,
96+
'auth_mode' => null,
97+
);
98+
99+
if (isset($options['url'])) {
100+
$parts = parse_url($options['url']);
101+
if (isset($parts['scheme'])) {
102+
$options['transport'] = $parts['scheme'];
103+
}
104+
if (isset($parts['user'])) {
105+
$options['username'] = $parts['user'];
106+
}
107+
if (isset($parts['pass'])) {
108+
$options['password'] = $parts['pass'];
109+
}
110+
if (isset($parts['host'])) {
111+
$options['host'] = $parts['host'];
112+
}
113+
if (isset($parts['port'])) {
114+
$options['port'] = $parts['port'];
115+
}
116+
if (isset($parts['query'])) {
117+
parse_str($parts['query'], $query);
118+
foreach ($options as $key => $value) {
119+
if (isset($query[$key])) {
120+
$options[$key] = $query[$key];
121+
}
122+
}
123+
}
124+
}
125+
126+
if (!isset($options['transport'])) {
127+
$options['transport'] = 'null';
128+
} elseif ('gmail' === $options['transport']) {
129+
$options['encryption'] = 'ssl';
130+
$options['auth_mode'] = 'login';
131+
$options['host'] = 'smtp.gmail.com';
132+
$options['transport'] = 'smtp';
133+
}
134+
135+
if (!isset($options['port'])) {
136+
$options['port'] = 'ssl' === $options['encryption'] ? 465 : 25;
137+
}
138+
139+
return $options;
140+
}
141+
}

0 commit comments

Comments
 (0)