[CLEANUP] Replace count with empty in EXT:indexed_search
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / PostProcess / MailPostProcessor.php
1 <?php
2 namespace TYPO3\CMS\Form\PostProcess;
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 TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Form\Domain\Model\Form;
19
20 /**
21 * The mail post processor
22 *
23 * @author Patrick Broens <patrick@patrickbroens.nl>
24 */
25 class MailPostProcessor implements \TYPO3\CMS\Form\PostProcess\PostProcessorInterface {
26
27 /**
28 * @var Form
29 */
30 protected $form;
31
32 /**
33 * @var array
34 */
35 protected $typoScript;
36
37 /**
38 * @var \TYPO3\CMS\Core\Mail\MailMessage
39 */
40 protected $mailMessage;
41
42 /**
43 * @var \TYPO3\CMS\Form\Request
44 */
45 protected $requestHandler;
46
47 /**
48 * @var array
49 */
50 protected $dirtyHeaders = array();
51
52 /**
53 * Constructor
54 *
55 * @param Form $form Form domain model
56 * @param array $typoScript Post processor TypoScript settings
57 */
58 public function __construct(Form $form, array $typoScript) {
59 $this->form = $form;
60 $this->typoScript = $typoScript;
61 $this->mailMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
62 $this->requestHandler = GeneralUtility::makeInstance(\TYPO3\CMS\Form\Request::class);
63 }
64
65 /**
66 * The main method called by the post processor
67 *
68 * Configures the mail message
69 *
70 * @return string HTML message from this processor
71 */
72 public function process() {
73 $this->setSubject();
74 $this->setFrom();
75 $this->setTo();
76 $this->setCc();
77 $this->setPriority();
78 $this->setOrganization();
79 // @todo The whole content rendering seems to be missing here!
80 $this->setHtmlContent();
81 $this->setPlainContent();
82 $this->addAttachmentsFromForm();
83 $this->send();
84 return $this->render();
85 }
86
87 /**
88 * Sets the subject of the mail message
89 *
90 * If not configured, it will use a default setting
91 *
92 * @return void
93 */
94 protected function setSubject() {
95 if (isset($this->typoScript['subject'])) {
96 $subject = $this->typoScript['subject'];
97 } elseif ($this->requestHandler->has($this->typoScript['subjectField'])) {
98 $subject = $this->requestHandler->get($this->typoScript['subjectField']);
99 } else {
100 $subject = 'Formmail on ' . GeneralUtility::getIndpEnv('HTTP_HOST');
101 }
102 $subject = $this->sanitizeHeaderString($subject);
103 $this->mailMessage->setSubject($subject);
104 }
105
106 /**
107 * Sets the sender of the mail message
108 *
109 * Mostly the sender is a combination of the name and the email address
110 *
111 * @return void
112 */
113 protected function setFrom() {
114 if ($this->typoScript['senderEmail']) {
115 $fromEmail = $this->typoScript['senderEmail'];
116 } elseif ($this->requestHandler->has($this->typoScript['senderEmailField'])) {
117 $fromEmail = $this->requestHandler->get($this->typoScript['senderEmailField']);
118 } else {
119 $fromEmail = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
120 }
121 if (!GeneralUtility::validEmail($fromEmail)) {
122 $fromEmail = \TYPO3\CMS\Core\Utility\MailUtility::getSystemFromAddress();
123 }
124 if ($this->typoScript['senderName']) {
125 $fromName = $this->typoScript['senderName'];
126 } elseif ($this->requestHandler->has($this->typoScript['senderNameField'])) {
127 $fromName = $this->requestHandler->get($this->typoScript['senderNameField']);
128 } else {
129 $fromName = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
130 }
131 $fromName = $this->sanitizeHeaderString($fromName);
132 if (!empty($fromName)) {
133 $from = array($fromEmail => $fromName);
134 } else {
135 $from = $fromEmail;
136 }
137 $this->mailMessage->setFrom($from);
138 }
139
140 /**
141 * Filter input-string for valid email addresses
142 *
143 * @param string $emails If this is a string, it will be checked for one or more valid email addresses.
144 * @return array List of valid email addresses
145 */
146 protected function filterValidEmails($emails) {
147 if (!is_string($emails)) {
148 // No valid addresses - empty list
149 return array();
150 }
151
152 /** @var $addressParser \TYPO3\CMS\Core\Mail\Rfc822AddressesParser */
153 $addressParser = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\Rfc822AddressesParser::class, $emails);
154 $addresses = $addressParser->parseAddressList();
155
156 $validEmails = array();
157 foreach ($addresses as $address) {
158 $fullAddress = $address->mailbox . '@' . $address->host;
159 if (GeneralUtility::validEmail($fullAddress)) {
160 if ($address->personal) {
161 $validEmails[$fullAddress] = $address->personal;
162 } else {
163 $validEmails[] = $fullAddress;
164 }
165 }
166 }
167 return $validEmails;
168 }
169
170 /**
171 * Adds the receiver of the mail message when configured
172 *
173 * Checks the address if it is a valid email address
174 *
175 * @return void
176 */
177 protected function setTo() {
178 $validEmails = $this->filterValidEmails($this->typoScript['recipientEmail']);
179 if (!empty($validEmails)) {
180 $this->mailMessage->setTo($validEmails);
181 }
182 }
183
184 /**
185 * Adds the carbon copy receiver of the mail message when configured
186 *
187 * Checks the address if it is a valid email address
188 *
189 * @return void
190 */
191 protected function setCc() {
192 $validEmails = $this->filterValidEmails($this->typoScript['ccEmail']);
193 if (!empty($validEmails)) {
194 $this->mailMessage->setCc($validEmails);
195 }
196 }
197
198 /**
199 * Set the priority of the mail message
200 *
201 * When not in settings, the value will be 3. If the priority is configured,
202 * but too big, it will be set to 5, which means very low.
203 *
204 * @return void
205 */
206 protected function setPriority() {
207 $priority = 3;
208 if ($this->typoScript['priority']) {
209 $priority = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->typoScript['priority'], 1, 5);
210 }
211 $this->mailMessage->setPriority($priority);
212 }
213
214 /**
215 * Add a text header to the mail header of the type Organization
216 *
217 * Sanitizes the header string when necessary
218 *
219 * @return void
220 */
221 protected function setOrganization() {
222 if ($this->typoScript['organization']) {
223 $organization = $this->typoScript['organization'];
224 $organization = $this->sanitizeHeaderString($organization);
225 $this->mailMessage->getHeaders()->addTextHeader('Organization', $organization);
226 }
227 }
228
229 /**
230 * Set the default character set used
231 *
232 * Respect formMailCharset if it was set, otherwise use metaCharset for mail
233 * if different from renderCharset
234 *
235 * @return void
236 */
237 protected function setCharacterSet() {
238 $characterSet = NULL;
239 if ($GLOBALS['TSFE']->config['config']['formMailCharset']) {
240 $characterSet = $GLOBALS['TSFE']->csConvObj->parse_charset($GLOBALS['TSFE']->config['config']['formMailCharset']);
241 } elseif ($GLOBALS['TSFE']->metaCharset != $GLOBALS['TSFE']->renderCharset) {
242 $characterSet = $GLOBALS['TSFE']->metaCharset;
243 }
244 if ($characterSet) {
245 $this->mailMessage->setCharset($characterSet);
246 }
247 }
248
249 /**
250 * Add the HTML content
251 *
252 * Add a MimePart of the type text/html to the message.
253 *
254 * @return void
255 */
256 protected function setHtmlContent() {
257 /** @var $view \TYPO3\CMS\Form\View\Mail\Html\HtmlView */
258 $view = GeneralUtility::makeInstance(\TYPO3\CMS\Form\View\Mail\Html\HtmlView::class, $this->form, $this->typoScript);
259 $htmlContent = $view->get();
260 $this->mailMessage->setBody($htmlContent, 'text/html');
261 }
262
263 /**
264 * Add the plain content
265 *
266 * Add a MimePart of the type text/plain to the message.
267 *
268 * @return void
269 */
270 protected function setPlainContent() {
271 /** @var $view \TYPO3\CMS\Form\View\Mail\Plain\PlainView */
272 $view = GeneralUtility::makeInstance(\TYPO3\CMS\Form\View\Mail\Plain\PlainView::class, $this->form);
273 $plainContent = $view->render();
274 $this->mailMessage->addPart($plainContent, 'text/plain');
275 }
276
277 /**
278 * Sends the mail.
279 * Sending the mail requires the recipient and message to be set.
280 *
281 * @return void
282 */
283 protected function send() {
284 if ($this->mailMessage->getTo() && $this->mailMessage->getBody()) {
285 $this->mailMessage->send();
286 }
287 }
288
289 /**
290 * Render the message after trying to send the mail
291 *
292 * @return string HTML message from the mail view
293 */
294 protected function render() {
295 /** @var $view \TYPO3\CMS\Form\View\Mail\MailView */
296 $view = GeneralUtility::makeInstance(\TYPO3\CMS\Form\View\Mail\MailView::class, $this->mailMessage, $this->typoScript);
297 return $view->render();
298 }
299
300 /**
301 * Checks string for suspicious characters
302 *
303 * @param string $string String to check
304 * @return string Valid or empty string
305 */
306 protected function sanitizeHeaderString($string) {
307 $pattern = '/[\\r\\n\\f\\e]/';
308 if (preg_match($pattern, $string) > 0) {
309 $this->dirtyHeaders[] = $string;
310 $string = '';
311 }
312 return $string;
313 }
314
315 /**
316 * Add attachments when uploaded
317 *
318 * @return void
319 */
320 protected function addAttachmentsFromForm() {
321 $formElements = $this->form->getElements();
322 $values = $this->requestHandler->getByMethod();
323 $this->addAttachmentsFromElements($formElements, $values);
324 }
325
326 /**
327 * Loop through all elements and attach the file when the element
328 * is a fileupload
329 *
330 * @param array $elements
331 * @param array $submittedValues
332 * @return void
333 */
334 protected function addAttachmentsFromElements($elements, $submittedValues) {
335 /** @var $element \TYPO3\CMS\Form\Domain\Model\Element\AbstractElement */
336 foreach ($elements as $element) {
337 if (is_a($element, \TYPO3\CMS\Form\Domain\Model\Element\ContainerElement::class)) {
338 $this->addAttachmentsFromElements($element->getElements(), $submittedValues);
339 continue;
340 }
341 if (is_a($element, \TYPO3\CMS\Form\Domain\Model\Element\FileuploadElement::class)) {
342 $elementName = $element->getName();
343 if (is_array($submittedValues[$elementName]) && isset($submittedValues[$elementName]['tempFilename'])) {
344 $filename = $submittedValues[$elementName]['tempFilename'];
345 if (is_file($filename) && GeneralUtility::isAllowedAbsPath($filename)) {
346 $this->mailMessage->attach(\Swift_Attachment::fromPath($filename)->setFilename($submittedValues[$elementName]['originalFilename']));
347 }
348 }
349 }
350 }
351 }
352
353 }