-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Notifier.php
114 lines (97 loc) · 4 KB
/
Notifier.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Notifier;
use Psr\Container\ContainerInterface;
use Symfony\Component\Notifier\Channel\ChannelInterface;
use Symfony\Component\Notifier\Channel\ChannelPolicy;
use Symfony\Component\Notifier\Channel\ChannelPolicyInterface;
use Symfony\Component\Notifier\Channel\SmsChannel;
use Symfony\Component\Notifier\Exception\LogicException;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\NoRecipient;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
/**
* @author Fabien Potencier <[email protected]>
*/
final class Notifier implements NotifierInterface
{
private array $adminRecipients = [];
/**
* @param ChannelInterface[]|ContainerInterface $channels
*/
public function __construct(
private array|ContainerInterface $channels,
private ?ChannelPolicyInterface $policy = null,
) {
}
public function send(Notification $notification, RecipientInterface ...$recipients): void
{
if (!$recipients) {
$recipients = [new NoRecipient()];
}
foreach ($recipients as $recipient) {
foreach ($this->getChannels($notification, $recipient) as $channel => $transportName) {
$channel->notify($notification, $recipient, $transportName);
}
}
}
public function addAdminRecipient(RecipientInterface $recipient): void
{
$this->adminRecipients[] = $recipient;
}
/**
* @return RecipientInterface[]
*/
public function getAdminRecipients(): array
{
return $this->adminRecipients;
}
/**
* @return iterable<ChannelInterface, string|null>
*/
private function getChannels(Notification $notification, RecipientInterface $recipient): iterable
{
$channels = $notification->getChannels($recipient);
if (!$channels) {
$errorPrefix = \sprintf('Unable to determine which channels to use to send the "%s" notification', $notification::class);
$error = 'you should either pass channels in the constructor, override its "getChannels()" method';
if (null === $this->policy) {
throw new LogicException(\sprintf('%s; %s, or configure a "%s".', $errorPrefix, $error, ChannelPolicy::class));
}
if (!$channels = $this->policy->getChannels($notification->getImportance())) {
throw new LogicException(\sprintf('%s; the "%s" returns no channels for importance "%s"; %s.', $errorPrefix, ChannelPolicy::class, $notification->getImportance(), $error));
}
}
foreach ($channels as $channelName) {
$transportName = null;
if (false !== $pos = strpos($channelName, '/')) {
$transportName = substr($channelName, $pos + 1);
$channelName = substr($channelName, 0, $pos);
}
if (null === $channel = $this->getChannel($channelName)) {
throw new LogicException(\sprintf('The "%s" channel does not exist.', $channelName));
}
if ($channel instanceof SmsChannel && $recipient instanceof NoRecipient) {
throw new LogicException(\sprintf('The "%s" channel needs a Recipient.', $channelName));
}
if (!$channel->supports($notification, $recipient)) {
throw new LogicException(\sprintf('The "%s" channel is not supported.', $channelName));
}
yield $channel => $transportName;
}
}
private function getChannel(string $name): ?ChannelInterface
{
if ($this->channels instanceof ContainerInterface) {
return $this->channels->has($name) ? $this->channels->get($name) : null;
}
return $this->channels[$name] ?? null;
}
}