Skip to content

Commit eb2ca0c

Browse files
committed
[Mailer] Add support for allowing some users even if recipients is defined in EnvelopeListener
1 parent 322acc8 commit eb2ca0c

File tree

3 files changed

+76
-3
lines changed

3 files changed

+76
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Dispatch Postmark's "406 - Inactive recipient" API error code as a `PostmarkDeliveryEvent` instead of throwing an exception
88
* Add DSN param `auto_tls` to disable automatic STARTTLS
9+
* Add support for allowing some users even if `recipients` is defined in `EnvelopeListener`
910

1011
7.0
1112
---

EventListener/EnvelopeListener.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* Manipulates the Envelope of a Message.
2121
*
2222
* @author Fabien Potencier <[email protected]>
23+
* @author Grégoire Pineau <[email protected]>
2324
*/
2425
class EnvelopeListener implements EventSubscriberInterface
2526
{
@@ -32,9 +33,13 @@ class EnvelopeListener implements EventSubscriberInterface
3233

3334
/**
3435
* @param array<Address|string> $recipients
36+
* @param string[] $allowedRecipients An array of regex to match the allowed recipients
3537
*/
36-
public function __construct(Address|string|null $sender = null, ?array $recipients = null)
37-
{
38+
public function __construct(
39+
Address|string|null $sender = null,
40+
?array $recipients = null,
41+
private array $allowedRecipients = [],
42+
) {
3843
if (null !== $sender) {
3944
$this->sender = Address::create($sender);
4045
}
@@ -57,7 +62,27 @@ public function onMessage(MessageEvent $event): void
5762
}
5863

5964
if ($this->recipients) {
60-
$event->getEnvelope()->setRecipients($this->recipients);
65+
$recipients = $this->recipients;
66+
if ($this->allowedRecipients) {
67+
foreach ($event->getEnvelope()->getRecipients() as $recipient) {
68+
foreach ($this->allowedRecipients as $allowedRecipient) {
69+
if (!preg_match('{\A'.$allowedRecipient.'\z}', $recipient->getAddress())) {
70+
continue;
71+
}
72+
// dedup
73+
foreach ($recipients as $r) {
74+
if ($r->getName() === $recipient->getName() && $r->getAddress() === $recipient->getAddress()) {
75+
continue 2;
76+
}
77+
}
78+
79+
$recipients[] = $recipient;
80+
continue 2;
81+
}
82+
}
83+
}
84+
85+
$event->getEnvelope()->setRecipients($recipients);
6186
}
6287
}
6388

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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\Component\Mailer\Tests\EventListener;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Mailer\Envelope;
16+
use Symfony\Component\Mailer\Event\MessageEvent;
17+
use Symfony\Component\Mailer\EventListener\EnvelopeListener;
18+
use Symfony\Component\Mime\Address;
19+
use Symfony\Component\Mime\RawMessage;
20+
21+
class EnvelopeListenerTest extends TestCase
22+
{
23+
/**
24+
* @dataProvider provideRecipientsTests
25+
*/
26+
public function testRecipients(array $expected, ?array $recipients = null, array $allowedRecipients = [])
27+
{
28+
$listener = new EnvelopeListener(null, $recipients, $allowedRecipients);
29+
$message = new RawMessage('message');
30+
$envelope = new Envelope(new Address('[email protected]'), [new Address('[email protected]'), new Address('[email protected]')]);
31+
$event = new MessageEvent($message, $envelope, 'default');
32+
33+
$listener->onMessage($event);
34+
35+
$recipients = array_map(fn (Address $a): string => $a->getAddress(), $event->getEnvelope()->getRecipients());
36+
$this->assertSame($expected, $recipients);
37+
}
38+
39+
public static function provideRecipientsTests(): iterable
40+
{
41+
yield [['[email protected]', '[email protected]'], null, []];
42+
yield [['[email protected]'], ['[email protected]'], []];
43+
yield [['[email protected]', '[email protected]'], ['[email protected]'], ['.*@example\.com']];
44+
yield [['[email protected]', '[email protected]', '[email protected]'], ['[email protected]'], ['.*@example\.com', '.*@symfony\.com']];
45+
yield [['[email protected]', '[email protected]'], ['[email protected]'], ['.*@example\.com', '.*@symfony\.com']];
46+
}
47+
}

0 commit comments

Comments
 (0)