MailTemplateService.php 12.9 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
	 * Send the Email
264
	 *
Torsten Oppermann's avatar
Torsten Oppermann committed
265
	 * @param boolean $isPreview
266
	 * @return boolean email was sent or added to mail queue successfully?
267
	 */
268
	public function sendEmail($isPreview = FALSE) {
269
		/** @var Template $template */
270
		$template = $this->templateRepository->findOneByTemplate(
271
			$this->extensionKey, $this->templateName, $this->language
272
		);
273

274
275
276
277
278
279
280
281
		// 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
282
				$this->setLanguage('en');
283
284
285
286
287
288
289
				// does an english default template exist ?
				if (file_exists($templatePath . $this->language . '.template.html')) {
					$this->sendEmail();
					return TRUE;
				}

				return FALSE;
290
			}
291
292
		}

Torsten Oppermann's avatar
Torsten Oppermann committed
293
294
295
296
		if ($isPreview) {
			$previewMarker = [];
			$markerArray = self::$registerArray[$this->extensionKey][$this->templateName]['marker'];
			foreach ($markerArray as $marker) {
297
298
299
				$previewMarker[$marker['marker']] = LocalizationUtility::translate(
					$marker['backend_translation_key'], $marker['extension_key']
				);
Torsten Oppermann's avatar
Torsten Oppermann committed
300
			}
301
			$this->setIgnoreMailQueue(TRUE);
Torsten Oppermann's avatar
Torsten Oppermann committed
302
303
304
			$this->setMarkers($previewMarker);
		}

305
		/** @var StandaloneView $emailView */
306
		$emailView = $this->objectManager->get(StandaloneView::class);
307

308
309
		if (!isset($defaultTemplateContent)) {
			$emailView->setTemplateSource($template->getContent());
310
			$subject = $template->getSubject();
311
312
		} else {
			$emailView->setTemplateSource($defaultTemplateContent);
313
314
315
316
317
318
319
320
321
322

			$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
				);
			}
323
		}
324
		$this->mailMessage->setSubject($subject);
325

326
		$emailView->assignMultiple($this->markers);
327
		$emailBody = $emailView->render();
328

329
330
331
		// 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);
332

333
		if ($this->ignoreMailQueue) {
334
			$this->addMailToMailQueue($subject, $emailBody, $this->priority, TRUE);
335
			$this->mailMessage->setBody($emailBody, 'text/html');
336
			$this->mailMessage->send();
337
		} else {
338
			$this->addMailToMailQueue($subject, $emailBody, $this->priority);
339
		}
340
341

		return TRUE;
342
343
344
	}

	/**
345
	 * Adds a new mail to the mail queue.
346
	 *
347
	 * @param string $subject
348
	 * @param string $emailBody
349
	 * @param int $priority
350
	 * @param bool $sent
351
	 */
352
	private function addMailToMailQueue($subject, $emailBody, $priority, $sent = FALSE) {
353
		$mail = $this->objectManager->get(Mail::class);
354
355
		$mail->setFromAddress($this->fromAddress);
		$mail->setToAddress($this->toAddresses);
356
		$mail->setMailSubject($subject);
357
		$mail->setMailBody($emailBody);
358
		$mail->setPriority($priority);
359
360
		$mail->setBccAddresses(implode(',', $this->bccAddresses));
		$mail->setCcAddresses(implode(',', $this->ccAddresses));
361
		$mail->setSent($sent);
362

363
		$mailRepository = $this->objectManager->get(MailRepository::class);
364
		$mailRepository->add($mail);
365
		$this->persistenceManager->persistAll();
366
	}
367
368
369

	/**
	 * @param array $registerArray
370
	 * @return void
371
	 */
372
	public static function setRegisterArray(array $registerArray) {
373
374
375
376
		self::$registerArray = $registerArray;
	}

	/**
377
	 * @param string $toAddresses
378
379
	 * @return MailTemplateService
	 */
380
381
382
	public function setToAddresses($toAddresses) {
		$this->toAddresses = $toAddresses;
		$this->mailMessage->setTo($toAddresses);
383
384
385
386
		return $this;
	}

	/**
387
	 * @param string $fromAddress
388
389
	 * @return MailTemplateService
	 */
390
	public function setFromAddress($fromAddress) {
391
392
		$this->fromAddress = $fromAddress;
		$this->mailMessage->setFrom($fromAddress);
393
394
395
396
		return $this;
	}

	/**
397
	 * @param array|string $ccAddresses
398
399
	 * @return MailTemplateService
	 */
400
	public function setCcAddresses($ccAddresses) {
401
402
		$this->ccAddresses[] = $ccAddresses;
		$this->mailMessage->setCc($this->ccAddresses);
403
404
405
406
		return $this;
	}

	/**
407
	 * @param string $replyToAddress
408
409
	 * @return MailTemplateService
	 */
410
	public function setReplyToAddress($replyToAddress) {
411
		$this->replyToAddress = $replyToAddress;
412
		$this->mailMessage->setReplyTo($replyToAddress);
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
		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;
	}

452
	/**
453
	 * @param array $markers
454
455
	 * @return MailTemplateService
	 */
456
457
	public function setMarkers(array $markers) {
		$this->markers = $markers;
458
459
		return $this;
	}
460
461
462
463
464
465

	/**
	 * @param array $bccAddresses
	 * @return MailTemplateService
	 */
	public function setBccAddresses(array $bccAddresses) {
466
467
		$this->bccAddresses[] = $bccAddresses;
		$this->mailMessage->setBcc($this->bccAddresses);
468
469
470
		return $this;
	}

471
472
473
474
475
476
477
478
	/**
	 * @param int $priority
	 * @return MailTemplateService
	 */
	public function setPriority($priority) {
		$this->priority = $priority;
		return $this;
	}
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493

	/**
	 * @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;
	}
494
495
496
497
498
499
500
501

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

502
}