Skip to content

Commit 438eb32

Browse files
committed
[FrameworkBundle][Mailer] Add a way to configure some email headers from semantic configuration
1 parent 5a74790 commit 438eb32

File tree

14 files changed

+301
-34
lines changed

14 files changed

+301
-34
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,7 @@ private function addMailerSection(ArrayNodeDefinition $rootNode)
14921492
->thenInvalid('"dsn" and "transports" cannot be used together.')
14931493
->end()
14941494
->fixXmlConfig('transport')
1495+
->fixXmlConfig('header')
14951496
->children()
14961497
->scalarNode('message_bus')->defaultNull()->info('The message bus to use. Defaults to the default bus if the Messenger component is installed.')->end()
14971498
->scalarNode('dsn')->defaultNull()->end()
@@ -1515,6 +1516,26 @@ private function addMailerSection(ArrayNodeDefinition $rootNode)
15151516
->end()
15161517
->end()
15171518
->end()
1519+
->arrayNode('headers')
1520+
->normalizeKeys(false)
1521+
->useAttributeAsKey('key')
1522+
->prototype('array')
1523+
->normalizeKeys(false)
1524+
->beforeNormalization()
1525+
->ifTrue(function ($v) {
1526+
if (\is_array($v)) {
1527+
return array_keys($v) !== ['value'];
1528+
}
1529+
1530+
return true;
1531+
})
1532+
->then(function ($v) { return ['value' => $v]; })
1533+
->end()
1534+
->children()
1535+
->variableNode('value')->end()
1536+
->end()
1537+
->end()
1538+
->end()
15181539
->end()
15191540
->end()
15201541
->end()

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
use Symfony\Component\Messenger\MessageBusInterface;
9090
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
9191
use Symfony\Component\Messenger\Transport\TransportInterface;
92+
use Symfony\Component\Mime\Header\Headers;
9293
use Symfony\Component\Mime\MimeTypeGuesserInterface;
9394
use Symfony\Component\Mime\MimeTypes;
9495
use Symfony\Component\Notifier\Bridge\Firebase\FirebaseTransportFactory;
@@ -1986,12 +1987,24 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
19861987
}
19871988
}
19881989

1989-
$recipients = $config['envelope']['recipients'] ?? null;
1990-
$sender = $config['envelope']['sender'] ?? null;
1991-
19921990
$envelopeListener = $container->getDefinition('mailer.envelope_listener');
1993-
$envelopeListener->setArgument(0, $sender);
1994-
$envelopeListener->setArgument(1, $recipients);
1991+
$envelopeListener->setArgument(0, $config['envelope']['sender'] ?? null);
1992+
$envelopeListener->setArgument(1, $config['envelope']['recipients'] ?? null);
1993+
1994+
if ($config['headers']) {
1995+
$headers = new Headers();
1996+
foreach ($config['headers'] as $name => $data) {
1997+
$value = $data['value'];
1998+
if (\in_array($name, ['from', 'to', 'cc', 'bcc', 'reply-to'])) {
1999+
$value = (array) $value;
2000+
}
2001+
$headers->addHeader($name, $value);
2002+
}
2003+
$messageListener = $container->getDefinition('mailer.message_listener');
2004+
$messageListener->setArgument(0, $headers);
2005+
} else {
2006+
$container->removeDefinition('mailer.message_listener');
2007+
}
19952008
}
19962009

19972010
private function registerNotifierConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
<tag name="kernel.event_subscriber"/>
4040
</service>
4141

42+
<service id="mailer.message_listener" class="Symfony\Component\Mailer\EventListener\MessageListener">
43+
<argument /> <!-- headers -->
44+
<tag name="kernel.event_subscriber"/>
45+
</service>
46+
4247
<service id="mailer.logger_message_listener" class="Symfony\Component\Mailer\EventListener\MessageLoggerListener">
4348
<tag name="kernel.event_subscriber"/>
4449
</service>

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,14 +560,19 @@
560560
<xsd:complexType name="mailer">
561561
<xsd:sequence>
562562
<xsd:element name="envelope" type="mailer_envelope" minOccurs="0" maxOccurs="1" />
563+
<xsd:element name="header" type="header" minOccurs="0" maxOccurs="unbounded" />
563564
</xsd:sequence>
564565
<xsd:attribute name="dsn" type="xsd:string" />
565566
<xsd:attribute name="message-bus" type="xsd:string" />
566567
</xsd:complexType>
567568

