MailTemplateService.php 26.7 KB
Newer Older
1
2
3
4
<?php

namespace SGalinski\SgMail\Service;

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/***************************************************************
 *  Copyright notice
 *
 *  (c) sgalinski Internet Services (https://www.sgalinski.de)
 *
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
28

29
use DateTime;
30
31
32
use SGalinski\SgMail\Domain\Model\Mail;
use SGalinski\SgMail\Domain\Model\Template;
use SGalinski\SgMail\Domain\Repository\MailRepository;
33
use SGalinski\SgMail\Domain\Repository\TemplateRepository;
34
35
use Swift_Attachment;
use Swift_OutputByteStream;
36
use TYPO3\CMS\Core\Mail\MailMessage;
37
use TYPO3\CMS\Core\Resource\FileInterface;
38
use TYPO3\CMS\Core\Resource\ResourceFactory;
39
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
40
use TYPO3\CMS\Core\Utility\GeneralUtility;
41
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
42
use TYPO3\CMS\Extbase\Object\ObjectManager;
43
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
44
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
45
use TYPO3\CMS\Fluid\View\StandaloneView;
46
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
47
use TYPO3\CMS\Frontend\Page\PageRepository;
48

49
50
51
/**
 * MailTemplateService
 */
52
class MailTemplateService {
53
	const MARKER_TYPE_STRING = 'String';
54
55
	const MARKER_TYPE_ARRAY = 'Array';
	const MARKER_TYPE_OBJECT = 'Object';
56
	const MARKER_TYPE_FILE = 'File';
57
	const DEFAULT_LANGUAGE = 'default';
58
	const DEFAULT_TEMPLATE_PATH = 'Resources/Private/Templates/SgMail/';
59
60
	const CACHE_NAME = 'sg_mail_registerArrayCache';
	const CACHE_LIFETIME_IN_SECONDS = 86400;
61
62
	const REGISTER_FILE = 'Register.php';
	const CONFIG_PATH = 'Configuration/MailTemplates';
63

64
	/**
65
	 * @var array $toAddresses
66
	 */
67
	private $toAddresses = [];
68
69

	/**
70
	 * @var string $fromAddress
71
	 */
72
	private $fromAddress;
73
74

	/**
75
	 * @var array $ccAddresses
76
	 */
Paul Ilea's avatar
Paul Ilea committed
77
	private $ccAddresses;
78
79

	/**
80
	 * @var string $replyToAddress
81
	 */
82
	private $replyToAddress;
83
84

	/**
85
	 * @var string $language
86
	 */
87
	private $language = 'default';
88
89

	/**
90
	 * @var boolean $ignoreMailQueue
91
	 */
92
	private $ignoreMailQueue = FALSE;
93
94
95
96
97
98
99

	/**
	 * @var \TYPO3\CMS\Core\Mail\MailMessage $mailMessage
	 */
	private $mailMessage;

	/**
100
	 * @var string $templateName
101
102
103
	 */
	private $templateName;

104
105
106
107
108
	/**
	 * @var string $subject
	 */
	private $subject;

109
	/**
110
	 * @var string $extensionKey
111
112
113
114
	 */
	private $extensionKey;

	/**
115
	 * @var array $markers
116
	 */
Torsten Oppermann's avatar
Torsten Oppermann committed
117
	private $markers;
118

119
120
121
	/**
	 * @var array $bccAddresses
	 */
Paul Ilea's avatar
Paul Ilea committed
122
	private $bccAddresses;
123

124
125
126
127
128
	/**
	 * @var int
	 */
	private $priority = Mail::PRIORITY_LOWEST;

129
130
131
132
133
	/**
	 * @var int
	 */
	private $pid;

134
135
136
137
138
	/**
	 * @var string
	 */
	private $fromName = '';

139
140
141
	/**
	 * @var \SGalinski\SgMail\Domain\Repository\TemplateRepository
	 */
142
143
144
145
146
147
	protected $templateRepository;

	/**
	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
	 */
	protected $persistenceManager;
148

149
150
151
152
153
	/**
	 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
	 */
	protected $objectManager;

154
155
	/**
	 * MailTemplateService constructor.
Paul Ilea's avatar
Paul Ilea committed
156
	 *
157
158
159
	 * @param string $templateName
	 * @param string $extensionKey
	 * @param string $markers
Paul Ilea's avatar
Paul Ilea committed
160
	 * @throws \InvalidArgumentException
161
	 */
162
163
164
165
166
	public function __construct($templateName = '', $extensionKey = '', $markers = '') {
		$this->templateName = $templateName;
		$this->extensionKey = $extensionKey;
		$this->markers = $markers;

167
168
169
170
171
172
		/** @var ObjectManager objectManager */
		$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		/** @var MailMessage mailMessage */
		$this->mailMessage = $this->objectManager->get(MailMessage::class);
		/** @var TypoScriptSettingsService $typoScriptSettingsService */
		$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
Torsten Oppermann's avatar
Torsten Oppermann committed
173
		$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
174
175
176
177
		/** @var TemplateRepository templateRepository */
		$this->templateRepository = $this->objectManager->get(TemplateRepository::class);
		/** @var PersistenceManager persistenceManager */
		$this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
178

179
		// use defaultMailFromAddress if it is provided in LocalConfiguration.php; use the sg_mail TS setting as fallback
180
		if (!filter_var($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'], FILTER_VALIDATE_EMAIL)) {
181
182
			$this->fromAddress = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
		} else {
Torsten Oppermann's avatar
Torsten Oppermann committed
183
			$this->fromAddress = $tsSettings['mail']['default']['from'];
184

Torsten Oppermann's avatar
Torsten Oppermann committed
185
			if (!filter_var($tsSettings['mail']['default']['from'], FILTER_VALIDATE_EMAIL)) {
186
187
				$this->fromAddress = 'noreply@example.org';
			} else {
Torsten Oppermann's avatar
Torsten Oppermann committed
188
				$this->fromAddress = $tsSettings['mail']['default']['from'];
189
			}
190
191
		}

192
		$this->mailMessage->setFrom($this->fromAddress);
193

Torsten Oppermann's avatar
Torsten Oppermann committed
194
195
		$this->bccAddresses = GeneralUtility::trimExplode(',', $tsSettings['mail']['default']['bcc']);
		$this->ccAddresses = GeneralUtility::trimExplode(',', $tsSettings['mail']['default']['cc']);
196
197
198
199
200
201
202
203
204
205
206
207
208

		foreach ($this->bccAddresses as $index => $email) {
			if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
				unset($this->bccAddresses[$index]);
			}
		}

		foreach ($this->ccAddresses as $index => $email) {
			if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
				unset($this->ccAddresses[$index]);
			}
		}

209
		if (count($this->bccAddresses) > 0) {
210
211
212
			$this->mailMessage->setBcc($this->bccAddresses);
		}

213
		if (count($this->ccAddresses) > 0) {
214
215
			$this->mailMessage->setCc($this->ccAddresses);
		}
216
217
	}

218
219
220
221
222
223
224
225
226
	/**
	 * Return default markers for sg_mail
	 *
	 * @param string $translationKey
	 * @param array $marker
	 * @param string $extensionKey
	 * @return array
	 */
	public static function getDefaultTemplateMarker($translationKey, array $marker, $extensionKey = 'sg_mail') {
227
		$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang.xlf:' . $translationKey;
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

		// Need the key for translations
		if (trim($extensionKey) === '') {
			return [];
		}

		$generatedMarker = [];
		foreach ($marker as $markerName) {
			$generatedMarker[] = [
				'marker' => $markerName,
				'value' => $languagePath . '.example.' . $markerName,
				'description' => $languagePath . '.description.' . $markerName,
				'backend_translation_key' => $translationKey . '.example.' . $markerName,
				'extension_key' => $extensionKey
			];
		}

		return $generatedMarker;
	}

248
	/**
249
	 * Send the Email
250
	 *
Torsten Oppermann's avatar
Torsten Oppermann committed
251
	 * @param boolean $isPreview
252
	 * @return boolean email was sent or added to mail queue successfully?
253
254
255
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
	 * @throws \InvalidArgumentException
	 * @throws \BadFunctionCallException
256
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
257
	 */
