MailTemplateService.php 14.8 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
30
31
use SGalinski\SgMail\Domain\Model\Mail;
use SGalinski\SgMail\Domain\Model\Template;
use SGalinski\SgMail\Domain\Repository\MailRepository;
32
use SGalinski\SgMail\Domain\Repository\TemplateRepository;
33
34
use Swift_Attachment;
use Swift_OutputByteStream;
35
36
37
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
38
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
39
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
40
41
use TYPO3\CMS\Fluid\View\StandaloneView;

42
43
44
/**
 * MailTemplateService
 */
45
class MailTemplateService {
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	/**
	 * @var string
	 */
	const MARKER_TYPE_STRING = 'String';

	/**
	 * @var string
	 */
	const MARKER_TYPE_DATE = 'Date';

	/**
	 * @var string
	 */
	const MARKER_TYPE_INTEGER = 'Integer';

62
	/**
63
	 * @var array $registerArray
64
	 */
65
	private static $registerArray = [];
66

67
	/**
68
	 * @var array $toAddresses
69
	 */
70
	private $toAddresses = [];
71
72

	/**
73
	 * @var string $fromAddress
74
	 */
75
	private $fromAddress;
76
77

	/**
78
	 * @var array $ccAddresses
79
	 */
80
	private $ccAddresses = [];
81
82

	/**
83
	 * @var string $replyToAddress
84
	 */
85
	private $replyToAddress;
86
87

	/**
88
	 * @var string $language
89
	 */
90
	private $language;
91
92

	/**
93
	 * @var boolean $ignoreMailQueue
94
	 */
95
	private $ignoreMailQueue = FALSE;
96
97
98
99
100
101
102

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

	/**
103
	 * @var string $templateName
104
105
106
107
	 */
	private $templateName;

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

