Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 53
Notifier
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 6
380
0.00% covered (danger)
0.00%
0 / 53
 __construct
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 4
 send
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 10
 addAdminRecipient
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 3
 getAdminRecipients
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 3
 getChannels
0.00% covered (danger)
0.00%
0 / 1
72
0.00% covered (danger)
0.00%
0 / 27
 getChannel
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 6
<?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\Exception\LogicException;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\AdminRecipient;
use Symfony\Component\Notifier\Recipient\NoRecipient;
use Symfony\Component\Notifier\Recipient\Recipient;
/**
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @experimental in 5.0
 */
final class Notifier implements NotifierInterface
{
    private $adminRecipients = [];
    private $channels;
    private $policy;
    /**
     * @param ChannelInterface[]|ContainerInterface $channels
     */
    public function __construct($channels, ChannelPolicyInterface $policy = null)
    {
        $this->channels = $channels;
        $this->policy = $policy;
    }
    public function send(Notification $notification, Recipient ...$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(AdminRecipient $recipient): void
    {
        $this->adminRecipients[] = $recipient;
    }
    /**
     * @return AdminRecipient[]
     */
    public function getAdminRecipients(): array
    {
        return $this->adminRecipients;
    }
    private function getChannels(Notification $notification, Recipient $recipient): iterable
    {
        $channels = $notification->getChannels($recipient);
        if (!$channels) {
            $errorPrefix = sprintf('Unable to determine which channels to use to send the "%s" notification', \get_class($notification));
            $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->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;
    }
}