258
	public function sendEmail($isPreview = FALSE): bool {
259
260
		$registerService = GeneralUtility::makeInstance(RegisterService::class);

261
262
263
		if (TYPO3_MODE === 'FE') {
			/** @var TypoScriptFrontendController $tsfe */
			$tsfe = $GLOBALS['TSFE'];
264
			$pageUid = (int) $tsfe->id;
265
266
267
268
		} else {
			$pageUid = (int) GeneralUtility::_GP('id');
		}

269
		if ($this->pid) {
270
271
272
273
274
275
276
277
278
279
			$pageUid = (int) $this->pid;
		}
		if ($pageUid === 0) {
			$pageRepository = $this->objectManager->get(PageRepository::class);
			$rootPageRows = $pageRepository->getRecordsByField(
				'pages', 'is_siteroot', 1, 'hidden = 0', '', 'sorting', 1
			);
			if ($rootPageRows && \count($rootPageRows)) {
				$pageUid = (int) $rootPageRows[0]['uid'];
			}
280
		}
281
		$siteRootId = BackendService::getSiteRoot($pageUid);
282

283
		/** @var Template $template */
284
		$template = $this->templateRepository->findOneByTemplate(
285
			$this->extensionKey, $this->templateName, $this->language, $siteRootId
286
		);
287

288
289
290
291
292
293
		if ($template === NULL) {
			$template = $this->templateRepository->findOneByTemplate(
				$this->extensionKey, $this->templateName, 'default', $siteRootId
			);
		}

294
295
296
297
298
		// if there is a template, prefer those values
		if ($template) {
			$this->loadTemplateValues($template);
		}

299
300
301
302
303
		// get default template content from register array
		$defaultTemplateContent = $registerService->getRegisterArray(
		)[$this->extensionKey][$this->templateName]['templateContent'];
//		var_dump($registerService->getRegisterArray()[$this->extensionKey][$this->templateName]); die();
//		var_dump($defaultTemplateContent); die();
304
305
		// If there is no template for this language, use the default template
		if ($template === NULL) {
306
307
308
			if ($defaultTemplateContent === NULL) {
				$templatePath = $registerService->getRegisterArray(
				)[$this->extensionKey][$this->templateName]['templatePath'];
309

310
311
				// only standard template file is considered since version 4.1
				$defaultTemplateFile = $templatePath . 'template.html';
Torsten Oppermann's avatar
Torsten Oppermann committed
312
313
				if (file_exists($defaultTemplateFile)) {
					$defaultTemplateContent = file_get_contents($defaultTemplateFile);
314
				} else {
315
316
317
318
319
320
321
322
323
324
325
326
327
					// use configured default html template
					/** @var TypoScriptSettingsService $typoScriptSettingsService */
					$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
					$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
					$defaultTemplateFile = GeneralUtility::getFileAbsFileName(
						$tsSettings['mail']['defaultHtmlTemplate']
					);

					if (file_exists($defaultTemplateFile)) {
						$defaultTemplateContent = file_get_contents($defaultTemplateFile);
					} else {
						return FALSE;
					}
328
				}
329
			}
330

331
		} elseif (filter_var($template->getToAddress(), FILTER_VALIDATE_EMAIL)) {
332
			$this->setToAddresses(trim($template->getToAddress()));
333
334
		}

Torsten Oppermann's avatar
Torsten Oppermann committed
335
336
		if ($isPreview) {
			$previewMarker = [];
Paul Ilea's avatar
Paul Ilea committed
337
			/** @var array $markerArray */
338
339

			$markerArray = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['marker'];
Torsten Oppermann's avatar
Torsten Oppermann committed
340
			foreach ($markerArray as $marker) {
341
342
343
344
345
346
347
348
349
350
351
352
				$markerPath = GeneralUtility::trimExplode('.', $marker['marker']);
				$temporaryMarkerArray = [];
				foreach (array_reverse($markerPath) as $index => $markerPathSegment) {
					if ($index === 0) {
						if ($marker['backend_translation_key']) {
							$temporaryMarkerArray[$markerPathSegment] = LocalizationUtility::translate(
								$marker['backend_translation_key'], $marker['extension_key']
							);
						} else {
							$temporaryMarkerArray[$markerPathSegment] = $marker['value'];
						}
					} else {
353
						$temporaryMarkerArray = [$markerPathSegment => $temporaryMarkerArray];
354
					}
355
				}
356
				$previewMarker = array_merge_recursive($previewMarker, $temporaryMarkerArray);
Torsten Oppermann's avatar
Torsten Oppermann committed
357
			}
358
			$this->setIgnoreMailQueue(TRUE);
Torsten Oppermann's avatar
Torsten Oppermann committed
359
360
361
			$this->setMarkers($previewMarker);
		}

362
		/** @var StandaloneView $emailView */
363
		$emailView = $this->objectManager->get(StandaloneView::class);
364
		$emailView->assignMultiple($this->markers);
Torsten Oppermann's avatar
Torsten Oppermann committed
365
		$emailView->assign('all_fields', $this->getAllMarker($this->markers));
366

367
		if (NULL === $defaultTemplateContent) {
368
369
370
			$emailView->setTemplateSource(\trim($template->getSubject()));
			$subject = $emailView->render();

371
372
			$emailView->setTemplateSource($template->getContent());
		} else {
373
			$subject = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['subject'];
374
375
			if (\is_array($subject)) {
				$subject = \trim(
376
					$registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['subject'][$this->language]
377
				);
378
			}
379
380
381
382
383
384
385
			if ($subject === NULL && $this->subject !== NULL) {
				$subject = $this->subject;
			}
			if ($subject !== NULL) {
				$emailView->setTemplateSource($subject);
				$subject = $emailView->render();
			}
386
			$emailView->setTemplateSource($defaultTemplateContent);
387
		}
388

Paul Ilea's avatar
Paul Ilea committed
389
		if ($this->subject !== '' && $this->subject !== NULL) {
390
391
392
			$subject = $this->subject;
		}

393
		$this->mailMessage->setSubject($subject);
394

395
		$emailBody = $emailView->render();
396

397
398
399
		// insert <br /> tags, but replace every instance of three or more successive breaks with just two.
		$emailBody = nl2br($emailBody);
		$emailBody = preg_replace('/(<br[\s]?[\/]?>[\s]*){3,}/', '<br /><br />', $emailBody);
400

401
402
403
		$isTemplateBlacklisted = self::isTemplateBlacklisted(
			$this->extensionKey, $this->templateName, $siteRootId
		);
404
		if ($this->ignoreMailQueue && !$isTemplateBlacklisted) {
405
			$this->mailMessage->setBody($emailBody, 'text/html');
406
407
408
			$plaintextService = GeneralUtility::makeInstance(PlaintextService::class);
			$plainTextBody = $plaintextService->makePlain($emailBody);
			$this->mailMessage->addPart($plainTextBody, 'text/plain');
409
			$this->mailMessage->send();
410
			$dateTime = new DateTime();
411
			$currentTimestamp = $dateTime->getTimestamp();
412
413
414
415

			if (!$isPreview) {
				$this->addMailToMailQueue(
					$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority,
416
					$currentTimestamp, $currentTimestamp, $this->language, $siteRootId
417
418
				);
			}
419

420
		} else {
421
422
			if (!$isPreview) {
				$this->addMailToMailQueue(
423
					$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority, 0, 0,
424
425
426
					$this->language, $siteRootId
				);
			}
427
		}
428
429

		return TRUE;
430
431
432
	}

	/**
433
	 * Adds a new mail to the mail queue.
434
	 *
435
436
	 * @param string $extensionKey
	 * @param string $templateName
437
	 * @param string $subject
438
	 * @param string $emailBody
439
	 * @param int $sendingTime
440
	 * @param int $priority
441
	 * @param int $lastSendingTime
442
	 * @param string $language
443
	 * @param int $pid
444
445
	 * @throws \InvalidArgumentException
	 * @throws \BadFunctionCallException
Paul Ilea's avatar
Paul Ilea committed
446
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
447
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
448
	 */