	/**
113
	 * @var array $markers
114
	 */
115
	private $markers = [];
116

117
118
119
	/**
	 * holds the TypoScript configuration for sg_mail
	 *
120
	 * @var array $tsSettings
121
122
123
	 */
	private $tsSettings = [];

124
125
126
127
128
	/**
	 * @var array $bccAddresses
	 */
	private $bccAddresses = [];

129
130
131
132
133
	/**
	 * @var int
	 */
	private $priority = Mail::PRIORITY_LOWEST;

134
135
136
	/**
	 * @var \SGalinski\SgMail\Domain\Repository\TemplateRepository
	 */
137
138
139
140
141
142
	protected $templateRepository;

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

144
145
146
147
148
	/**
	 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
	 */
	protected $objectManager;

149
150
151
152
153
	/**
	 * @var array
	 */
	private $attachments = [];

154
155
156
157
	/**
	 * MailTemplateService constructor.
	 */
	public function __construct() {
158
159
160
161
162
163
		/** @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);
164
165
		$this->tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
		$this->language = $this->tsSettings['templateDefaultLanguage'];
166
167
168
169
		/** @var TemplateRepository templateRepository */
		$this->templateRepository = $this->objectManager->get(TemplateRepository::class);
		/** @var PersistenceManager persistenceManager */
		$this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
170
171
172

		$this->fromAddress = $this->tsSettings['mail']['default']['from'];
		$this->mailMessage->setFrom($this->fromAddress);
173
		$this->bccAddresses = GeneralUtility::trimExplode(',', $this->tsSettings['mail']['default']['bcc']);
174
175
176
177
178
179
180
181
182
183
184
185
186
187
		$this->ccAddresses = GeneralUtility::trimExplode(',', $this->tsSettings['mail']['default']['cc']);

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

188
		if (count($this->bccAddresses) > 0) {
189
190
191
			$this->mailMessage->setBcc($this->bccAddresses);
		}

192
		if (count($this->ccAddresses) > 0) {
193
194
			$this->mailMessage->setCc($this->ccAddresses);
		}
195
196
	}

Torsten Oppermann's avatar
Torsten Oppermann committed
197
	/**
Torsten Oppermann's avatar
Torsten Oppermann committed
198
	 * register a template with sg_mail
Fabian Galinski's avatar
Fabian Galinski committed
199
	 *
200
201
202
	 * description and subject can now be an array i.e. with elements such as 'en' => 'english description'
	 * or an translation string used in locallang.xml
	 *
203
	 * @param string $extension
Torsten Oppermann's avatar
Torsten Oppermann committed
204
205
	 * @param string $templateName
	 * @param string $templatePath
206
	 * @param mixed $description
207
	 * @param array $markers
208
	 * @param mixed $subject
Torsten Oppermann's avatar
Torsten Oppermann committed
209
	 */
210
	public static function registerTemplate(
211
		$extension, $templateName, $templatePath, $description, array $markers, $subject
212
	) {
213
		MailTemplateService::$registerArray[$extension][$templateName] = [
214
			'templatePath' => $templatePath,
215
			'description' => $description,
216
			'marker' => $markers,
217
			'extension' => $extension,
218
			'templateName' => $templateName,
219
			'subject' => $subject
220
221
		];
	}
222

223
224
225
226
227
228
229
230
231
	/**
	 * 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') {
232
		$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang.xlf:' . $translationKey;
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252

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

253
	/**
Torsten Oppermann's avatar
Torsten Oppermann committed
254
	 * Get all registered templates
Fabian Galinski's avatar
Fabian Galinski committed
255
	 *
256
	 * @return array
257
	 */
258
259
	public static function getRegisterArray() {
		return self::$registerArray;
260
	}
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
	/**
	 * Sets the predefined values for this template, supplied by the Editor, if possible
	 * values for cc, bcc, replyTo, fromMail and fromName
	 *
	 * @param string $extensionKey
	 * @param string $templateName
	 * @param string $language
	 * @return bool
	 */
	public function loadPredefinedValuesForTemplate($extensionKey, $templateName, $language) {
		/** @var Template $template */
		$template = $this->templateRepository->findOneByTemplate(
			$this->extensionKey, $this->templateName, $this->language
		);

		if ($template !== NULL) {
			$this->setCcAddresses(explode(',', $template->getCc()));
			$this->setBccAddresses(explode(',', $template->getBcc()));
			$this->setReplyToAddress($template->getReplyTo());
			$this->setFromAddress($template->getFromMail(), $template->getFromName());
282
			return TRUE;
283
284
		}

285
		return FALSE;
286
287
	}

288
	/**
289
	 * Send the Email
290
	 *
Torsten Oppermann's avatar
Torsten Oppermann committed
291
	 * @param boolean $isPreview
292
	 * @return boolean email was sent or added to mail queue successfully?
293
	 */
294
	public function sendEmail($isPreview = FALSE) {
295
		/** @var Template $template */
296
		$template = $this->templateRepository->findOneByTemplate(
297
			$this->extensionKey, $this->templateName, $this->language
298
		);
299

300
301
302
303
304
305
306
307
		// If there is no template for this language, use the default template
		if ($template === NULL) {
			$templatePath = self::$registerArray[$this->extensionKey][$this->templateName]['templatePath'];
			$templateFile = $templatePath . $this->language . '.template.html';
			if (file_exists($templateFile)) {
				$defaultTemplateContent = file_get_contents($templatePath . $this->language . '.template.html');
			} else {
				// no language found and no default template
Torsten Oppermann's avatar
Torsten Oppermann committed
308
				$this->setLanguage('en');
309
310
311
312
313
314
315
				// does an english default template exist ?
				if (file_exists($templatePath . $this->language . '.template.html')) {
					$this->sendEmail();
					return TRUE;
				}

				return FALSE;
316
			}
317
318
		}

Torsten Oppermann's avatar
Torsten Oppermann committed
319
320
321
322
		if ($isPreview) {
			$previewMarker = [];
			$markerArray = self::$registerArray[$this->extensionKey][$this->templateName]['marker'];
			foreach ($markerArray as $marker) {
323
324
325
326
327
328
329
				if ($marker['backend_translation_key']) {
					$previewMarker[$marker['marker']] = LocalizationUtility::translate(
						$marker['backend_translation_key'], $marker['extension_key']
					);
				} else {
					$previewMarker[$marker['marker']] = $marker['value'];
				}
Torsten Oppermann's avatar
Torsten Oppermann committed
330
			}
331
			$this->setIgnoreMailQueue(TRUE);
Torsten Oppermann's avatar
Torsten Oppermann committed
332
333
334
			$this->setMarkers($previewMarker);
		}

335
		/** @var StandaloneView $emailView */
336
		$emailView = $this->objectManager->get(StandaloneView::class);
337

338
339
		if (!isset($defaultTemplateContent)) {
			$emailView->setTemplateSource($template->getContent());
340
			$subject = $template->getSubject();
341
342
		} else {
			$emailView->setTemplateSource($defaultTemplateContent);
343
344
345
346
347
348
349
350
351
352

			$subject = self::$registerArray[$this->extensionKey][$this->templateName]['subject'];
			if (is_array($subject)) {
				$subject = self::$registerArray[$this->extensionKey][$this->templateName]['subject'][$this->language];
			} else {
				$subject = LocalizationUtility::translate(
					self::$registerArray[$this->extensionKey][$this->templateName]['subject'],
					$this->extensionKey
				);
			}
353
		}
354
		$this->mailMessage->setSubject($subject);
355

356
		$emailView->assignMultiple($this->markers);
357
		$emailBody = $emailView->render();
358

359
360
361
		// 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);
362

363
		if ($this->ignoreMailQueue) {
364
365
366
			$this->addMailToMailQueue(
				$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority, TRUE
			);
367
			$this->mailMessage->setBody($emailBody, 'text/html');
368
			$this->mailMessage->send();
369
		} else {
370
			$this->addMailToMailQueue($this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority);
371
		}
372
373

		return TRUE;
374
375
376
	}

