[BUGFIX] Fix several typos in php comments
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Mail / Mailer.php
1 <?php
2 namespace TYPO3\CMS\Core\Mail;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\EventDispatcher\EventDispatcherInterface;
18 use Symfony\Component\Mailer\MailerInterface;
19 use Symfony\Component\Mailer\SentMessage;
20 use Symfony\Component\Mailer\SmtpEnvelope;
21 use Symfony\Component\Mailer\Transport\TransportInterface;
22 use Symfony\Component\Mime\Address;
23 use Symfony\Component\Mime\Email;
24 use Symfony\Component\Mime\NamedAddress;
25 use Symfony\Component\Mime\RawMessage;
26 use TYPO3\CMS\Core\EventDispatcher\EventDispatcher;
27 use TYPO3\CMS\Core\Exception as CoreException;
28 use TYPO3\CMS\Core\Mail\Event\AfterMailerInitializationEvent;
29 use TYPO3\CMS\Core\Utility\GeneralUtility;
30 use TYPO3\CMS\Core\Utility\MailUtility;
31
32 /**
33 * Adapter for Symfony/Mailer to be used by TYPO3 extensions.
34 *
35 * This will use the setting in TYPO3_CONF_VARS to choose the correct transport
36 * for it to work out-of-the-box.
37 */
38 class Mailer implements MailerInterface
39 {
40 /**
41 * @var TransportInterface
42 */
43 protected $transport;
44
45 /**
46 * @var array
47 */
48 protected $mailSettings = [];
49
50 /**
51 * @var SentMessage|null
52 */
53 protected $sentMessage;
54
55 /**
56 * @var string This will be added as X-Mailer to all outgoing mails
57 */
58 protected $mailerHeader = 'TYPO3';
59
60 /**
61 * When constructing, also initializes the Symfony Transport like configured
62 *
63 * @param TransportInterface|null $transport optionally pass a transport to the constructor.
64 * @throws CoreException
65 */
66 public function __construct(TransportInterface $transport = null)
67 {
68 if ($transport !== null) {
69 $this->transport = $transport;
70 } else {
71 if (empty($this->mailSettings)) {
72 $this->injectMailSettings();
73 }
74 try {
75 $this->initializeTransport();
76 } catch (\Exception $e) {
77 throw new CoreException($e->getMessage(), 1291068569);
78 }
79 }
80 $this->getEventDispatcher()->dispatch(new AfterMailerInitializationEvent($this));
81 }
82
83 /**
84 * @inheritdoc
85 */
86 public function send(RawMessage $message, SmtpEnvelope $envelope = null): void
87 {
88 if ($message instanceof Email) {
89 // Ensure to always have a From: header set
90 if (empty($message->getFrom())) {
91 $address = MailUtility::getSystemFromAddress();
92 if ($address) {
93 $name = MailUtility::getSystemFromName();
94 if ($name) {
95 $from = new NamedAddress($address, $name);
96 } else {
97 $from = new Address($address);
98 }
99 $message->from($from);
100 }
101 }
102 if (empty($message->getReplyTo())) {
103 $replyTo = MailUtility::getSystemReplyTo();
104 if (!empty($replyTo)) {
105 $address = key($replyTo);
106 if ($address === 0) {
107 $replyTo = new Address($replyTo[$address]);
108 } else {
109 $replyTo = new NamedAddress(reset($replyTo), $address);
110 }
111 $message->replyTo($replyTo);
112 }
113 }
114 $message->getHeaders()->addTextHeader('X-Mailer', $this->mailerHeader);
115 }
116
117 $this->sentMessage = $this->transport->send($message, $envelope);
118 }
119
120 public function getSentMessage(): ?SentMessage
121 {
122 return $this->sentMessage;
123 }
124
125 public function getTransport(): TransportInterface
126 {
127 return $this->transport;
128 }
129
130 /**
131 * Prepares a transport using the TYPO3_CONF_VARS configuration
132 *
133 * Used options:
134 * $TYPO3_CONF_VARS['MAIL']['transport'] = 'smtp' | 'sendmail' | 'null' | 'mbox'
135 *
136 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_server'] = 'smtp.example.org';
137 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_port'] = '25';
138 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_encrypt'] = FALSE; # requires openssl in PHP
139 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_username'] = 'username';
140 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_password'] = 'password';
141 *
142 * $TYPO3_CONF_VARS['MAIL']['transport_sendmail_command'] = '/usr/sbin/sendmail -bs'
143 *
144 * @throws CoreException
145 * @throws \RuntimeException
146 */
147 private function initializeTransport()
148 {
149 $this->transport = $this->getTransportFactory()->get($this->mailSettings);
150 }
151
152 /**
153 * This method is only used in unit tests
154 *
155 * @param array $mailSettings
156 * @internal
157 */
158 public function injectMailSettings(array $mailSettings = null)
159 {
160 if (is_array($mailSettings)) {
161 $this->mailSettings = $mailSettings;
162 } else {
163 $this->mailSettings = (array)$GLOBALS['TYPO3_CONF_VARS']['MAIL'];
164 }
165 }
166
167 /**
168 * Returns the real transport (not a spool).
169 *
170 * @return TransportInterface
171 */
172 public function getRealTransport(): TransportInterface
173 {
174 $mailSettings = !empty($this->mailSettings) ? $this->mailSettings : (array)$GLOBALS['TYPO3_CONF_VARS']['MAIL'];
175 unset($mailSettings['transport_spool_type']);
176 return $this->getTransportFactory()->get($mailSettings);
177 }
178
179 /**
180 * @return TransportFactory
181 */
182 protected function getTransportFactory(): TransportFactory
183 {
184 return GeneralUtility::makeInstance(TransportFactory::class);
185 }
186
187 /**
188 * Emits a signal after mailer initialization
189 */
190 protected function getEventDispatcher(): EventDispatcherInterface
191 {
192 return GeneralUtility::makeInstance(EventDispatcher::class);
193 }
194 }