449
	private function addMailToMailQueue(
450
		$extensionKey, $templateName, $subject, $emailBody, $priority, $sendingTime = 0,
451
		$lastSendingTime = 0, $language = self::DEFAULT_LANGUAGE, $pid = 0
452
	) {
453
		$mail = $this->objectManager->get(Mail::class);
454
		$mail->setPid($pid);
455
456
		$mail->setExtensionKey($extensionKey);
		$mail->setTemplateName($templateName);
457
		$mail->setLanguage($language);
458
		$mail->setBlacklisted(self::isTemplateBlacklisted($extensionKey, $templateName, $pid));
459

460
		$mail->setFromAddress($this->fromAddress);
461
		$mail->setFromName($this->fromName);
462

463
		$mail->setToAddress($this->toAddresses);
464
		$mail->setMailSubject($subject);
465
		$mail->setMailBody($emailBody);
466
		$mail->setPriority($priority);
467
468
		$mail->setBccAddresses($this->bccAddresses);
		$mail->setCcAddresses($this->ccAddresses);
469
		$mail->setSendingTime($sendingTime);
470
		$mail->setLastSendingTime($lastSendingTime);
471
		$mail->setReplyTo($this->replyToAddress);
472
473
474
475
476
		foreach ($this->markers as $marker) {
			if ($marker instanceof FileReference) {
				$mail->addAttachment($marker);
			}
		}
477

478
		$mailRepository = $this->objectManager->get(MailRepository::class);
479
		$mailRepository->add($mail);
480
		$this->persistenceManager->persistAll();
481
	}