	/**
377
	 * Adds a new mail to the mail queue.
378
	 *
379
380
	 * @param string $extensionKey
	 * @param string $templateName
381
	 * @param string $subject
382
	 * @param string $emailBody
383
	 * @param int $priority
384
	 * @param bool $sent
385
	 */
386
	private function addMailToMailQueue($extensionKey, $templateName, $subject, $emailBody, $priority, $sent = FALSE) {
387
		$mail = $this->objectManager->get(Mail::class);
388
389
		$mail->setExtensionKey($extensionKey);
		$mail->setTemplateName($templateName);
390
391
		$mail->setFromAddress($this->fromAddress);
		$mail->setToAddress($this->toAddresses);
392
		$mail->setMailSubject($subject);
393
		$mail->setMailBody($emailBody);
394
		$mail->setPriority($priority);
395
396
		$mail->setBccAddresses(implode(',', $this->bccAddresses));
		$mail->setCcAddresses(implode(',', $this->ccAddresses));
397
		$mail->setSent($sent);
398

399
		$mailRepository = $this->objectManager->get(MailRepository::class);
400
		$mailRepository->add($mail);
401
		$this->persistenceManager->persistAll();
402
	}
403

404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
	/**
	 * Send a Mail from the queue, identified by its id
	 *
	 * @param int $uid
	 */
	public function sendMailFromQueue($uid) {
		$mailRepository = $this->objectManager->get(MailRepository::class);
		/** @var Mail $mailToSend */
		$mailToSend = $mailRepository->findByUid($uid)->getFirst();

		if ($mailToSend) {
			$this->mailMessage->setBody($mailToSend->getMailBody(), 'text/html');
			$this->mailMessage->setTo($mailToSend->getToAddress());
			$this->mailMessage->setFrom($mailToSend->getFromAddress(), $mailToSend->getFromName());
			$this->mailMessage->setSubject($mailToSend->getMailSubject());

			$this->mailMessage->send();
		}
	}

424
425
	/**
	 * @param array $registerArray
426
	 * @return void
427
	 */
428
	public static function setRegisterArray(array $registerArray) {
429
430
431
432
		self::$registerArray = $registerArray;
	}

	/**
433
	 * @param string $toAddresses
434
435
	 * @return MailTemplateService
	 */
436
437
438
	public function setToAddresses($toAddresses) {
		$this->toAddresses = $toAddresses;
		$this->mailMessage->setTo($toAddresses);
439
440
441
442
		return $this;
	}

	/**
443
	 * @param string $fromAddress
444
	 * @param string $fromName
445
446
	 * @return MailTemplateService
	 */
447
	public function setFromAddress($fromAddress, $fromName = '') {
448
		$this->fromAddress = $fromAddress;
449
		$this->mailMessage->setFrom($fromAddress, $fromName);
450
451
452
453
		return $this;
	}

	/**
454
	 * @param array|string $ccAddresses
455
456
	 * @return MailTemplateService
	 */
457
	public function setCcAddresses($ccAddresses) {
458
459
		$this->ccAddresses[] = $ccAddresses;
		$this->mailMessage->setCc($this->ccAddresses);
460
461
462
463
		return $this;
	}

	/**
464
	 * @param string $replyToAddress
465
466
	 * @return MailTemplateService
	 */
467
	public function setReplyToAddress($replyToAddress) {
468
		$this->replyToAddress = $replyToAddress;
469
		$this->mailMessage->setReplyTo($replyToAddress);
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
		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;
	}

509
	/**
510
	 * @param array $markers
511
512
	 * @return MailTemplateService
	 */
513
514
	public function setMarkers(array $markers) {
		$this->markers = $markers;
515
516
		return $this;
	}
517
518
519
520
521
522

	/**
	 * @param array $bccAddresses
	 * @return MailTemplateService
	 */
	public function setBccAddresses(array $bccAddresses) {
523
524
		$this->bccAddresses[] = $bccAddresses;
		$this->mailMessage->setBcc($this->bccAddresses);
525
526
527
		return $this;
	}

528
529
530
531
532
533
534
535
	/**
	 * @param int $priority
	 * @return MailTemplateService
	 */
	public function setPriority($priority) {
		$this->priority = $priority;
		return $this;
	}
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

	/**
	 * @param Swift_OutputByteStream $data
	 * @param string $path
	 * @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;
	}
551
552
553
554
555
556
557
558

	/**
	 * @return MailMessage
	 */
	public function getMailMessage() {
		return $this->mailMessage;
	}

559
}