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
		/** @var ObjectManager objectManager */
		$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		$this->mailMessage = $this->objectManager->get(MailMessage::class);
		$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
Torsten Oppermann's avatar
Torsten Oppermann committed
171
		$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
172
173
		$this->templateRepository = $this->objectManager->get(TemplateRepository::class);
		$this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
174

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

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

188
		$this->mailMessage->setFrom($this->fromAddress);
189

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

		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]);
			}
		}

205
		if (\count($this->bccAddresses) > 0) {
206
207
208
			$this->mailMessage->setBcc($this->bccAddresses);
		}

209
		if (\count($this->ccAddresses) > 0) {
210
211
			$this->mailMessage->setCc($this->ccAddresses);
		}
212
213
	}

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

		// 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;
	}

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

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

265
		if ($this->pid) {
266
			$pageUid = $this->pid;
267
		}
268

269
270
271
272
273
274
275
276
		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'];
			}
277
		}
278
		$siteRootId = BackendService::getSiteRoot($pageUid);
279

280
		/** @var Template $template */
281
		$template = $this->templateRepository->findOneByTemplate(
282
			$this->extensionKey, $this->templateName, $this->language, $siteRootId
283
		);
284

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

291
292
293
294
295
		// if there is a template, prefer those values
		if ($template) {
			$this->loadTemplateValues($template);
		}

296
		// get default template content from register array
297
298
299
		$defaultTemplateContent = $registerService->getRegisterArray()
		[$this->extensionKey][$this->templateName]['templateContent'];

300
301
		// If there is no template for this language, use the default template
		if ($template === NULL) {
302
			if ($defaultTemplateContent === NULL) {
303
304
				$templatePath = $registerService->getRegisterArray()
				[$this->extensionKey][$this->templateName]['templatePath'];
305

306
307
				// only standard template file is considered since version 4.1
				$defaultTemplateFile = $templatePath . 'template.html';
Torsten Oppermann's avatar
Torsten Oppermann committed
308
309
				if (file_exists($defaultTemplateFile)) {
					$defaultTemplateContent = file_get_contents($defaultTemplateFile);
310
				} else {
311
312
313
314
315
316
317
318
319
320
321
322
323
					// 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;
					}
324
				}
325
			}
326

327
		} elseif (filter_var($template->getToAddress(), FILTER_VALIDATE_EMAIL)) {
328
			$this->setToAddresses(trim($template->getToAddress()));
329
330
		}

Torsten Oppermann's avatar
Torsten Oppermann committed
331
332
		if ($isPreview) {
			$previewMarker = [];
333

334
			/** @var array $markerArray */
335
			$markerArray = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['marker'];
Torsten Oppermann's avatar
Torsten Oppermann committed
336
			foreach ($markerArray as $marker) {
337
338
339
340
341
342
343
344
345
346
347
348
				$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 {
349
						$temporaryMarkerArray = [$markerPathSegment => $temporaryMarkerArray];
350
					}
351
				}
352
				$previewMarker = array_merge_recursive($previewMarker, $temporaryMarkerArray);
Torsten Oppermann's avatar
Torsten Oppermann committed
353
			}
354
			$this->setIgnoreMailQueue(TRUE);
Torsten Oppermann's avatar
Torsten Oppermann committed
355
356
357
			$this->setMarkers($previewMarker);
		}

358
		/** @var StandaloneView $emailView */
359
		$emailView = $this->objectManager->get(StandaloneView::class);
360
		$emailView->assignMultiple($this->markers);
Torsten Oppermann's avatar
Torsten Oppermann committed
361
		$emailView->assign('all_fields', $this->getAllMarker($this->markers));
362

Paul Ilea's avatar
Paul Ilea committed
363
		if ($template !== NULL) {
364
365
366
			$emailView->setTemplateSource(\trim($template->getSubject()));
			$subject = $emailView->render();

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

Paul Ilea's avatar
Paul Ilea committed
386
		if ($this->subject !== '' && $this->subject !== NULL) {
387
388
389
			$subject = $this->subject;
		}

390
		$this->mailMessage->setSubject($subject);
391

392
		$emailBody = $emailView->render();
393

394
395
396
		// 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);
397

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

			if (!$isPreview) {
				$this->addMailToMailQueue(
					$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority,
413
					$currentTimestamp, $currentTimestamp, $this->language, $siteRootId
414
415
				);
			}
416

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

		return TRUE;
427
428
429
	}

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

457
		$mail->setFromAddress($this->fromAddress);
458
		$mail->setFromName($this->fromName);
459

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

475
		$mailRepository = $this->objectManager->get(MailRepository::class);
476
		$mailRepository->add($mail);
477
		$this->persistenceManager->persistAll();
478
	}
479

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

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

506
			if ($mailToSend->getBccAddresses()) {
507
508
509
				$this->mailMessage->setBcc(GeneralUtility::trimExplode(',', $mailToSend->getBccAddresses()));
			}

510
			if ($mailToSend->getCcAddresses()) {
511
512
513
514
515
516
				$this->mailMessage->setCc(GeneralUtility::trimExplode(',', $mailToSend->getCcAddresses()));
			}

			if ($mailToSend->getReplyTo()) {
				$this->mailMessage->setReplyTo($mailToSend->getReplyTo());
			}
517
518
519
520
521
522
523
524
525
526
527
528
			$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())
					);
				}
			}
529
			$dateTime = new DateTime();
530
531
532
			if ((int) $mailToSend->getSendingTime() === 0) {
				$mailToSend->setSendingTime($dateTime->getTimestamp());
			}