482

483
484
485
486
	/**
	 * Send a Mail from the queue, identified by its id
	 *
	 * @param int $uid
Paul Ilea's avatar
Paul Ilea committed
487
488
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
489
490
491
492
	 */
	public function sendMailFromQueue($uid) {
		$mailRepository = $this->objectManager->get(MailRepository::class);
		/** @var Mail $mailToSend */
493
		$mailToSend = $mailRepository->findOneByUid($uid);
494

495
		if ($mailToSend && !$mailToSend->getBlacklisted()) {
496
			$this->mailMessage->setBody($mailToSend->getMailBody(), 'text/html');
497
498
499
			$plaintextService = GeneralUtility::makeInstance(PlaintextService::class);
			$plaintextBody = $plaintextService->makePlain($mailToSend->getMailBody());
			$this->mailMessage->addPart($plaintextBody, 'text/plain');
500
501
502
503
504
505
			$toAddresses = trim($mailToSend->getToAddress());
			$addressesArray = GeneralUtility::trimExplode(',', $toAddresses, TRUE);
			if (\count($addressesArray) > 1) {
				$toAddresses = $addressesArray;
			}
			$this->mailMessage->setTo($toAddresses);
506
507
			$this->mailMessage->setFrom($mailToSend->getFromAddress(), $mailToSend->getFromName());
			$this->mailMessage->setSubject($mailToSend->getMailSubject());
508

509
			if ($mailToSend->getBccAddresses()) {
510
511
512
				$this->mailMessage->setBcc(GeneralUtility::trimExplode(',', $mailToSend->getBccAddresses()));
			}

513
			if ($mailToSend->getCcAddresses()) {
514
515
516
517
518
519
				$this->mailMessage->setCc(GeneralUtility::trimExplode(',', $mailToSend->getCcAddresses()));
			}

			if ($mailToSend->getReplyTo()) {
				$this->mailMessage->setReplyTo($mailToSend->getReplyTo());
			}
520
521
522
523
524
525
526
527
528
529
530
531
			$attachments = $mailToSend->getAttachments();
			if ($attachments->count() > 0) {
				foreach ($attachments as $attachment) {
					/**
					 * @var FileReference $attachment
					 */
					$file = $attachment->getOriginalResource()->getOriginalFile();
					$this->mailMessage->attach(
						\Swift_Attachment::newInstance($file->getContents(), $file->getName(), $file->getMimeType())
					);
				}
			}
532
			$dateTime = new DateTime();
533
534
535
			if ((int) $mailToSend->getSendingTime() === 0) {
				$mailToSend->setSendingTime($dateTime->getTimestamp());
			}
536
			$mailToSend->setLastSendingTime($dateTime->getTimestamp());
537
			$this->mailMessage->send();
538
			$mailRepository->update($mailToSend);
539
540
541
		}
	}