569+
<xsd:complexType name="header" mixed="true">
570+
<xsd:attribute name="key" type="xsd:string" use="required" />
571+
</xsd:complexType>
572+
568573
<xsd:complexType name="mailer_envelope">
569574
<xsd:sequence>
570-
<xsd:element name="sender" type="xsd:string" />
575+
<xsd:element name="sender" type="xsd:string" minOccurs="0" maxOccurs="1" />
571576
<xsd:element name="recipients" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
572577
</xsd:sequence>
573578
</xsd:complexType>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
493493
'transports' => [],
494494
'enabled' => !class_exists(FullStack::class) && class_exists(Mailer::class),
495495
'message_bus' => null,
496+
'headers' => [],
496497
],
497498
'notifier' => [
498499
'enabled' => !class_exists(FullStack::class) && class_exists(Notifier::class),

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/mailer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,10 @@
77
'sender' => 'sender@example.org',
88
'recipients' => ['redirected@example.org', 'redirected1@example.org'],
99
],
10+
'headers' => [
11+
'from' => 'from@example.org',
12+
'bcc' => ['bcc1@example.org', 'bcc2@example.org'],
13+
'foo' => 'bar',
14+
],
1015
],
1116
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/mailer.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
<framework:recipients>redirected@example.org</framework:recipients>
1414
<framework:recipients>redirected1@example.org</framework:recipients>
1515
</framework:envelope>
16+
<framework:header key="from">from@example.org</framework:header>
17+
<framework:header key="bcc">bcc1@example.org</framework:header>
18+
<framework:header key="foo">bar</framework:header>
1619
</framework:mailer>
1720
</framework:config>
1821
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/mailer.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ framework:
66
recipients:
77
- redirected@example.org
88
- redirected1@example.org
9+
headers:
10+
from: from@example.org
11+
bcc: [bcc1@example.org, bcc2@example.org]
12+
foo: bar

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 2 additions & 2 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": "^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",

src/Symfony/Component/Mailer/EventListener/MessageListener.php

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313

1414
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1515
use Symfony\Component\Mailer\Event\MessageEvent;
16+
use Symfony\Component\Mailer\Exception\InvalidArgumentException;
17+
use Symfony\Component\Mailer\Exception\RuntimeException;
1618
use Symfony\Component\Mime\BodyRendererInterface;
1719
use Symfony\Component\Mime\Header\Headers;
20+
use Symfony\Component\Mime\Header\MailboxListHeader;
1821
use Symfony\Component\Mime\Message;
1922

2023
/**
@@ -24,13 +27,38 @@
2427
*/
2528
class MessageListener implements EventSubscriberInterface
2629
{
30+
public const HEADER_SET_IF_EMPTY = 1;
31+
public const HEADER_ADD = 2;
32+
public const HEADER_REPLACE = 3;
33+
public const DEFAULT_RULES = [
34+
'from' => self::HEADER_SET_IF_EMPTY,
35+
'return-path' => self::HEADER_SET_IF_EMPTY,
36+
'reply-to' => self::HEADER_ADD,
37+
'to' => self::HEADER_SET_IF_EMPTY,
38+
'cc' => self::HEADER_ADD,
39+
'bcc' => self::HEADER_ADD,
40+
];
41+
2742
private $headers;
43+
private $headerRules = [];
2844
private $renderer;
2945

30-
public function __construct(Headers $headers = null, BodyRendererInterface $renderer = null)
46+
public function __construct(Headers $headers = null, BodyRendererInterface $renderer = null, array $headerRules = self::DEFAULT_RULES)
3147
{
3248
$this->headers = $headers;
3349
$this->renderer = $renderer;
50+
foreach ($headerRules as $headerName => $rule) {
51+
$this->addHeaderRule($headerName, $rule);
52+
}
53+
}
54+
55+
public function addHeaderRule(string $headerName, int $rule)
56+
{
57+
if ($rule < 1 || $rule > 3) {
58+
throw new InvalidArgumentException(sprintf('The "%d" rule is not supported.', $rule));
59+
}
60+
61+
$this->headerRules[$headerName] = $rule;
3462
}
3563

3664
public function onMessage(MessageEvent $event): void
@@ -54,14 +82,38 @@ private function setHeaders(Message $message): void
5482
foreach ($this->headers->all() as $name => $header) {
5583
if (!$headers->has($name)) {
5684
$headers->add($header);
57-
} else {
58-
if (Headers::isUniqueHeader($name)) {
59-
continue;
60-
}
61-
$headers->add($header);
85+
86+
continue;
87+
}
88+
89+
switch ($this->headerRules[$name] ?? self::HEADER_SET_IF_EMPTY) {
90+
case self::HEADER_SET_IF_EMPTY:
91+
break;
92+
93+
case self::HEADER_REPLACE:
94+
$headers->remove($name);
95+
$headers->add($header);
96+
97+
break;
98+
99+
case self::HEADER_ADD:
100+
if (!Headers::isUniqueHeader($name)) {
101+
$headers->add($header);
102+
103+
break;
104+
}
105+
106+
$h = $headers->get($name);
107+
if (!$h instanceof MailboxListHeader) {
108+
throw new RuntimeException(sprintf('Unable to set header "%s".', $name));
109+
}
110+
111+
Headers::checkHeaderClass($header);
112+
foreach ($header->getAddresses() as $address) {
113+
$h->addAddress($address);
114+
}
62115
}
63116
}
64-
$message->setHeaders($headers);
65117
}
66118

67119
private function renderMessage(Message $message): void

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy