FestinHegre/vendor/symfony/notifier/Notifier.php
2024-09-26 17:26:04 +02:00

115 lines
4.0 KiB
PHP

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <fabien@symfony.com>
*/
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;
}
}