[FEATURE] Add signal for mailer initialization
[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 // Make sure Swift's auto-loader is registered
18 require_once PATH_typo3 . 'contrib/swiftmailer/lib/swift_required.php';
19
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Extbase\Object\ObjectManager;
22 use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
23
24 /**
25 * Adapter for Swift_Mailer to be used by TYPO3 extensions.
26 *
27 * This will use the setting in TYPO3_CONF_VARS to choose the correct transport
28 * for it to work out-of-the-box.
29 *
30 * @author Ernesto Baschny <ernst@cron-it.de>
31 */
32 class Mailer extends \Swift_Mailer {
33
34 /**
35 * @var \Swift_Transport
36 */
37 protected $transport;
38
39 /**
40 * @var array
41 */
42 protected $mailSettings = array();
43
44 /**
45 * When constructing, also initializes the \Swift_Transport like configured
46 *
47 * @param null|\Swift_Transport $transport optionally pass a transport to the constructor.
48 * @throws \TYPO3\CMS\Core\Exception
49 */
50 public function __construct(\Swift_Transport $transport = NULL) {
51 if ($transport !== NULL) {
52 $this->transport = $transport;
53 } else {
54 if (empty($this->mailSettings)) {
55 $this->injectMailSettings();
56 }
57 try {
58 $this->initializeTransport();
59 } catch (\Exception $e) {
60 throw new \TYPO3\CMS\Core\Exception($e->getMessage(), 1291068569);
61 }
62 }
63 parent::__construct($this->transport);
64
65 $this->emitPostInitializeMailerSignal();
66 }
67
68 /**
69 * Prepares a transport using the TYPO3_CONF_VARS configuration
70 *
71 * Used options:
72 * $TYPO3_CONF_VARS['MAIL']['transport'] = 'smtp' | 'sendmail' | 'mail' | 'mbox'
73 *
74 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_server'] = 'smtp.example.org';
75 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_port'] = '25';
76 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_encrypt'] = FALSE; # requires openssl in PHP
77 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_username'] = 'username';
78 * $TYPO3_CONF_VARS['MAIL']['transport_smtp_password'] = 'password';
79 *
80 * $TYPO3_CONF_VARS['MAIL']['transport_sendmail_command'] = '/usr/sbin/sendmail -bs'
81 *
82 * @throws \TYPO3\CMS\Core\Exception
83 * @throws \RuntimeException
84 */
85 private function initializeTransport() {
86 switch ($this->mailSettings['transport']) {
87 case 'smtp':
88 // Get settings to be used when constructing the transport object
89 list($host, $port) = preg_split('/:/', $this->mailSettings['transport_smtp_server']);
90 if ($host === '') {
91 throw new \TYPO3\CMS\Core\Exception('$TYPO3_CONF_VARS[\'MAIL\'][\'transport_smtp_server\'] needs to be set when transport is set to "smtp"', 1291068606);
92 }
93 if ($port === NULL || $port === '') {
94 $port = '25';
95 }
96 $useEncryption = $this->mailSettings['transport_smtp_encrypt'] ?: NULL;
97 // Create our transport
98 $this->transport = \Swift_SmtpTransport::newInstance($host, $port, $useEncryption);
99 // Need authentication?
100 $username = $this->mailSettings['transport_smtp_username'];
101 if ($username !== '') {
102 $this->transport->setUsername($username);
103 }
104 $password = $this->mailSettings['transport_smtp_password'];
105 if ($password !== '') {
106 $this->transport->setPassword($password);
107 }
108 break;
109 case 'sendmail':
110 $sendmailCommand = $this->mailSettings['transport_sendmail_command'];
111 if (empty($sendmailCommand)) {
112 throw new \TYPO3\CMS\Core\Exception('$TYPO3_CONF_VARS[\'MAIL\'][\'transport_sendmail_command\'] needs to be set when transport is set to "sendmail"', 1291068620);
113 }
114 // Create our transport
115 $this->transport = \Swift_SendmailTransport::newInstance($sendmailCommand);
116 break;
117 case 'mbox':
118 $mboxFile = $this->mailSettings['transport_mbox_file'];
119 if ($mboxFile == '') {
120 throw new \TYPO3\CMS\Core\Exception('$TYPO3_CONF_VARS[\'MAIL\'][\'transport_mbox_file\'] needs to be set when transport is set to "mbox"', 1294586645);
121 }
122 // Create our transport
123 $this->transport = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MboxTransport::class, $mboxFile);
124 break;
125 case 'mail':
126 // Create the transport, no configuration required
127 $this->transport = \Swift_MailTransport::newInstance();
128 break;
129 default:
130 // Custom mail transport
131 $customTransport = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($this->mailSettings['transport'], $this->mailSettings);
132 if ($customTransport instanceof \Swift_Transport) {
133 $this->transport = $customTransport;
134 } else {
135 throw new \RuntimeException($this->mailSettings['transport'] . ' is not an implementation of \\Swift_Transport,
136 but must implement that interface to be used as a mail transport.', 1323006478);
137 }
138 }
139 }
140
141 /**
142 * This method is only used in unit tests
143 *
144 * @param array $mailSettings
145 * @access private
146 */
147 public function injectMailSettings(array $mailSettings = NULL) {
148 if (is_array($mailSettings)) {
149 $this->mailSettings = $mailSettings;
150 } else {
151 $this->mailSettings = (array)$GLOBALS['TYPO3_CONF_VARS']['MAIL'];
152 }
153 }
154
155 /**
156 * Get the object manager
157 *
158 * @return \TYPO3\CMS\Extbase\Object\ObjectManager
159 */
160 protected function getObjectManager() {
161 return GeneralUtility::makeInstance(ObjectManager::class);
162 }
163
164 /**
165 * Get the SignalSlot dispatcher
166 *
167 * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
168 */
169 protected function getSignalSlotDispatcher() {
170 return $this->getObjectManager()->get(Dispatcher::class);
171 }
172
173 /**
174 * Emits a signal after mailer initialization
175 *
176 * @return void
177 */
178 protected function emitPostInitializeMailerSignal() {
179 $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Mail\\Mailer', 'postInitializeMailer', array($this));
180 }
181 }