542
	/**
543
	 * @param string $toAddresses
544
545
	 * @return MailTemplateService
	 */
546
	public function setToAddresses($toAddresses) {
547
548
549
550
551
552
553
554
		$toAddresses = trim(preg_replace('~\x{00a0}~siu', ' ', $toAddresses));
		$this->toAddresses = $toAddresses;

		$addressesArray = GeneralUtility::trimExplode(',', $toAddresses, TRUE);
		if (\count($addressesArray) > 1) {
			$toAddresses = $addressesArray;
		}
		$this->mailMessage->setTo($toAddresses);
555
556
557
558
		return $this;
	}

	/**
559
	 * @param string $fromAddress
560
	 * @param string $fromName
561
562
	 * @return MailTemplateService
	 */
563
	public function setFromAddress($fromAddress, $fromName = '') {
564
565
566
567
568
		if ($fromAddress) {
			$this->fromAddress = $fromAddress;
			$this->mailMessage->setFrom($fromAddress, $fromName);
		}

569
570
571
572
		return $this;
	}

	/**
573
	 * @param string $ccAddresses
574
575
	 * @return MailTemplateService
	 */
576
	public function setCcAddresses($ccAddresses) {
577
578
		if ($ccAddresses) {
			$this->ccAddresses = $ccAddresses;
579
			$this->mailMessage->setCc(GeneralUtility::trimExplode(',', $this->ccAddresses));
580
581
		}

582
583
584
585
		return $this;
	}

	/**
586
	 * @param string $replyToAddress
587
588
	 * @return MailTemplateService
	 */
589
	public function setReplyToAddress($replyToAddress) {
590
591
592
593
594
		if ($replyToAddress) {
			$this->replyToAddress = $replyToAddress;
			$this->mailMessage->setReplyTo($replyToAddress);
		}

595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
		return $this;
	}

	/**
	 * @param string $language
	 * @return MailTemplateService
	 */
	public function setLanguage($language) {
		$this->language = $language;
		return $this;
	}

	/**
	 * @param boolean $ignoreMailQueue
	 * @return MailTemplateService
	 */
	public function setIgnoreMailQueue($ignoreMailQueue) {
		$this->ignoreMailQueue = $ignoreMailQueue;
		return $this;
	}

	/**
	 * @param string $templateName
	 * @return MailTemplateService
	 */
	public function setTemplateName($templateName) {
		$this->templateName = $templateName;
		return $this;
	}

	/**
	 * @param string $extensionKey
	 * @return MailTemplateService
	 */
	public function setExtensionKey($extensionKey) {
		$this->extensionKey = $extensionKey;
		return $this;
	}

634
	/**
635
	 * @param array $markers
636
637
	 * @return MailTemplateService
	 */
638
639
	public function setMarkers(array $markers) {
		$this->markers = $markers;
640
641
		return $this;
	}
642
643

	/**
644
	 * @param string $bccAddresses
645
646
	 * @return MailTemplateService
	 */
647
	public function setBccAddresses($bccAddresses) {
648
649
		if ($bccAddresses) {
			$this->bccAddresses = $bccAddresses;
650
			$this->mailMessage->setBcc(GeneralUtility::trimExplode(',', $this->bccAddresses));
651
652
		}

653
654
655
		return $this;
	}

656
657
658
659
660
661
662
663
	/**
	 * @param int $priority
	 * @return MailTemplateService
	 */
	public function setPriority($priority) {
		$this->priority = $priority;
		return $this;
	}
664
665
666

	/**
	 * @param Swift_OutputByteStream $data
Paul Ilea's avatar
Paul Ilea committed
667
	 * @param string $filename
668
669
670
671
672
673
674
675
676
677
678
	 * @param string $contentType
	 * @return MailTemplateService
	 */
	public function addAttachment($data, $filename, $contentType) {
		$attachment = Swift_Attachment::newInstance()
			->setFilename($filename)
			->setContentType($contentType)
			->setBody($data);
		$this->mailMessage->attach($attachment);
		return $this;
	}
679

680
681
682
	/**
	 * Add a file resource as attachment
	 *
683
	 * @param FileInterface|FileReference $file
684
685
	 * @return MailTemplateService
	 */
