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

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\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\Mailer\Event\MessageEvent;
  13. use Symfony\Component\Mailer\Exception\InvalidArgumentException;
  14. use Symfony\Component\Mailer\Exception\RuntimeException;
  15. use Symfony\Component\Mime\BodyRendererInterface;
  16. use Symfony\Component\Mime\Header\Headers;
  17. use Symfony\Component\Mime\Header\MailboxListHeader;
  18. use Symfony\Component\Mime\Message;
  19. /**
  20. * Manipulates the headers and the body of a Message.
  21. *
  22. * @author Fabien Potencier <fabien@symfony.com>
  23. */
  24. class MessageListener implements EventSubscriberInterface
  25. {
  26. public const HEADER_SET_IF_EMPTY = 1;
  27. public const HEADER_ADD = 2;
  28. public const HEADER_REPLACE = 3;
  29. public const DEFAULT_RULES = [
  30. 'from' => self::HEADER_SET_IF_EMPTY,
  31. 'return-path' => self::HEADER_SET_IF_EMPTY,
  32. 'reply-to' => self::HEADER_ADD,
  33. 'to' => self::HEADER_SET_IF_EMPTY,
  34. 'cc' => self::HEADER_ADD,
  35. 'bcc' => self::HEADER_ADD,
  36. ];
  37. private $headers;
  38. private $headerRules = [];
  39. private $renderer;
  40. public function __construct(?Headers $headers = null, ?BodyRendererInterface $renderer = null, array $headerRules = self::DEFAULT_RULES)
  41. {
  42. $this->headers = $headers;
  43. $this->renderer = $renderer;
  44. foreach ($headerRules as $headerName => $rule) {
  45. $this->addHeaderRule($headerName, $rule);
  46. }
  47. }
  48. public function addHeaderRule(string $headerName, int $rule): void
  49. {
  50. if ($rule < 1 || $rule > 3) {
  51. throw new InvalidArgumentException(sprintf('The "%d" rule is not supported.', $rule));
  52. }
  53. $this->headerRules[strtolower($headerName)] = $rule;
  54. }
  55. public function onMessage(MessageEvent $event): void
  56. {
  57. $message = $event->getMessage();
  58. if (!$message instanceof Message) {
  59. return;
  60. }
  61. $this->setHeaders($message);
  62. $this->renderMessage($message);
  63. }
  64. private function setHeaders(Message $message): void
  65. {
  66. if (!$this->headers) {
  67. return;
  68. }
  69. $headers = $message->getHeaders();
  70. foreach ($this->headers->all() as $name => $header) {
  71. if (!$headers->has($name)) {
  72. $headers->add($header);
  73. continue;
  74. }
  75. switch ($this->headerRules[$name] ?? self::HEADER_SET_IF_EMPTY) {
  76. case self::HEADER_SET_IF_EMPTY:
  77. break;
  78. case self::HEADER_REPLACE:
  79. $headers->remove($name);
  80. $headers->add($header);
  81. break;
  82. case self::HEADER_ADD:
  83. if (!Headers::isUniqueHeader($name)) {
  84. $headers->add($header);
  85. break;
  86. }
  87. $h = $headers->get($name);
  88. if (!$h instanceof MailboxListHeader) {
  89. throw new RuntimeException(sprintf('Unable to set header "%s".', $name));
  90. }
  91. Headers::checkHeaderClass($header);
  92. foreach ($header->getAddresses() as $address) {
  93. $h->addAddress($address);
  94. }
  95. }
  96. }
  97. }
  98. private function renderMessage(Message $message): void
  99. {
  100. if (!$this->renderer) {
  101. return;
  102. }
  103. $this->renderer->render($message);
  104. }
  105. public static function getSubscribedEvents()
  106. {
  107. return [
  108. MessageEvent::class => 'onMessage',
  109. ];
  110. }
  111. }