‪TYPO3CMS  ‪main
EmailFinisher.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 
19 
20 use Symfony\Component\Mime\Address;
32 
60 {
64  protected ‪$defaultOptions = [
65  'recipientName' => '',
66  'senderName' => '',
67  'addHtmlPart' => true,
68  'attachUploads' => true,
69  ];
70 
77  protected function ‪executeInternal()
78  {
79  $languageBackup = null;
80  // Flexform overrides write strings instead of integers so
81  // we need to cast the string '0' to false.
82  if (
83  isset($this->options['addHtmlPart'])
84  && $this->options['addHtmlPart'] === '0'
85  ) {
86  $this->options['addHtmlPart'] = false;
87  }
88 
89  $subject = (string)$this->‪parseOption('subject');
90  $recipients = $this->‪getRecipients('recipients');
91  $senderAddress = $this->‪parseOption('senderAddress');
92  $senderAddress = is_string($senderAddress) ? $senderAddress : '';
93  $senderName = $this->‪parseOption('senderName');
94  $senderName = is_string($senderName) ? $senderName : '';
95  $replyToRecipients = $this->‪getRecipients('replyToRecipients');
96  $carbonCopyRecipients = $this->‪getRecipients('carbonCopyRecipients');
97  $blindCarbonCopyRecipients = $this->‪getRecipients('blindCarbonCopyRecipients');
98  $addHtmlPart = $this->‪parseOption('addHtmlPart') ? true : false;
99  $attachUploads = $this->‪parseOption('attachUploads');
100  $title = (string)$this->‪parseOption('title') ?: $subject;
101 
102  if ($subject === '') {
103  throw new ‪FinisherException('The option "subject" must be set for the EmailFinisher.', 1327060320);
104  }
105  if (empty($recipients)) {
106  throw new ‪FinisherException('The option "recipients" must be set for the EmailFinisher.', 1327060200);
107  }
108  if (empty($senderAddress)) {
109  throw new ‪FinisherException('The option "senderAddress" must be set for the EmailFinisher.', 1327060210);
110  }
111 
112  $formRuntime = $this->finisherContext->getFormRuntime();
113 
114  $translationService = GeneralUtility::makeInstance(TranslationService::class);
115  if (is_string($this->options['translation']['language'] ?? null) && $this->options['translation']['language'] !== '') {
116  $languageBackup = $translationService->getLanguage();
117  $translationService->setLanguage($this->options['translation']['language']);
118  }
119 
120  $mail = $this
121  ->initializeFluidEmail($formRuntime)
122  ->from(new Address($senderAddress, $senderName))
123  ->to(...$recipients)
124  ->subject($subject)
126  ->assign('title', $title);
127 
128  if (!empty($replyToRecipients)) {
129  $mail->replyTo(...$replyToRecipients);
130  }
131 
132  if (!empty($carbonCopyRecipients)) {
133  $mail->cc(...$carbonCopyRecipients);
134  }
135 
136  if (!empty($blindCarbonCopyRecipients)) {
137  $mail->bcc(...$blindCarbonCopyRecipients);
138  }
139 
140  if (!empty($languageBackup)) {
141  $translationService->setLanguage($languageBackup);
142  }
143 
144  if ($attachUploads) {
145  foreach ($formRuntime->getFormDefinition()->getRenderablesRecursively() as $element) {
146  if (!$element instanceof ‪FileUpload) {
147  continue;
148  }
149  $file = $formRuntime[$element->getIdentifier()];
150  if ($file) {
151  if ($file instanceof ‪FileReference) {
152  $file = $file->getOriginalResource();
153  }
154  $mail->attach($file->getContents(), $file->getName(), $file->getMimeType());
155  }
156  }
157  }
158 
159  // TODO: DI should be used to inject the MailerInterface
160  GeneralUtility::makeInstance(MailerInterface::class)->send($mail);
161  }
162 
163  protected function ‪initializeFluidEmail(‪FormRuntime $formRuntime): ‪FluidEmail
164  {
165  $templateConfiguration = ‪$GLOBALS['TYPO3_CONF_VARS']['MAIL'];
166 
167  if (is_array($this->options['templateRootPaths'] ?? null)) {
168  $templateConfiguration['templateRootPaths'] = array_replace_recursive(
169  $templateConfiguration['templateRootPaths'],
170  $this->options['templateRootPaths']
171  );
172  ksort($templateConfiguration['templateRootPaths']);
173  }
174 
175  if (is_array($this->options['partialRootPaths'] ?? null)) {
176  $templateConfiguration['partialRootPaths'] = array_replace_recursive(
177  $templateConfiguration['partialRootPaths'],
178  $this->options['partialRootPaths']
179  );
180  ksort($templateConfiguration['partialRootPaths']);
181  }
182 
183  if (is_array($this->options['layoutRootPaths'] ?? null)) {
184  $templateConfiguration['layoutRootPaths'] = array_replace_recursive(
185  $templateConfiguration['layoutRootPaths'],
186  $this->options['layoutRootPaths']
187  );
188  ksort($templateConfiguration['layoutRootPaths']);
189  }
190 
191  $fluidEmail = GeneralUtility::makeInstance(
192  FluidEmail::class,
193  GeneralUtility::makeInstance(TemplatePaths::class, $templateConfiguration)
194  );
195 
196  if (!isset($this->options['templateName']) || $this->options['templateName'] === '') {
197  throw new ‪FinisherException('The option "templateName" must be set to use FluidEmail.', 1599834020);
198  }
199 
200  // Migrate old template name to default FluidEmail name
201  if ($this->options['templateName'] === '{@format}.html') {
202  $this->options['templateName'] = 'Default';
203  }
204 
205  $fluidEmail
206  ->setRequest($this->finisherContext->getRequest())
207  ->setTemplate($this->options['templateName'])
208  ->assignMultiple([
209  'finisherVariableProvider' => $this->finisherContext->getFinisherVariableProvider(),
210  'form' => $formRuntime,
211  ]);
212 
213  if (is_array($this->options['variables'] ?? null)) {
214  $fluidEmail->assignMultiple($this->options['variables']);
215  }
216 
217  $fluidEmail
218  ->getViewHelperVariableContainer()
219  ->addOrUpdate(RenderRenderableViewHelper::class, 'formRuntime', $formRuntime);
220 
221  return $fluidEmail;
222  }
223 
229  protected function ‪getRecipients(string $listOption): array
230  {
231  $recipients = $this->‪parseOption($listOption) ?? [];
232  if (!is_array($recipients) || $recipients === []) {
233  return [];
234  }
235 
236  $addresses = [];
237  foreach ($recipients as $address => $name) {
238  // The if is needed to set address and name with TypoScript
240  if (is_array($name)) {
241  $address = $name[0] ?? '';
242  $name = $name[1] ?? '';
243  } else {
244  $address = $name;
245  $name = '';
246  }
247  }
248 
249  if (!GeneralUtility::validEmail($address)) {
250  // Drop entries without valid address
251  continue;
252  }
253  $addresses[] = new Address($address, $name);
254  }
255  return $addresses;
256  }
257 }
‪TYPO3\CMS\Form\Domain\Runtime\FormRuntime
Definition: FormRuntime.php:106
‪TYPO3\CMS\Fluid\View\TemplatePaths
Definition: TemplatePaths.php:39
‪TYPO3\CMS\Form\Service\TranslationService
Definition: TranslationService.php:45
‪TYPO3\CMS\Core\Mail\FluidEmail\FORMAT_BOTH
‪const FORMAT_BOTH
Definition: FluidEmail.php:38
‪TYPO3\CMS\Core\Mail\MailerInterface
Definition: MailerInterface.php:28
‪TYPO3\CMS\Form\Domain\Finishers
Definition: AbstractFinisher.php:22
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher\parseOption
‪string array int null parseOption(string $optionName)
Definition: AbstractFinisher.php:139
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher\initializeFluidEmail
‪initializeFluidEmail(FormRuntime $formRuntime)
Definition: EmailFinisher.php:162
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher\getRecipients
‪getRecipients(string $listOption)
Definition: EmailFinisher.php:228
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger(mixed $var)
Definition: MathUtility.php:69
‪TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher
Definition: AbstractFinisher.php:41
‪TYPO3\CMS\Core\Mail\FluidEmail
Definition: FluidEmail.php:35
‪TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException
Definition: FinisherException.php:25
‪TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper
Definition: RenderRenderableViewHelper.php:41
‪TYPO3\CMS\Core\Mail\FluidEmail\FORMAT_PLAIN
‪const FORMAT_PLAIN
Definition: FluidEmail.php:37
‪TYPO3\CMS\Extbase\Domain\Model\FileReference
Definition: FileReference.php:28
‪TYPO3\CMS\Form\Domain\Runtime\FormRuntime
Definition: FormSession.php:18
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher\$defaultOptions
‪array $defaultOptions
Definition: EmailFinisher.php:63
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher
Definition: EmailFinisher.php:60
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload
Definition: FileUpload.php:28
‪TYPO3\CMS\Form\Domain\Finishers\EmailFinisher\executeInternal
‪executeInternal()
Definition: EmailFinisher.php:76