686
687
688
689
	public function addFileResourceAttachment($file) {
		if ($file instanceof FileReference) {
			$file = $file->getOriginalResource()->getOriginalFile();
		}
690
691
692
693
694
695
696
697
698
699
700
701
		$fileReference = $this->objectManager->get(FileReference::class);
		$resourceFactory = $this->objectManager->get(ResourceFactory::class);
		$falFileReference = $resourceFactory->createFileReferenceObject(
			[
				'uid_local' => $file->getUid(),
				'uid_foreign' => uniqid('NEW_', TRUE),
				'uid' => uniqid('NEW_', TRUE),
				'crop' => NULL,
			]
		);
		$fileReference->setOriginalResource($falFileReference);
		$this->markers[] = $fileReference;
702
703
		$this->addAttachment($file->getContents(), $file->getName(), $file->getMimeType());
		return $this;
704
705
	}

706
707
708
709
710
711
712
	/**
	 * @return MailMessage
	 */
	public function getMailMessage() {
		return $this->mailMessage;
	}

713
714
715
716
717
718
	/**
	 * use all values from the given template
	 *
	 * @param Template $template
	 */
	private function loadTemplateValues($template) {
719
720
721
722
723
724
725
726
727
728
729
730
731
732
		$fromName = $template->getFromName();
		if ($fromName === '' && $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']) {
			$fromName = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
		}

		$fromMail = $template->getFromMail();
		if (!filter_var($fromMail, FILTER_VALIDATE_EMAIL)) {
			$fromMail = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
			if (!filter_var($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'], FILTER_VALIDATE_EMAIL)) {
				$fromMail = 'noreply@example.com';
			}
		}

		$this->setFromAddress($fromMail, $fromName);
733
734
735
		$this->setCcAddresses($template->getCc());
		$this->setBccAddresses($template->getBcc());
		$this->setReplyToAddress($template->getReplyTo());
736
		$this->setFromName($fromName);
737
738
739
740
741
742
743
744
		$this->setReplyToAddress($template->getReplyTo());
	}

	/**
	 * @param string $fromName
	 */
	public function setFromName($fromName) {
		$this->fromName = $fromName;
745
	}
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762

	/**
	 * Provides translation for the marker data type
	 *
	 * @param string $markerType
	 */
	public static function getReadableMarkerType($markerType) {
		switch ($markerType) {
			case self::MARKER_TYPE_STRING :
				LocalizationUtility::translate('backend.marker.type.string', 'sg_mail');
				break;
			case self::MARKER_TYPE_ARRAY :
				LocalizationUtility::translate('backend.marker.type.array', 'sg_mail');
				break;
			case self::MARKER_TYPE_OBJECT :
				LocalizationUtility::translate('backend.marker.type.object', 'sg_mail');
				break;
763
764
765
			case self::MARKER_TYPE_FILE:
				LocalizationUtility::translate('backend.marker.type.file', 'sg_mail');
				break;
766
767
768
769
			default:
				LocalizationUtility::translate('backend.marker.type.mixed', 'sg_mail');
		}
	}
770
771
772
773
774
775
776
777
778
779
780

	/**
	 * set the page id from which this was called
	 *
	 * @param int $pid
	 * @return MailTemplateService
	 */
	public function setPid($pid) {
		$this->pid = (int) $pid;
		return $this;
	}
781

782
783
784
785
786
787
788
	/**
	 * Get all registered templates
	 *
	 * @return array
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
	 * @throws \BadFunctionCallException
	 * @throws \InvalidArgumentException
789
	 * @deprecated since 4.7.0 will be removed in 5.0.0. Use the RegistrationService class instead
790
	 */
791
792
793
	public static function getRegisterArray(): array {
		// @TODO remove this deprecated function in version 5.0.0
		self::logDeprecation('registerExtensions');
794

795
796
797
		$registrationService = GeneralUtility::makeInstance(RegisterService::class);
		// write entries for old extensions intto the file list
		self::registerExtensions();
798

799
		return $registrationService->getRegisterArray();
800
801
	}

802
803
804
805
806
	/**
	 * Iterate over all installed extensions and look for sg_mail configuration files
	 * If found, register the template(s)
	 *
	 * @throws \BadFunctionCallException
807
	 * @deprecated since 4.7.0 will be removed in 5.0.0. Use the RegistrationService class instead
808
	 */
809
	public static function registerExtensions() {
810
811
812
		// @TODO remove this deprecated function in version 5.0.0
		self::logDeprecation('registerExtensions');

813
814
815
816
		$extensionList = ExtensionManagementUtility::getLoadedExtensionListArray();

		foreach ($extensionList as $extensionName) {
			$extensionConfigDirectory = ExtensionManagementUtility::extPath($extensionName);
817
			$extensionConfigDirectory .= self::CONFIG_PATH;
818

Torsten Oppermann's avatar
Torsten Oppermann committed
819
820
821
			if (\is_dir($extensionConfigDirectory)) {
				$configFiles = GeneralUtility::getFilesInDir($extensionConfigDirectory);
				foreach ($configFiles as $configFile) {
822
					$pathToRegistrationFile = $extensionConfigDirectory . '/' . $configFile;
823

824
					if (!\file_exists($pathToRegistrationFile)) {
Torsten Oppermann's avatar
Torsten Oppermann committed
825
826
						continue;
					}
Torsten Oppermann's avatar
Torsten Oppermann committed
827
					$GLOBALS['sg_mail']['sg_mail'][$configFile] = $pathToRegistrationFile;
Torsten Oppermann's avatar
Torsten Oppermann committed
828
				}
829
830
			}
		}
831
	}
832
833
834
835
836
837
838
839
840
841
842
843
844

	/**
	 * Checks if a template is blacklisted for a given siterootId
	 *
	 * @param string $extensionKey
	 * @param string $templateName
	 * @param int $siteRootId
	 * @return boolean
	 * @throws \InvalidArgumentException
	 * @throws \BadFunctionCallException
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
	 */
	public static function isTemplateBlacklisted($extensionKey, $templateName, $siteRootId): bool {
845
		$nonBlacklistedTemplates = BackendService::getNonBlacklistedTemplates($siteRootId);
846

847
848
		if ($nonBlacklistedTemplates[$extensionKey]) {
			return $nonBlacklistedTemplates[$extensionKey][$templateName] ? FALSE : TRUE;
849
850
851
852
		}

		return TRUE;
	}
853
854
855
856
857
858
859
860
861
862
863
864
865
866

	/**
	 * @return string
	 */
	public function getSubject(): string {
		return $this->subject;
	}

	/**
	 * @param string $subject
	 */
	public function setSubject(string $subject) {
		$this->subject = $subject;
	}
867
868
869
870
871
872
873

	/**
	 * Get a single variable containing a list of all markers
	 *
	 * @param array $markers
	 * @return string
	 */
874
	private function getAllMarker(array $markers): string {
875
876
877
		$allMarker = '';

		foreach ($markers as $key => $value) {
878
			if (\is_string($value)) {
879
				$allMarker .= $key . ': ' . $value . PHP_EOL;
880
			} elseif (\is_array($value)) {
881
				foreach ($value as $innerKey => $innerValue) {
Torsten Oppermann's avatar
Torsten Oppermann committed
882
					$allMarker .= $key . '.' . $innerKey . ': ' . $innerValue . PHP_EOL;
883
				}
884
			} elseif (\is_bool($value)) {
Torsten Oppermann's avatar
Torsten Oppermann committed
885
886
				$valueAsString = $value ? 'true' : 'false';
				$allMarker .= $key . ': ' . $valueAsString . PHP_EOL;
887
888
889
890
			} elseif (\is_object($value)) {
				if (method_exists($value, '__toString')) {
					$allMarker .= $key . ': ' . $value->__toString() . PHP_EOL;
				}
891
892
893
894
895
			}
		}

		return $allMarker;
	}
896
897
898
899
900
901
902
903
904
905
906

	/**
	 * function to call a deprecation log entry (but only once per request / class)
	 *
	 * @param $function
	 */
	private static function logDeprecation($function) {
		GeneralUtility::deprecationLog(
			'The function ' . $function . ' is deprecated since version 4.7.0 and will be removed in version 5.0.0'
		);
	}
907
}