1<?php
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;
18
19/**
20 * SwiftMailerHandler uses Swift_Mailer to send the emails
21 *
22 * @author Gyula Sallai
23 */
24class SwiftMailerHandler extends MailHandler
25{
26    protected $mailer;
27    private $messageTemplate;
28
29    /**
30     * @param \Swift_Mailer           $mailer  The mailer to use
31     * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
32     * @param int                     $level   The minimum logging level at which this handler will be triggered
33     * @param bool                    $bubble  Whether the messages that are handled can bubble up the stack or not
34     */
35    public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true)
36    {
37        parent::__construct($level, $bubble);
38
39        $this->mailer = $mailer;
40        $this->messageTemplate = $message;
41    }
42
43    /**
44     * {@inheritdoc}
45     */
46    protected function send($content, array $records)
47    {
48        $this->mailer->send($this->buildMessage($content, $records));
49    }
50
51    /**
52     * Gets the formatter for the Swift_Message subject.
53     *
54     * @param  string             $format The format of the subject
55     * @return FormatterInterface
56     */
57    protected function getSubjectFormatter($format)
58    {
59        return new LineFormatter($format);
60    }
61
62    /**
63     * Creates instance of Swift_Message to be sent
64     *
65     * @param  string         $content formatted email body to be sent
66     * @param  array          $records Log records that formed the content
67     * @return \Swift_Message
68     */
69    protected function buildMessage($content, array $records)
70    {
71        $message = null;
72        if ($this->messageTemplate instanceof \Swift_Message) {
73            $message = clone $this->messageTemplate;
74            $message->generateId();
75        } elseif (is_callable($this->messageTemplate)) {
76            $message = call_user_func($this->messageTemplate, $content, $records);
77        }
78
79        if (!$message instanceof \Swift_Message) {
80            throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it');
81        }
82
83        if ($records) {
84            $subjectFormatter = $this->getSubjectFormatter($message->getSubject());
85            $message->setSubject($subjectFormatter->format($this->getHighestRecord($records)));
86        }
87
88        $message->setBody($content);
89        if (version_compare(Swift::VERSION, '6.0.0', '>=')) {
90            $message->setDate(new \DateTimeImmutable());
91        } else {
92            $message->setDate(time());
93        }
94
95        return $message;
96    }
97
98    /**
99     * BC getter, to be removed in 2.0
100     */
101    public function __get($name)
102    {
103        if ($name === 'message') {
104            trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', E_USER_DEPRECATED);
105
106            return $this->buildMessage(null, array());
107        }
108
109        throw new \InvalidArgumentException('Invalid property '.$name);
110    }
111}
112