vendor/symfony/mailer/EventListener/MessageListener.php line 66

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Mailer\EventListener;
  11. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\Mailer\Event\MessageEvent;
  14. use Symfony\Component\Mailer\Exception\InvalidArgumentException;
  15. use Symfony\Component\Mailer\Exception\LogicException;
  16. use Symfony\Component\Mailer\Exception\RuntimeException;
  17. use Symfony\Component\Mime\BodyRendererInterface;
  18. use Symfony\Component\Mime\Header\Headers;
  19. use Symfony\Component\Mime\Header\MailboxListHeader;
  20. use Symfony\Component\Mime\Message;
  21. /**
  22.  * Manipulates the headers and the body of a Message.
  23.  *
  24.  * @author Fabien Potencier <fabien@symfony.com>
  25.  */
  26. class MessageListener implements EventSubscriberInterface
  27. {
  28.     public const HEADER_SET_IF_EMPTY 1;
  29.     public const HEADER_ADD 2;
  30.     public const HEADER_REPLACE 3;
  31.     public const DEFAULT_RULES = [
  32.         'from' => self::HEADER_SET_IF_EMPTY,
  33.         'return-path' => self::HEADER_SET_IF_EMPTY,
  34.         'reply-to' => self::HEADER_ADD,
  35.         'to' => self::HEADER_SET_IF_EMPTY,
  36.         'cc' => self::HEADER_ADD,
  37.         'bcc' => self::HEADER_ADD,
  38.     ];
  39.     private ?Headers $headers;
  40.     private array $headerRules = [];
  41.     private ?BodyRendererInterface $renderer;
  42.     public function __construct(Headers $headers nullBodyRendererInterface $renderer null, array $headerRules self::DEFAULT_RULES)
  43.     {
  44.         $this->headers $headers;
  45.         $this->renderer $renderer;
  46.         foreach ($headerRules as $headerName => $rule) {
  47.             $this->addHeaderRule($headerName$rule);
  48.         }
  49.     }
  50.     public function addHeaderRule(string $headerNameint $rule): void
  51.     {
  52.         if ($rule || $rule 3) {
  53.             throw new InvalidArgumentException(sprintf('The "%d" rule is not supported.'$rule));
  54.         }
  55.         $this->headerRules[strtolower($headerName)] = $rule;
  56.     }
  57.     public function onMessage(MessageEvent $event): void
  58.     {
  59.         $message $event->getMessage();
  60.         if (!$message instanceof Message) {
  61.             return;
  62.         }
  63.         $this->setHeaders($message);
  64.         $this->renderMessage($message);
  65.     }
  66.     private function setHeaders(Message $message): void
  67.     {
  68.         if (!$this->headers) {
  69.             return;
  70.         }
  71.         $headers $message->getHeaders();
  72.         foreach ($this->headers->all() as $name => $header) {
  73.             if (!$headers->has($name)) {
  74.                 $headers->add($header);
  75.                 continue;
  76.             }
  77.             switch ($this->headerRules[$name] ?? self::HEADER_SET_IF_EMPTY) {
  78.                 case self::HEADER_SET_IF_EMPTY:
  79.                     break;
  80.                 case self::HEADER_REPLACE:
  81.                     $headers->remove($name);
  82.                     $headers->add($header);
  83.                     break;
  84.                 case self::HEADER_ADD:
  85.                     if (!Headers::isUniqueHeader($name)) {
  86.                         $headers->add($header);
  87.                         break;
  88.                     }
  89.                     $h $headers->get($name);
  90.                     if (!$h instanceof MailboxListHeader) {
  91.                         throw new RuntimeException(sprintf('Unable to set header "%s".'$name));
  92.                     }
  93.                     Headers::checkHeaderClass($header);
  94.                     foreach ($header->getAddresses() as $address) {
  95.                         $h->addAddress($address);
  96.                     }
  97.             }
  98.         }
  99.     }
  100.     private function renderMessage(Message $message): void
  101.     {
  102.         if (!$this->renderer) {
  103.             if ($message instanceof TemplatedEmail && ($message->getTextTemplate() || $message->getHtmlTemplate())) {
  104.                 throw new LogicException(sprintf('You must configure a "%s" when a "%s" instance has a text or HTML template set.'BodyRendererInterface::class, get_debug_type($message)));
  105.             }
  106.             return;
  107.         }
  108.         $this->renderer->render($message);
  109.     }
  110.     public static function getSubscribedEvents(): array
  111.     {
  112.         return [
  113.             MessageEvent::class => 'onMessage',
  114.         ];
  115.     }
  116. }