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

Merge branch 'feature_security_update' into 'master'

Feature security update

See merge request !11
parents 56a2d3b1 2d4040b3
No related branches found
No related tags found
1 merge request!11Feature security update
Showing
with 622 additions and 362 deletions
......@@ -85,27 +85,28 @@ class SendMailCommandController extends CommandController {
$mailMessage->setFrom($fromAddress, $mailToSend->getFromName());
$mailMessage->setTo($toAddresses);
$mailMessage->setSubject($mailSubject);
if (count($ccAddresses)) {
if (\count($ccAddresses)) {
$mailMessage->setCc($ccAddresses);
}
if (count($bccAddresses)) {
if (\count($bccAddresses)) {
$mailMessage->setBcc($bccAddresses);
}
$mailMessage->setBody($mailBody, 'text/html');
$plaintextService = GeneralUtility::makeInstance(PlaintextService::class);
$plaintextBody = $plaintextService->makePlain($mailBody);
$mailMessage->addPart($plaintextBody, 'text/plain');
$plaintextService = GeneralUtility::makeInstance(PlaintextService::class);
$plaintextBody = $plaintextService->makePlain($mailBody);
$mailMessage->addPart($plaintextBody, 'text/plain');
$attachments = $mailToSend->getAttachments();
if ($attachments->count() > 0) {
foreach ($attachments as $attachment) {
$attachments = $mailToSend->getAttachments();
if ($attachments->count() > 0) {
foreach ($attachments as $attachment) {
/**
* @var FileReference $attachment
*/
$file = $attachment->getOriginalResource()->getOriginalFile();
$mailMessage->attach(
\Swift_Attachment::newInstance($file->getContents(), $file->getName(), $file->getMimeType())
$mailMessage->attach(
\Swift_Attachment::newInstance($file->getContents(), $file->getName(), $file->getMimeType())
);
}
}
......
......@@ -28,6 +28,7 @@ namespace SGalinski\SgMail\Controller;
use SGalinski\SgMail\Service\BackendService;
use SGalinski\SgMail\Service\MailTemplateService;
use SGalinski\SgMail\Service\RegisterService;
use SGalinski\SgMail\Service\TypoScriptSettingsService;
use SGalinski\SgMail\Session\PhpSession;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
......@@ -143,10 +144,13 @@ class ConfigurationController extends ActionController {
];
}
$this->writeRegisterFile($templateName, self::DEFAULT_EXTENSION_KEY, $markers, $subject, $description);
$registerService = $this->objectManager->get(RegisterService::class);
$registerService->writeRegisterFile(
$templateName, self::DEFAULT_EXTENSION_KEY, $markers, $subject, $description
);
MailTemplateService::registerExtensions();
$this->clearCaches();
$registerService->clearCaches();
// store selected template & extension key in the session
if (!($this->session instanceof PhpSession)) {
......@@ -163,86 +167,4 @@ class ConfigurationController extends ActionController {
['message' => LocalizationUtility::translate('backend.create_message', 'sg_mail')]
);
}
/**
* Write the mail registration file
*
* @TODO move this to the register service class when security update is merged. refactor in FormEditorController xclass as well
*
* @param string $templateKey
* @param string $extensionKey
* @param array $markers
* @param string $subject
* @param string $description
*/
private function writeRegisterFile($templateKey, $extensionKey, $markers, $subject, $description) {
// get the location where registrations should be stored
$configurationLocation = $this->getRegistrationPath();
$registerFolder = GeneralUtility::getFileAbsFileName(
$configurationLocation
);
// create folder
GeneralUtility::mkdir($registerFolder);
$registerFile = GeneralUtility::getFileAbsFileName(
$registerFolder . '/' . $templateKey . '.php'
);
// build the register array
$newRegisterArray = [
'extension_key' => $extensionKey,
'template_key' => $templateKey,
'description' => $description,
'subject' => $subject,
'markers' => []
];
// add the markers for this template
foreach ($markers as $marker) {
$markerName = $marker['identifier'];
$newRegisterArray['markers'][] = [
'marker' => $markerName,
'type' => MailTemplateService::MARKER_TYPE_STRING,
'value' => $marker['value'],
'description' => $marker['description']
];
}
file_put_contents($registerFile, '<?php return ' . var_export($newRegisterArray, TRUE) . ';');
}
/**
* Returns the path to the configured location where automatic mail template registrations should be
*
* @TODO move this to the register service class when security update is merged. refactor in FormEditorController xclass as well
*
* @return string
*/
private function getRegistrationPath(): string {
// get typoscript settings from sg mail
/** @var TypoScriptSettingsService $typoScriptSettingsService */
$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
// get the location where automatic registrations should be stored
return 'EXT:' . $tsSettings['mail']['configurationLocation'] . '/' . MailTemplateService::CONFIG_PATH;
}
/**
* Clear the sgmail register cache
*
* @TODO move this to the register service class when security update is merged. refactor in FormEditorController xclass as well
*
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
private function clearCaches() {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$cacheManager = $objectManager->get(CacheManager::class);
/** @var FrontendInterface $cache */
$cache = $cacheManager->getCache(MailTemplateService::CACHE_NAME);
/** @var FrontendInterface $cache */
$cache->flush();
}
}
......@@ -29,10 +29,12 @@ namespace SGalinski\SgMail\Controller;
use SGalinski\SgMail\Domain\Model\Template;
use SGalinski\SgMail\Service\BackendService;
use SGalinski\SgMail\Service\MailTemplateService;
use SGalinski\SgMail\Service\RegisterService;
use SGalinski\SgMail\Session\PhpSession;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
......@@ -101,22 +103,22 @@ class MailController extends ActionController {
$this->redirect('index', $this->session->getDataByKey('mode'));
}
$registerArray = BackendService::getNonBlacklistedTemplates($pid);
$removeExtensionKeys = [];
$registerArray = BackendService::getNonBlacklistedTemplates($pid);
foreach ($registerArray as $extensionKey => $extensionTemplates) {
if (\count($extensionTemplates) === 0) {
$removeExtensionKeys[] = $extensionKey;
}
}
foreach ($removeExtensionKeys as $extensionKey) {
unset($registerArray[$extensionKey]);
}
reset($registerArray);
// if no extensions are registered, redirect to empty action
if (empty($registerArray)) {
$this->redirect('empty');
if (!\is_array($registerArray) || \count($registerArray) <= 0) {
$this->forward('empty');
}
// if no template & extensionKey is selected look for them in the session
......@@ -125,7 +127,8 @@ class MailController extends ActionController {
$this->session->getDataByKey('selectedTemplate') !== NULL &&
$this->session->getDataByKey('selectedExtension') !== NULL &&
!MailTemplateService::isTemplateBlacklisted(
$this->session->getDataByKey('selectedExtension'), $this->session->getDataByKey('selectedTemplate'),
$this->session->getDataByKey('selectedExtension'),
$this->session->getDataByKey('selectedTemplate'),
$pid
)
) {
......@@ -156,7 +159,6 @@ class MailController extends ActionController {
foreach ($templatesFromDb as $key => $template) {
if ($template === NULL) {
$defaultTemplatePath = $registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['templatePath'];
$defaultTemplateFile = $defaultTemplatePath . $key . '.' . 'template.html';
$fallbackTemplateFile = $defaultTemplatePath . 'template.html';
$templateFromFile = new Template();
......@@ -174,12 +176,12 @@ class MailController extends ActionController {
}
$templateFromFile->setSubject($subject);
$subject = $registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['subject'];
if (file_exists($defaultTemplateFile)) {
$templateFromFile->setContent(file_get_contents($defaultTemplateFile));
} else {
if (file_exists($fallbackTemplateFile)) {
$templateFromFile->setContent(file_get_contents($fallbackTemplateFile));
}
if ($registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['templateContent']) {
$templateFromFile->setContent(
$registerArray[$parameters['selectedExtension']][$parameters['selectedTemplate']]['templateContent']
);
} elseif (file_exists($fallbackTemplateFile)) {
$templateFromFile->setContent(file_get_contents($fallbackTemplateFile));
}
} else {
$templates[$key] = $template;
......@@ -259,6 +261,8 @@ class MailController extends ActionController {
}
$this->view->assign('defaultLanguageLabel', $defaultLanguageLabel);
// @TODO reemove with version 5.0.0
$this->view->assign('deprecationWarnings', $this->getDeprecationWarnings());
}
/**
......@@ -358,6 +362,47 @@ class MailController extends ActionController {
}
/**
* Returns an array with deprecation warnings, regarding the old registration
*
* @TODO remove this with version 5.0.0
* @return array
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
private function getDeprecationWarnings(): array {
$deprecationWarnings = [];
$extensionList = ExtensionManagementUtility::getLoadedExtensionListArray();
$registerService = $this->objectManager->get(RegisterService::class);
$registerArray = $registerService->getRegisterArray();
foreach ($extensionList as $extensionName) {
$extensionConfigDirectory = ExtensionManagementUtility::extPath($extensionName) .
MailTemplateService::CONFIG_PATH;
if (!\is_dir($extensionConfigDirectory)) {
continue;
}
$configFiles = GeneralUtility::getFilesInDir($extensionConfigDirectory);
foreach ($configFiles as $configFile) {
$pathToRegistrationFile = $extensionConfigDirectory . '/' . $configFile;
if (!\is_file($pathToRegistrationFile)) {
continue;
}
$registrationArray = include $pathToRegistrationFile;
$extensionKey = $registrationArray['extension_key'];
$templateKey = $registrationArray['template_key'];
if ($registerArray[$extensionKey][$templateKey]['insecureRegistration']) {
$code = '$GLOBALS[\'sg_mail\'][\'' . $extensionKey . '\'][\'' . $templateKey . '\'] = \'EXT:' .
$extensionName . '/' . MailTemplateService::CONFIG_PATH . '/' . $configFile . '\';';
$deprecationWarnings[] = ['code' => $code];
}
}
}
return $deprecationWarnings;
}
/**
* reset template values to default state for a specific language (delete from db)
*
......
......@@ -186,8 +186,6 @@ class QueueController extends ActionController {
* 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
*/
......@@ -197,7 +195,7 @@ class QueueController extends ActionController {
header('Content-Type: application/force-download');
header('Content-Transfer-Encoding: Binary');
header('Content-Disposition: attachment; filename="export.csv"');
header('Content-Length: ' . strlen($exportString));
header('Content-Length: ' . \strlen($exportString));
echo $exportString;
exit(0);
}
......
......@@ -58,7 +58,7 @@ abstract class AbstractRepository extends Repository {
* @param bool $ignoreEnableFields
* @return string
*/
protected function getEnableFieldsStatement($table, $alias = '', $ignoreEnableFields = FALSE) {
protected function getEnableFieldsStatement($table, $alias = '', $ignoreEnableFields = FALSE): string {
if (TYPO3_MODE === 'FE' && $GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {
/** @var PageRepository $pageRepository */
$pageRepository = $GLOBALS['TSFE']->sys_page;
......
......@@ -90,12 +90,10 @@ class MailRepository extends AbstractRepository {
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']);
}
} elseif ($filters['filterLanguage'] && $filters['filterLanguage'] !== 0
&& $filters['filterLanguage'] !== '0' && $filters['filterLanguage'] !== ''
) {
$constraintsAnd[] = $query->equals('language', $filters['filterLanguage']);
}
$constraintsOr = [];
......
......@@ -26,7 +26,6 @@ namespace SGalinski\SgMail\Domain\Repository;
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\SgMail\Domain\Model\Template;
use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
......
......@@ -92,7 +92,7 @@ class FormsFinisher extends AbstractFinisher {
}
}
$templateName = $this->parseOption('template');
$templateName = trim($this->parseOption('template'));
if ($this->parseOption('template') === '') {
$templateName = $formDefinition->getIdentifier();
}
......@@ -100,19 +100,42 @@ class FormsFinisher extends AbstractFinisher {
$ignoreMailQueue = (boolean) $this->parseOption('ignoreMailQueue');
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var \SGalinski\SgMail\Service\MailTemplateService $mailTemplateService */
$mailTemplateService = $objectManager->get(
MailTemplateService::class, $templateName, $this->parseOption('extension'), $markers
MailTemplateService::class, $templateName, 'sg_mail', $markers
);
$mailTemplateService->setIgnoreMailQueue($ignoreMailQueue);
$mailTemplateService->setLanguage($GLOBALS['TSFE']->config['config']['language']);
$mailTemplateService->setToAddresses($this->parseOption('mailTo'));
$mailTemplateService->setFromAddress($this->parseOption('mailFrom'));
$mailTemplateService->setFromName($this->parseOption('userName'));
$mailTemplateService->setReplyToAddress($this->parseOption('replyTo'));
$mailTemplateService->setCcAddresses($this->parseOption('cc'));
$mailTemplateService->setBccAddresses($this->parseOption('bcc'));
$mailToAdresses = trim($this->parseOption('mailTo'));
if ($mailToAdresses !== '') {
$mailTemplateService->setToAddresses($this->parseOption('mailTo'));
}
$fromAddress = trim($this->parseOption('mailFrom'));
if ($fromAddress !== '') {
$mailTemplateService->setFromAddress($fromAddress);
}
$fromName = trim($this->parseOption('userName'));
if ($fromName !== '') {
$mailTemplateService->setFromName($fromName);
}
$replyTo = trim($this->parseOption('replyTo'));
if ($replyTo !== '') {
$mailTemplateService->setReplyToAddress($replyTo);
}
$ccAddresses = trim($this->parseOption('cc'));
if ($ccAddresses !== '') {
$mailTemplateService->setCcAddresses($ccAddresses);
}
$bccAddresses = trim($this->parseOption('bcc'));
if ($bccAddresses !== '') {
$mailTemplateService->setBccAddresses($bccAddresses);
}
$mailTemplateService->sendEmail();
}
......
......@@ -36,11 +36,9 @@ use TYPO3\CMS\Core\Database\DatabaseConnection;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository;
use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
......@@ -70,7 +68,7 @@ class BackendService {
* @return array
* @throws \InvalidArgumentException
*/
public static function getPages() {
public static function getPages(): array {
$out = [];
/** @var $databaseConnection DatabaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
......@@ -139,7 +137,7 @@ class BackendService {
* @param int $currentPid
* @return int
*/
public static function getSiteRoot($currentPid) {
public static function getSiteRoot($currentPid): int {
$rootLine = BackendUtility::BEgetRootLine((int) $currentPid);
$siteRoot = ['uid' => 0];
......@@ -165,7 +163,7 @@ class BackendService {
*/
public static function getSelectedTemplates(
$selectedExtension, $selectedTemplate, array $languages, $pid
) {
): array {
$selectedTemplates = [];
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
......@@ -187,7 +185,7 @@ class BackendService {
* @return array
* @throws \InvalidArgumentException
*/
public static function getLanguages() {
public static function getLanguages(): array {
/** @var $databaseConnection DatabaseConnection */
$databaseConnection = $GLOBALS['TYPO3_DB'];
/** @var QueryResultInterface $rows */
......@@ -219,7 +217,7 @@ class BackendService {
* @return array
* @throws \InvalidArgumentException
*/
public static function getLanguageLabels(array $languages) {
public static function getLanguageLabels(array $languages): array {
$languageLabels = [];
foreach ($languages as $language) {
......@@ -235,12 +233,12 @@ class BackendService {
* @return array
* @throws \InvalidArgumentException
*/
public static function getLanguagesForFilter() {
public static function getLanguagesForFilter(): array {
$languages = self::getLanguages();
array_unshift($languages, ['isocode' => '', 'name' => '']);
$filterLanguages = [];
if (count($languages) > 0) {
if (\count($languages) > 0) {
foreach ($languages as $language) {
$filterLanguages[$language['isocode']] = $language['name'];
}
......@@ -285,9 +283,9 @@ class BackendService {
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
*/
public static function saveTemplate($pid, $selectedExtension, $selectedTemplate, $language, $templateData) {
public static function saveTemplate($pid, $selectedExtension, $selectedTemplate, $language, $templateData
): Template {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var TemplateRepository $templateRepository */
$templateRepository = $objectManager->get(TemplateRepository::class);
/** @var Template $template */
......@@ -335,7 +333,7 @@ class BackendService {
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @throws \InvalidArgumentException
*/
public static function getCsvFromQueue(array $filters = []) {
public static function getCsvFromQueue(array $filters = []): string {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var MailRepository $mailRepository */
$mailRepository = $objectManager->get(MailRepository::class);
......@@ -343,7 +341,7 @@ class BackendService {
$pageUid = (int) GeneralUtility::_GP('id');
/** @var array $queue */
$queue = $mailRepository->findAllEntries($pageUid, 0, $filters);
$totalQueueSize = count($queue);
$totalQueueSize = \count($queue);
$exportString = '';
if ($totalQueueSize && $queue) {
......@@ -359,7 +357,7 @@ class BackendService {
if ($first) {
$first = FALSE;
foreach ($mail as $field => $value) {
if (!in_array($field, $ignoreFields, TRUE)) {
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) {
......@@ -375,8 +373,8 @@ class BackendService {
/** @var array $mail */
foreach ($queue as $mail) {
foreach ($mail as $field => $value) {
if (!in_array($field, $ignoreFields, TRUE)) {
if (in_array($field, $dateFields, TRUE)) {
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;
......@@ -410,9 +408,10 @@ class BackendService {
*/
public static function getNonBlacklistedTemplates($siteRootId): array {
$siteRootId = (int) $siteRootId;
$registerArray = MailTemplateService::getRegisterArray();
$extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_mail'], []);
$registerService = GeneralUtility::makeInstance(RegisterService::class);
$registerArray = $registerService->getRegisterArray();
$extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_mail'], ['array']);
if (isset($extensionConfiguration['excludeTemplates']) && $extensionConfiguration['excludeTemplates'] !== '') {
$excludedTemplatesWithSiteId = GeneralUtility::trimExplode(
';', $extensionConfiguration['excludeTemplates'], TRUE
......@@ -431,7 +430,7 @@ class BackendService {
}
}
// filter out excluded templates from all domains
// filter out excluded templates from all domains
if (isset($extensionConfiguration['excludeTemplatesAllDomains']) && $extensionConfiguration['excludeTemplatesAllDomains'] !== '') {
$excludedTemplates = GeneralUtility::trimExplode(
',', $extensionConfiguration['excludeTemplatesAllDomains'], TRUE
......
......@@ -33,8 +33,6 @@ use SGalinski\SgMail\Domain\Repository\MailRepository;
use SGalinski\SgMail\Domain\Repository\TemplateRepository;
use Swift_Attachment;
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\Resource\FileInterface;
use TYPO3\CMS\Core\Resource\ResourceFactory;
......@@ -168,14 +166,10 @@ class MailTemplateService {
/** @var ObjectManager objectManager */
$this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var MailMessage mailMessage */
$this->mailMessage = $this->objectManager->get(MailMessage::class);
/** @var TypoScriptSettingsService $typoScriptSettingsService */
$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
/** @var TemplateRepository templateRepository */
$this->templateRepository = $this->objectManager->get(TemplateRepository::class);
/** @var PersistenceManager persistenceManager */
$this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
// use defaultMailFromAddress if it is provided in LocalConfiguration.php; use the sg_mail TS setting as fallback
......@@ -208,11 +202,11 @@ class MailTemplateService {
}
}
if (count($this->bccAddresses) > 0) {
if (\count($this->bccAddresses) > 0) {
$this->mailMessage->setBcc($this->bccAddresses);
}
if (count($this->ccAddresses) > 0) {
if (\count($this->ccAddresses) > 0) {
$this->mailMessage->setCc($this->ccAddresses);
}
}
......@@ -225,7 +219,7 @@ class MailTemplateService {
* @param string $extensionKey
* @return array
*/
public static function getDefaultTemplateMarker($translationKey, array $marker, $extensionKey = 'sg_mail') {
public static function getDefaultTemplateMarker($translationKey, array $marker, $extensionKey = 'sg_mail'): array {
$languagePath = 'LLL:EXT:' . $extensionKey . '/Resources/Private/Language/locallang.xlf:' . $translationKey;
// Need the key for translations
......@@ -258,6 +252,8 @@ class MailTemplateService {
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
*/
public function sendEmail($isPreview = FALSE): bool {
$registerService = GeneralUtility::makeInstance(RegisterService::class);
if (TYPO3_MODE === 'FE') {
/** @var TypoScriptFrontendController $tsfe */
$tsfe = $GLOBALS['TSFE'];
......@@ -267,8 +263,9 @@ class MailTemplateService {
}
if ($this->pid) {
$pageUid = (int) $this->pid;
$pageUid = $this->pid;
}
if ($pageUid === 0) {
$pageRepository = $this->objectManager->get(PageRepository::class);
$rootPageRows = $pageRepository->getRecordsByField(
......@@ -296,37 +293,46 @@ class MailTemplateService {
$this->loadTemplateValues($template);
}
$defaultTemplateContent = NULL;
// get default template content from register array
$defaultTemplateContent = $registerService->getRegisterArray()
[$this->extensionKey][$this->templateName]['templateContent'];
// If there is no template for this language, use the default template
if ($template === NULL) {
if ($defaultTemplateContent === NULL) {
$templatePath = $registerService->getRegisterArray()
[$this->extensionKey][$this->templateName]['templatePath'];
$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 {
// use configured default html template
/** @var TypoScriptSettingsService $typoScriptSettingsService */
$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
$defaultTemplateFile = GeneralUtility::getFileAbsFileName($tsSettings['mail']['defaultHtmlTemplate']);
// 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;
// use configured default html template
/** @var TypoScriptSettingsService $typoScriptSettingsService */
$typoScriptSettingsService = $this->objectManager->get(TypoScriptSettingsService::class);
$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
$defaultTemplateFile = GeneralUtility::getFileAbsFileName(
$tsSettings['mail']['defaultHtmlTemplate']
);
if (file_exists($defaultTemplateFile)) {
$defaultTemplateContent = file_get_contents($defaultTemplateFile);
} else {
return FALSE;
}
}
}
} elseif (filter_var($template->getToAddress(), FILTER_VALIDATE_EMAIL)) {
$this->setToAddresses(trim($template->getToAddress()));
}
if ($isPreview) {
$previewMarker = [];
/** @var array $markerArray */
$markerArray = self::getRegisterArray()[$this->extensionKey][$this->templateName]['marker'];
$markerArray = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['marker'];
foreach ($markerArray as $marker) {
$markerPath = GeneralUtility::trimExplode('.', $marker['marker']);
$temporaryMarkerArray = [];
......@@ -360,10 +366,11 @@ class MailTemplateService {
$emailView->setTemplateSource($template->getContent());
} else {
$subject = self::getRegisterArray()[$this->extensionKey][$this->templateName]['subject'];
$subject = $registerService->getRegisterArray()[$this->extensionKey][$this->templateName]['subject'];
if (\is_array($subject)) {
$subject = \trim(
self::getRegisterArray()[$this->extensionKey][$this->templateName]['subject'][$this->language]
$registerService->getRegisterArray()
[$this->extensionKey][$this->templateName]['subject'][$this->language]
);
}
if ($subject === NULL && $this->subject !== NULL) {
......@@ -533,7 +540,7 @@ class MailTemplateService {
* @param string $toAddresses
* @return MailTemplateService
*/
public function setToAddresses($toAddresses) {
public function setToAddresses($toAddresses): MailTemplateService {
$toAddresses = trim(preg_replace('~\x{00a0}~siu', ' ', $toAddresses));
$this->toAddresses = $toAddresses;
......@@ -550,7 +557,7 @@ class MailTemplateService {
* @param string $fromName
* @return MailTemplateService
*/
public function setFromAddress($fromAddress, $fromName = '') {
public function setFromAddress($fromAddress, $fromName = ''): MailTemplateService {
if ($fromAddress) {
$this->fromAddress = $fromAddress;
$this->mailMessage->setFrom($fromAddress, $fromName);
......@@ -563,7 +570,7 @@ class MailTemplateService {
* @param string $ccAddresses
* @return MailTemplateService
*/
public function setCcAddresses($ccAddresses) {
public function setCcAddresses($ccAddresses): MailTemplateService {
if ($ccAddresses) {
$this->ccAddresses = $ccAddresses;
$this->mailMessage->setCc(GeneralUtility::trimExplode(',', $this->ccAddresses));
......@@ -576,7 +583,7 @@ class MailTemplateService {
* @param string $replyToAddress
* @return MailTemplateService
*/
public function setReplyToAddress($replyToAddress) {
public function setReplyToAddress($replyToAddress): MailTemplateService {
if ($replyToAddress) {
$this->replyToAddress = $replyToAddress;
$this->mailMessage->setReplyTo($replyToAddress);
......@@ -589,7 +596,7 @@ class MailTemplateService {
* @param string $language
* @return MailTemplateService
*/
public function setLanguage($language) {
public function setLanguage($language): MailTemplateService {
$this->language = $language;
return $this;
}
......@@ -598,7 +605,7 @@ class MailTemplateService {
* @param boolean $ignoreMailQueue
* @return MailTemplateService
*/
public function setIgnoreMailQueue($ignoreMailQueue) {
public function setIgnoreMailQueue($ignoreMailQueue): MailTemplateService {
$this->ignoreMailQueue = $ignoreMailQueue;
return $this;
}
......@@ -607,7 +614,7 @@ class MailTemplateService {
* @param string $templateName
* @return MailTemplateService
*/
public function setTemplateName($templateName) {
public function setTemplateName($templateName): MailTemplateService {
$this->templateName = $templateName;
return $this;
}
......@@ -616,7 +623,7 @@ class MailTemplateService {
* @param string $extensionKey
* @return MailTemplateService
*/
public function setExtensionKey($extensionKey) {
public function setExtensionKey($extensionKey): MailTemplateService {
$this->extensionKey = $extensionKey;
return $this;
}
......@@ -625,7 +632,7 @@ class MailTemplateService {
* @param array $markers
* @return MailTemplateService
*/
public function setMarkers(array $markers) {
public function setMarkers(array $markers): MailTemplateService {
$this->markers = $markers;
return $this;
}
......@@ -634,7 +641,7 @@ class MailTemplateService {
* @param string $bccAddresses
* @return MailTemplateService
*/
public function setBccAddresses($bccAddresses) {
public function setBccAddresses($bccAddresses): MailTemplateService {
if ($bccAddresses) {
$this->bccAddresses = $bccAddresses;
$this->mailMessage->setBcc(GeneralUtility::trimExplode(',', $this->bccAddresses));
......@@ -647,7 +654,7 @@ class MailTemplateService {
* @param int $priority
* @return MailTemplateService
*/
public function setPriority($priority) {
public function setPriority($priority): MailTemplateService {
$this->priority = $priority;
return $this;
}
......@@ -658,7 +665,7 @@ class MailTemplateService {
* @param string $contentType
* @return MailTemplateService
*/
public function addAttachment($data, $filename, $contentType) {
public function addAttachment($data, $filename, $contentType): MailTemplateService {
$attachment = Swift_Attachment::newInstance()
->setFilename($filename)
->setContentType($contentType)
......@@ -673,7 +680,7 @@ class MailTemplateService {
* @param FileInterface|FileReference $file
* @return MailTemplateService
*/
public function addFileResourceAttachment($file) {
public function addFileResourceAttachment($file): MailTemplateService {
if ($file instanceof FileReference) {
$file = $file->getOriginalResource()->getOriginalFile();
}
......@@ -696,7 +703,7 @@ class MailTemplateService {
/**
* @return MailMessage
*/
public function getMailMessage() {
public function getMailMessage(): MailMessage {
return $this->mailMessage;
}
......@@ -764,7 +771,7 @@ class MailTemplateService {
* @param int $pid
* @return MailTemplateService
*/
public function setPid($pid) {
public function setPid($pid): MailTemplateService {
$this->pid = (int) $pid;
return $this;
}
......@@ -776,25 +783,17 @@ class MailTemplateService {
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \BadFunctionCallException
* @throws \InvalidArgumentException
* @deprecated since 4.7.0 will be removed in 5.0.0. Use the RegistrationService class instead
*/
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 = [];
}
public static function getRegisterArray(): array {
// @TODO remove this deprecated function in version 5.0.0
self::logDeprecation('registerExtensions');
$cache->set($cacheId, $entry, [], self::CACHE_LIFETIME_IN_SECONDS);
}
$registrationService = GeneralUtility::makeInstance(RegisterService::class);
// write entries for old extensions into the file list
self::registerExtensions();
return $entry;
return $registrationService->getRegisterArray();
}
/**
......@@ -802,104 +801,34 @@ class MailTemplateService {
* If found, register the template(s)
*
* @throws \BadFunctionCallException
* @return array
* @deprecated since 4.7.0 will be removed in 5.0.0. Use the RegistrationService class instead
*/
public static function registerExtensions(): array {
// clear registerArray
$registerArray = [];
public static function registerExtensions() {
// @TODO remove this deprecated function in version 5.0.0
self::logDeprecation('registerExtensions');
$extensionList = ExtensionManagementUtility::getLoadedExtensionListArray();
foreach ($extensionList as $extensionName) {
$extensionConfigDirectory = ExtensionManagementUtility::extPath($extensionName);
$extensionConfigDirectory .= self::CONFIG_PATH;
if (\is_dir($extensionConfigDirectory)) {
$configFiles = GeneralUtility::getFilesInDir($extensionConfigDirectory);
foreach ($configFiles as $configFile) {
if (!\file_exists($extensionConfigDirectory . '/' . $configFile)) {
continue;
}
$configArray = (include $extensionConfigDirectory . '/' . $configFile);
$extensionKey = $configArray['extension_key'];
$templateKey = $configArray['template_key'];
if ($extensionKey === NULL || $templateKey === NULL) {
continue;
}
$registerArray = self::writeRegisterArrayEntry(
$registerArray, $extensionKey, $templateKey, $configArray
);
}
if (!\is_dir($extensionConfigDirectory)) {
continue;
}
}
return $registerArray;
}
/**
* writes a single entry into the register array
*
* @param array $registerArray
* @param string $extensionKey
* @param string $templateKey
* @param array $configArray
* @param bool $transformTemplateFolder
* @param string $storeTemplateExtension
* @return array
*/
private static function writeRegisterArrayEntry(
array $registerArray, $extensionKey, $templateKey, array $configArray,
$transformTemplateFolder = TRUE, $storeTemplateExtension = ''
) {
// If it is not explicitly set in which extension the html should be located, use the extension set in the template settings
if ($storeTemplateExtension === '') {
$storeTemplateExtension = $extensionKey;
}
// give the option to use the template key as folder name. this is used mainly with auto registering
$templateDirectory = $templateKey;
$configFiles = GeneralUtility::getFilesInDir($extensionConfigDirectory);
foreach ($configFiles as $configFile) {
$pathToRegistrationFile = $extensionConfigDirectory . '/' . $configFile;
if (!\is_file($pathToRegistrationFile)) {
continue;
}
// by default folders with underscore will be transformed to upper camelcase
if ($transformTemplateFolder) {
// transform template directory name: your_templates => YourTemplates/
$templateDirectoryParts = GeneralUtility::trimExplode('_', $templateKey);
$templateDirectory = '';
foreach ($templateDirectoryParts as $part) {
$templateDirectory .= ucfirst($part);
$GLOBALS['sg_mail'][$extensionName][$configFile] = $pathToRegistrationFile;
}
}
$templateDirectory .= '/';
$templatePath = ExtensionManagementUtility::extPath($storeTemplateExtension) . self::DEFAULT_TEMPLATE_PATH
. $templateDirectory;
if ($configArray['template_path']) {
$templatePath = $configArray[$templateKey];
}
$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;
}
/**
* Checks if a template is blacklisted for a given siterootId
* Checks if a template is blacklisted for a given siteroot id
*
* @param string $extensionKey
* @param string $templateName
......@@ -961,4 +890,15 @@ class MailTemplateService {
return $allMarker;
}
/**
* function to call a deprecation log entry (but only once per request / class)
*
* @param $function
*/
private static function logDeprecation($function) {
GeneralUtility::deprecationLog(
'The function ' . $function . ' is deprecated since version 4.7.0 and will be removed in version 5.0.0'
);
}
}
<?php
namespace SGalinski\SgMail\Service;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
/**
* Provides an api for registering your mail templates
*/
class RegisterService implements \TYPO3\CMS\Core\SingletonInterface {
const CACHE_NAME = 'sg_mail_registerArrayCache';
const CACHE_LIFETIME_IN_SECONDS = 86400;
const DEFAULT_TEMPLATE_PATH = 'Resources/Private/Templates/SgMail/';
const CONFIG_PATH = 'Configuration/MailTemplates/Forms';
/**
* contains the actual registration data
*
* @var array
*/
private $registerArray = [];
/**
* Get all registered templates from the cache. if the cache expired, the entries are generated
*
* @return array
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \BadFunctionCallException
* @throws \InvalidArgumentException
*/
public function getRegisterArray(): array {
if (\count($this->registerArray) > 1) {
return $this->registerArray;
}
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
$cache = $cacheManager->getCache(self::CACHE_NAME);
$registerArray = $cache->get('sg_mail');
if (!$registerArray || !\is_array($registerArray)) {
$registerArray = $this->registerExtensions();
if (\is_array($registerArray)) {
$cache->set('sg_mail', $registerArray, [], self::CACHE_LIFETIME_IN_SECONDS);
}
}
if (!\is_array($registerArray)) {
$registerArray = [];
}
return $registerArray;
}
/**
* Read every registered file and create a registration entry in the registerArray if possible
*
* @return array
*/
private function registerExtensions(): array {
$this->registerArray = [];
// @TODO remove in version 5.0.0
$extensionConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_mail'], ['array']);
if (((int) $extensionConfiguration['supportOldRegistrations']) === 0) {
MailTemplateService::registerExtensions();
}
foreach ($GLOBALS['sg_mail'] as $extensionName => $templates) {
foreach ($templates as $templateKey => $registerFile) {
// already registered in the new way? Then don't load the old one again.
// @TODO remove in version 5.0.0
$insecureRegistration = FALSE;
if (strpos($templateKey, '.php')) {
$insecureRegistration = TRUE;
$registerFileTest = str_replace('.php', '', $templateKey);
$registerFileTest = GeneralUtility::camelCaseToLowerCaseUnderscored($registerFileTest);
if (isset($GLOBALS['sg_mail'][$extensionName][$registerFileTest]) ||
isset($GLOBALS['sg_mail']['sg_mail'][$registerFileTest])
) {
continue;
}
}
$registerFile = GeneralUtility::getFileAbsFileName($registerFile);
if (!\is_file($registerFile)) {
continue;
}
$configArray = (include $registerFile);
$extensionKey = $configArray['extension_key'];
$templateKey = $configArray['template_key'];
if ($extensionKey === NULL) {
continue;
}
$this->writeRegisterArrayEntry($extensionKey, $templateKey, $configArray, $insecureRegistration);
}
}
// read automatically created extensionName registrations and write the entries
$configurationLocation = $this->getRegistrationPath();
$registerFolder = GeneralUtility::getFileAbsFileName($configurationLocation);
if (\is_dir($registerFolder)) {
$configFiles = GeneralUtility::getFilesInDir($registerFolder);
foreach ($configFiles as $configFile) {
$pathToRegistrationFile = $registerFolder . '/' . $configFile;
if (!\is_file($pathToRegistrationFile)) {
continue;
}
// get file name without folders
$pathAsArray = GeneralUtility::trimExplode('/', $pathToRegistrationFile);
$filename = $pathAsArray[\count($pathAsArray) - 1];
$filenameWithoutHash = GeneralUtility::trimExplode('_', $filename)[1];
$hash = md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . '|' . $filenameWithoutHash);
// if the filename doesn't start with the hash value, ignore it
if (strpos($filename, $hash) !== 0) {
continue;
}
$configArray = (include $pathToRegistrationFile);
$extensionKey = $configArray['extension_key'];
$templateKey = $configArray['template_key'];
if ($extensionKey === NULL || $templateKey === NULL) {
continue;
}
$this->writeRegisterArrayEntry($extensionKey, $templateKey, $configArray, FALSE);
}
}
return $this->registerArray;
}
/**
* write a single entry into the register array
*
* @param string $extensionKey
* @param string $templateKey
* @param array $configArray
* @param bool $insecureRegistration
*/
private function writeRegisterArrayEntry(
$extensionKey, $templateKey, array $configArray, $insecureRegistration = FALSE
) {
// transform template directory name: your_templates => YourTemplates/
$templateDirectoryParts = GeneralUtility::trimExplode('_', $templateKey);
$templateDirectory = '';
foreach ($templateDirectoryParts as $part) {
$templateDirectory .= \ucfirst($part);
}
$templateDirectory .= '/';
if ($configArray['template_path']) {
$templatePath = $configArray['template_path'];
} else {
$templatePath = ExtensionManagementUtility::extPath($extensionKey) .
self::DEFAULT_TEMPLATE_PATH . $templateDirectory;
}
if (!\is_dir($templatePath)) {
$templatePath = '';
}
$description = $configArray['description'];
$subject = $configArray['subject'];
$marker = $configArray['markers'];
$templateContent = $configArray['templateContent'];
$this->registerArray[$extensionKey][$templateKey] = [
'templatePath' => $templatePath,
'description' => $description,
'marker' => $marker,
'extension' => $extensionKey,
'templateName' => $templateKey,
'subject' => $subject,
'templateContent' => $templateContent,
'insecureRegistration' => $insecureRegistration
];
}
/**
* Returns the path to the configured location where automatic mail template registrations should be
*
* @return string
*/
private function getRegistrationPath(): string {
// get typoscript settings from sg mail
/** @var TypoScriptSettingsService $typoScriptSettingsService */
$typoScriptSettingsService = GeneralUtility::makeInstance(TypoScriptSettingsService::class);
$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
// get the location where automatic registrations should be stored
return 'EXT:' . $tsSettings['mail']['configurationLocation'] . '/' . self::CONFIG_PATH;
}
/**
* Clear the sgmail register cache
*
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function clearCaches() {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$cacheManager = $objectManager->get(CacheManager::class);
/** @var FrontendInterface $cache */
$cache = $cacheManager->getCache(self::CACHE_NAME);
/** @var FrontendInterface $cache */
$cache->flush();
}
/**
* Write the mail registration file
*
* @param string $templateKey
* @param string $extensionKey
* @param array $markers
* @param string $subject
* @param string $description
*/
public function writeRegisterFile($templateKey, $extensionKey, $markers, $subject, $description) {
// get the location where registrations should be stored
$configurationLocation = $this->getRegistrationPath();
$registerFolder = GeneralUtility::getFileAbsFileName(
$configurationLocation
);
// create folder
GeneralUtility::mkdir($registerFolder);
$registerFile = GeneralUtility::getFileAbsFileName(
$registerFolder . '/' . $templateKey . '.php'
);
// build the register array
$newRegisterArray = [
'extension_key' => $extensionKey,
'template_key' => $templateKey,
'description' => $description,
'subject' => $subject,
'markers' => []
];
// add the markers for this template
foreach ($markers as $marker) {
$markerName = $marker['identifier'];
$newRegisterArray['markers'][] = [
'marker' => $markerName,
'type' => MailTemplateService::MARKER_TYPE_STRING,
'value' => $marker['value'],
'description' => $marker['description']
];
}
file_put_contents($registerFile, '<?php return ' . var_export($newRegisterArray, TRUE) . ';');
}
}
......@@ -24,6 +24,9 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\SgMail\Service\RegisterService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class ExtensionConfiguration
*
......@@ -40,7 +43,8 @@ class ExtensionConfiguration {
$result = '';
try {
$registerArray = \SGalinski\SgMail\Service\MailTemplateService::getRegisterArray();
$registerService = GeneralUtility::makeInstance(RegisterService::class);
$registerArray = $registerService->getRegisterArray();
foreach ($registerArray as $extensionKey => $extension) {
/** @var array $extension */
foreach ($extension as $templateKey => $template) {
......
......@@ -26,10 +26,13 @@ namespace SGalinski\SgMail\XClass\Form;
***************************************************************/
use SGalinski\SgMail\Service\MailTemplateService;
use SGalinski\SgMail\Service\RegisterService;
use SGalinski\SgMail\Service\TypoScriptSettingsService;
use Symfony\Component\Yaml\Yaml;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Resource\ResourceStorage;
use TYPO3\CMS\Core\Resource\StorageRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Form\Type\FormDefinitionArray;
......@@ -68,6 +71,8 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public function saveFormAction(string $formPersistenceIdentifier, FormDefinitionArray $formDefinition) {
$registrationService = $this->objectManager->get(RegisterService::class);
/** @noinspection PhpInternalEntityUsedInspection */
parent::saveFormAction($formPersistenceIdentifier, $formDefinition);
......@@ -78,8 +83,6 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
/** @var array $finishers */
$finishers = $formDefinition['finishers'];
$extensionKey = '';
$templateKey = '';
foreach ($finishers as $finisher) {
......@@ -94,54 +97,64 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
// retrieve the extension and template key and jump out of loop
$extensionKey = $finisher['options']['extension'];
$templateKey = $finisher['options']['template'];
break;
}
$templateKey = str_replace('_', '-', $finisher['options']['template']);
// if no template key was explicitly set, use the form identifier as template key
if ($templateKey === '') {
$templateKey = $formDefinition['identifier'];
}
// if no template key was explicitly set, use the form identifier as template key
if ($templateKey === '') {
$templateKey = $formDefinition['identifier'] . '-' . $finisher['identifier'];
}
// if there was no sg mail finisher or an missing key then simply exit the function
if ($extensionKey === '' || $templateKey === '') {
return;
}
// if there was no sg mail finisher or an missing key then simply exit the function
if ($extensionKey === '' || $templateKey === '') {
return;
}
// parse yaml for form fields
$absoluteFilePath = GeneralUtility::getFileAbsFileName($formPersistenceIdentifier);
$parsedYaml = Yaml::parse(file_get_contents($absoluteFilePath));
// parse yaml for form fields
if (strpos($formPersistenceIdentifier, 'EXT:') === 0) {
$absoluteFilePath = GeneralUtility::getFileAbsFileName($formPersistenceIdentifier);
} else {
list($storageUid, $fileIdentifier) = explode(':', $formPersistenceIdentifier, 2);
$storageRepository = $this->objectManager->get(StorageRepository::class);
$storage = $storageRepository->findByUid($storageUid);
if (!$storage instanceof ResourceStorage || !$storage->isBrowsable()) {
throw new \InvalidArgumentException(
sprintf('Could not access storage with uid "%d".', $storageUid)
);
}
$absoluteFilePath = $storage->getFile($fileIdentifier);
}
$renderables = [];
foreach ($parsedYaml['renderables'] as $formPage) {
if (\is_array($formPage['renderables'])) {
foreach ($formPage['renderables'] as $row) {
if (!\is_array($row) || !$row['type']) {
continue;
}
$parsedYaml = Yaml::parse(file_get_contents($absoluteFilePath));
if ($row['type'] === 'GridRow') {
foreach ($row['renderables'] as $renderableInsideGridrow) {
$renderables[] = $renderableInsideGridrow;
$renderables = [];
foreach ($parsedYaml['renderables'] as $formPage) {
if (\is_array($formPage['renderables'])) {
foreach ($formPage['renderables'] as $row) {
if (!\is_array($row) || !$row['type']) {
continue;
}
} elseif (!\in_array($row['type'], self::IGNORE_FIELDS, TRUE)) {
$renderables[] = $row;
if ($row['type'] === 'GridRow') {
foreach ($row['renderables'] as $renderableInsideGridrow) {
$renderables[] = $renderableInsideGridrow;
}
} elseif (!\in_array($row['type'], self::IGNORE_FIELDS, TRUE)) {
$renderables[] = $row;
}
}
} else {
return;
}
} else {
return;
}
}
// write the new Register.php file
$this->writeRegisterFile($renderables, $extensionKey, $templateKey);
// call register function in mail template service class
MailTemplateService::registerExtensions();
// write the new Register.php file and add it to the registrationFiles array in the RegisterService
$this->writeRegisterFile($renderables, $extensionKey, $templateKey);
}
// clear caches
$this->clearCaches();
// call register function in register service class
$registrationService->clearCaches();
$registrationService->getRegisterArray();
}
/**
......@@ -150,19 +163,21 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
* @param array $renderables
* @param string $extensionKey
* @param string $templateKey
* @return string
*/
private function writeRegisterFile(array $renderables, $extensionKey, $templateKey) {
private function writeRegisterFile(array $renderables, $extensionKey, $templateKey): string {
// get the location where automatic registrations should be stored
$configurationLocation = $this->getRegistrationPath();
$registerFolder = GeneralUtility::getFileAbsFileName(
$configurationLocation
);
// create folder
GeneralUtility::mkdir($registerFolder);
$hashPrefix = md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . '|' . $templateKey . '.php');
$registerFile = GeneralUtility::getFileAbsFileName(
$registerFolder . '/' . $templateKey . '.php'
$registerFolder . '/' . $hashPrefix . '_' . $templateKey . '.php'
);
// build the register array
......@@ -191,6 +206,8 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
}
file_put_contents($registerFile, '<?php return ' . var_export($newRegisterArray, TRUE) . ';');
return $registerFile;
}
/**
......@@ -203,7 +220,7 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
$cacheManager = $objectManager->get(CacheManager::class);
/** @var FrontendInterface $cache */
$cache = $cacheManager->getCache(MailTemplateService::CACHE_NAME);
$cache = $cacheManager->getCache(RegisterService::CACHE_NAME);
/** @var FrontendInterface $cache */
$cache->flush();
}
......@@ -220,6 +237,6 @@ class FormEditorController extends \TYPO3\CMS\Form\Controller\FormEditorControll
$tsSettings = $typoScriptSettingsService->getSettings(0, 'tx_sgmail');
// get the location where automatic registrations should be stored
return 'EXT:' . $tsSettings['mail']['configurationLocation'] . '/' . MailTemplateService::CONFIG_PATH;
return 'EXT:' . $tsSettings['mail']['configurationLocation'] . '/' . RegisterService::CONFIG_PATH;
}
}
......@@ -11,7 +11,6 @@ TYPO3:
label: 'A Label that seems to be never used...'
predefinedDefaults:
options:
extension: 'sg_mail'
template: ''
automaticRegistration: true
ignoreMailQueue: true
......@@ -27,7 +26,6 @@ TYPO3:
label: 'A Label that seems to be never used...'
predefinedDefaults:
options:
extension: 'sg_mail'
template: ''
automaticRegistration: true
ignoreMailQueue: true
......@@ -60,11 +58,6 @@ TYPO3:
10: 'TYPO3.CMS.Form.mixins.formElementMixins.BaseCollectionEditorsMixin'
100:
label: "Mail Templates - E-Mail to the website user"
110:
identifier: 'extension'
templateName: 'Inspector-TextEditor'
label: 'Extension key'
propertyPath: 'options.extension'
120:
identifier: 'template'
templateName: 'Inspector-TextEditor'
......@@ -124,11 +117,6 @@ TYPO3:
10: 'TYPO3.CMS.Form.mixins.formElementMixins.BaseCollectionEditorsMixin'
100:
label: "Mail Templates - E-Mail to the website admin"
110:
identifier: 'extension'
templateName: 'Inspector-TextEditor'
label: 'Extension key'
propertyPath: 'options.extension'
120:
identifier: 'template'
templateName: 'Inspector-TextEditor'
......
......@@ -23,8 +23,12 @@ sg_mail ist multi-site and multi-language ready.
### Registering your Extension
To register your extension with sg_mail, you need a **Configuration File** for each template you want to integrate.
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.
It needs be a *.php* file and has to be inside the Configuration folder **typo3conf/ext/{your_extension}/Configuration/Sgmail** of your extension.
Additionally you need to make your registration file known in your **ext_localconf.php** file:
// register mail templates
$GLOBALS['sgmail']['my_extension_key']['unique_template_name'] = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('my_extension_key') . '/Configuration/SgMail/MyTemplate.php';
sg_mail will automatically parse valid configuration files of all extensions within your TYPO3 instance.
......@@ -159,11 +163,6 @@ This happens also if the given iso code of the language is not known (inside the
In your template editor you have automatically all languages of your page shown.
## Using sg_mail with Formhandler
In your **setup.txt** of your formhandler extension, you have to invoke the **FormhandlerFinisherService** of sg_mail.
This is done in a similar fashion as with the usual finisher classes.
### Example
finishers {
......
......@@ -53,10 +53,6 @@
<source><![CDATA[CC (Carbon Copy Receiver, comma separated)]]></source>
<target><![CDATA[CC (Kopieempfänger, komma-separiert)]]></target>
</trans-unit>
<trans-unit id="backend.configuration" approved="yes">
<source><![CDATA[Configuration editor]]></source>
<target><![CDATA[Konfigurationseditor]]></target>
</trans-unit>
<trans-unit id="backend.content" approved="yes">
<source><![CDATA[Text]]></source>
<target><![CDATA[Text]]></target>
......@@ -109,6 +105,12 @@
<source><![CDATA[Do you really want to reset this template?]]></source>
<target><![CDATA[Möchten Sie wirklich den Ursprungszustand wiederherstellen?]]></target>
</trans-unit>
<trans-unit id="backend.deprecationInfo" approved="yes" xml:space="preserve">
<source><![CDATA[Some template configurations have been registered in an old way and won`t work in future versions.
Please register your configurations in the according ext_localconf.php.]]></source>
<target><![CDATA[Es wurden Template Registrierungen entdeckt, die in zukünftigen Versionen nicht mehr funktionieren werden.
Bitte registrieren Sie Ihre Templates in den entsprechenden ext_localconf.php Dateien.]]></target>
</trans-unit>
<trans-unit id="backend.description" approved="yes">
<source><![CDATA[Description]]></source>
<target><![CDATA[Beschreibung]]></target>
......@@ -333,6 +335,10 @@
<source><![CDATA[Show]]></source>
<target><![CDATA[Anzeigen]]></target>
</trans-unit>
<trans-unit id="backend.showDeprecation" approved="yes">
<source><![CDATA[Show/Hide deprecated registrations]]></source>
<target><![CDATA[Einträge anzeigen/ausblenden]]></target>
</trans-unit>
<trans-unit id="backend.subject" approved="yes">
<source><![CDATA[Subject]]></source>
<target><![CDATA[Betreff]]></target>
......@@ -385,6 +391,10 @@
<source><![CDATA[Example]]></source>
<target><![CDATA[Beispiel]]></target>
</trans-unit>
<trans-unit id="configuration.enableSecurity" approved="yes">
<source><![CDATA[Only use the secure functions to register the configuration files]]></source>
<target><![CDATA[Nur die sichere Registrierung von Konfigurationen verwenden]]></target>
</trans-unit>
<trans-unit id="configuration.excludeTemplates" approved="yes" xml:space="preserve">
<source><![CDATA[Exclude Mail Templates for certain Domains
......@@ -445,4 +455,4 @@ Die Templates declined und approved der Extension sg_comments sind für alle Dom
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
</xliff>
......@@ -42,6 +42,16 @@
<trans-unit id="backend.cc">
<source><![CDATA[CC (Carbon Copy Receiver, comma separated)]]></source>
</trans-unit>
<trans-unit id="backend.content">
<source><![CDATA[Text]]></source>
</trans-unit>
<trans-unit id="backend.delete_template">
<source><![CDATA[Do you really want to reset this template?]]></source>
</trans-unit>
<trans-unit id="backend.deprecationInfo" xml:space="preserve">
<source><![CDATA[Some template configurations have been registered in an old way and won`t work in future versions.
Please register your configurations in the according ext_localconf.php.]]></source>
</trans-unit>
<trans-unit id="backend.configuration">
<source><![CDATA[Configuration editor]]></source>
</trans-unit>
......@@ -252,6 +262,9 @@
<trans-unit id="backend.showBody">
<source><![CDATA[Show]]></source>
</trans-unit>
<trans-unit id="backend.showDeprecation">
<source><![CDATA[Show/Hide deprecated registrations]]></source>
</trans-unit>
<trans-unit id="backend.subject">
<source><![CDATA[Subject]]></source>
</trans-unit>
......@@ -291,6 +304,9 @@
<trans-unit id="backend.value">
<source><![CDATA[Example]]></source>
</trans-unit>
<trans-unit id="configuration.enableSecurity">
<source><![CDATA[Only use the secure functions to register the configuration files]]></source>
</trans-unit>
<trans-unit id="configuration.excludeTemplates" xml:space="preserve">
<source><![CDATA[Exclude Mail Templates for certain Domains
......@@ -330,4 +346,4 @@ The templates declined and approved of the sg_comments extension are blacklisted
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
</xliff>
......@@ -25,6 +25,22 @@
<div class="col-md-12 row">
<div class="col-md-12">
<div class="form-group">
<f:if condition="{deprecationWarnings}">
<div class="panel panel-danger">
<div class="panel-heading">
<f:translate key="backend.deprecationInfo" /> <br/>
<a style="text-decoration: underline;" href="#" data-toggle="collapse" data-target="#deprecationPanel"><f:translate key="backend.showDeprecation" /></a>
</div>
<div id="deprecationPanel" class="collapse">
<div class="panel-body">
<f:for each="{deprecationWarnings}" as="warning">
<small>{warning.code}</small>
<br>
</f:for>
</div>
</div>
</div>
</f:if>
<table class="table table-hover">
<thead>
<tr>
......
......@@ -5,4 +5,7 @@ excludeTemplatesAllDomains =
excludeTemplates =
# cat=general; type=user[EXT:sg_mail/Classes/UserFunc/ExtensionConfiguration.php:ExtensionConfiguration->displayTemplates]; label=LLL:EXT:sg_mail/Resources/Private/Language/locallang.xlf:configuration.templateList
templates =
\ No newline at end of file
templates =
# cat=general; type=boolean; label=LLL:EXT:sg_mail/Resources/Private/Language/locallang.xlf:configuration.enableSecurity
supportOldRegistrations = 0
......@@ -41,7 +41,6 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['tx_sgmail_up
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['tx_sgmail_update_languages'] = \SGalinski\SgMail\Updates\UpdateLanguages::class;
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update']['tx_sgmail_update_german_as_default'] = \SGalinski\SgMail\Updates\UpdateGermanAsDefault::class;
if (TYPO3_MODE === 'BE') {
$tsPath = $extPath . 'Configuration/TypoScript/';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup(file_get_contents($tsPath . 'setup.ts'));
......@@ -56,9 +55,8 @@ $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Form\Controller\FormMan
'className' => \SGalinski\SgMail\XClass\Form\FormManagerController::class,
];
// Cache registration
$cacheName = \SGalinski\SgMail\Service\MailTemplateService::CACHE_NAME;
$cacheName = \SGalinski\SgMail\Service\RegisterService::CACHE_NAME;
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheName])) {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$cacheName] = [];
}
......@@ -67,4 +65,3 @@ if (!isset($TYPO3_CONF_VARS['SYS']['caching']['cacheConfigurations'][$cacheName]
'citypower'
];
}
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