1<?php declare(strict_types=1); 2 3/* 4 * This file is part of the Monolog package. 5 * 6 * (c) Jordi Boggiano <j.boggiano@seld.be> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Monolog\Handler; 13 14use Monolog\Logger; 15use Monolog\Formatter\FormatterInterface; 16use Monolog\Formatter\LineFormatter; 17use Swift_Message; 18use Swift; 19 20/** 21 * SwiftMailerHandler uses Swift_Mailer to send the emails 22 * 23 * @author Gyula Sallai 24 */ 25class SwiftMailerHandler extends MailHandler 26{ 27 protected $mailer; 28 private $messageTemplate; 29 30 /** 31 * @psalm-param Swift_Message|callable(string, array): Swift_Message $message 32 * 33 * @param \Swift_Mailer $mailer The mailer to use 34 * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced 35 * @param string|int $level The minimum logging level at which this handler will be triggered 36 * @param bool $bubble Whether the messages that are handled can bubble up the stack or not 37 */ 38 public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, bool $bubble = true) 39 { 40 parent::__construct($level, $bubble); 41 42 $this->mailer = $mailer; 43 $this->messageTemplate = $message; 44 } 45 46 /** 47 * {@inheritdoc} 48 */ 49 protected function send(string $content, array $records): void 50 { 51 $this->mailer->send($this->buildMessage($content, $records)); 52 } 53 54 /** 55 * Gets the formatter for the Swift_Message subject. 56 * 57 * @param string|null $format The format of the subject 58 */ 59 protected function getSubjectFormatter(?string $format): FormatterInterface 60 { 61 return new LineFormatter($format); 62 } 63 64 /** 65 * Creates instance of Swift_Message to be sent 66 * 67 * @param string $content formatted email body to be sent 68 * @param array $records Log records that formed the content 69 * @return Swift_Message 70 */ 71 protected function buildMessage(string $content, array $records): Swift_Message 72 { 73 $message = null; 74 if ($this->messageTemplate instanceof Swift_Message) { 75 $message = clone $this->messageTemplate; 76 $message->generateId(); 77 } elseif (is_callable($this->messageTemplate)) { 78 $message = ($this->messageTemplate)($content, $records); 79 } 80 81 if (!$message instanceof Swift_Message) { 82 throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); 83 } 84 85 if ($records) { 86 $subjectFormatter = $this->getSubjectFormatter($message->getSubject()); 87 $message->setSubject($subjectFormatter->format($this->getHighestRecord($records))); 88 } 89 90 $mime = 'text/plain'; 91 if ($this->isHtmlBody($content)) { 92 $mime = 'text/html'; 93 } 94 95 $message->setBody($content, $mime); 96 /** @phpstan-ignore-next-line */ 97 if (version_compare(Swift::VERSION, '6.0.0', '>=')) { 98 $message->setDate(new \DateTimeImmutable()); 99 } else { 100 /** @phpstan-ignore-next-line */ 101 $message->setDate(time()); 102 } 103 104 return $message; 105 } 106} 107