MailTemplateService.php 13.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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
	/**
	 * 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());
			return true;
		}

		return false;
	}

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
			$this->addMailToMailQueue($subject, $emailBody, $this->priority, TRUE);
365
			$this->mailMessage->setBody($emailBody, 'text/html');
366
			$this->mailMessage->send();
367
		} else {
368
			$this->addMailToMailQueue($subject, $emailBody, $this->priority);
369
		}
370
371

		return TRUE;
372
373
374
	}

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

393
		$mailRepository = $this->objectManager->get(MailRepository::class);
394
		$mailRepository->add($mail);
395
		$this->persistenceManager->persistAll();
396
	}
397
398
399

	/**
	 * @param array $registerArray
400
	 * @return void
401
	 */
402
	public static function setRegisterArray(array $registerArray) {
403
404
405
406
		self::$registerArray = $registerArray;
	}

	/**
407
	 * @param string $toAddresses
408
409
	 * @return MailTemplateService
	 */
410
411
412
	public function setToAddresses($toAddresses) {
		$this->toAddresses = $toAddresses;
		$this->mailMessage->setTo($toAddresses);
413
414
415
416
		return $this;
	}

	/**
417
	 * @param string $fromAddress
418
	 * @param string $fromName
419
420
	 * @return MailTemplateService
	 */
421
	public function setFromAddress($fromAddress, $fromName = '') {
422
		$this->fromAddress = $fromAddress;
423
		$this->mailMessage->setFrom($fromAddress, $fromName);
424
425
426
427
		return $this;
	}

	/**
428
	 * @param array|string $ccAddresses
429
430
	 * @return MailTemplateService
	 */
431
	public function setCcAddresses($ccAddresses) {
432
433
		$this->ccAddresses[] = $ccAddresses;
		$this->mailMessage->setCc($this->ccAddresses);
434
435
436
437
		return $this;
	}

	/**
438
	 * @param string $replyToAddress
439
440
	 * @return MailTemplateService
	 */
441
	public function setReplyToAddress($replyToAddress) {
442
		$this->replyToAddress = $replyToAddress;
443
		$this->mailMessage->setReplyTo($replyToAddress);
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
		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;
	}

483
	/**
484
	 * @param array $markers
485
486
	 * @return MailTemplateService
	 */
487
488
	public function setMarkers(array $markers) {
		$this->markers = $markers;
489
490
		return $this;
	}
491
492
493
494
495
496

	/**
	 * @param array $bccAddresses
	 * @return MailTemplateService
	 */
	public function setBccAddresses(array $bccAddresses) {
497
498
		$this->bccAddresses[] = $bccAddresses;
		$this->mailMessage->setBcc($this->bccAddresses);
499
500
501
		return $this;
	}

502
503
504
505
506
507
508
509
	/**
	 * @param int $priority
	 * @return MailTemplateService
	 */
	public function setPriority($priority) {
		$this->priority = $priority;
		return $this;
	}
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

	/**
	 * @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;
	}
525
526
527
528
529
530
531
532

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

533
}