‪TYPO3CMS  11.5
TransportFactory.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
18 namespace ‪TYPO3\CMS\Core\Mail;
19 
20 use Psr\Log\LoggerAwareInterface;
21 use Psr\Log\LoggerAwareTrait;
22 use Symfony\Component\Mailer\Transport;
23 use Symfony\Component\Mailer\Transport\NullTransport;
24 use Symfony\Component\Mailer\Transport\SendmailTransport;
25 use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport;
26 use Symfony\Component\Mailer\Transport\TransportInterface;
27 use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
33 
37 class ‪TransportFactory implements ‪SingletonInterface, LoggerAwareInterface
38 {
39  use LoggerAwareTrait;
40 
41  public const ‪SPOOL_MEMORY = 'memory';
42  public const ‪SPOOL_FILE = 'file';
43 
47  protected ‪$dispatcher;
48 
52  protected ‪$logManager;
53 
54  public function ‪__construct(EventDispatcherInterface ‪$dispatcher, ‪LogManagerInterface ‪$logManager)
55  {
56  $this->dispatcher = ‪$dispatcher;
57  $this->logManager = ‪$logManager;
58  }
59 
68  public function get(array $mailSettings): TransportInterface
69  {
70  if (!isset($mailSettings['transport'])) {
71  throw new \InvalidArgumentException('Key "transport" must be set in the mail settings', 1469363365);
72  }
73  if ($mailSettings['transport'] === 'spool') {
74  throw new \InvalidArgumentException('Mail transport can not be set to "spool"', 1469363238);
75  }
76 
77  $transportType = isset($mailSettings['transport_spool_type'])
78  && !empty($mailSettings['transport_spool_type'])
79  ? 'spool' : (string)$mailSettings['transport'];
80 
81  switch ($transportType) {
82  case 'spool':
83  $transport = $this->‪createSpool($mailSettings);
84  break;
85  case 'smtp':
86  // Get settings to be used when constructing the transport object
87  if (
88  isset($mailSettings['transport_smtp_server'])
89  && strpos($mailSettings['transport_smtp_server'], ':') > 0
90  ) {
91  $parts = ‪GeneralUtility::trimExplode(':', $mailSettings['transport_smtp_server'], true);
92  $host = $parts[0];
93  $port = $parts[1] ?? null;
94  } else {
95  $host = (string)($mailSettings['transport_smtp_server'] ?? '');
96  $port = null;
97  }
98 
99  if ($host === '') {
100  throw new Exception('$GLOBALS[\'TYPO3_CONF_VARS\'][\'MAIL\'][\'transport_smtp_server\'] needs to be set when transport is set to "smtp".', 1291068606);
101  }
102  if ($port === null) {
103  $port = 25;
104  } else {
105  $port = (int)$port;
106  }
107  $useEncryption = (bool)($mailSettings['transport_smtp_encrypt'] ?? false) ?: null;
108  // Create transport
109  $transport = new EsmtpTransport(
110  $host,
111  $port,
112  $useEncryption,
113  $this->dispatcher,
114  $this->logManager->getLogger(EsmtpTransport::class)
115  );
116  // Need authentication?
117  $username = (string)($mailSettings['transport_smtp_username'] ?? '');
118  if ($username !== '') {
119  $transport->setUsername($username);
120  }
121  $password = (string)($mailSettings['transport_smtp_password'] ?? '');
122  if ($password !== '') {
123  $transport->setPassword($password);
124  }
125  $mailDomain = (string)($mailSettings['transport_smtp_domain'] ?? '');
126  if ($mailDomain !== '') {
127  $transport->setLocalDomain($mailDomain);
128  }
129  break;
130  case 'sendmail':
131  $sendmailCommand = $mailSettings['transport_sendmail_command'] ?? @ini_get('sendmail_path');
132  if (empty($sendmailCommand)) {
133  $sendmailCommand = '/usr/sbin/sendmail -bs';
134  $this->logger->warning('Mailer transport "sendmail" was chosen without a specific command, using "{command}"', ['command' => $sendmailCommand]);
135  }
136  // Create transport
137  $transport = new SendmailTransport(
138  $sendmailCommand,
139  $this->dispatcher,
140  $this->logManager->getLogger(SendmailTransport::class)
141  );
142  break;
143  case 'mbox':
144  $mboxFile = (string)($mailSettings['transport_mbox_file'] ?? '');
145  if ($mboxFile === '') {
146  throw new Exception('$GLOBALS[\'TYPO3_CONF_VARS\'][\'MAIL\'][\'transport_mbox_file\'] needs to be set when transport is set to "mbox".', 1294586645);
147  }
148  $fileNameValidator = GeneralUtility::makeInstance(FileNameValidator::class);
149  if (!$fileNameValidator->isValid($mboxFile)) {
150  throw new Exception('$GLOBALS[\'TYPO3_CONF_VARS\'][\'MAIL\'][\'transport_mbox_file\'] failed against deny-pattern', 1705312431);
151  }
152  // Create our transport
153  $transport = GeneralUtility::makeInstance(
154  MboxTransport::class,
155  $mboxFile,
156  $this->dispatcher,
157  $this->logManager->getLogger(MboxTransport::class)
158  );
159  break;
160  // Used for testing purposes
161  case 'null':
162  case NullTransport::class:
163  $transport = new NullTransport(
164  $this->dispatcher,
165  $this->logManager->getLogger(NullTransport::class)
166  );
167  break;
168  // Used by Symfony's Transport Factory
169  case !empty($mailSettings['dsn']):
170  case 'dsn':
171  ‪if (empty($mailSettings['dsn'])) {
172  throw new Exception('$GLOBALS[\'TYPO3_CONF_VARS\'][\'MAIL\'][\'dsn\'] needs to be set when transport is set to "dsn".', 1615021869);
173  }
174  $transport = Transport::fromDsn(
175  $mailSettings['dsn'],
176  $this->dispatcher,
177  null,
178  $this->logManager->getLogger(Transport::class)
179  );
180  break;
181  default:
182  // Custom mail transport
183  $transport = GeneralUtility::makeInstance($mailSettings['transport'], $mailSettings);
184  if (!$transport instanceof TransportInterface) {
185  throw new \RuntimeException($mailSettings['transport'] . ' is not an implementation of Symfony\Mailer\TransportInterface,
186  but must implement that interface to be used as a mail transport.', 1323006478);
187  }
188  }
189  return $transport;
190  }
191 
199  protected function ‪createSpool(array $mailSettings): DelayedTransportInterface
200  {
201  $transportSpoolType = (string)($mailSettings['transport_spool_type'] ?? '');
202  switch ($transportSpoolType) {
203  case ‪self::SPOOL_FILE:
204  $path = GeneralUtility::getFileAbsFileName($mailSettings['transport_spool_filepath'] ?? '');
205  if (empty($path)) {
206  throw new \RuntimeException('The Spool Type filepath must be configured for TYPO3 in order to be used. Be sure that it\'s not accessible via the web.', 1518558797);
207  }
208  $spool = GeneralUtility::makeInstance(
209  FileSpool::class,
210  $path,
211  $this->dispatcher,
212  $this->logManager->getLogger(FileSpool::class)
213  );
214  break;
216  $spool = GeneralUtility::makeInstance(
217  MemorySpool::class,
218  $this->dispatcher,
219  $this->logManager->getLogger(MemorySpool::class)
220  );
221  break;
222  default:
223  $spool = GeneralUtility::makeInstance($transportSpoolType, $mailSettings);
224  if (!($spool instanceof DelayedTransportInterface)) {
225  throw new \RuntimeException(
226  $mailSettings['transport_spool_type'] . ' is not an implementation of DelayedTransportInterface, but must implement that interface to be used as a mail spool.',
227  1466799482
228  );
229  }
230  break;
231  }
232  return $spool;
233  }
234 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Resource\Security\FileNameValidator
Definition: FileNameValidator.php:25
‪TYPO3\CMS\Core\Log\LogManagerInterface
Definition: LogManagerInterface.php:24
‪TYPO3\CMS\Core\Exception
‪TYPO3\CMS\Core\Mail\TransportFactory\SPOOL_FILE
‪const SPOOL_FILE
Definition: TransportFactory.php:42
‪TYPO3\CMS\Core\Mail\TransportFactory\SPOOL_MEMORY
‪const SPOOL_MEMORY
Definition: TransportFactory.php:41
‪TYPO3\CMS\Core\Mail\TransportFactory\$logManager
‪LogManagerInterface $logManager
Definition: TransportFactory.php:50
‪TYPO3\CMS\Core\Mail\DelayedTransportInterface
Definition: DelayedTransportInterface.php:26
‪TYPO3\CMS\Core\Mail\TransportFactory\__construct
‪__construct(EventDispatcherInterface $dispatcher, LogManagerInterface $logManager)
Definition: TransportFactory.php:52
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪if
‪if(PHP_SAPI !=='cli')
Definition: checkNamespaceIntegrity.php:25
‪TYPO3\CMS\Core\Mail\TransportFactory\$dispatcher
‪EventDispatcherInterface $dispatcher
Definition: TransportFactory.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Mail\TransportFactory\createSpool
‪DelayedTransportInterface createSpool(array $mailSettings)
Definition: TransportFactory.php:197
‪TYPO3\CMS\Core\Mail
Definition: DelayedTransportInterface.php:18
‪TYPO3\CMS\Core\Mail\TransportFactory
Definition: TransportFactory.php:38