Skip to content
Snippets Groups Projects
Commit b7984100 authored by Stefan Galinski's avatar Stefan Galinski :video_game:
Browse files

Merge branch 'new_version_4_1' into 'master'

New version 4 1

See merge request !3
parents 284119d3 7adf9692
No related branches found
No related tags found
1 merge request!3New version 4 1
Showing
with 1602 additions and 853 deletions
...@@ -52,9 +52,12 @@ class SendMailCommandController extends CommandController { ...@@ -52,9 +52,12 @@ class SendMailCommandController extends CommandController {
* *
* @param int $sendCount * @param int $sendCount
* @return void * @return void
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
*/ */
public function runSendMailsCommand($sendCount = 50) { public function runSendMailsCommand($sendCount = 50) {
$mailsToSend = $this->mailRepository->findMailsToSend($sendCount); $mailsToSend = $this->mailRepository->findMailsToSend($sendCount);
foreach ($mailsToSend as $mailToSend) { foreach ($mailsToSend as $mailToSend) {
/** @var Mail $mailToSend */ /** @var Mail $mailToSend */
$fromAddress = $mailToSend->getFromAddress(); $fromAddress = $mailToSend->getFromAddress();
...@@ -64,7 +67,9 @@ class SendMailCommandController extends CommandController { ...@@ -64,7 +67,9 @@ class SendMailCommandController extends CommandController {
$mailSubject = $mailToSend->getMailSubject(); $mailSubject = $mailToSend->getMailSubject();
$mailBody = $mailToSend->getMailBody(); $mailBody = $mailToSend->getMailBody();
$mailToSend->setSent(TRUE); $mailToSend->setSendingTime(time());
$mailToSend->setLastSendingTime(time());
$this->mailRepository->update($mailToSend); $this->mailRepository->update($mailToSend);
if (empty($fromAddress) || empty($toAddress) || empty($mailSubject)) { if (empty($fromAddress) || empty($toAddress) || empty($mailSubject)) {
continue; continue;
......
<?php <?php
namespace SGalinski\SgMail\Controller; namespace SGalinski\SgMail\Controller;
/*************************************************************** /***************************************************************
...@@ -69,20 +70,16 @@ class MailController extends ActionController { ...@@ -69,20 +70,16 @@ class MailController extends ActionController {
/** /**
* Show template Selection and enable content input + mail preview * Show template Selection and enable content input + mail preview
* *
* @param string $selectedTemplate * @param array $parameters
* @param string $selectedExtension
* @param string $selectedLanguageLeft
* @param string $selectedLanguageRight
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
* @throws \BadFunctionCallException
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/ */
public function indexAction( public function indexAction(array $parameters = []) {
$selectedTemplate = NULL, $selectedExtension = NULL, $selectedLanguageLeft = NULL, $pid = (int) GeneralUtility::_GP('id');
$selectedLanguageRight = NULL
) {
$siteRootId = BackendService::getSiteRoot((int) GeneralUtility::_GP('id'));
if (!($this->session instanceof PhpSession)) { if (!($this->session instanceof PhpSession)) {
$this->session = $this->objectManager->get(PhpSession::class); $this->session = $this->objectManager->get(PhpSession::class);
...@@ -96,89 +93,72 @@ class MailController extends ActionController { ...@@ -96,89 +93,72 @@ class MailController extends ActionController {
$this->redirect('empty'); $this->redirect('empty');
} }
$languages = BackendService::getLanguages(); if ($parameters['selectedTemplate'] === NULL || $parameters['selectedTemplate'] === '') {
$parameters['selectedExtension'] = key($registerArray);
$this->view->assign('languages', $languages); $parameters['selectedTemplate'] = key($registerArray[$parameters['selectedExtension']]);
$this->view->assign('templates', MailTemplateService::getRegisterArray());
// get language selection or read from cache or get default
$selectedLanguages = BackendService::getSelectedLanguages(
$selectedLanguageLeft, $selectedLanguageRight, $this->session, $languages
);
if ($selectedTemplate === NULL || $selectedTemplate === '') {
$selectedExtension = key($registerArray);
$selectedTemplate = key($registerArray[$selectedExtension]);
} }
$selectedTemplates = BackendService::getSelectedTemplates( $languages = BackendService::getLanguages();
$selectedExtension, $selectedTemplate, $selectedLanguages, $this->session, $siteRootId
$templatesFromDb = BackendService::getSelectedTemplates(
$parameters['selectedExtension'], $parameters['selectedTemplate'], $languages,
$pid
); );
if ($selectedTemplates['left'] instanceof Template) { // if no templates are in the db, get the default from the files
$this->view->assign('contentLeft', $selectedTemplates['left']->getContent()); $templates = [];
$this->view->assign('fromNameLeft', $selectedTemplates['left']->getFromName()); $subject = $registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['subject'];
$this->view->assign('fromMailLeft', $selectedTemplates['left']->getFromMail()); /** @var Template $template */
$this->view->assign('ccLeft', $selectedTemplates['left']->getCc()); foreach ($templatesFromDb as $key => $template) {
$this->view->assign('bccLeft', $selectedTemplates['left']->getBcc()); if ($template === NULL) {
$this->view->assign('replyToLeft', $selectedTemplates['left']->getReplyTo()); $defaultTemplatePath = $registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['templatePath'];
} else { $defaultTemplateFile = $defaultTemplatePath . $key . '.' . 'template.html';
$defaultTemplatePath = $registerArray[$selectedExtension][$selectedTemplate]['templatePath']; $fallbackTemplateFile = $defaultTemplatePath . 'template.html';
$defaultTemplateFile = $defaultTemplatePath . $selectedLanguages['left'] . '.' . 'template.html';
if (file_exists($defaultTemplateFile)) { $templateFromFile = new Template();
$this->view->assign('contentLeft', file_get_contents($defaultTemplateFile)); $templateFromFile->setLanguage($key);
$templates[$key] = $templateFromFile;
if (file_exists($defaultTemplateFile)) {
$templateFromFile->setContent(file_get_contents($defaultTemplateFile));
$templateFromFile->setSubject($subject);
} else {
// set subject from register array
$templateFromFile->setSubject(LocalizationUtility::translate($subject, $this->extensionName));
if (file_exists($fallbackTemplateFile)) {
$templateFromFile->setContent(file_get_contents($fallbackTemplateFile));
}
}
} else {
$templates[$key] = $template;
$template->setIsOverwritten(TRUE);
} }
} }
if ($selectedTemplates['right'] instanceof Template) { // calculating optimal column width for the view
$this->view->assign('contentRight', $selectedTemplates['right']->getContent()); $colspace = 4;
$this->view->assign('fromNameRight', $selectedTemplates['right']->getFromName()); $templateCount = count($templates);
$this->view->assign('fromMailRight', $selectedTemplates['right']->getFromMail()); if ($templateCount % 2 === 0 && $templateCount <= 4) {
$this->view->assign('ccRight', $selectedTemplates['right']->getCc()); $colspace = 6;
$this->view->assign('bccRight', $selectedTemplates['right']->getBcc()); } elseif ($templateCount === 1) {
$this->view->assign('replyToRight', $selectedTemplates['right']->getReplyTo()); $colspace = 12;
} else {
$defaultTemplatePath = $registerArray[$selectedExtension][$selectedTemplate]['templatePath'];
$defaultTemplateFile = $defaultTemplatePath . $selectedLanguages['right'] . '.' . 'template.html';
if (file_exists($defaultTemplateFile)) {
$this->view->assign('contentRight', file_get_contents($defaultTemplateFile));
}
} }
$subject = $registerArray[$selectedExtension][$selectedTemplate]['subject']; $this->view->assign('colspace', $colspace);
$this->view->assign('languageTemplates', $templates);
if (is_array($subject)) { $this->view->assign('languageLabels', BackendService::getLanguageLabels($languages));
$this->view->assign( $this->view->assign('templates', MailTemplateService::getRegisterArray());
'subjectLeft', $selectedTemplates['left'] !== NULL ? $selectedTemplates['left']->getSubject() :
$registerArray[$selectedExtension][$selectedTemplate]['subject'][$selectedLanguages['left']]
);
$this->view->assign(
'subjectRight', $selectedTemplates['right'] !== NULL ? $selectedTemplates['right']->getSubject() :
$registerArray[$selectedExtension][$selectedTemplate]['subject'][$selectedLanguages['right']]
);
} else {
$translatedSubjects = BackendService::getTranslatedTemplateSubject(
$subject, $selectedExtension, $selectedLanguages
);
$this->view->assign(
'subjectLeft', $selectedTemplates['left'] !== NULL ? $selectedTemplates['left']->getSubject() :
$translatedSubjects['left']
);
$this->view->assign( $templateDescription = $registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['description'];
'subjectRight', $selectedTemplates['right'] !== NULL ? $selectedTemplates['right']->getSubject() :
$translatedSubjects['right']
);
}
$templateDescription = $registerArray[$selectedExtension][$selectedTemplate]['description'];
if (is_array($templateDescription)) { if (is_array($templateDescription)) {
$templateDescription = $templateDescription[$selectedLanguages['left']]; if ($languages[0]['isocode']) {
$templateDescription = $templateDescription[$languages[0]['isocode']];
}
} else { } else {
$templateDescription = LocalizationUtility::translate( $templateDescription = LocalizationUtility::translate(
$templateDescription, $selectedExtension $templateDescription, $parameters['selectedExtension']
); );
} }
...@@ -186,167 +166,118 @@ class MailController extends ActionController { ...@@ -186,167 +166,118 @@ class MailController extends ActionController {
$pageUid = (int) GeneralUtility::_GP('id'); $pageUid = (int) GeneralUtility::_GP('id');
$pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1)); $pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1));
if ($pageInfo) { if ($pageInfo && $pageInfo['is_siteroot'] === '1') {
$this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
$this->docHeaderComponent->setMetaInformation($pageInfo);
BackendService::makeButtons($this->docHeaderComponent, $this->request);
$this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
$this->view->assign('templateDescription', $templateDescription); $this->view->assign('templateDescription', $templateDescription);
$this->view->assign('selectedTemplate', $registerArray[$selectedExtension][$selectedTemplate]); $this->view->assign(
$this->view->assign('selectedTemplateKey', $selectedTemplate); 'selectedTemplate', $registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]
$this->view->assign('selectedExtensionKey', $selectedExtension); );
$this->view->assign('selectedLanguageLeft', $selectedLanguages['left']); $this->view->assign('selectedTemplateKey', $parameters['selectedTemplate']);
$this->view->assign('selectedLanguageRight', $selectedLanguages['right']); $this->view->assign('selectedExtensionKey', $parameters['selectedExtension']);
$this->view->assign('mode', 'editor'); $this->view->assign('mode', 'editor');
} else {
$this->view->assign('pages', BackendService::getPages());
} }
$this->view->assign('typo3Version', VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version)); $this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
} $this->docHeaderComponent->setMetaInformation($pageInfo);
BackendService::makeButtons($this->docHeaderComponent, $this->request);
/** $this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
* Save content (left & right) $this->view->assign('typo3Version', VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version));
* if left & right is the same language, the right content will apply only if its another language $this->view->assign('beUserMail', $GLOBALS['BE_USER']->user['email']);
*
* @param string $contentLeft // get the default language label and pass it to the view
* @param string $contentRight $languageService = $GLOBALS['LANG'];
* @param string $selectedExtension $pageTsConfig = BackendUtility::getPagesTSconfig($pageUid);
* @param string $selectedTemplate if (VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version) >= 8000000) {
* @param string $selectedLanguageLeft $defaultLanguageLabel = $languageService->sL(
* @param string $selectedLanguageRight 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage'
* @param string $subjectLeft );
* @param string $subjectRight } else {
* @param string $fromNameLeft $defaultLanguageLabel = $languageService->sL(
* @param string $fromMailLeft 'lll:EXT:lang/locallang_mod_web_list.xlf:defaultLanguage'
* @param string $ccLeft
* @param string $bccLeft
* @param string $replyToLeft
* @param string $fromNameRight
* @param string $fromMailRight
* @param string $ccRight
* @param string $bccRight
* @param string $replyToRight
* @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
*/
public function saveAction(
$contentLeft = NULL, $contentRight = NULL, $selectedExtension = NULL, $selectedTemplate = NULL,
$selectedLanguageLeft = NULL, $selectedLanguageRight = NULL, $subjectLeft = NULL, $subjectRight = NULL,
$fromNameLeft = NULL, $fromMailLeft = NULL, $ccLeft = NULL, $bccLeft = NULL, $replyToLeft = NULL,
$fromNameRight = NULL, $fromMailRight = NULL, $ccRight = NULL, $bccRight = NULL, $replyToRight = NULL
) {
$this->saveTemplate(
$selectedExtension, $selectedTemplate, $selectedLanguageLeft, $contentLeft, $subjectLeft,
$fromNameLeft, $fromMailLeft, $ccLeft, $bccLeft, $replyToLeft
);
if ($selectedLanguageLeft !== $selectedLanguageRight) {
$this->saveTemplate(
$selectedExtension, $selectedTemplate, $selectedLanguageRight, $contentRight, $subjectRight,
$fromNameRight, $fromMailRight, $ccRight, $bccRight, $replyToRight
); );
} }
$message = LocalizationUtility::translate('backend.success', 'sg_mail'); if (isset($pageTsConfig['mod.']['SHARED.']['defaultLanguageLabel'])) {
$this->addFlashMessage($message, '', FlashMessage::OK); $defaultLanguageLabel = $pageTsConfig['mod.']['SHARED.']['defaultLanguageLabel'];
$arguments = $this->request->getArguments(); }
$this->redirect('index', NULL, NULL, $arguments);
$this->view->assign('defaultLanguageLabel', $defaultLanguageLabel);
} }
/** /**
* Save or update the template in the DB, depending if it already exists or not * send a test email to a given address
* redirect to index action
* *
* @param string $selectedExtension * @param array $parameters
* @param string $selectedTemplate
* @param string $selectedLanguage
* @param string $selectedContent
* @param string $selectedSubject
* @param string $selectedFromName
* @param string $selectedFromMail
* @param string $selectedCc
* @param string $selectedBcc
* @param string $selectedReplyTo
* @return Template $template
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
* @throws \BadFunctionCallException
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/ */
private function saveTemplate( public function sendTestMailAction(array $parameters = []) {
$selectedExtension, $selectedTemplate, $selectedLanguage, $selectedContent, $selectedSubject, foreach ((array) $parameters['templates'] as $parameter) {
$selectedFromName, $selectedFromMail, $selectedCc, $selectedBcc, $selectedReplyTo $ccAddresses = GeneralUtility::trimExplode(',', $parameter['cc']);
) { if (count($ccAddresses) > 0) {
$siteRootId = BackendService::getSiteRoot((int) GeneralUtility::_GP('id'));
foreach ($ccAddresses as $ccAddress) {
/** @var Template $template */ if (!filter_var($ccAddress, FILTER_VALIDATE_EMAIL) && trim($ccAddress) !== '') {
$template = $this->templateRepository->findOneByTemplate( $message = LocalizationUtility::translate('backend.error_cc', 'sg_mail');
$selectedExtension, $selectedTemplate, $selectedLanguage, $siteRootId $this->addFlashMessage($message, '', FlashMessage::WARNING);
);
$arguments = $this->request->getArguments();
$this->redirect('index', NULL, NULL, $arguments);
}
}
}
$templateAlreadyExists = TRUE; $bccAddresses = GeneralUtility::trimExplode(',', $parameter['bcc']);
$objectManager = GeneralUtility::makeInstance(ObjectManager::class); if (count($bccAddresses) > 0) {
if ($template === NULL) { foreach ($bccAddresses as $bccAddress) {
$templateAlreadyExists = FALSE; if (!filter_var($bccAddress, FILTER_VALIDATE_EMAIL) && trim($bccAddress) !== '') {
$template = $objectManager->get(Template::class); $message = LocalizationUtility::translate('backend.error_bcc', 'sg_mail');
$this->addFlashMessage($message, '', FlashMessage::WARNING);
$arguments = $this->request->getArguments();
$this->redirect('index', NULL, NULL, $arguments);
}
}
}
} }
$template->setExtensionKey($selectedExtension); foreach ((array) $parameters['templates'] as $key => $template) {
$template->setTemplateName($selectedTemplate); BackendService::saveTemplate(
$template->setLanguage($selectedLanguage); (int) GeneralUtility::_GP('id'), $parameters['selectedExtension'], $parameters['selectedTemplate'],
$template->setContent($selectedContent); $key, $template
$template->setSubject($selectedSubject); );
$template->setFromName($selectedFromName);
$template->setFromMail($selectedFromMail);
$template->setCc($selectedCc);
$template->setBcc($selectedBcc);
$template->setReplyTo($selectedReplyTo);
$template->setSiteRootId($siteRootId);
if ($templateAlreadyExists) {
$this->templateRepository->update($template);
} else {
$this->templateRepository->add($template);
} }
return $template; $message = LocalizationUtility::translate('backend.success', 'sg_mail');
} $this->addFlashMessage($message, '', FlashMessage::OK);
if (!filter_var($parameters['emailAddress'], FILTER_VALIDATE_EMAIL)) {
$arguments = $this->request->getArguments();
$this->redirect('index', NULL, NULL, $arguments);
}
/**
* send a test email to a given address
* redirect to index action
*
* @param string $emailAddress
* @param string $selectedTemplateKey
* @param string $selectedExtensionKey
* @param string $selectedLanguageLeft
* @param string $selectedLanguageRight
* @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
*/
public function sendTestMailAction(
$emailAddress, $selectedExtensionKey, $selectedTemplateKey, $selectedLanguageLeft, $selectedLanguageRight
) {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class); $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var \SGalinski\SgMail\Service\MailTemplateService $mailTemplateService */ /** @var \SGalinski\SgMail\Service\MailTemplateService $mailTemplateService */
$mailTemplateService = $objectManager->get(MailTemplateService::class); $mailTemplateService = $objectManager->get(
$mailTemplateService->setLanguage($selectedLanguageLeft); MailTemplateService::class, $parameters['selectedTemplate'], $parameters['selectedExtension']
$mailTemplateService->setToAddresses($emailAddress); );
$mailTemplateService->setFromAddress('noreply@example.org'); $mailIsSend = FALSE;
$mailTemplateService->setTemplateName($selectedTemplateKey);
$mailTemplateService->setExtensionKey($selectedExtensionKey); foreach ((array) $parameters['templates'] as $key => $template) {
$mailIsSend = $mailTemplateService->sendEmail(TRUE); $mailTemplateService->setLanguage($key);
$mailTemplateService->setToAddresses($parameters['emailAddress']);
if ($selectedLanguageRight !== $selectedLanguageLeft) { $mailTemplateService->setFromAddress($template['fromMail']);
/** @var \SGalinski\SgMail\Service\MailTemplateService $mailTemplateService */ $mailTemplateService->setTemplateName($parameters['selectedTemplate']);
$mailTemplateService = $objectManager->get(MailTemplateService::class); $mailTemplateService->setExtensionKey($parameters['selectedExtension']);
$mailTemplateService->setLanguage($selectedLanguageRight);
$mailTemplateService->setToAddresses($emailAddress);
$mailTemplateService->setFromAddress('noreply@example.org');
$mailTemplateService->setTemplateName($selectedTemplateKey);
$mailTemplateService->setExtensionKey($selectedExtensionKey);
$mailIsSend = $mailTemplateService->sendEmail(TRUE); $mailIsSend = $mailTemplateService->sendEmail(TRUE);
} }
...@@ -374,13 +305,12 @@ class MailController extends ActionController { ...@@ -374,13 +305,12 @@ class MailController extends ActionController {
* *
* @param string $template * @param string $template
* @param string $extensionKey * @param string $extensionKey
* @param string $language
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
*/ */
public function resetAction($template, $extensionKey, $language = '') { public function resetAction($template, $extensionKey) {
$this->templateRepository->deleteTemplate($extensionKey, $template, $language); $this->templateRepository->deleteTemplate($extensionKey, $template);
$message = LocalizationUtility::translate('backend.template_reset', 'sg_mail'); $message = LocalizationUtility::translate('backend.template_reset', 'sg_mail');
$this->addFlashMessage($message, '', FlashMessage::OK); $this->addFlashMessage($message, '', FlashMessage::OK);
......
<?php <?php
namespace SGalinski\SgMail\Controller; namespace SGalinski\SgMail\Controller;
/*************************************************************** /***************************************************************
...@@ -60,51 +61,102 @@ class QueueController extends ActionController { ...@@ -60,51 +61,102 @@ class QueueController extends ActionController {
/** /**
* @param string $selectedTemplate * @param string $selectedTemplate
* @param string $selectedExtension * @param string $selectedExtension
* @param array $filters
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @throws \BadFunctionCallException
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/ */
public function indexAction($selectedTemplate = NULL, $selectedExtension = NULL) { public function indexAction($selectedTemplate = NULL, $selectedExtension = NULL, array $filters = []) {
$registerArray = MailTemplateService::getRegisterArray(); $filterTemplate = $_POST['filterTemplate'];
$filters['filterExtension'] = $filterTemplate;
$filters['filterTemplate'] = $filterTemplate;
if ($_POST['filterTemplate'] !== '') {
$extensionTemplateFilterArray = explode('###', $filterTemplate);
$filters['filterExtension'] = $extensionTemplateFilterArray[0];
$filters['filterTemplate'] = $extensionTemplateFilterArray[1];
}
$this->view->assign('selectedTemplateFilter', $filters['filterTemplate']);
$this->view->assign('selectedExtensionFilter', $filters['filterExtension']);
$registerArray = MailTemplateService::getRegisterArray();
if ($selectedTemplate === NULL || $selectedTemplate === '') { if ($selectedTemplate === NULL || $selectedTemplate === '') {
$selectedExtension = key($registerArray); $selectedExtension = key($registerArray);
$selectedTemplate = key($registerArray[$selectedExtension]); $selectedTemplate = key($registerArray[$selectedExtension]);
} }
$siteRootId = BackendService::getSiteRoot((int) GeneralUtility::_GP('id')); $pageUid = (int) GeneralUtility::_GP('id');
$queue = $this->mailRepository->findAllEntries($selectedExtension, $selectedTemplate, $siteRootId); $queue = $this->mailRepository->findAllEntries($pageUid, 0, $filters);
// create doc header component // create doc header component
$pageUid = (int) GeneralUtility::_GP('id');
$pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1)); $pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1));
if ($pageInfo && $pageInfo['is_siteroot'] === '1') {
if ($pageInfo) {
$this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
$this->docHeaderComponent->setMetaInformation($pageInfo);
$this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
BackendService::makeButtons($this->docHeaderComponent, $this->request);
$this->view->assign('selectedTemplateKey', $selectedTemplate); $this->view->assign('selectedTemplateKey', $selectedTemplate);
$this->view->assign('selectedExtensionKey', $selectedExtension); $this->view->assign('selectedExtensionKey', $selectedExtension);
$this->view->assign('templates', $registerArray); $this->view->assign('templates', $registerArray);
$this->view->assign('queue', $queue);
$this->view->assign('templatesFilter', BackendService::getTemplatesForFilter());
$this->view->assign('languages', BackendService::getLanguagesForFilter());
$this->view->assign('mode', 'queue'); $this->view->assign('mode', 'queue');
if (!$filters['filterSent']) {
$filters['filterSent'] = 0;
}
$this->view->assign('filters', $filters);
$this->view->assign('queue', $queue);
$this->view->assign(
'filterFields', [
BackendService::SENDER_FILTER_OPTION => LocalizationUtility::translate(
'backend.filter.from', 'SgMail'
),
BackendService::RECIPIENT_FILTER_OPTION => LocalizationUtility::translate(
'backend.filter.to', 'SgMail'
),
BackendService::SUBJECT_FILTER_OPTION => LocalizationUtility::translate(
'backend.filter.subject', 'SgMail'
),
BackendService::MAILTEXT_FILTER_OPTION => LocalizationUtility::translate(
'backend.filter.mailtext', 'SgMail'
),
BackendService::CC_FILTER_OPTION => LocalizationUtility::translate('backend.filter.cc', 'SgMail'),
BackendService::BCC_FILTER_OPTION => LocalizationUtility::translate('backend.filter.bcc', 'SgMail'),
BackendService::FROM_NAME_FILTER_OPTION => LocalizationUtility::translate(
'backend.filter.from_name', 'SgMail'
),
BackendService::REPLY_TO_NAME_FILTER_OPTION => LocalizationUtility::translate(
'backend.filter.reply_to', 'SgMail'
),
]
);
} else {
$this->view->assign('pages', BackendService::getPages());
} }
$this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
$this->docHeaderComponent->setMetaInformation($pageInfo);
$this->view->assign('docHeader', $this->docHeaderComponent->docHeaderContent());
BackendService::makeButtons($this->docHeaderComponent, $this->request);
$this->view->assign('typo3Version', VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version)); $this->view->assign('typo3Version', VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version));
} }
/** /**
* send or resend a mail in the queue * send or resend a mail in the queue
* *
* @param int $uid * @param int $uid
* @param string $selectedTemplate
* @param string $selectedExtension
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException * @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
*/ */
public function sendMailAction($uid) { public function sendMailAction($uid, $selectedTemplate, $selectedExtension) {
$mailService = new MailTemplateService(); $mailService = new MailTemplateService();
$mailService->sendMailFromQueue($uid); $mailService->sendMailFromQueue($uid);
...@@ -113,4 +165,24 @@ class QueueController extends ActionController { ...@@ -113,4 +165,24 @@ class QueueController extends ActionController {
$arguments = $this->request->getArguments(); $arguments = $this->request->getArguments();
$this->redirect('index', NULL, NULL, $arguments); $this->redirect('index', NULL, NULL, $arguments);
} }
/**
* Download the queue data as a csv file, respecting the filter settings
*
* @param array $filters
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @throws \InvalidArgumentException
*/
public function exportAction(array $filters = []) {
$exportString = BackendService::getCsvFromQueue($filters);
header('Content-Type: application/force-download');
header('Content-Transfer-Encoding: Binary');
header('Content-Disposition: attachment; filename="export.csv"');
header('Content-Length: ' . strlen($exportString));
echo $exportString;
exit(0);
}
} }
...@@ -40,9 +40,9 @@ class Mail extends AbstractEntity { ...@@ -40,9 +40,9 @@ class Mail extends AbstractEntity {
const PRIORITY_HIGHEST = 200; const PRIORITY_HIGHEST = 200;
/** /**
* @var int * @var string
*/ */
protected $siteRootId = 0; protected $language = '';
/** /**
* @var string * @var string
...@@ -64,11 +64,6 @@ class Mail extends AbstractEntity { ...@@ -64,11 +64,6 @@ class Mail extends AbstractEntity {
*/ */
protected $fromAddress = ''; protected $fromAddress = '';
/**
* @var bool
*/
protected $sent = FALSE;
/** /**
* @var int * @var int
*/ */
...@@ -109,6 +104,11 @@ class Mail extends AbstractEntity { ...@@ -109,6 +104,11 @@ class Mail extends AbstractEntity {
*/ */
protected $sendingTime = 0; protected $sendingTime = 0;
/**
* @var int
*/
protected $lastSendingTime = 0;
/** /**
* @return string * @return string
*/ */
...@@ -169,21 +169,6 @@ class Mail extends AbstractEntity { ...@@ -169,21 +169,6 @@ class Mail extends AbstractEntity {
$this->fromAddress = $fromAddress; $this->fromAddress = $fromAddress;
} }
/**
* @return bool
*/
public function getSent() {
return $this->sent;
}
/**
* @param bool $sent
* @return void
*/
public function setSent($sent) {
$this->sent = ($sent === TRUE);
}
/** /**
* @return int * @return int
*/ */
...@@ -294,20 +279,34 @@ class Mail extends AbstractEntity { ...@@ -294,20 +279,34 @@ class Mail extends AbstractEntity {
* @param int $sendingTime * @param int $sendingTime
*/ */
public function setSendingTime($sendingTime) { public function setSendingTime($sendingTime) {
$this->sendingTime = $sendingTime; $this->sendingTime = (int) $sendingTime;
} }
/** /**
* @return int * @return int
*/ */
public function getSiteRootId() { public function getLastSendingTime() {
return $this->siteRootId; return $this->lastSendingTime;
}
/**
* @param int $sendingTime
*/
public function setLastSendingTime($sendingTime) {
$this->lastSendingTime = (int) $sendingTime;
}
/**
* @return string
*/
public function getLanguage() {
return $this->language;
} }
/** /**
* @param int $siteRootId * @param string $language
*/ */
public function setSiteRootId($siteRootId) { public function setLanguage($language) {
$this->siteRootId = (int) $siteRootId; $this->language = $language;
} }
} }
...@@ -32,11 +32,6 @@ use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; ...@@ -32,11 +32,6 @@ use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
* Template domain model * Template domain model
*/ */
class Template extends AbstractEntity { class Template extends AbstractEntity {
/**
* @var int
*/
protected $siteRootId = 0;
/** /**
* @var string * @var string
*/ */
...@@ -87,6 +82,16 @@ class Template extends AbstractEntity { ...@@ -87,6 +82,16 @@ class Template extends AbstractEntity {
*/ */
protected $replyTo = ''; protected $replyTo = '';
/**
* @var string
*/
protected $toAddress = '';
/**
* @var boolean
*/
protected $isOverwritten = FALSE;
/** /**
* @return string * @return string
*/ */
...@@ -228,16 +233,30 @@ class Template extends AbstractEntity { ...@@ -228,16 +233,30 @@ class Template extends AbstractEntity {
} }
/** /**
* @return int * @return bool
*/
public function getIsOverwritten() {
return $this->isOverwritten;
}
/**
* @param bool $isOverwritten
*/
public function setIsOverwritten($isOverwritten) {
$this->isOverwritten = (bool) $isOverwritten;
}
/**
* @return string
*/ */
public function getSiteRootId() { public function getToAddress() {
return $this->siteRootId; return $this->toAddress;
} }
/** /**
* @param int $siteRootId * @param string $toAddress
*/ */
public function setSiteRootId($siteRootId) { public function setToAddress($toAddress) {
$this->siteRootId = (int) $siteRootId; $this->toAddress = $toAddress;
} }
} }
...@@ -26,6 +26,7 @@ namespace SGalinski\SgMail\Domain\Repository; ...@@ -26,6 +26,7 @@ namespace SGalinski\SgMail\Domain\Repository;
* This copyright notice MUST APPEAR in all copies of the script! * This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/ ***************************************************************/
use SGalinski\SgMail\Service\BackendService;
use TYPO3\CMS\Extbase\Persistence\Generic\Query; use TYPO3\CMS\Extbase\Persistence\Generic\Query;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
...@@ -33,6 +34,9 @@ use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; ...@@ -33,6 +34,9 @@ use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
* Repository for the Mail object * Repository for the Mail object
*/ */
class MailRepository extends AbstractRepository { class MailRepository extends AbstractRepository {
const SENT = '1';
const NOT_SENT = '2';
/** /**
* Returns all mails that are still not sent ordered by priority. * Returns all mails that are still not sent ordered by priority.
* *
...@@ -53,21 +57,109 @@ class MailRepository extends AbstractRepository { ...@@ -53,21 +57,109 @@ class MailRepository extends AbstractRepository {
/** /**
* Find all mails (sent & unsent) for extension key and template name * Find all mails (sent & unsent) for extension key and template name
* *
* @param string $extensionKey * @param int $pid
* @param string $templateName
* @param int $siteroot
* @param int $limit * @param int $limit
* @param array $filters
* @return array|QueryResultInterface * @return array|QueryResultInterface
* @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
*/ */
public function findAllEntries($extensionKey, $templateName, $siteroot = 0, $limit = NULL) { public function findAllEntries($pid = 0, $limit = NULL, array $filters = []) {
$query = $this->createQuery(); $query = $this->createQuery();
if ($limit) { if ($limit) {
$query->setLimit($limit); $query->setLimit($limit);
} }
$constraintsAnd[] = $query->equals('extension_key', $extensionKey); if ($filters['filterExtension'] && $filters['filterExtension'] !== 0
$constraintsAnd[] = $query->equals('template_name', $templateName); && $filters['filterExtension'] !== '0' && $filters['filterExtension'] !== ''
$constraintsAnd[] = $query->equals('site_root_id', (int) $siteroot); ) {
$constraintsAnd[] = $query->equals('extension_key', $filters['filterExtension']);
}
if ($filters['filterTemplate'] && $filters['filterTemplate'] !== 0
&& $filters['filterTemplate'] !== '0' && $filters['filterTemplate'] !== ''
) {
$constraintsAnd[] = $query->equals('template_name', $filters['filterTemplate']);
}
// if this language is no in the sys lang table, then include it with the default lang
if ($filters['filterLanguage'] === 'default') {
foreach (BackendService::getLanguages() as $lang) {
$constraintsAnd[] = $query->logicalNot($query->equals('language', $lang['isocode']));
}
} else {
if ($filters['filterLanguage'] && $filters['filterLanguage'] !== 0
&& $filters['filterLanguage'] !== '0' && $filters['filterLanguage'] !== ''
) {
$constraintsAnd[] = $query->equals('language', $filters['filterLanguage']);
}
}
$constraintsOr = [];
$search = '%' . $filters['filterSearch'] . '%';
if ($filters['filterFields'] && trim('' !== $filters['filterFields'])) {
foreach ($filters['filterFields'] as $field) {
switch ($field) {
case BackendService::SENDER_FILTER_OPTION :
$constraintsOr[] = $query->like('from_address', $search);
break;
case BackendService::RECIPIENT_FILTER_OPTION :
$constraintsOr[] = $query->like('to_address', $search);
break;
case BackendService::SUBJECT_FILTER_OPTION :
$constraintsOr[] = $query->like('mail_subject', $search);
break;
case BackendService::MAILTEXT_FILTER_OPTION :
$constraintsOr[] = $query->like('mail_body', $search);
break;
case BackendService::CC_FILTER_OPTION :
$constraintsOr[] = $query->like('cc_addresses', $search);
break;
case BackendService::BCC_FILTER_OPTION :
$constraintsOr[] = $query->like('bcc_addresses', $search);
break;
case BackendService::FROM_NAME_FILTER_OPTION :
$constraintsOr[] = $query->like('from_name', $search);
break;
case BackendService::REPLY_TO_NAME_FILTER_OPTION :
$constraintsOr[] = $query->like('reply_to', $search);
break;
}
}
} else { // if nothing selected, search in all fields
$constraintsOr[] = $query->like('from_address', $search);
$constraintsOr[] = $query->like('to_address', $search);
$constraintsOr[] = $query->like('mail_subject', $search);
$constraintsOr[] = $query->like('mail_body', $search);
$constraintsOr[] = $query->like('cc_addresses', $search);
$constraintsOr[] = $query->like('bcc_addresses', $search);
$constraintsOr[] = $query->like('from_name', $search);
$constraintsOr[] = $query->like('reply_to', $search);
}
$constraintsAnd[] = $query->logicalOr($constraintsOr);
$fromTime = strtotime($filters['filterFromDate']);
if ($fromTime) {
$constraintsAnd[] = $query->greaterThanOrEqual('last_sending_time', $fromTime);
}
$toTime = strtotime($filters['filterToDate']);
if ($toTime) {
$constraintsAnd[] = $query->lessThanOrEqual('last_sending_time', $toTime);
}
if ($filters['filterSent']) {
switch ($filters['filterSent']) {
case self::SENT:
$constraintsAnd[] = $query->greaterThan('last_sending_time', 0);
break;
case self::NOT_SENT:
$constraintsAnd[] = $query->equals('last_sending_time', 0);
break;
}
}
$constraintsAnd[] = $query->equals('pid', (int) $pid);
$query->setOrderings(['tstamp' => Query::ORDER_DESCENDING]); $query->setOrderings(['tstamp' => Query::ORDER_DESCENDING]);
return $query->matching($query->logicalAnd($constraintsAnd))->execute(TRUE); return $query->matching($query->logicalAnd($constraintsAnd))->execute(TRUE);
......
...@@ -38,11 +38,11 @@ class TemplateRepository extends AbstractRepository { ...@@ -38,11 +38,11 @@ class TemplateRepository extends AbstractRepository {
* @param string $extensionKey * @param string $extensionKey
* @param string $templateName * @param string $templateName
* @param string $language * @param string $language
* @param int $siteRoot * @param int $pid
* *
* @return Template * @return Template
*/ */
public function findOneByTemplate($extensionKey, $templateName, $language, $siteRoot = 0) { public function findOneByTemplate($extensionKey, $templateName, $language, $pid = 0) {
$query = $this->createQuery(); $query = $this->createQuery();
$querySettings = $this->objectManager->get(Typo3QuerySettings::class); $querySettings = $this->objectManager->get(Typo3QuerySettings::class);
...@@ -51,7 +51,7 @@ class TemplateRepository extends AbstractRepository { ...@@ -51,7 +51,7 @@ class TemplateRepository extends AbstractRepository {
$constraintsAnd[] = $query->equals('extension_key', $extensionKey); $constraintsAnd[] = $query->equals('extension_key', $extensionKey);
$constraintsAnd[] = $query->equals('template_name', $templateName); $constraintsAnd[] = $query->equals('template_name', $templateName);
$constraintsAnd[] = $query->equals('language', $language); $constraintsAnd[] = $query->equals('language', $language);
$constraintsAnd[] = $query->equals('site_root_id', (int) $siteRoot); $constraintsAnd[] = $query->equals('pid', (int) $pid);
$query->matching( $query->matching(
$query->logicalAnd($constraintsAnd) $query->logicalAnd($constraintsAnd)
...@@ -67,18 +67,15 @@ class TemplateRepository extends AbstractRepository { ...@@ -67,18 +67,15 @@ class TemplateRepository extends AbstractRepository {
* *
* @param $extensionKey * @param $extensionKey
* @param $templateName * @param $templateName
* @param $language
*/ */
public function deleteTemplate($extensionKey, $templateName, $language) { public function deleteTemplate($extensionKey, $templateName) {
/** @var $databaseConnection DatabaseConnection */ /** @var $databaseConnection DatabaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB']; $databaseConnection = $GLOBALS['TYPO3_DB'];
$tableName = 'tx_sgmail_domain_model_template'; $tableName = 'tx_sgmail_domain_model_template';
$where = 'extension_key = ' . $databaseConnection->fullQuoteStr($extensionKey, $tableName); $where = 'extension_key = ' . $databaseConnection->fullQuoteStr($extensionKey, $tableName);
$where.= ' AND template_name = ' . $databaseConnection->fullQuoteStr($templateName, $tableName); $where.= ' AND template_name = ' . $databaseConnection->fullQuoteStr($templateName, $tableName);
if ($language !== '') {
$where.= ' AND language = ' . $databaseConnection->fullQuoteStr($language, $tableName);
}
$databaseConnection->exec_DELETEquery($tableName, $where); $databaseConnection->exec_DELETEquery($tableName, $where);
} }
} }
<?php
namespace SGalinski\SgMail\Example;
/***************************************************************
* 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\Service\RegisterInterface;
/**
* Example Registration for a Template
*
* @package SGalinski\SgMail\Example
*/
class Register implements RegisterInterface {
/**
* @var array
*/
private $markers = [];
/**
* @var array
*/
private $subject = [];
/**
* @var string
*/
private $description;
/**
* the extension key
*
* @var string
*/
private $extensionKey;
/**
* a unique name for this template
*
* @var string
*/
private $templateKey;
/**
* path where the template is located
*
* @var string
*/
private $templatePath;
/**
* initialize certain values
*/
public function init() {
$templateArray = [
'firstName' => 'Max',
'lastName' => 'Mustermann'
];
$this->markers = [
[
'marker' => 'firstname',
'type' => \SGalinski\SgMail\Service\MailTemplateService::MARKER_TYPE_STRING,
'value' => 'Max',
'description' => 'The first name of the customer'
],
[
'marker' => 'lastname',
'type' => \SGalinski\SgMail\Service\MailTemplateService::MARKER_TYPE_STRING,
'value' => 'Mustermann',
'description' => 'The last name of the customer'
],
[
'marker' => 'person',
'type' => \SGalinski\SgMail\Service\MailTemplateService::MARKER_TYPE_ARRAY,
'value' => $templateArray,
'description' => 'An array with the customer data',
'usage' => '{person.firstName}, {person.lastName}'
]
];
$this->description = 'Description about the Template';
$this->subject = [
'en' => 'The english subject text',
'de' => 'The german subject text'
];
$this->templateKey = 'notice_mail_admin';
$this->extensionKey = 'sg_sample';
}
/**
* Calls MailTemplateService registerTemplate with according values.
*/
public function registerTemplate() {
\SGalinski\SgMail\Service\MailTemplateService::registerTemplate(
$this->extensionKey, $this->templateKey, $this->templatePath, $this->description, $this->markers,
$this->subject
);
}
/**
* @return array
*/
public function getMarkers() {
return $this->markers;
}
/**
* @param array $markers
* @return RegisterInterface
*/
public function setMarkers(array $markers) {
$this->markers = $markers;
return $this;
}
/**
* @return array
*/
public function getSubject() {
return $this->subject;
}
/**
* @param array $subject
* @return RegisterInterface
*/
public function setSubject(array $subject) {
$this->subject = $subject;
return $this;
}
/**
* @return string
*/
public function getDescription() {
return $this->description;
}
/**
* @param string $description
* @return RegisterInterface
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* @return string
*/
public function getExtensionKey() {
return $this->extensionKey;
}
/**
* @param string $extensionKey
* @return RegisterInterface
*/
public function setExtensionKey($extensionKey) {
$this->extensionKey = $extensionKey;
return $this;
}
/**
* @return string
*/
public function getTemplateKey() {
return $this->templateKey;
}
/**
* @param string $templateKey
* @return RegisterInterface
*/
public function setTemplateKey($templateKey) {
$this->templateKey = $templateKey;
return $this;
}
/**
* @return string
*/
public function getTemplatePath() {
return $this->templatePath;
}
/**
* @param string $templatePath
* @return RegisterInterface
*/
public function setTemplatePath($templatePath) {
$this->templatePath = $templatePath;
return $this;
}
}
?>
\ No newline at end of file
...@@ -26,6 +26,8 @@ namespace SGalinski\SgMail\Service; ...@@ -26,6 +26,8 @@ namespace SGalinski\SgMail\Service;
* This copyright notice MUST APPEAR in all copies of the script! * This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/ ***************************************************************/
use SGalinski\SgMail\Domain\Model\Template;
use SGalinski\SgMail\Domain\Repository\MailRepository;
use SGalinski\SgMail\Domain\Repository\TemplateRepository; use SGalinski\SgMail\Domain\Repository\TemplateRepository;
use TYPO3\CMS\Backend\Template\Components\ButtonBar; use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent; use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
...@@ -34,15 +36,26 @@ use TYPO3\CMS\Core\Database\DatabaseConnection; ...@@ -34,15 +36,26 @@ use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository;
use TYPO3\CMS\Extbase\Mvc\Request; use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Lang\Domain\Repository\LanguageRepository;
/** /**
* Backend Service class * Backend Service class
*/ */
class BackendService { class BackendService {
// options for the queue search filter
const SENDER_FILTER_OPTION = 0;
const RECIPIENT_FILTER_OPTION = 1;
const SUBJECT_FILTER_OPTION = 2;
const MAILTEXT_FILTER_OPTION = 3;
const CC_FILTER_OPTION = 4;
const BCC_FILTER_OPTION = 5;
const FROM_NAME_FILTER_OPTION = 6;
const REPLY_TO_NAME_FILTER_OPTION = 7;
/** /**
* Get all pages the be user has access to * Get all pages the be user has access to
...@@ -51,6 +64,7 @@ class BackendService { ...@@ -51,6 +64,7 @@ class BackendService {
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public static function getPages() { public static function getPages() {
$out = [];
/** @var $databaseConnection DatabaseConnection */ /** @var $databaseConnection DatabaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB']; $databaseConnection = $GLOBALS['TYPO3_DB'];
$rows = $databaseConnection->exec_SELECTgetRows( $rows = $databaseConnection->exec_SELECTgetRows(
...@@ -59,7 +73,13 @@ class BackendService { ...@@ -59,7 +73,13 @@ class BackendService {
'deleted = 0 AND is_siteroot = 1' 'deleted = 0 AND is_siteroot = 1'
); );
return $rows; foreach ($rows as $row) {
$pageInfo = BackendUtility::readPageAccess($row['uid'], $GLOBALS['BE_USER']->getPagePermsClause(1));
if ($pageInfo) {
$out[] = $pageInfo;
}
}
return $out;
} }
/** /**
...@@ -119,6 +139,34 @@ class BackendService { ...@@ -119,6 +139,34 @@ class BackendService {
return $siteRoot['uid']; return $siteRoot['uid'];
} }
/**
* Get the selected templates for the selected language
*
* @param string $selectedExtension
* @param string $selectedTemplate
* @param array $languages
* @param int $pid
* @return array
* @throws \InvalidArgumentException
*/
public static function getSelectedTemplates(
$selectedExtension, $selectedTemplate, array $languages, $pid
) {
$selectedTemplates = [];
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var TemplateRepository $templateRepository */
$templateRepository = $objectManager->get(TemplateRepository::class);
foreach ($languages as $language) {
$selectedTemplates[$language['isocode']] = $templateRepository->findOneByTemplate(
$selectedExtension, $selectedTemplate, $language['isocode'], $pid
);
}
return $selectedTemplates;
}
/** /**
* get an array of all the locales for the activated languages * get an array of all the locales for the activated languages
* *
...@@ -126,123 +174,205 @@ class BackendService { ...@@ -126,123 +174,205 @@ class BackendService {
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public static function getLanguages() { public static function getLanguages() {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class); /** @var $databaseConnection DatabaseConnection */
/** @var LanguageRepository $languageRepository */ $databaseConnection = $GLOBALS['TYPO3_DB'];
$languageRepository = $objectManager->get(LanguageRepository::class); /** @var QueryResultInterface $rows */
$activatedLanguages = $languageRepository->findSelected(); $rows = $databaseConnection->exec_SELECTgetRows(
'*',
'sys_language',
'hidden = 0'
);
$languages = [];
// adding default language
$languages[] = ['isocode' => MailTemplateService::DEFAULT_LANGUAGE, 'name' => LocalizationUtility::translate(
'backend.language_default', 'SgMail'
)];
$languages = ['en']; foreach ($rows as $language) {
foreach ($activatedLanguages as $language) { $languages[] = ['isocode' => $language['language_isocode'],
$languages[] = $language->getLocale(); 'name' => $language['title']];
} }
return $languages; return $languages;
} }
/** /**
* Get the previous selected languages, the actual selection or the default * get an array of all the labels for the activated languages
* format ['left' => languagecode, 'right' => ...]
* *
* @param string $selectedLanguageLeft
* @param string $selectedLanguageRight
* @param \SGalinski\SgMail\Session\PhpSession $session
* @param array $languages * @param array $languages
* @return array * @return array
* @throws \InvalidArgumentException
*/ */
public static function getSelectedLanguages( public static function getLanguageLabels(array $languages) {
$selectedLanguageLeft, $selectedLanguageRight, $session, array $languages $languageLabels = [];
) {
$selectedLanguages = [ foreach ($languages as $language) {
'left' => $selectedLanguageLeft, $languageLabels[$language['isocode']] = $language['name'];
'right' => $selectedLanguageRight }
];
return $languageLabels;
if ($selectedLanguageLeft === NULL) { }
$selectedLanguageLeftFromSession = $session->getDataByKey('selectedLanguageLeft');
if ($selectedLanguageLeftFromSession !== NULL) { /**
$selectedLanguages['left'] = $selectedLanguageLeftFromSession; * Get the languages in an array suitable for filtering
} else { *
$selectedLanguages['left'] = $languages[0]; * @return array
* @throws \InvalidArgumentException
*/
public static function getLanguagesForFilter() {
$languages = self::getLanguages();
array_unshift($languages, ['isocode' => '', 'name' => '']);
$filterLanguages = [];
if (count($languages) > 0) {
foreach ($languages as $language) {
$filterLanguages[$language['isocode']] = $language['name'];
} }
} }
if ($selectedLanguageRight === NULL) { return $filterLanguages;
$selectedLanguageRightFromSession = $session->getDataByKey('selectedLanguageRight'); }
if ($selectedLanguageRightFromSession === NULL) {
if (isset($languages[1])) { /**
$selectedLanguages['right'] = $languages[1]; * Get the template keys in an array suitable for filtering
} else { *
$selectedLanguages['right'] = $languages[0]; * @return array
} */
} else { public static function getTemplatesForFilter() {
$selectedLanguages['right'] = $selectedLanguageRightFromSession; $registerArray = MailTemplateService::getRegisterArray();
$templates = [];
foreach ($registerArray as $extensions) {
foreach ($extensions as $template => $key) {
$templates[$key['extension']][] = $key['templateName'];
} }
} }
return $selectedLanguages; array_unshift($templates, '');
return $templates;
} }
/** /**
* Get the selected templates for the selected language * Save or update the template in the DB, depending if it already exists or not
* *
* @param int $pid
* @param string $selectedExtension * @param string $selectedExtension
* @param string $selectedTemplate * @param string $selectedTemplate
* @param array $selectedLanguages * @param string $language
* @param \SGalinski\SgMail\Session\PhpSession $session * @param array $templateData
* @param int $siteRootId * @return Template $template
* @return array
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
*/ */
public static function getSelectedTemplates( public static function saveTemplate($pid, $selectedExtension, $selectedTemplate, $language, $templateData) {
$selectedExtension, $selectedTemplate, array $selectedLanguages, &$session, $siteRootId
) {
$selectedTemplates = [];
$objectManager = GeneralUtility::makeInstance(ObjectManager::class); $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var TemplateRepository $templateRepository */ /** @var TemplateRepository $templateRepository */
$templateRepository = $objectManager->get(TemplateRepository::class); $templateRepository = $objectManager->get(TemplateRepository::class);
$session->setDataByKey('selectedLanguageLeft', $selectedLanguages['left']); /** @var Template $template */
$session->setDataByKey('selectedLanguageRight', $selectedLanguages['right']); $template = $templateRepository->findOneByTemplate(
$selectedExtension, $selectedTemplate, $language, $pid
$selectedTemplates['left'] = $templateRepository->findOneByTemplate(
$selectedExtension, $selectedTemplate, $selectedLanguages['left'], $siteRootId
);
$selectedTemplates['right'] = $templateRepository->findOneByTemplate(
$selectedExtension, $selectedTemplate, $selectedLanguages['right'], $siteRootId
); );
return $selectedTemplates; $templateAlreadyExists = TRUE;
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
if ($template === NULL) {
$templateAlreadyExists = FALSE;
$template = $objectManager->get(Template::class);
}
$template->setExtensionKey($selectedExtension);
$template->setTemplateName($selectedTemplate);
$template->setLanguage($language);
$template->setContent($templateData['content']);
$template->setSubject($templateData['subject']);
$template->setFromName($templateData['fromName']);
$template->setFromMail($templateData['fromMail']);
$template->setCc($templateData['cc']);
$template->setBcc($templateData['bcc']);
$template->setReplyTo($templateData['replyTo']);
$template->setToAddress($templateData['toAddress']);
if ($templateAlreadyExists) {
$templateRepository->update($template);
} else {
$templateRepository->add($template);
}
return $template;
} }
/** /**
* Get the translated subjects for the selected mail templates * Generate a csv string from the queues, respecting the given filters
* *
* @param $subject * @param array $filters
* @param $selectedExtension * @return string
* @param $selectedLanguages * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @return array * @throws \InvalidArgumentException
*/ */
public static function getTranslatedTemplateSubject($subject, $selectedExtension, $selectedLanguages) { public static function getCsvFromQueue(array $filters = []) {
$translatedSubjects = []; $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var MailRepository $mailRepository */
$mailRepository = $objectManager->get(MailRepository::class);
$langFile = GeneralUtility::readLLfile( $pageUid = (int) GeneralUtility::_GP('id');
'EXT:' . $selectedExtension . '/Resources/Private/Language/locallang.xlf', $selectedLanguages['left'] /** @var array $queue */
); $queue = $mailRepository->findAllEntries($pageUid, 0, $filters);
$translatedSubjectLeft = $langFile['default'][$subject][0]['target']; $totalQueueSize = count($queue);
if ($langFile[$selectedLanguages['left']][$subject][0]) { $exportString = '';
$translatedSubjectLeft = $langFile[$selectedLanguages['left']][$subject][0]['target'];
}
$translatedSubjects['left'] = $translatedSubjectLeft;
$langFile = GeneralUtility::readLLfile( if ($totalQueueSize && $queue) {
'EXT:' . $selectedExtension . '/Resources/Private/Language/locallang.xlf', $selectedLanguages['right'] $ignoreFields = ['uid', 'pid', 'tstamp',
); 'password', 'starttime', 'endtime', 'deleted', 'sent', 'priority', 'crdate', 'cruser_id', 'hidden'];
$translatedSubjectRight = $langFile['default'][$subject][0]['target']; $dateFields = ['tstamp', 'starttime', 'endtime', 'crdate'];
if ($langFile[$selectedLanguages['right']][$subject][0]) {
$translatedSubjectRight = $langFile[$selectedLanguages['right']][$subject][0]['target']; $export = [[]];
$first = TRUE;
/** @var array $mail */
foreach ($queue as $mail) {
if ($first) {
$first = FALSE;
foreach ($mail as $field => $value) {
if (!in_array($field, $ignoreFields, TRUE)) {
$label = isset($GLOBALS['TCA']['tx_sgmail_domain_model_mail']['columns'][$field]) ?
$GLOBALS['TCA']['fe_users']['columns'][$field]['label'] : '';
if (strpos($label, 'LLL:') === 0) {
$label = $GLOBALS['LANG']->sL($label);
}
$export[0][] = $label ?: $field;
}
}
}
}
$line = 1;
/** @var array $mail */
foreach ($queue as $mail) {
foreach ($mail as $field => $value) {
if (!in_array($field, $ignoreFields, TRUE)) {
if (in_array($field, $dateFields, TRUE)) {
$export[$line][] = $value ? date('d.m.Y', $value) : '';
} else {
$export[$line][] = (string) $value;
}
}
}
$line++;
}
foreach ($export as $line) {
/** @var array $line */
$fields = [];
foreach ($line as $field) {
$fields[] = '"' . $field . '"';
}
$exportString .= implode(',', $fields) . ';' . LF;
}
} }
$translatedSubjects['right'] = $translatedSubjectRight;
return $translatedSubjects; return trim(preg_replace('/\s\s+/', ' ', strip_tags($exportString)));
} }
} }
...@@ -33,12 +33,16 @@ use SGalinski\SgMail\Domain\Repository\MailRepository; ...@@ -33,12 +33,16 @@ use SGalinski\SgMail\Domain\Repository\MailRepository;
use SGalinski\SgMail\Domain\Repository\TemplateRepository; use SGalinski\SgMail\Domain\Repository\TemplateRepository;
use Swift_Attachment; use Swift_Attachment;
use Swift_OutputByteStream; use Swift_OutputByteStream;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Mail\MailMessage; use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager; use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility; use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/** /**
* MailTemplateService * MailTemplateService
...@@ -47,11 +51,10 @@ class MailTemplateService { ...@@ -47,11 +51,10 @@ class MailTemplateService {
const MARKER_TYPE_STRING = 'String'; const MARKER_TYPE_STRING = 'String';
const MARKER_TYPE_ARRAY = 'Array'; const MARKER_TYPE_ARRAY = 'Array';
const MARKER_TYPE_OBJECT = 'Object'; const MARKER_TYPE_OBJECT = 'Object';
const DEFAULT_LANGUAGE = 'default';
/** const DEFAULT_TEMPLATE_PATH = 'Resources/Private/Templates/SgMail/';
* @var array $registerArray const CACHE_NAME = 'sg_mail_registerArrayCache';
*/ const CACHE_LIFETIME_IN_SECONDS = 86400;
private static $registerArray = [];
/** /**
* @var array $toAddresses * @var array $toAddresses
...@@ -76,7 +79,7 @@ class MailTemplateService { ...@@ -76,7 +79,7 @@ class MailTemplateService {
/** /**
* @var string $language * @var string $language
*/ */
private $language; private $language = 'default';
/** /**
* @var boolean $ignoreMailQueue * @var boolean $ignoreMailQueue
...@@ -101,14 +104,7 @@ class MailTemplateService { ...@@ -101,14 +104,7 @@ class MailTemplateService {
/** /**
* @var array $markers * @var array $markers
*/ */
private $markers = []; private $markers;
/**
* holds the TypoScript configuration for sg_mail
*
* @var array $tsSettings
*/
private $tsSettings;
/** /**
* @var array $bccAddresses * @var array $bccAddresses
...@@ -120,6 +116,11 @@ class MailTemplateService { ...@@ -120,6 +116,11 @@ class MailTemplateService {
*/ */
private $priority = Mail::PRIORITY_LOWEST; private $priority = Mail::PRIORITY_LOWEST;
/**
* @var int
*/
private $pid;
/** /**
* @var string * @var string
*/ */
...@@ -143,26 +144,45 @@ class MailTemplateService { ...@@ -143,26 +144,45 @@ class MailTemplateService {
/** /**
* MailTemplateService constructor. * MailTemplateService constructor.
* *
* @param string $templateName
* @param string $extensionKey
* @param string $markers
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
public function __construct() { public function __construct($templateName = '', $extensionKey = '', $markers = '') {
$this->templateName = $templateName;
$this->extensionKey = $extensionKey;
$this->markers = $markers;
/** @var ObjectManager objectManager */ /** @var ObjectManager objectManager */
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class); $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var MailMessage mailMessage */ /** @var MailMessage mailMessage */
$this->mailMessage = $this->objectManager->get(MailMessage::class); $this->mailMessage = $this->objectManager->get(MailMessage::class);
/** @var TypoScriptSettingsService $typoScriptSettingsService */ /** @var TypoScriptSettingsService $typoScriptSettingsService */
$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class); $typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
$this->tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail'); $tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
$this->language = $this->tsSettings['templateDefaultLanguage'];
/** @var TemplateRepository templateRepository */ /** @var TemplateRepository templateRepository */
$this->templateRepository = $this->objectManager->get(TemplateRepository::class); $this->templateRepository = $this->objectManager->get(TemplateRepository::class);
/** @var PersistenceManager persistenceManager */ /** @var PersistenceManager persistenceManager */
$this->persistenceManager = $this->objectManager->get(PersistenceManager::class); $this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
$this->fromAddress = $this->tsSettings['mail']['default']['from']; // 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'];
} else {
$this->fromAddress = $tsSettings['mail']['default']['from'];
if (!filter_var($tsSettings['mail']['default']['from'], FILTER_VALIDATE_EMAIL)) {
$this->fromAddress = 'noreply@example.org';
} else {
$this->fromAddress = $tsSettings['mail']['default']['from'];
}
}
$this->mailMessage->setFrom($this->fromAddress); $this->mailMessage->setFrom($this->fromAddress);
$this->bccAddresses = GeneralUtility::trimExplode(',', $this->tsSettings['mail']['default']['bcc']);
$this->ccAddresses = GeneralUtility::trimExplode(',', $this->tsSettings['mail']['default']['cc']); $this->bccAddresses = GeneralUtility::trimExplode(',', $tsSettings['mail']['default']['bcc']);
$this->ccAddresses = GeneralUtility::trimExplode(',', $tsSettings['mail']['default']['cc']);
foreach ($this->bccAddresses as $index => $email) { foreach ($this->bccAddresses as $index => $email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
...@@ -185,59 +205,6 @@ class MailTemplateService { ...@@ -185,59 +205,6 @@ class MailTemplateService {
} }
} }
/**
* register a template with sg_mail
*
* 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
*
* @deprecated public usage of this function is deprecated. use registerByFile instead
* @param string $extension
* @param string $templateName
* @param string $templatePath
* @param mixed $description
* @param array $markers
* @param mixed $subject
* @param string $usage
*/
public static function registerTemplate(
$extension, $templateName, $templatePath, $description, array $markers, $subject, $usage = ''
) {
MailTemplateService::$registerArray[$extension][$templateName] = [
'templatePath' => $templatePath,
'description' => $description,
'marker' => $markers,
'extension' => $extension,
'templateName' => $templateName,
'subject' => $subject,
'usage' => $usage
];
}
/**
* call in extlocalconf of an extension if you have a custom register class
*
* @param RegisterInterface $fileNameWithNamespace
* @param boolean $initObject Should the object initialize itself ?
*
* @return bool
* @throws \InvalidArgumentException
*/
public static function registerByFile($fileNameWithNamespace, $initObject = TRUE) {
$registerObject = GeneralUtility::makeInstance($fileNameWithNamespace);
// check instance of interface
if (!($registerObject instanceof RegisterInterface)) {
return FALSE;
}
// object calls registerTemplate, alternative way instead of localconf call
if ($initObject) {
$registerObject->init();
}
$registerObject->registerTemplate();
return TRUE;
}
/** /**
* Return default markers for sg_mail * Return default markers for sg_mail
* *
...@@ -268,24 +235,28 @@ class MailTemplateService { ...@@ -268,24 +235,28 @@ class MailTemplateService {
return $generatedMarker; return $generatedMarker;
} }
/**
* Get all registered templates
*
* @return array
*/
public static function getRegisterArray() {
return self::$registerArray;
}
/** /**
* Send the Email * Send the Email
* *
* @param boolean $isPreview * @param boolean $isPreview
* @return boolean email was sent or added to mail queue successfully? * @return boolean email was sent or added to mail queue successfully?
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \InvalidArgumentException
* @throws \BadFunctionCallException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
*/ */
public function sendEmail($isPreview = FALSE) { public function sendEmail($isPreview = FALSE) {
$pageUid = (int) GeneralUtility::_GP('id'); if (TYPO3_MODE === 'FE') {
/** @var TypoScriptFrontendController $tsfe */
$tsfe = $GLOBALS['TSFE'];
$pageUid = $tsfe->id;
} else {
$pageUid = (int) GeneralUtility::_GP('id');
}
if ($this->pid) {
$pageUid = $this->pid;
}
$siteRootId = BackendService::getSiteRoot($pageUid); $siteRootId = BackendService::getSiteRoot($pageUid);
/** @var Template $template */ /** @var Template $template */
...@@ -293,34 +264,38 @@ class MailTemplateService { ...@@ -293,34 +264,38 @@ class MailTemplateService {
$this->extensionKey, $this->templateName, $this->language, $siteRootId $this->extensionKey, $this->templateName, $this->language, $siteRootId
); );
if ($template === NULL) {
$template = $this->templateRepository->findOneByTemplate(
$this->extensionKey, $this->templateName, 'default', $siteRootId
);
}
// if there is a template, prefer those values // if there is a template, prefer those values
if ($template) { if ($template) {
$this->loadTemplateValues($template); $this->loadTemplateValues($template);
} }
$defaultTemplateContent = NULL;
// If there is no template for this language, use the default template // If there is no template for this language, use the default template
if ($template === NULL) { 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
$this->setLanguage($this->tsSettings['templateDefaultLanguage'] ?: 'en');
// does an english default template exist ?
if (file_exists($templatePath . $this->language . '.template.html')) {
$this->sendEmail();
return TRUE;
}
$templatePath = self::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 {
return FALSE; return FALSE;
} }
} elseif (filter_var($template->getToAddress(), FILTER_VALIDATE_EMAIL)) {
$this->setToAddresses(trim($template->getToAddress()));
} }
if ($isPreview) { if ($isPreview) {
$previewMarker = []; $previewMarker = [];
/** @var array $markerArray */ /** @var array $markerArray */
$markerArray = self::$registerArray[$this->extensionKey][$this->templateName]['marker']; $markerArray = self::getRegisterArray()[$this->extensionKey][$this->templateName]['marker'];
foreach ($markerArray as $marker) { foreach ($markerArray as $marker) {
$markerPath = GeneralUtility::trimExplode('.', $marker['marker']); $markerPath = GeneralUtility::trimExplode('.', $marker['marker']);
$temporaryMarkerArray = []; $temporaryMarkerArray = [];
...@@ -334,7 +309,7 @@ class MailTemplateService { ...@@ -334,7 +309,7 @@ class MailTemplateService {
$temporaryMarkerArray[$markerPathSegment] = $marker['value']; $temporaryMarkerArray[$markerPathSegment] = $marker['value'];
} }
} else { } else {
$temporaryMarkerArray = [ $markerPathSegment => $temporaryMarkerArray]; $temporaryMarkerArray = [$markerPathSegment => $temporaryMarkerArray];
} }
} }
$previewMarker = array_merge_recursive($previewMarker, $temporaryMarkerArray); $previewMarker = array_merge_recursive($previewMarker, $temporaryMarkerArray);
...@@ -352,12 +327,13 @@ class MailTemplateService { ...@@ -352,12 +327,13 @@ class MailTemplateService {
} else { } else {
$emailView->setTemplateSource($defaultTemplateContent); $emailView->setTemplateSource($defaultTemplateContent);
$subject = self::$registerArray[$this->extensionKey][$this->templateName]['subject']; $subject = self::getRegisterArray()[$this->extensionKey][$this->templateName]['subject'];
if (is_array($subject)) { if (is_array($subject)) {
$subject = self::$registerArray[$this->extensionKey][$this->templateName]['subject'][$this->language]; $subject = self::getRegisterArray(
)[$this->extensionKey][$this->templateName]['subject'][$this->language];
} else { } else {
$subject = LocalizationUtility::translate( $subject = LocalizationUtility::translate(
self::$registerArray[$this->extensionKey][$this->templateName]['subject'], self::getRegisterArray()[$this->extensionKey][$this->templateName]['subject'],
$this->extensionKey $this->extensionKey
); );
} }
...@@ -375,13 +351,22 @@ class MailTemplateService { ...@@ -375,13 +351,22 @@ class MailTemplateService {
$this->mailMessage->setBody($emailBody, 'text/html'); $this->mailMessage->setBody($emailBody, 'text/html');
$this->mailMessage->send(); $this->mailMessage->send();
$dateTime = new DateTime(); $dateTime = new DateTime();
$this->addMailToMailQueue( $currentTimestamp = $dateTime->getTimestamp();
$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority,
$dateTime->getTimestamp(), TRUE if (!$isPreview) {
); $this->addMailToMailQueue(
$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority,
$currentTimestamp, $currentTimestamp, $this->language, $siteRootId
);
}
} else { } else {
$this->addMailToMailQueue($this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority); if (!$isPreview) {
$this->addMailToMailQueue(
$this->extensionKey, $this->templateName, $subject, $emailBody, $this->priority, 0, 0,
$this->language, $siteRootId
);
}
} }
return TRUE; return TRUE;
...@@ -396,31 +381,34 @@ class MailTemplateService { ...@@ -396,31 +381,34 @@ class MailTemplateService {
* @param string $emailBody * @param string $emailBody
* @param int $sendingTime * @param int $sendingTime
* @param int $priority * @param int $priority
* @param bool $sent * @param int $lastSendingTime
* @param string $language
* @param int $pid
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException * @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
*/ */
private function addMailToMailQueue( private function addMailToMailQueue(
$extensionKey, $templateName, $subject, $emailBody, $priority, $sendingTime = 0, $sent = FALSE $extensionKey, $templateName, $subject, $emailBody, $priority, $sendingTime = 0,
$lastSendingTime = 0, $language = self::DEFAULT_LANGUAGE, $pid = 0
) { ) {
$mail = $this->objectManager->get(Mail::class); $mail = $this->objectManager->get(Mail::class);
$mail->setPid($pid);
$mail->setExtensionKey($extensionKey); $mail->setExtensionKey($extensionKey);
$mail->setTemplateName($templateName); $mail->setTemplateName($templateName);
$mail->setLanguage($language);
$mail->setFromAddress($this->fromAddress); $mail->setFromAddress($this->fromAddress);
$mail->setFromName($this->fromName); $mail->setFromName($this->fromName);
$mail->setToAddress($this->toAddresses); $mail->setToAddress($this->toAddresses);
$mail->setMailSubject($subject); $mail->setMailSubject($subject);
$mail->setMailBody($emailBody); $mail->setMailBody($emailBody);
$mail->setPriority($priority); $mail->setPriority($priority);
$mail->setBccAddresses($this->bccAddresses); $mail->setBccAddresses($this->bccAddresses);
$mail->setCcAddresses($this->ccAddresses); $mail->setCcAddresses($this->ccAddresses);
$mail->setSent($sent);
$mail->setSendingTime($sendingTime); $mail->setSendingTime($sendingTime);
$mail->setLastSendingTime($lastSendingTime);
$mail->setReplyTo($this->replyToAddress); $mail->setReplyTo($this->replyToAddress);
$pageUid = (int) GeneralUtility::_GP('id');
$siteRootId = BackendService::getSiteRoot($pageUid);
$mail->setSiteRootId($siteRootId);
$mailRepository = $this->objectManager->get(MailRepository::class); $mailRepository = $this->objectManager->get(MailRepository::class);
$mailRepository->add($mail); $mailRepository->add($mail);
$this->persistenceManager->persistAll(); $this->persistenceManager->persistAll();
...@@ -439,9 +427,8 @@ class MailTemplateService { ...@@ -439,9 +427,8 @@ class MailTemplateService {
$mailToSend = $mailRepository->findOneByUid($uid); $mailToSend = $mailRepository->findOneByUid($uid);
if ($mailToSend) { if ($mailToSend) {
$this->mailMessage->setBody($mailToSend->getMailBody(), 'text/html'); $this->mailMessage->setBody($mailToSend->getMailBody(), 'text/html');
$this->mailMessage->setTo($mailToSend->getToAddress()); $this->mailMessage->setTo(trim($mailToSend->getToAddress()));
$this->mailMessage->setFrom($mailToSend->getFromAddress(), $mailToSend->getFromName()); $this->mailMessage->setFrom($mailToSend->getFromAddress(), $mailToSend->getFromName());
$this->mailMessage->setSubject($mailToSend->getMailSubject()); $this->mailMessage->setSubject($mailToSend->getMailSubject());
...@@ -457,30 +444,21 @@ class MailTemplateService { ...@@ -457,30 +444,21 @@ class MailTemplateService {
$this->mailMessage->setReplyTo($mailToSend->getReplyTo()); $this->mailMessage->setReplyTo($mailToSend->getReplyTo());
} }
$dateTime = new DateTime();
$mailToSend->setLastSendingTime($dateTime->getTimestamp());
$this->mailMessage->send(); $this->mailMessage->send();
$mailRepository->update($mailToSend);
if (!$mailToSend->getSent()) {
$mailToSend->setSent(TRUE);
$mailRepository->update($mailToSend);
}
} }
} }
/**
* @param array $registerArray
* @return void
*/
public static function setRegisterArray(array $registerArray) {
self::$registerArray = $registerArray;
}
/** /**
* @param string $toAddresses * @param string $toAddresses
* @return MailTemplateService * @return MailTemplateService
*/ */
public function setToAddresses($toAddresses) { public function setToAddresses($toAddresses) {
$this->toAddresses = $toAddresses; $toAddresses = preg_replace('~\x{00a0}~siu',' ', $toAddresses);
$this->mailMessage->setTo($toAddresses); $this->toAddresses = trim($toAddresses);
$this->mailMessage->setTo(trim($toAddresses));
return $this; return $this;
} }
...@@ -619,11 +597,24 @@ class MailTemplateService { ...@@ -619,11 +597,24 @@ class MailTemplateService {
* @param Template $template * @param Template $template
*/ */
private function loadTemplateValues($template) { private function loadTemplateValues($template) {
$this->setFromAddress($template->getFromMail(), $template->getFromName()); $fromName = $template->getFromName();
if ($fromName === '' && $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']) {
$fromName = $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'];
}
$fromMail = $template->getFromMail();
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';
}
}
$this->setFromAddress($fromMail, $fromName);
$this->setCcAddresses($template->getCc()); $this->setCcAddresses($template->getCc());
$this->setBccAddresses($template->getBcc()); $this->setBccAddresses($template->getBcc());
$this->setReplyToAddress($template->getReplyTo()); $this->setReplyToAddress($template->getReplyTo());
$this->setFromName($template->getFromName()); $this->setFromName($fromName);
$this->setReplyToAddress($template->getReplyTo()); $this->setReplyToAddress($template->getReplyTo());
} }
...@@ -654,4 +645,99 @@ class MailTemplateService { ...@@ -654,4 +645,99 @@ class MailTemplateService {
LocalizationUtility::translate('backend.marker.type.mixed', 'sg_mail'); LocalizationUtility::translate('backend.marker.type.mixed', 'sg_mail');
} }
} }
/**
* set the page id from which this was called
*
* @param int $pid
* @return MailTemplateService
*/
public function setPid($pid) {
$this->pid = (int) $pid;
return $this;
}
/**
* Get all registered templates
*
* @return array
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \BadFunctionCallException
* @throws \InvalidArgumentException
*/
public static function getRegisterArray() {
/** @var CacheManager $cacheManager */
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
/** @var FrontendInterface $cache */
$cache = $cacheManager->getCache(self::CACHE_NAME);
$cacheId = md5('sg_mail');
/** @var array entry */
if (($entry = $cache->get($cacheId)) === FALSE) {
$entry = self::registerExtensions();
if ($entry === NULL) {
$entry = [];
}
$cache->set($cacheId, $entry, [], self::CACHE_LIFETIME_IN_SECONDS);
}
return $entry;
}
/**
* Iterate over all installed extensions and look for sg_mail configuration files
* If found, register the template(s)
*
* @throws \BadFunctionCallException
* @return array
*/
public static function registerExtensions() {
// clear registerArray
$registerArray = [];
$extensionList = ExtensionManagementUtility::getLoadedExtensionListArray();
foreach ($extensionList as $extensionName) {
$extensionConfigDirectory = ExtensionManagementUtility::extPath($extensionName);
$extensionConfigDirectory .= '/Configuration/MailTemplates';
$configFiles = GeneralUtility::getFilesInDir($extensionConfigDirectory);
foreach ($configFiles as $configFile) {
$configArray = (include $extensionConfigDirectory . '/' . $configFile);
$extensionKey = $configArray['extension_key'];
$templateKey = $configArray['template_key'];
// transform template directory name: your_templates => YourTemplates/
$templateDirectoryParts = GeneralUtility::trimExplode('_', $configArray['template_key']);
$templateDirectory = '';
foreach ($templateDirectoryParts as $part) {
$templateDirectory .= ucfirst($part);
}
$templateDirectory .= '/';
$templatePath = ExtensionManagementUtility::extPath(
$extensionName
) . self::DEFAULT_TEMPLATE_PATH . $templateDirectory;
if ($configArray['template_path']) {
$templatePath = $configArray['template_key'];
}
$description = $configArray['description'];
$subject = $configArray['subject'];
$marker = $configArray['markers'];
$registerArray[$extensionKey][$templateKey] = [
'templatePath' => $templatePath,
'description' => $description,
'marker' => $marker,
'extension' => $extensionKey,
'templateName' => $templateKey,
'subject' => $subject
];
}
}
return $registerArray;
}
} }
...@@ -42,7 +42,7 @@ class PhpSession implements SingletonInterface { ...@@ -42,7 +42,7 @@ class PhpSession implements SingletonInterface {
*/ */
public function __construct() { public function __construct() {
session_start(); session_start();
$this->sessionKey = uniqid(); $this->sessionKey = uniqid('sgalinski', TRUE);
} }
/** /**
......
<?php
namespace SGalinski\SgMail\Updates;
/***************************************************************
* 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 TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Install\Updates\AbstractUpdate;
/**
* Makes german templates the default and former default as english templates
*/
class UpdateGermanAsDefault extends AbstractUpdate {
/**
* @var string
*/
protected $title = 'Makes german templates the default and former default as english templates. WARNING: ONLY EXECUTE THIS IF IT MAKES SENSE FOR YOUR TYPO3 INSTANCE';
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
*/
protected $objectManager;
/**
* @var string
*/
protected $table = 'tx_sgmail_domain_model_template';
/**
* Checks whether updates are required.
*
* @param string &$description The description for the update
* @return bool Whether an update is required (TRUE) or not (FALSE)
*/
public function checkForUpdate(&$description) {
$description = 'Update if there are german templates';
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
// are there sent emails ?
$where = 'language ="de"';
$result = $databaseConnection->exec_SELECTquery('*', $this->table, $where);
if ($result->num_rows > 0) {
return TRUE;
}
return !(!FALSE || $this->isWizardDone());
}
/**
* Performs the according updates.
*
* @param array &$dbQueries Queries done in this update
* @param mixed &$customMessages Custom messages
* @return bool Whether everything went smoothly or not
*/
public function performUpdate(array &$dbQueries, &$customMessages) {
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
$dbQueries = [];
$where = 'language = "de"';
$resultGerman = $databaseConnection->exec_SELECTquery('uid', $this->table, $where)->fetch_all();
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
$where = 'language = "default"';
$resultDefault = $databaseConnection->exec_SELECTquery('uid', $this->table, $where)->fetch_all();
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
/** @var array $resultGerman */
foreach ($resultGerman as $row) {
$where = 'uid = ' . $row[0];
$databaseConnection->exec_UPDATEquery($this->table, $where, ['language' => 'default']);
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
}
/** @var array $resultGerman */
foreach ($resultDefault as $row) {
$where = 'uid = ' . $row[0];
$databaseConnection->exec_UPDATEquery($this->table, $where, ['language' => 'en']);
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
}
$this->markWizardAsDone();
return TRUE;
}
}
<?php
namespace SGalinski\SgMail\Updates;
/***************************************************************
* 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\Service\BackendService;
use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Install\Updates\AbstractUpdate;
/**
* Fix all incorrect / deprecated language codes (be languages instead of sys languages) in the database
*/
class UpdateLanguages extends AbstractUpdate {
/**
* @var string
*/
protected $title = 'Find all templates & queue entries with an incorrect (be languages instead of sys languages) language code and fix it';
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
*/
protected $objectManager;
/**
* @var array
*/
protected $tables = [
'tx_sgmail_domain_model_mail', 'tx_sgmail_domain_model_template'
];
/**
* is used to map language codes. If empty the updatewizard will ignore this update
* example: you want to change en-us to en
* [
* 'en-us' => 'en'
* ]
*
* @var array
*/
protected $languageMap = [
];
/**
* Checks whether updates are required.
*
* @param string &$description The description for the update
* @return bool Whether an update is required (TRUE) or not (FALSE)
* @throws \InvalidArgumentException
*/
public function checkForUpdate(&$description) {
$upgradeNecessary = FALSE;
if (count($this->languageMap) > 0) {
$languages = BackendService::getLanguages();
$where = 'language NOT IN (';
foreach ($languages as $language) {
$where .= '"' . $language['isocode'] . '",';
}
$where = rtrim($where, ',');
$where .= ')';
$description = 'Check all the language codes in the database';
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $this->getDatabaseConnection();
foreach ($this->tables as $table) {
/** @var \mysqli_result $result */
$result = $databaseConnection->exec_SELECTquery('distinct language', $table, $where);
if ($result->num_rows > 0) {
$upgradeNecessary = TRUE;
break;
}
}
}
return !(!$upgradeNecessary || $this->isWizardDone());
}
/**
* Performs the accordant updates.
*
* @param array &$dbQueries Queries done in this update
* @param mixed &$customMessages Custom messages
* @return bool Whether everything went smoothly or not
*/
public function performUpdate(array &$dbQueries, &$customMessages) {
$dbQueries = [];
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $this->getDatabaseConnection();
foreach ($this->tables as $table) {
foreach ($this->languageMap as $origin => $target) {
$where = 'language = ' . $origin;
$databaseConnection->exec_UPDATEquery($table, $where, [
'language' => $target
]);
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
}
}
$this->markWizardAsDone();
return TRUE;
}
}
<?php
namespace SGalinski\SgMail\Updates;
/***************************************************************
* 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\Service\BackendService;
use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Install\Updates\AbstractUpdate;
/**
* Migrate template db entries to the correct root pages
*/
class UpdatePidToSiteRoot extends AbstractUpdate {
/**
* @var string
*/
protected $title = 'Find all templates & queue entries with site root and assign the correct site root id as pid. Also check if the pids are actually site roots and update them accordingly';
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
*/
protected $objectManager;
/**
* @var array
*/
protected $tables = [
'tx_sgmail_domain_model_mail', 'tx_sgmail_domain_model_template'
];
/**
* Checks whether updates are required.
*
* @param string &$description The description for the update
* @return bool Whether an update is required (TRUE) or not (FALSE)
*/
public function checkForUpdate(&$description) {
$description = 'Move site root ids to pid & update pids to their correspondent site root ids';
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
// check if site_root columns actually exist
$hasColumn = [];
foreach ($this->tables as $table) {
$hasColumn[$table] = $this->siteRootColumnExists($table);
}
// are there site root columns differing from pids?
$where = 'site_root_id <> pid';
foreach ($this->tables as $table) {
if (!$hasColumn[$table]) {
continue;
}
$result = $databaseConnection->exec_SELECTquery('*', $table, $where);
if ($result->num_rows > 0) {
return TRUE;
break;
}
}
// are the pids not belonging to site root pages ?
foreach ($this->tables as $table) {
$result = $databaseConnection->exec_SELECTquery('pid', $table, '')->fetch_all();
foreach ($result as $row) {
$siteRootId = BackendService::getSiteRoot($row[0]);
if ($siteRootId !== $row[0]) {
return TRUE;
}
}
}
return !(!FALSE || $this->isWizardDone());
}
/**
* Performs the according updates.
*
* @param array &$dbQueries Queries done in this update
* @param mixed &$customMessages Custom messages
* @return bool Whether everything went smoothly or not
*/
public function performUpdate(array &$dbQueries, &$customMessages) {
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
$dbQueries = [];
// set pids to siteroot
foreach ($this->tables as $table) {
if (!$this->siteRootColumnExists($table)) {
continue;
}
$result = $databaseConnection->exec_SELECTquery('uid, site_root_id', $table, '')->fetch_all();
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
/** @var array $result */
foreach ($result as $row) {
$where = 'uid = ' . $row[0];
$databaseConnection->exec_UPDATEquery($table, $where, ['pid' => $row[1]]);
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
}
}
// check if pid is a site root, if not update it to the nearest one
foreach ($this->tables as $table) {
$result = $databaseConnection->exec_SELECTquery('uid, pid', $table, '')->fetch_all();
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
/** @var array $result */
foreach ($result as $row) {
$siteRootId = BackendService::getSiteRoot($row[1]);
if ($siteRootId === 0) {
$siteRootId = 1;
}
if ($siteRootId !== (int) $row[1]) {
$where = 'uid = ' . $row[0];
$databaseConnection->exec_UPDATEquery($table, $where, ['pid' => $siteRootId]);
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
}
}
}
$this->markWizardAsDone();
return TRUE;
}
/**
* check if site_root columns actually exist
*
* @param $table
* @return bool
*/
private function siteRootColumnExists($table) {
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
$result = $databaseConnection->admin_get_fields($table);
foreach ($result as $column) {
if ($column['Field'] === 'site_root_id') {
return TRUE;
}
}
return FALSE;
}
}
<?php
namespace SGalinski\SgMail\Updates;
/***************************************************************
* 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 TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Install\Updates\AbstractUpdate;
/**
* Update the correct sending times (if any)
*/
class UpdateSendingTimes extends AbstractUpdate {
/**
* @var string
*/
protected $title = 'Find all sent mails and set the sending time to the tstamp field';
/**
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
*/
protected $objectManager;
/**
* @var string
*/
protected $table = 'tx_sgmail_domain_model_mail';
/**
* Checks whether updates are required.
*
* @param string &$description The description for the update
* @return bool Whether an update is required (TRUE) or not (FALSE)
*/
public function checkForUpdate(&$description) {
$description = 'Update the sending times if mails have been sent';
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
// are there sent emails ?
$where = 'sending_time > 0 AND last_sending_time = 0';
$result = $databaseConnection->exec_SELECTquery('*', $this->table, $where);
if ($result->num_rows > 0) {
return TRUE;
}
return !(!FALSE || $this->isWizardDone());
}
/**
* Performs the according updates.
*
* @param array &$dbQueries Queries done in this update
* @param mixed &$customMessages Custom messages
* @return bool Whether everything went smoothly or not
*/
public function performUpdate(array &$dbQueries, &$customMessages) {
/** @var DatabaseConnection $databaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
$dbQueries = [];
$where = 'sending_time > 0 AND last_sending_time = 0';
$result = $databaseConnection->exec_SELECTquery('uid, sending_time', $this->table, $where)->fetch_all();
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
/** @var array $result */
foreach ($result as $row) {
$where = 'uid = ' . $row[0];
$databaseConnection->exec_UPDATEquery($this->table, $where, ['last_sending_time' => $row[1]]);
$dbQueries[] = $databaseConnection->debug_lastBuiltQuery;
}
$this->markWizardAsDone();
return TRUE;
}
}
...@@ -32,21 +32,21 @@ return [ ...@@ -32,21 +32,21 @@ return [
'tstamp' => 'tstamp', 'tstamp' => 'tstamp',
'crdate' => 'crdate', 'crdate' => 'crdate',
'cruser_id' => 'cruser_id', 'cruser_id' => 'cruser_id',
'searchFields' => 'mail_subject, mail_body, to_address, from_address, from_name, bcc_addresses, cc_addresses, extension_key, template_name, site_root_id', 'searchFields' => 'mail_subject, mail_body, to_address, from_address, from_name, bcc_addresses, cc_addresses, extension_key, template_name, sending_time, last_sending_time, language',
'dividers2tabs' => TRUE, 'dividers2tabs' => TRUE,
'delete' => 'deleted', 'delete' => 'deleted',
'enablecolumns' => [ 'enablecolumns' => [
'disabled' => 'hidden', 'disabled' => 'hidden',
], ],
'default_sortby' => 'ORDER BY sent ASC, priority DESC', 'default_sortby' => 'ORDER BY priority DESC',
'iconfile' => 'EXT:sg_mail/Resources/Public/Icons/ModuleIconTCA.svg' 'iconfile' => 'EXT:sg_mail/Resources/Public/Icons/ModuleIconTCA.svg'
], ],
'interface' => [ 'interface' => [
'showRecordFieldList' => 'hidden, mail_subject, mail_body, to_address, from_address, sent, priority, from_name, bcc_addresses, cc_addresses, extension_key, template_name, site_root_id', 'showRecordFieldList' => 'hidden, mail_subject, mail_body, to_address, from_address, priority, from_name, bcc_addresses, cc_addresses, extension_key, template_name, sending_time, last_sending_time, language',
], ],
'types' => [ 'types' => [
'1' => [ '1' => [
'showitem' => 'hidden;;1, sent, priority, to_address, from_address, mail_subject, mail_body, from_name, bcc_addresses, cc_addresses, extension_key, template_name, site_root_id' 'showitem' => 'hidden;;1, priority, to_address, from_address, mail_subject, mail_body, from_name, bcc_addresses, cc_addresses, extension_key, template_name, sending_time, last_sending_time, language'
], ],
], ],
'columns' => [ 'columns' => [
...@@ -91,13 +91,6 @@ return [ ...@@ -91,13 +91,6 @@ return [
'eval' => 'required, email' 'eval' => 'required, email'
], ],
], ],
'sent' => [
'exclude' => TRUE,
'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.sent',
'config' => [
'type' => 'check',
],
],
'priority' => [ 'priority' => [
'exclude' => TRUE, 'exclude' => TRUE,
'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.priority', 'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.priority',
...@@ -151,6 +144,13 @@ return [ ...@@ -151,6 +144,13 @@ return [
'type' => 'input' 'type' => 'input'
], ],
], ],
'last_sending_time' => [
'exclude' => TRUE,
'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.last_sending_time',
'config' => [
'type' => 'input'
],
],
'reply_to' => [ 'reply_to' => [
'exclude' => TRUE, 'exclude' => TRUE,
'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.reply_to', 'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.reply_to',
...@@ -158,12 +158,12 @@ return [ ...@@ -158,12 +158,12 @@ return [
'type' => 'input' 'type' => 'input'
], ],
], ],
'site_root_id' => [ 'language' => [
'exclude' => TRUE, 'exclude' => TRUE,
'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.site_root_id', 'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_mail.language',
'config' => [ 'config' => [
'type' => 'input', 'type' => 'input',
'eval' => 'int' 'eval' => 'required, trim'
], ],
] ]
] ]
......
...@@ -33,7 +33,7 @@ return [ ...@@ -33,7 +33,7 @@ return [
'tstamp' => 'tstamp', 'tstamp' => 'tstamp',
'crdate' => 'crdate', 'crdate' => 'crdate',
'cruser_id' => 'cruser_id', 'cruser_id' => 'cruser_id',
'searchFields' => 'extension_key, template_name, language, subject, fromName, fromMail, replyTo, site_root_id', 'searchFields' => 'extension_key, template_name, language, subject, fromName, fromMail, replyTo, to_address',
'dividers2tabs' => TRUE, 'dividers2tabs' => TRUE,
'delete' => 'deleted', 'delete' => 'deleted',
'enablecolumns' => [ 'enablecolumns' => [
...@@ -43,11 +43,11 @@ return [ ...@@ -43,11 +43,11 @@ return [
'iconfile' => 'EXT:sg_mail/Resources/Public/Icons/ModuleIconTCA.svg' 'iconfile' => 'EXT:sg_mail/Resources/Public/Icons/ModuleIconTCA.svg'
], ],
'interface' => [ 'interface' => [
'showRecordFieldList' => 'extension_key, template_name, language, content, subject, fromName, fromMail, cc, bcc, replyTo, site_root_id' 'showRecordFieldList' => 'extension_key, template_name, language, content, subject, fromName, fromMail, cc, bcc, replyTo, to_address'
], ],
'types' => [ 'types' => [
'1' => [ '1' => [
'showitem' => 'hidden;;1, extension_key, template_name, language, content, subject, fromName, fromMail, cc, bcc, replyTo, site_root_id' 'showitem' => 'hidden;;1, extension_key, template_name, language, content, subject, fromName, fromMail, cc, bcc, replyTo, to_address'
], ],
], ],
'columns' => [ 'columns' => [
...@@ -134,12 +134,11 @@ return [ ...@@ -134,12 +134,11 @@ return [
'type' => 'input' 'type' => 'input'
], ],
], ],
'site_root_id' => [ 'to_address' => [
'exclude' => TRUE, 'exclude' => TRUE,
'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_template.site_root_id', 'label' => 'LLL:EXT:sg_mail/Resources/Private/Language/locallang_db.xlf:tx_sgmail_domain_model_template.toAddress',
'config' => [ 'config' => [
'type' => 'input', 'type' => 'input'
'eval' => 'int'
], ],
] ]
] ]
......
...@@ -17,54 +17,112 @@ It also supports Templates in various languages, which can be managed in the bac ...@@ -17,54 +17,112 @@ It also supports Templates in various languages, which can be managed in the bac
Additionally sg_mail provides a finisher class for the [Formhandler](https://typo3.org/extensions/repository/view/formhandler) extension, making it possible to manage its templates in the backend. Additionally sg_mail provides a finisher class for the [Formhandler](https://typo3.org/extensions/repository/view/formhandler) extension, making it possible to manage its templates in the backend.
sg_mail ist multi-site and multi-language ready.
## Usage ## Usage
### Registering your Extension ### Registering your Extension
To make sg_mail available for your extension, you have to register it inside your **ext_localconf.php** To register your extension with sg_mail, you need a **Configuration File** for each template you want to integrate.
by supplying a path string to an implementation of **SGalinski\SgMail\Service\RegisterInterface** with: It needs be a *.php* file and has to be inside the Configuration folder **typo3conf/ext/{your_extension}/Configuration** of your extension.
The naming of the file should be in upper camel case, matching your template name.
* your extension key sg_mail will automatically parse valid configuration files of all extensions within your TYPO3 instance.
* a name for the template
* the path to your default template files (template files should be named *language_code*.template.html. Example: en.template.html)
* a brief description of the template (when is it used ?)
* the template markers(placeholder variables)
* the subjects for all templates. Here you have to use an associative array language_code => subject
**Example** : Inside the file you have mandatory and optional settings you can define:
A fully working example class can be found here: **SGalinski\SgMail\Example\Register** **Mandatory**
All you need to do to get the example to work is registering your class in **ext_localconf.php** with: - extension_key
Needed to associate this template with the appropriate extension,
\SGalinski\SgMail\Service\MailTemplateService::registerByFile('SGalinski\SgMail\Example\Register');
- template_key
A unique identifier of your template.
- description
A short description of your templates usage, displayed in the backend template editor. This should be a **language label**
- subject
The default mail subject used for this Template. Here you can also provide a language label.
- markers
An array of placeholder variables. Are dynamically replaced by the appropriate values. If you don't want any markers, provide an empty array.
A marker needs to be structured as follows:
- marker
The variables name used in your templates.
- type
Here you can specify the variable type by using one of the constants in the **\SGalinski\SgMail\Service\MailTemplateService** class.
- value
An example value of this marker. Also used for previewing your mails in the backend module.
- description
A short text describing the purpose of this marker.
**Optional**
- template_path
You can provide a path to your mail template that differs from the default path with this setting.
**The template folder**
If not overwritten in your configuration file, the default location for your extensions templates is **ext/sg_example/Resources/Private/Templates/SgMail/{TemplateNameInUpperCamelCase}**.
Inside this folder you need a folder for every template you want to register. The name of the template file itself should be **template.html**
**Example:**
Your configuration file for the template "confirm_mail" should be located at **../Configuration/ConfirmMail.php**.
A possible ConfirmMail.php file could look like this:
return [
'extension_key' => 'sg_example',
'template_key' => 'confirm_mail',
'description' => 'LLL:EXT:sg_example/Resources/Private/Language/locallang.xlf:mail.confirm.description',
'subject' => 'LLL:EXT:sg_example/Resources/Private/Language/locallang.xlf:mail.confirm.subject',
'markers' => [
[
'marker' => 'username',
'type' => \SGalinski\SgMail\Service\MailTemplateService::MARKER_TYPE_STRING,
'value' => 'max.mustermann@example.org',
'description' => 'LLL:EXT:sg_energieportal/Resources/Private/Language/locallang.xlf:mail.marker.username'
],
.... // more markers
]
];
The default path to the template.html file: ext/sg_example/Resources/Private/Templates/SgMail/ConfirmMail
### Send an email with the MailTemplateService ### Send an email with the MailTemplateService
Basic Usage: Basic Usage:
1. Get an instance of MailTemplateService 1. Get an instance of MailTemplateService
2. Set all desired fields (i.e. setLanguage, setToAddresses, setTemplateName, setExtensionKey etc.) 2. Provide the **template_name**, **extension_key** and marker array in the constructor
3. Invoke the **sendEmail()** function 3. Set or override all desired fields (i.e. setLanguage, setToAddresses, setTemplateName, setExtensionKey etc.)
4. Invoke the **sendEmail()** function
Example: Example:
// get an instance of the service // get an instance of the service
/** @var MailTemplateService $mailService */ /** @var MailTemplateService $mailService */
$mailService = $this->objectManager->get(MailTemplateService::class); $mailService = $this->objectManager->get(MailTemplateService::class, 'confirm_mail', sg_example', ['username' => $username]);
// set the extension key & template name (mandatory!)
$mailService->setExtensionKey('your_extension_key');
$mailService->setTemplateName($this->settings['templateName']);
// set all the custom fields, these fields all have fallbacks from your configuration or the code
$mailService->setFromName($this->settings['fromName']); $mailService->setFromName($this->settings['fromName']);
$mailService->setFromAddress($this->settings['fromEmail']); $mailService->setFromAddress($this->settings['fromEmail']);
$mailService->setToAddresses([$emailAddress]); $mailService->setToAddresses([$emailAddress]);
$mailService->setIgnoreMailQueue(TRUE); $mailService->setIgnoreMailQueue(TRUE);
$mailService->setMarkers(['link' => $uri]);
// set the proper language for the mail // set the pageId (mandatory since version 4.0!!!)
$mailService->setPid(123);
// set the proper language for the mail (not necessary if you want the default language)
$mailService->setLanguage($GLOBALS['TSFE']->config['config']['language']); $mailService->setLanguage($GLOBALS['TSFE']->config['config']['language']);
// finally send the mail // finally send the mail
...@@ -94,6 +152,13 @@ Go to your scheduler module in the TYPO3 Backend and setup a scheduled CommandCo ...@@ -94,6 +152,13 @@ Go to your scheduler module in the TYPO3 Backend and setup a scheduled CommandCo
For more information on the TYPO3 scheduler extension read its [manual](https://docs.typo3.org/typo3cms/extensions/scheduler/Index.html). For more information on the TYPO3 scheduler extension read its [manual](https://docs.typo3.org/typo3cms/extensions/scheduler/Index.html).
## Language handling
When you provide no language to the MailService API, the default language of the TYPO3 instance is used.
This happens also if the given iso code of the language is not known (inside the **sys_lang** table).
In your template editor you have automatically all languages of your page shown.
## Using sg_mail with Formhandler ## Using sg_mail with Formhandler
In your **setup.txt** of your formhandler extension, you have to invoke the **FormhandlerFinisherService** of sg_mail. In your **setup.txt** of your formhandler extension, you have to invoke the **FormhandlerFinisherService** of sg_mail.
...@@ -145,6 +210,7 @@ With the **Mail Queue** mode, you can see the current content of your mailing qu ...@@ -145,6 +210,7 @@ With the **Mail Queue** mode, you can see the current content of your mailing qu
<br> <br>
<img height="20px" width="20px" src="https://camo.githubusercontent.com/4b1188209e740e17a4ec0cd6583425696809017b/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d766965772e737667"> View the content of this mail <img height="20px" width="20px" src="https://camo.githubusercontent.com/4b1188209e740e17a4ec0cd6583425696809017b/68747470733a2f2f7261776769742e636f6d2f5459504f332f5459504f332e49636f6e732f6d61737465722f646973742f616374696f6e732f616374696f6e732d646f63756d656e742d766965772e737667"> View the content of this mail
Additionally you can now filter the mail queue or export it to a csv file.
## Developer Guide ## Developer Guide
...@@ -164,84 +230,14 @@ This extension uses two database tables: ...@@ -164,84 +230,14 @@ This extension uses two database tables:
The extbase model classes for these tables are located at the *Domain\Model* folder. The extbase model classes for these tables are located at the *Domain\Model* folder.
### Service Classes ### Service Classes
##### Register Interface
To register your extension you need at least one implementation of this interface.
Inside the **init()** function of your Implementation you should define variables for the following purposes:
###### Template Key
A unique Identifier for this particular template. It should be obvious from the template key for what purpose this template is intended.
###### Extension Key
The extension key of the TYPO3 extension registering with sg_mail. This should be the same for all of your extensions!
###### Description
A brief description about the template, visible in the backend module
###### subject
The default subject text for the emails. It is possible to specify language specific texts with an associative array:
[
'en' => 'english subject',
'de' => 'german subject',
...
]
###### markers
This is an array of information for substitute variables that are used to replace certain values at runtime.
Each Array element should be its own array and structured like this:
[
'marker' => 'marker_name',
'type' => \SGalinski\SgMail\Service\MailTemplateService::MARKER_TYPE_STRING,
'value' => 'some value',
'description' => 'This marker is used for X in the email'
]
marker = the variable name you use in the template
type = the date type of the variable
value = an example value, visible in the backend to the editors
description = a brief description for what this variable is intended for
Finally you have to call the function **\SGalinski\SgMail\Service\MailTemplateService::registerTemplate** (this is only marked deprecated for public use)
inside your **register()** function and pass all the necessary values.
Now you can register the class in your **ext_localconf.php** with
\SGalinski\SgMail\Service\MailTemplateService::registerByFile('SGalinski\SgMail\Example\Register');
You find a complete example of this process in the file **SGalinski\SgMail\Example\Register**
---
#### MailTemplateService #### MailTemplateService
This class provides you with an API to the mailing functionality and various helper functions regarding the your templates. This class provides you with an API to the mailing functionality and various helper functions regarding the your templates.
Here is an overview of some important functions: Here is an overview of some important functions:
###### function registerTemplate
A static function that adds your template to the service. Should be called from within your **Register** class (see **RegisterInterface**).
###### function registerByFile
Registers a template by providing a complete class name of your **RegisterInterface** implementation as an argument.
Needs to be called from within your **ext_localconf.php**.
###### function getDefaultTemplateMarker ###### function getDefaultTemplateMarker
Reads custom example template marker from your **locallang.xlf**. This is only useful if you need multi language examples in your Backend Marker Reads custom example template marker from your **locallang.xlf**. This is only useful if you need multi language examples in your Backend Marker
###### function getRegisterArray
Returns an array of all registered templates, with each element in the following format:
[
'templatePath' => '/path/to/template',
'description' => 'description of the template',
'marker' => $arrayOfMarkers,
'extension' => 'extension_key',
'templateName' => 'unique_template_name',
'subject' => 'The mail subject',
'usage' => 'optional description of this templates usage'
]
###### function loadPredefinedValuesForTemplate ###### function loadPredefinedValuesForTemplate
Sets the predefined values for this template that have been supplied by the editor. Use this method if you have no custom values for Sets the predefined values for this template that have been supplied by the editor. Use this method if you have no custom values for
...@@ -253,10 +249,6 @@ Sends your mail or adds it to the mailing queue, depending on the settings. You ...@@ -253,10 +249,6 @@ Sends your mail or adds it to the mailing queue, depending on the settings. You
###### function sendMailFromQueue ###### function sendMailFromQueue
Forces the sending of an E-Mail from within the queue. If it has already been sent, it gets send again. Forces the sending of an E-Mail from within the queue. If it has already been sent, it gets send again.
###### function setRegisterArray
Enables you to overwrite the register array. This overwrites **ALL** registered templates with the supplied data
and should be handled with care.
###### function addAttachment ###### function addAttachment
With this function you can add attachments to your mail. The attachment must be of type *Swift_OutputByteStream*. You must also specify the content-type of the attachment. With this function you can add attachments to your mail. The attachment must be of type *Swift_OutputByteStream*. You must also specify the content-type of the attachment.
......
...@@ -9,17 +9,29 @@ ...@@ -9,17 +9,29 @@
<authorEmail>torsten@sgalinski.de</authorEmail> <authorEmail>torsten@sgalinski.de</authorEmail>
</header> </header>
<body> <body>
<trans-unit id="backend.all" approved="yes">
<source>All</source>
<target>Alle</target>
</trans-unit>
<trans-unit id="backend.bcc" approved="yes"> <trans-unit id="backend.bcc" approved="yes">
<source>BCC (Blind Carbon Copy Receiver, comma separated)</source> <source>BCC (Blind Carbon Copy Receiver, comma separated)</source>
<target>BCC (Blindempfänger, komma-separiert)</target> <target>BCC (Blindempfänger, komma-separiert)</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.button_download_csv" approved="yes">
<source>Export CSV</source>
<target>CSV exportieren</target>
</trans-unit>
<trans-unit id="backend.button_reset" approved="yes"> <trans-unit id="backend.button_reset" approved="yes">
<source>Reset Template</source> <source>Reset Template</source>
<target>Zurücksetzen</target> <target>Zurücksetzen</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.button_reset_all" approved="yes"> <trans-unit id="backend.button_reset_all" approved="yes">
<source>Reset all languages for this template(!!!)</source> <source>Reset template</source>
<target>Alle Sprachen für dieses Template zurücksetzen(!!!)</target> <target>Template zurücksetzen</target>
</trans-unit>
<trans-unit id="backend.button_reset_filter" approved="yes">
<source>Reset</source>
<target>Zurücksetzen</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.cc" approved="yes"> <trans-unit id="backend.cc" approved="yes">
<source>CC (Carbon Copy Receiver, comma separated)</source> <source>CC (Carbon Copy Receiver, comma separated)</source>
...@@ -41,10 +53,90 @@ ...@@ -41,10 +53,90 @@
<source>Email</source> <source>Email</source>
<target>E-Mail</target> <target>E-Mail</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.entry_date" approved="yes">
<source>Queue Entry Date</source>
<target>Erstellungsdatum</target>
</trans-unit>
<trans-unit id="backend.error_bcc" approved="yes">
<source>The bcc addresses are invalid</source>
<target>Ungültige Blindempfänger Adressen (bcc)</target>
</trans-unit>
<trans-unit id="backend.error_cc" approved="yes">
<source>The cc addresses are invalid</source>
<target>Ungültige Kopieempfänger Adressen (cc)</target>
</trans-unit>
<trans-unit id="backend.failure_mail" approved="yes"> <trans-unit id="backend.failure_mail" approved="yes">
<source>There was an error when sending the preview email. Please check your configuration.</source> <source>There was an error when sending the preview email. Please check your configuration.</source>
<target>Ein Fehler ist aufgetreten. Bitte überprüfen Sie die Konfiguration.</target> <target>Ein Fehler ist aufgetreten. Bitte überprüfen Sie die Konfiguration.</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.filter.bcc" approved="yes">
<source>BCC address</source>
<target>BCC Adressen</target>
</trans-unit>
<trans-unit id="backend.filter.cc" approved="yes">
<source>CC address</source>
<target>CC Adressen</target>
</trans-unit>
<trans-unit id="backend.filter.date_from" approved="yes">
<source>Last sent time since:</source>
<target>Zuletzt gesendet von:</target>
</trans-unit>
<trans-unit id="backend.filter.date_to" approved="yes">
<source>Last sent until:</source>
<target>Zuletzt gesendet bis:</target>
</trans-unit>
<trans-unit id="backend.filter.extension" approved="yes">
<source>Extension</source>
<target>Extension</target>
</trans-unit>
<trans-unit id="backend.filter.fields.description" approved="yes">
<source>Search fields (all by default):</source>
<target>Suchfelder (standardmäßig alle):</target>
</trans-unit>
<trans-unit id="backend.filter.filter" approved="yes">
<source>Filter</source>
<target>Filter anwenden</target>
</trans-unit>
<trans-unit id="backend.filter.from" approved="yes">
<source>Sender address</source>
<target>Absender</target>
</trans-unit>
<trans-unit id="backend.filter.from_name" approved="yes">
<source>From name</source>
<target>Absendername</target>
</trans-unit>
<trans-unit id="backend.filter.language" approved="yes">
<source>Language:</source>
<target>Sprache:</target>
</trans-unit>
<trans-unit id="backend.filter.mailtext" approved="yes">
<source>Mailtext</source>
<target>Mailinhalt</target>
</trans-unit>
<trans-unit id="backend.filter.reply_to" approved="yes">
<source>Reply to</source>
<target>Antwort Adresse</target>
</trans-unit>
<trans-unit id="backend.filter.search" approved="yes">
<source>Search for:</source>
<target>Suchen nach:</target>
</trans-unit>
<trans-unit id="backend.filter.subject" approved="yes">
<source>Subject</source>
<target>Betreff</target>
</trans-unit>
<trans-unit id="backend.filter.template" approved="yes">
<source>Template</source>
<target>Template</target>
</trans-unit>
<trans-unit id="backend.filter.to" approved="yes">
<source>Recipient address</source>
<target>Empfänger</target>
</trans-unit>
<trans-unit id="backend.from" approved="yes">
<source>From</source>
<target>Absender</target>
</trans-unit>
<trans-unit id="backend.fromAddress" approved="yes"> <trans-unit id="backend.fromAddress" approved="yes">
<source>Sender Email Address</source> <source>Sender Email Address</source>
<target>Absender-E-Mail-Adresse</target> <target>Absender-E-Mail-Adresse</target>
...@@ -57,6 +149,22 @@ ...@@ -57,6 +149,22 @@
<source>Sender Name</source> <source>Sender Name</source>
<target>Absender-Name</target> <target>Absender-Name</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.fromUser" approved="yes">
<source>From User (overwrites other from fields):</source>
<target>Absender Benutzer (hat Vorrang falls gesetzt):</target>
</trans-unit>
<trans-unit id="backend.is_overwritten" approved="yes">
<source>(overwritten)</source>
<target>(überschrieben)</target>
</trans-unit>
<trans-unit id="backend.language_default" approved="yes">
<source>Default</source>
<target>Standard</target>
</trans-unit>
<trans-unit id="backend.last_sent" approved="yes">
<source>Last Sent</source>
<target>Zuletzt gesendet</target>
</trans-unit>
<trans-unit id="backend.mail_queue" approved="yes"> <trans-unit id="backend.mail_queue" approved="yes">
<source>Mail Queue</source> <source>Mail Queue</source>
<target>Mail-Queue</target> <target>Mail-Queue</target>
...@@ -81,9 +189,17 @@ ...@@ -81,9 +189,17 @@
<source>No template was registered.</source> <source>No template was registered.</source>
<target>Es wurde noch kein Template registriert.</target> <target>Es wurde noch kein Template registriert.</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.no_extensions" approved="yes">
<source>No extensions registered</source>
<target>Es wurden noch keine Extensions registriert</target>
</trans-unit>
<trans-unit id="backend.no_queue_entries" approved="yes"> <trans-unit id="backend.no_queue_entries" approved="yes">
<source>There are no entries in the mail queue for this template.</source> <source>Your filter criteria didn't match any entries.</source>
<target>Es gibt keine Einträge für dieses Template.</target> <target>Es wurden keine Einträge für Ihre Filtereinstellungen gefunden.</target>
</trans-unit>
<trans-unit id="backend.no_site_root" approved="yes">
<source>Please select one of the following website roots:</source>
<target>Bitte wählen Sie eine der folgenden Webseiten:</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.not_sent" approved="yes"> <trans-unit id="backend.not_sent" approved="yes">
<source>Not Sent</source> <source>Not Sent</source>
...@@ -109,6 +225,10 @@ ...@@ -109,6 +225,10 @@
<source>Language (reloads the page):</source> <source>Language (reloads the page):</source>
<target>Sprache (lädt die Seite neu):</target> <target>Sprache (lädt die Seite neu):</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.send_again" approved="yes">
<source>Send</source>
<target>Senden</target>
</trans-unit>
<trans-unit id="backend.send_mail_again" approved="yes"> <trans-unit id="backend.send_mail_again" approved="yes">
<source>Send this email again?</source> <source>Send this email again?</source>
<target>Diese E-Mail nochmals versenden?</target> <target>Diese E-Mail nochmals versenden?</target>
...@@ -117,9 +237,13 @@ ...@@ -117,9 +237,13 @@
<source>Send this email now?</source> <source>Send this email now?</source>
<target>Diese E-Mail jetzt versenden?</target> <target>Diese E-Mail jetzt versenden?</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.send_now" approved="yes">
<source>Send</source>
<target>Senden</target>
</trans-unit>
<trans-unit id="backend.send_test" approved="yes"> <trans-unit id="backend.send_test" approved="yes">
<source>Send Preview Mail (Save First!)</source> <source>Save and send preview mails</source>
<target>Sende Vorschau-Mail (Bitte vorher speichern!)</target> <target>Speichern und Vorschau-Mail senden</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.sending_time" approved="yes"> <trans-unit id="backend.sending_time" approved="yes">
<source>Sending Time</source> <source>Sending Time</source>
...@@ -130,8 +254,8 @@ ...@@ -130,8 +254,8 @@
<target>Versendet</target> <target>Versendet</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.showBody" approved="yes"> <trans-unit id="backend.showBody" approved="yes">
<source>Show Mail</source> <source>Show</source>
<target>Mail anzeigen</target> <target>Anzeigen</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.subject" approved="yes"> <trans-unit id="backend.subject" approved="yes">
<source>Subject</source> <source>Subject</source>
...@@ -142,8 +266,8 @@ ...@@ -142,8 +266,8 @@
<target>Erfolgreich gespeichert!</target> <target>Erfolgreich gespeichert!</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.success_mail" approved="yes"> <trans-unit id="backend.success_mail" approved="yes">
<source>Preview Email sent</source> <source>Preview Emails sent</source>
<target>Vorschau-E-Mail wurde versendet</target> <target>Vorschau E-Mails wurden versendet</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.success_mail_queue" approved="yes"> <trans-unit id="backend.success_mail_queue" approved="yes">
<source>Email succesfully sent</source> <source>Email succesfully sent</source>
...@@ -161,21 +285,29 @@ ...@@ -161,21 +285,29 @@
<source>The template was resetted successfully.</source> <source>The template was resetted successfully.</source>
<target>Das Template erfolgreich zurückgesetzt.</target> <target>Das Template erfolgreich zurückgesetzt.</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.to_form" approved="yes">
<source>To (If set, this overwrites the recipient everytime!) </source>
<target>Empfänger (Falls angegeben, wird der Empfänger immer überschrieben!)</target>
</trans-unit>
<trans-unit id="backend.to" approved="yes">
<source>To</source>
<target>Empfänger</target>
</trans-unit>
<trans-unit id="backend.toAddress" approved="yes"> <trans-unit id="backend.toAddress" approved="yes">
<source>Receiver</source> <source>Receiver</source>
<target>Empfänger</target> <target>Empfänger</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.type" approved="yes"> <trans-unit id="backend.type" approved="yes">
<source>Marker Type</source> <source>Type</source>
<target>Marker-Typ</target> <target>Typ</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.usage" approved="yes"> <trans-unit id="backend.usage" approved="yes">
<source>Usage in Template</source> <source>Usage in Template</source>
<target>Nutzung im Template</target> <target>Nutzung im Template</target>
</trans-unit> </trans-unit>
<trans-unit id="backend.value" approved="yes"> <trans-unit id="backend.value" approved="yes">
<source>Example Value</source> <source>Example</source>
<target>Beispielwert</target> <target>Beispiel</target>
</trans-unit> </trans-unit>
<trans-unit id="mlang_labels_tabdescr" approved="yes"> <trans-unit id="mlang_labels_tabdescr" approved="yes">
<source>Mail Templates</source> <source>Mail Templates</source>
......
...@@ -33,6 +33,14 @@ ...@@ -33,6 +33,14 @@
<source>Sender Name</source> <source>Sender Name</source>
<target>Absender-Name</target> <target>Absender-Name</target>
</trans-unit> </trans-unit>
<trans-unit id="tx_sgmail_domain_model_mail.language" approved="yes">
<source>Language</source>
<target>Sprache</target>
</trans-unit>
<trans-unit id="tx_sgmail_domain_model_mail.last_sending_time" approved="yes">
<source>Last sent</source>
<target>Letzer Versand</target>
</trans-unit>
<trans-unit id="tx_sgmail_domain_model_mail.mail_body" approved="yes"> <trans-unit id="tx_sgmail_domain_model_mail.mail_body" approved="yes">
<source>Mail text</source> <source>Mail text</source>
<target>Mail-Text</target> <target>Mail-Text</target>
...@@ -125,6 +133,10 @@ ...@@ -125,6 +133,10 @@
<source>Template Name</source> <source>Template Name</source>
<target>Template-Name</target> <target>Template-Name</target>
</trans-unit> </trans-unit>
<trans-unit id="tx_sgmail_domain_model_template.toAddress" approved="yes">
<source>To Address</source>
<target>Empfänger Adresse</target>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment