Skip to content
Snippets Groups Projects
MailTemplateService.php 35.4 KiB
Newer Older
<?php

namespace SGalinski\SgMail\Service;

/***************************************************************
 *  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!
 ***************************************************************/
use SGalinski\SgMail\Domain\Model\Layout;
use SGalinski\SgMail\Domain\Model\Mail;
use SGalinski\SgMail\Domain\Model\Template;
Paul Ilea's avatar
Paul Ilea committed
use SGalinski\SgMail\Domain\Repository\LayoutRepository;
use SGalinski\SgMail\Domain\Repository\MailRepository;
use SGalinski\SgMail\Domain\Repository\TemplateRepository;
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Resource\ResourceFactory;
Paul Ilea's avatar
Paul Ilea committed
use TYPO3\CMS\Core\Routing\SiteMatcher;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
class MailTemplateService {
	const MARKER_TYPE_STRING = 'String';
	const MARKER_TYPE_ARRAY = 'Array';
	const MARKER_TYPE_OBJECT = 'Object';
	const MARKER_TYPE_FILE = 'File';
	const DEFAULT_LANGUAGE = 'default';
	const DEFAULT_TEMPLATE_PATH = 'Resources/Private/Templates/SgMail/';
	const CACHE_NAME = 'sg_mail_registerArrayCache';
	const CACHE_LIFETIME_IN_SECONDS = 86400;
	const REGISTER_FILE = 'Register.php';
	const CONFIG_PATH = 'Configuration/MailTemplates';
	 * @var array
	private static $templateObjectCache = [];

	/**
	 * @var array
	 */
	private static $mailObjectCache = [];
	/**
	 * @var \SGalinski\SgMail\Domain\Repository\TemplateRepository
	 */
	protected $templateRepository;
	/**
	 * @var \SGalinski\SgMail\Domain\Repository\LayoutRepository
	 */
	protected $layoutRepository;
	/**
	 * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
	 */
	protected $persistenceManager;
	/**
	 * @var \TYPO3\CMS\Extbase\Object\ObjectManager
	 */
	protected $objectManager;
	/**
	 * @var \TYPO3\CMS\Core\Resource\ResourceFactory
	 */
	protected $resourceFactory;
	 * @var string $fromAddress
	private $ccAddresses;
	 * @var string $replyToAddress
	 * @var string $language
	private $language = 'default';
	 * @var boolean $ignoreMailQueue
	private $ignoreMailQueue = FALSE;
	/**
	 * @var \TYPO3\CMS\Core\Mail\MailMessage $mailMessage
	 */
	private $mailMessage;
	/**
	 * @var string $templateName
	 */
	private $templateName;
	/**
	 * @var string $overwrittenEmailBody
	 */
	private $overwrittenEmailBody = '';
	 * @var string $extensionKey
	 */
	private $extensionKey;
	/**
	 * @var array $markers
Torsten Oppermann's avatar
Torsten Oppermann committed
	private $markers;
	/**
	 * @var array $markerLabels
	 */
	private $markerLabels;
	private $bccAddresses;
	/**
	 * @var int
	 */
	private $priority = Mail::PRIORITY_LOWEST;
	/**
	 * @var string
	 */
	private $fromName = '';
	/**
	 * @var string
	 */
	private $mailBodyToSend;
	/**
	 * @var string
	 */
	private $subjectToSend;
	 * @var string
	 */
	private $defaultFromAddress;

	/**
	 * @var string
	 */
	private $defaultFromName;

	/**
	 * MailTemplateService constructor.
	 * @param string $templateName
	 * @param string $extensionKey
	 * @param array $markers
	 * @param array $markerLabels
	 * @throws \InvalidArgumentException
	public function __construct($templateName = '', $extensionKey = '', $markers = [], $markerLabels = []) {
		$this->templateName = $templateName;
		$this->extensionKey = $extensionKey;
		$this->markers = $markers;
		$this->markerLabels = $markerLabels;
		/** @var ObjectManager objectManager */
		$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
		$this->mailMessage = $this->objectManager->get(MailMessage::class);
		$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
		$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
		$this->templateRepository = $this->objectManager->get(TemplateRepository::class);
Paul Ilea's avatar
Paul Ilea committed
		$this->layoutRepository = $this->objectManager->get(LayoutRepository::class);
		$this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
		$this->resourceFactory = $this->objectManager->get(ResourceFactory::class);
		// use defaultMailFromAddress if it is provided in LocalConfiguration.php; use the sg_mail TS setting as fallback
		if (\filter_var($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'], FILTER_VALIDATE_EMAIL)) {
			$this->fromAddress = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
			$this->defaultFromAddress = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'];
			if (!\filter_var($tsSettings['mail']['default']['from'], FILTER_VALIDATE_EMAIL)) {
				$this->fromAddress = 'noreply@example.org';
				$this->defaultFromAddress = 'noreply@example.org';
			} else {
				$this->fromAddress = $tsSettings['mail']['default']['from'];
				$this->defaultFromAddress = $tsSettings['mail']['default']['from'];
			}
		if ($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']) {
			$this->fromName = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
			$this->defaultFromName = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
		}

		$this->mailMessage->setFrom($this->fromAddress, $this->fromName);
		$this->bccAddresses = GeneralUtility::trimExplode(',', $tsSettings['mail']['default']['bcc']);
		$this->ccAddresses = GeneralUtility::trimExplode(',', $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]);
			}
		}

		if (\count($this->bccAddresses) > 0) {
		if (\count($this->ccAddresses) > 0) {
			$this->mailMessage->setCc($this->ccAddresses);
		}
	/**
	 * 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;
			case self::MARKER_TYPE_FILE:
				LocalizationUtility::translate('backend.marker.type.file', 'sg_mail');
				break;
			default:
				LocalizationUtility::translate('backend.marker.type.mixed', 'sg_mail');
		}
	}

	/**
	 * 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'): array {
		$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang.xlf:' . $translationKey;
		// 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;
	}

	/**
	 * @param string $language
	 * @return MailTemplateService
	 */
	public function setLanguage($language): MailTemplateService {
		$this->language = $language;
		return $this;
	}

	/**
	 * @param string $templateName
	 * @return MailTemplateService
	 */
	public function setTemplateName($templateName): MailTemplateService {
		$this->templateName = $templateName;
		return $this;
	}

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

	/**
	 * @param array $markers
	 * @return MailTemplateService
	 */
	public function addMarkers(array $markers): MailTemplateService {
		$this->setMarkers(\array_merge($this->markers, $markers));
		return $this;
	}

	/**
	 * @param array $markers
	 * @return MailTemplateService
	 */
	public function setMarkers(array $markers): MailTemplateService {
		$this->markers = $markers;
		foreach ($markers as $key => $currentMarker) {
			if (!\is_array($currentMarker) || !isset($currentMarker['markerLabel'])) {
				continue;
			}
			$this->markerLabels[$key] = $currentMarker['markerLabel'];
		}

		return $this;
	}

	/**
	 * @param int $priority
	 * @return MailTemplateService
	 */
	public function setPriority($priority): MailTemplateService {
		$this->priority = $priority;
		return $this;
	}

	/**
	 * Adds a file resource as attachment
	 *
	 * @throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
	public function addFileResourceAttachment(
		FileReference $fileReference = NULL, File $file = NULL
	): MailTemplateService {
		if (!$file) {
			if (!$fileReference) {
				return $this;
			}

			$originalResource = $fileReference->getOriginalResource();
			if (!$originalResource) {
				return $this;
			}

			$file = $originalResource->getOriginalFile();
			if (!$file) {
				return $this;
			}
		}

		$coreFileReferenceMailFile = $this->resourceFactory->createFileReferenceObject(
			[
				'table_local' => 'sys_file',
				'uid' => uniqid('NEW_MAIL', TRUE)
			]
		);

		$newFileReference = GeneralUtility::makeInstance(FileReference::class);
		$newFileReference->setOriginalResource($coreFileReferenceMailFile);

		$this->markers[] = $newFileReference;
		return $this;
	}

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

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

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

	/**
	 * @param string $subject
	 */
	public function setSubject(string $subject) {
	/**
	 * Set preview markers for the template editor
	 *
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
	 */
	public function setPreviewMarkers() {
		$previewMarker = [];

		// get default template content from register array
		$registerService = GeneralUtility::makeInstance(RegisterService::class);
		/** @var array $markerArray */
		$markerArray = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['marker'];

		foreach ($markerArray as $marker) {
			$markerPath = GeneralUtility::trimExplode('.', $marker['marker']);
			$temporaryMarkerArray = [];
			foreach (\array_reverse($markerPath) as $index => $markerPathSegment) {
				if ($index === 0) {
					if ($marker['markerLabel']) {
						$markerPathSegment = $marker['markerLabel'];
					}

					if ($marker['backend_translation_key']) {
						$temporaryMarkerArray[$markerPathSegment] = LocalizationUtility::translate(
							$marker['backend_translation_key'], $marker['extension_key']
						);
					} else {
						$temporaryMarkerArray[$markerPathSegment] = $marker['value'];
					}
				} else {
					$temporaryMarkerArray = [$markerPathSegment => $temporaryMarkerArray];
				}
			}
			/** @noinspection SlowArrayOperationsInLoopInspection */
			$previewMarker = \array_merge_recursive($previewMarker, $temporaryMarkerArray);
		}
		$this->setMarkers($previewMarker);
	}

	 * Send the Email
	 * @param bool $isPreview
	 * @param Template|null $template
	 * @return bool email was sent or added to mail queue successfully?
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
	 * @throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
	 * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
	public function sendEmail($isPreview = FALSE, $isNewsletter = FALSE): bool {
		if ($isPreview) { //TODO: remove this from here
			$this->setIgnoreMailQueue(TRUE);
		$success = FALSE;
		// Get page ID
		// TODO: this doesn't belong here. The API user needs to provide the UID
		$siteRootId = $this->getSiteRootId();
		try {
			$template = $this->getTemplate($siteRootId);
		} catch (\Exception $e) {
			return FALSE;
		}

		$registerService = GeneralUtility::makeInstance(RegisterService::class);

		// Load the values from the template if they are set
		if (!$isNewsletter && $template !== NULL) {
			$this->loadTemplateValues($template);
		}

		// get default template content from register array
		$defaultTemplateContent = $this->getDefaultTemplateContent($template, $registerService);

		// set the ToAddress if there are no placeholders in it
		// TODO: does this belong here?
		if ($template !== NULL && \filter_var($template->getToAddress(), FILTER_VALIDATE_EMAIL)) {
			$this->setToAddresses(\trim($template->getToAddress()));
		}

		$this->parseValuesForMail($template, $registerService, $defaultTemplateContent, $siteRootId);

		$mail = $this->addMailToMailQueue(
			$this->extensionKey, $this->templateName, $this->getSubjectToSend(), $this->getMailBodyToSend(),
			$this->priority,
			0, 0, $this->language, $siteRootId
		);
		self::$mailObjectCache[$mail->getUid()] = $mail; // add it to cache to avoid extra DB queries
		if ($this->ignoreMailQueue) {
			$success = $this->sendMailFromQueue($mail->getUid());
		}

		//TODO: this can be avoided if the sending logic is decoupled from this function
		if ($isPreview) {
			$mailRepository = $this->objectManager->get(MailRepository::class);
			$mailRepository->remove($mail);
			$this->persistenceManager->persistAll();
		}

		return $success;
	}

	/**
	 * @param boolean $ignoreMailQueue
	 * @return MailTemplateService
	 */
	public function setIgnoreMailQueue($ignoreMailQueue): MailTemplateService {
		$this->ignoreMailQueue = $ignoreMailQueue;
		return $this;
	}

	/**
	 * Get site root ID
	 *
	 * @return int
	 */
	public function getSiteRootId(): int {
		$pageUid = $this->getPageUid();
		return BackendService::getSiteRoot($pageUid);
	 * Gets the current PageUid
	protected function getPageUid(): int {
		if (TYPO3_MODE === 'FE') {
			/** @var TypoScriptFrontendController $typoscriptFrontendController */
			$typoscriptFrontendController = $GLOBALS['TSFE'];
			$pageUid = (int) $typoscriptFrontendController->id;
		} else {
			$pageUid = (int) GeneralUtility::_GP('id');
		}

			$pageUid = $this->getAnyRootPageUid();
		}
		return $pageUid;
	}

	/**
	 * Gets the page uid of any root page in the page tree
	 *
	 * @return int
	 */
	private function getAnyRootPageUid() {
		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
			'pages'
		);
		$rootPageRows = $queryBuilder->select('*')
			->from('pages')
			->where(
				$queryBuilder->expr()->eq(
					'is_siteroot', 1
			)
			->andWhere(
				$queryBuilder->expr()->eq(
					'hidden', 0
		if ($rootPageRows && \count($rootPageRows)) {
			$pageUid = (int) $rootPageRows[0]['uid'];
	/**
	 * Get the template object
	 *
	 * @param int $siteRootId
	 * @return null|object|Template|FALSE
	 * @throws \Exception
	 */
	private function getTemplate($siteRootId) {
		$isTemplateBlacklisted = self::isTemplateBlacklisted($this->extensionKey, $this->templateName, $siteRootId);
		if ($isTemplateBlacklisted) {
			throw new \Exception('The template is blacklisted');
		$templateHash = $this->getTemplateHash($this->extensionKey, $this->templateName, $siteRootId, $this->language);
		if (isset(self::$templateObjectCache[$templateHash])
			&& self::$templateObjectCache[$templateHash] instanceof Template) {
			return self::$templateObjectCache[$templateHash];
		}
		$template = $this->templateRepository->findOneByTemplate(
			$this->extensionKey, $this->templateName, $this->language, $siteRootId
		if ($template === NULL) {
			$template = $this->templateRepository->findOneByTemplate(
				$this->extensionKey, $this->templateName, 'default', $siteRootId
			);
		}
		self::$templateObjectCache[$templateHash] = $template;
	/**
	 * Checks if a template is blacklisted for a given siteroot id
	 *
	 * @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 {
		$nonBlacklistedTemplates = BackendService::getNonBlacklistedTemplates($siteRootId);
		if ($nonBlacklistedTemplates[$extensionKey]) {
			return $nonBlacklistedTemplates[$extensionKey][$templateName] ? FALSE : TRUE;
		}

		return TRUE;
	}

	/**
	 * Get the hash for the object cache
	 *
	 * @param $extensionKey
	 * @param $templateName
	 * @param $siteRootId
	 * @param $languageId
	 * @return string
	 */
	private function getTemplateHash($extensionKey, $templateName, $siteRootId, $languageId) {
		return md5($extensionKey . '_' . $templateName . '_' . $siteRootId . '_' . $languageId);
	}

	/**
	 * use all values from the given template
	 *
	 * @param Template $template
	 */
	private function loadTemplateValues(Template $template) {
		$fromName = \trim($template->getFromName());
		if ($fromName === '') {
			$fromName = $this->fromName;
		}
		if ($fromName === '' && $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']) {
			$fromName = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
		}

		$fromMail = $this->getValidFromMail(\trim($template->getFromMail()));
		// The setters check if the value is empty or not
		$this->setFromAddress($fromMail, $fromName);
		$this->setCcAddresses($template->getCc());
		$this->setBccAddresses($template->getBcc());
		$this->setReplyToAddress($template->getReplyTo());
		$this->setFromName($fromName);
	}

	/**
	 * Sets the fromMail property of the mailTemplateService.
	 * Checks validity and uses all available fallbacks
	 *
	 * @param string $fromMail
	 * @return string
	 */
	private function getValidFromMail($fromMail): string {
		$fromMail = \trim($fromMail);
		if (!\filter_var($fromMail, FILTER_VALIDATE_EMAIL)) {
			$fromMail = $this->fromAddress;
		}
		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';
			}
		}

		return $fromMail;
	}

	/**
	 * @param string $fromAddress
	 * @param string $fromName
	 * @return MailTemplateService
	 */
	public function setFromAddress($fromAddress, $fromName = ''): MailTemplateService {
		if ($fromAddress) {
			$this->fromAddress = $fromAddress;
			$this->mailMessage->setFrom($fromAddress, $fromName);
		}

		return $this;
	}

	/**
	 * @param string $ccAddresses
	 * @return MailTemplateService
	 */
	public function setCcAddresses($ccAddresses): MailTemplateService {
		if ($ccAddresses) {
			$this->ccAddresses = $ccAddresses;
			$this->mailMessage->setCc(GeneralUtility::trimExplode(',', $this->ccAddresses));
		}

		return $this;
	}

	/**
	 * @param string $bccAddresses
	 * @return MailTemplateService
	 */
	public function setBccAddresses($bccAddresses): MailTemplateService {
		if ($bccAddresses) {
			$this->bccAddresses = $bccAddresses;
			$this->mailMessage->setBcc(GeneralUtility::trimExplode(',', $this->bccAddresses));
		}

		return $this;
	}

	/**
	 * @param string $replyToAddress
	 * @return MailTemplateService
	 */
	public function setReplyToAddress($replyToAddress): MailTemplateService {
		if ($replyToAddress) {
			$this->replyToAddress = $replyToAddress;
			$this->mailMessage->setReplyTo($replyToAddress);
		}

		return $this;
	}

	/**
	 * @param string $fromName
	 */
	public function setFromName($fromName) {
		$this->fromName = $fromName;
	}

	/**
	 * Get the default content for this template
	 *
	 * @param Template|null $template
	 * @param RegisterService $registerService
	 * @return bool|false|string
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
	 */
	protected function getDefaultTemplateContent($template, $registerService) {
		$defaultTemplateContent =
			$registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['templateContent'];
		// If there is no template for this language, use the default template
		if ($template === NULL && $defaultTemplateContent === NULL) {
			$templatePath =
				$registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['templatePath'];

			// only standard template file is considered since version 4.1
			$defaultTemplateFile = $templatePath . 'template.html';
			if (\file_exists($defaultTemplateFile)) {
				$defaultTemplateContent = \file_get_contents($defaultTemplateFile);
			} else {
				// 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);
		return $defaultTemplateContent;
	}
	/**
	 * @param string $toAddresses
	 * @return MailTemplateService
	 */
	public function setToAddresses($toAddresses): MailTemplateService {
		$normalizedToAddresses = trim(preg_replace('~\x{00a0}~iu', ' ', $toAddresses));
		$this->toAddresses = $normalizedToAddresses;

		$addressesArray = GeneralUtility::trimExplode(',', $normalizedToAddresses, TRUE);
		if (\count($addressesArray) > 1) {
			$normalizedToAddresses = $addressesArray;
		}
		$this->mailMessage->setTo($normalizedToAddresses);
		return $this;
	}

	 * Sets the values to send the mail with from the template or register service
	 *
	 * @param Template|null $template
	 * @param RegisterService $registerService
	 * @param string $defaultTemplateContent
	 * @param int $siteRootId
	 * @param boolean $isNewsletter
	 * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
		$template, RegisterService $registerService, $defaultTemplateContent,
		/** @var StandaloneView $emailView */
		$emailView = $this->objectManager->get(StandaloneView::class);
		$emailView->assignMultiple($this->markers);
Torsten Oppermann's avatar
Torsten Oppermann committed
		$emailView->assign('all_fields', $this->getAllMarker($this->markers));
		//TODO: make this as the lines below the next block
		$overwrittenEmailBody = $this->getOverwrittenEmailBody();
		$overwrittenSubject = '';
		if ($this->subject !== '' && $this->subject !== NULL) {
			$overwrittenSubject = $this->subject;
		}

		if ($template !== NULL) {
			$subject = $this->parseMarkers(
				trim(empty($overwrittenSubject) ? $template->getSubject() : $overwrittenSubject),
				$emailView
			$layoutId = $template->getLayout();
			$templateContent = $template->getContent();
			$this->setSubjectToSend($subject);
			$subject = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['subject'];
			if (\is_array($subject)) {
				$subject = \trim(
					$registerService->getRegisterArray()
					[$this->extensionKey][$this->templateName]['subject'][$this->language]
			$subject = $this->parseMarkers(
				(empty($overwrittenSubject) ? $subject : $overwrittenSubject),
				$emailView
			);
			$layoutId = 0;
			$templateContent = $defaultTemplateContent;
		}
		$this->setSubjectToSend($subject);
		$this->mailMessage->setSubject($subject);
			$this->setFromName($this->parseMarkers($this->fromName, $emailView));
			$this->setFromAddress($this->parseMarkers($this->fromAddress, $emailView));
			$this->setReplyToAddress($this->parseMarkers($this->replyToAddress, $emailView));
		if ($this->ccAddresses) {
			$this->setCcAddresses($this->parseMarkers($this->ccAddresses, $emailView));
			$this->setBccAddresses($this->parseMarkers($this->bccAddresses, $emailView));
			$this->setToAddresses($this->parseMarkers($this->toAddresses, $emailView));
		}

		// reset template source back to default
		$emailView->setTemplateSource(
			empty($overwrittenEmailBody) ? $templateContent : $overwrittenEmailBody
		// 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);
		$layout = $this->getLayoutSource($layoutId, $siteRootId);
		$emailHTMLHead = '';
		if ($layout) {
			$emailHTMLHead = $layout->getHeadContent();
			$emailBody = \str_replace('###CONTENT###', $emailBody, $layout->getContent());
		}
		$this->mailBodyToSend = '<html><head>' . $emailHTMLHead . '</head><body>' . $emailBody . '</body></html>';
	 * Get a single variable containing a list of all markers
	 * @param array $markers
	 * @return string
	private function getAllMarker(array $markers): string {
		$allMarker = '';
		foreach ($markers as $key => $value) {
			if (\array_key_exists($key, $this->markerLabels) && $this->markerLabels[$key] !== NULL) {
				$key = $this->markerLabels[$key];
			}
			if (\is_string($value)) {
				$allMarker .= $key . ': ' . $value . PHP_EOL;
			} elseif (\is_array($value)) {
				foreach ($value as $innerKey => $innerValue) {
					$allMarker .= $key . '.' . $innerKey . ': ' . $innerValue . PHP_EOL;
				}
			} elseif (\is_bool($value)) {
				$valueAsString = $value ? 'true' : 'false';
				$allMarker .= $key . ': ' . $valueAsString . PHP_EOL;
			} elseif (\is_object($value)) {
				if (\method_exists($value, '__toString')) {
					$allMarker .= $key . ': ' . $value->__toString() . PHP_EOL;
				}
			}
		return $allMarker;
	}
	/**
	 * @return string
	 */
	public function getOverwrittenEmailBody(): string {
		return $this->overwrittenEmailBody;
	}
	/**
	 * @param string $overwrittenEmailBody
	 */
	public function setOverwrittenEmailBody(string $overwrittenEmailBody) {
		$this->overwrittenEmailBody = $overwrittenEmailBody;
	}
	/**
	 * Parses markers in an email View.
	 * !!! CHANGES THE SOURCE PATH AND IT SHOULD BE RESET BACK TO THE ORIGINAL!!!
	 *
	 * @param string $text
	 * @param StandaloneView $emailView
	 * @return mixed
	 */
	protected function parseMarkers($text, $emailView) {
		$text = (string) $text;
		if (strpos($text, '{') !== FALSE) {
			$emailView->setTemplateSource($text);
			return $emailView->render();