[FEATURE] Integrate Swift Mailer's spool transport
[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 Swift_Transport;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Extbase\Object\ObjectManager;
20 use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
21
22 /**
23 * Adapter for Swift_Mailer to be used by TYPO3 extensions.
24 *
25 * This will use the setting in TYPO3_CONF_VARS to choose the correct transport
26 * for it to work out-of-the-box.
27 */
28 class Mailer extends \Swift_Mailer
29 {
30 /**
31 * @var \Swift_Transport
32 */
33 protected $transport;
34
35 /**
36 * @var array
37 */
38 protected $mailSettings = [];
39
40 /**
41 * When constructing, also initializes the \Swift_Transport like configured
42 *
43 * @param \Swift_Transport|null $transport optionally pass a transport to the constructor.
44 * @throws \TYPO3\CMS\Core\Exception
45 */
46 public function __construct(\Swift_Transport $transport = null)
47 {
48 if ($transport !== null) {
49 $this->transport = $transport;
50 } else {
51 if (empty($this->mailSettings)) {
52 $this->injectMailSettings();
53 }
54 try {
55 $this->initializeTransport();
56 } catch (\Exception $e) {
57 throw new \TYPO3\CMS\Core\Exception($e->getMessage(), 1291068569);
58 }
59 }
60 parent::__construct($this->transport);
61
62 $this->emitPostInitializeMailerSignal();
63 }
64
65 /**
66 * Prepares a transport using the TYPO3_CONF_VARS configuration
67 *
68 * Used options:
69 * $TYPO3_CONF_VARS['MAIL']['transport'] = 'smtp' | 'sendmail' | 'mail' | 'mbox'
70 *
71 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_server'] = 'smtp.example.org';
72 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_port'] = '25';
73 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_encrypt'] = FALSE; # requires openssl in PHP
74 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_username'] = 'username';
75 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_password'] = 'password';
76 *
77 * $TYPO3_CONF_VARS['MAIL']['transport_sendmail_command'] = '/usr/sbin/sendmail -bs'
78 *
79 * @throws \TYPO3\CMS\Core\Exception
80 * @throws \RuntimeException
81 */
82 private function initializeTransport()
83 {
84 $this->transport = $this->getTransportFactory()->get($this->mailSettings);
85 }
86
87 /**
88 * This method is only used in unit tests
89 *
90 * @param array $mailSettings
91 * @access private
92 */
93 public function injectMailSettings(array $mailSettings = null)
94 {
95 if (is_array($mailSettings)) {
96 $this->mailSettings = $mailSettings;
97 } else {
98 $this->mailSettings = (array)$GLOBALS['TYPO3_CONF_VARS']['MAIL'];
99 }
100 }
101
102 /**
103 * Returns the real transport (not a spool).
104 *
105 * @return \Swift_Transport
106 * @api
107 */
108 public function getRealTransport(): Swift_Transport
109 {
110 $mailSettings = (false === empty($this->mailSettings)) ? $this->mailSettings: (array)$GLOBALS['TYPO3_CONF_VARS']['MAIL'];
111 unset($mailSettings['transport_spool_type']);
112 return $this->getTransportFactory()->get($mailSettings);
113 }
114
115 /**
116 * @return TransportFactory
117 */
118 protected function getTransportFactory(): TransportFactory
119 {
120 return GeneralUtility::makeInstance(TransportFactory::class);
121 }
122
123 /**
124 * Get the object manager
125 *
126 * @return \TYPO3\CMS\Extbase\Object\ObjectManager
127 */
128 protected function getObjectManager()
129 {
130 return GeneralUtility::makeInstance(ObjectManager::class);
131 }
132
133 /**
134 * Get the SignalSlot dispatcher
135 *
136 * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
137 */
138 protected function getSignalSlotDispatcher()
139 {
140 return $this->getObjectManager()->get(Dispatcher::class);
141 }
142
143 /**
144 * Emits a signal after mailer initialization
145 */
146 protected function emitPostInitializeMailerSignal()
147 {
148 $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Mail\\Mailer', 'postInitializeMailer', [$this]);
149 }
150 }