MailTemplateService.php 13 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
300
301
302
303
				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
304
			}
305
			$this->setIgnoreMailQueue(TRUE);
Torsten Oppermann's avatar
Torsten Oppermann committed
306
307
308
			$this->setMarkers($previewMarker);
		}

309
		/** @var StandaloneView $emailView */
310
		$emailView = $this->objectManager->get(StandaloneView::class);
311

312
313
		if (!isset($defaultTemplateContent)) {
			$emailView->setTemplateSource($template->getContent());
314
			$subject = $template->getSubject();
315
316
		} else {
			$emailView->setTemplateSource($defaultTemplateContent);
317
318
319
320
321
322
323
324
325
326

			$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
				);
			}
327
		}
328
		$this->mailMessage->setSubject($subject);
329

330
		$emailView->assignMultiple($this->markers);
331
		$emailBody = $emailView->render();
332

333
334
335
		// 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);
336

337
		if ($this->ignoreMailQueue) {
338
			$this->addMailToMailQueue($subject, $emailBody, $this->priority, TRUE);
339
			$this->mailMessage->setBody($emailBody, 'text/html');
340
			$this->mailMessage->send();
341
		} else {
342
			$this->addMailToMailQueue($subject, $emailBody, $this->priority);
343
		}
344
345

		return TRUE;
346
347
348
	}

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

367
		$mailRepository = $this->objectManager->get(MailRepository::class);
368
		$mailRepository->add($mail);
369
		$this->persistenceManager->persistAll();
370
	}
371
372
373

	/**
	 * @param array $registerArray
374
	 * @return void
375
	 */
376
	public static function setRegisterArray(array $registerArray) {
377
378
379
380
		self::$registerArray = $registerArray;
	}

	/**
381
	 * @param string $toAddresses
382
383
	 * @return MailTemplateService
	 */
384
385
386
	public function setToAddresses($toAddresses) {
		$this->toAddresses = $toAddresses;
		$this->mailMessage->setTo($toAddresses);
387
388
389
390
		return $this;
	}

	/**
391
	 * @param string $fromAddress
392
393
	 * @return MailTemplateService
	 */
394
	public function setFromAddress($fromAddress) {
395
396
		$this->fromAddress = $fromAddress;
		$this->mailMessage->setFrom($fromAddress);
397
398
399
400
		return $this;
	}

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

	/**
411
	 * @param string $replyToAddress
412
413
	 * @return MailTemplateService
	 */
414
	public function setReplyToAddress($replyToAddress) {
415
		$this->replyToAddress = $replyToAddress;
416
		$this->mailMessage->setReplyTo($replyToAddress);
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
452
453
454
455
		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;
	}

456
	/**
457
	 * @param array $markers
458
459
	 * @return MailTemplateService
	 */
460
461
	public function setMarkers(array $markers) {
		$this->markers = $markers;
462
463
		return $this;
	}
464
465
466
467
468
469

	/**
	 * @param array $bccAddresses
	 * @return MailTemplateService
	 */
	public function setBccAddresses(array $bccAddresses) {
470
471
		$this->bccAddresses[] = $bccAddresses;
		$this->mailMessage->setBcc($this->bccAddresses);
472
473
474
		return $this;
	}

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

	/**
	 * @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;
	}
498
499
500
501
502
503
504
505

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

506
}