123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <?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.1
- */
- 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;
- }
- }
|