533
			$mailToSend->setLastSendingTime($dateTime->getTimestamp());
534
			$this->mailMessage->send();
535
			$mailRepository->update($mailToSend);
536
537
538
		}
	}

539
	/**
540
	 * @param string $toAddresses
541
542
	 * @return MailTemplateService
	 */
543
	public function setToAddresses($toAddresses): MailTemplateService {
544
545
546
547
548
549
550
551
		$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);
552
553
554
555
		return $this;
	}

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

566
567
568
569
		return $this;
	}

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

579
580
581
582
		return $this;
	}

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

592
593
594
595
596
597
598
		return $this;
	}

	/**
	 * @param string $language
	 * @return MailTemplateService
	 */
599
	public function setLanguage($language): MailTemplateService {
600
601
602
603
604
605
606
607
		$this->language = $language;
		return $this;
	}

	/**
	 * @param boolean $ignoreMailQueue
	 * @return MailTemplateService
	 */
608
	public function setIgnoreMailQueue($ignoreMailQueue): MailTemplateService {
609
610
611
612
613
614
615
616
		$this->ignoreMailQueue = $ignoreMailQueue;
		return $this;
	}

	/**
	 * @param string $templateName
	 * @return MailTemplateService
	 */
617
	public function setTemplateName($templateName): MailTemplateService {
618
619
620
621
622
623
624
625
		$this->templateName = $templateName;
		return $this;
	}

	/**
	 * @param string $extensionKey
	 * @return MailTemplateService
	 */
626
	public function setExtensionKey($extensionKey): MailTemplateService {
627
628
629
630
		$this->extensionKey = $extensionKey;
		return $this;
	}

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

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

650
651
652
		return $this;
	}

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

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

677
678
679
	/**
	 * Add a file resource as attachment
	 *
680
	 * @param FileInterface|FileReference $file
681
682
	 * @return MailTemplateService
	 */
683
	public function addFileResourceAttachment($file): MailTemplateService {
684
685
686
		if ($file instanceof FileReference) {
			$file = $file->getOriginalResource()->getOriginalFile();
		}
687
688
689
690
691
692
693
694
695
696
697
698
		$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;
699
700
		$this->addAttachment($file->getContents(), $file->getName(), $file->getMimeType());
		return $this;
701
702
	}

703
704
705
	/**
	 * @return MailMessage
	 */
706
	public function getMailMessage(): MailMessage {
707
708
709
		return $this->mailMessage;
	}

710
711
712
713
714
715
	/**
	 * use all values from the given template
	 *
	 * @param Template $template
	 */
	private function loadTemplateValues($template) {
716
717
718
719
720
721
722
723
724
725
726
727
728
729
		$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);
730
731
732
		$this->setCcAddresses($template->getCc());
		$this->setBccAddresses($template->getBcc());
		$this->setReplyToAddress($template->getReplyTo());
733
		$this->setFromName($fromName);
734
735
736
737
738
739
740
741
		$this->setReplyToAddress($template->getReplyTo());
	}

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

	/**
	 * 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;
760
761
762
			case self::MARKER_TYPE_FILE:
				LocalizationUtility::translate('backend.marker.type.file', 'sg_mail');
				break;
763
764
765
766
			default:
				LocalizationUtility::translate('backend.marker.type.mixed', 'sg_mail');
		}
	}
767
768
769
770
771
772
773

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

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

792
		$registrationService = GeneralUtility::makeInstance(RegisterService::class);
793
		// write entries for old extensions into the file list
794
		self::registerExtensions();
795

796
		return $registrationService->getRegisterArray();
797
798
	}

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

810
811
812
		$extensionList = ExtensionManagementUtility::getLoadedExtensionListArray();
		foreach ($extensionList as $extensionName) {
			$extensionConfigDirectory = ExtensionManagementUtility::extPath($extensionName);
813
			$extensionConfigDirectory .= self::CONFIG_PATH;
814
815
816
			if (!\is_dir($extensionConfigDirectory)) {
				continue;
			}
817

818
819
820
821
822
			$configFiles = GeneralUtility::getFilesInDir($extensionConfigDirectory);
			foreach ($configFiles as $configFile) {
				$pathToRegistrationFile = $extensionConfigDirectory . '/' . $configFile;
				if (!\is_file($pathToRegistrationFile)) {
					continue;
Torsten Oppermann's avatar
Torsten Oppermann committed
823
				}
824
825

				$GLOBALS['sg_mail'][$extensionName][$configFile] = $pathToRegistrationFile;
826
827
			}
		}
828
	}
829
830

	/**
831
	 * Checks if a template is blacklisted for a given siteroot id
832
833
834
835
836
837
838
839
840
841
	 *
	 * @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 {
842
		$nonBlacklistedTemplates = BackendService::getNonBlacklistedTemplates($siteRootId);
843

844
845
		if ($nonBlacklistedTemplates[$extensionKey]) {
			return $nonBlacklistedTemplates[$extensionKey][$templateName] ? FALSE : TRUE;
846
847
848
849
		}

		return TRUE;
	}
850
851
852
853
854
855
856
857
858
859
860
861
862
863

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

	/**
	 * @param string $subject
	 */
	public function setSubject(string $subject) {
		$this->subject = $subject;
	}
864
865
866
867
868
869
870

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

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

		return $allMarker;
	}
893
894
895
896
897
898
899
900
901
902
903

	/**
	 * 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'
		);
	}
904
}