Newer
Older
<?php
namespace SGalinski\SgMail\Service;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;

Torsten Oppermann
committed
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;
Stefan Galinski
committed
const DEFAULT_TEMPLATE_PATH = 'Resources/Private/Templates/SgMail/';
const CONFIG_PATH = 'Configuration/MailTemplates/Forms';
* contains the actual registration data
*
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 {
Stefan Galinski
committed
if (\count($this->registerArray) > 1) {
return $this->registerArray;
}
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
$cache = $cacheManager->getCache(self::CACHE_NAME);
Stefan Galinski
committed
$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);
Stefan Galinski
committed
}
Stefan Galinski
committed
if (!\is_array($registerArray)) {
$registerArray = [];
Stefan Galinski
committed
return $registerArray;

Torsten Oppermann
committed
* Read every registered file and create a registration entry in the registerArray if possible
* @return array
private function registerExtensions(): array {
$this->registerArray = [];

Torsten Oppermann
committed
Stefan Galinski
committed
// @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'];
Stefan Galinski
committed
if ($extensionKey === NULL) {
Stefan Galinski
committed
$this->writeRegisterArrayEntry($extensionKey, $templateKey, $configArray, $insecureRegistration);
Stefan Galinski
committed
// 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)) {
// get file name without folders
$pathAsArray = GeneralUtility::trimExplode('/', $pathToRegistrationFile);
$filename = $pathAsArray[\count($pathAsArray) - 1];
$filenameWithoutHash = GeneralUtility::trimExplode('_', $filename, FALSE, 2)[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) {
$configArray = (include $pathToRegistrationFile);

Torsten Oppermann
committed
$extensionKey = $configArray['extension_key'];
$templateKey = $configArray['template_key'];
if ($extensionKey === NULL || $templateKey === NULL) {
continue;
}
Stefan Galinski
committed
$this->writeRegisterArrayEntry($extensionKey, $templateKey, $configArray, FALSE);

Torsten Oppermann
committed
}
}
return $this->registerArray;

Torsten Oppermann
committed
}
/**
* write a single entry into the register array
*
* @param string $extensionKey
* @param string $templateKey

Torsten Oppermann
committed
* @param array $configArray
Stefan Galinski
committed
* @param bool $insecureRegistration

Torsten Oppermann
committed
*/
private function writeRegisterArrayEntry(
Stefan Galinski
committed
$extensionKey, $templateKey, array $configArray, $insecureRegistration = FALSE
// template_path means where to find the mail body content (usually it's set directly in the registration
// as template_content)

Torsten Oppermann
committed
if ($configArray['template_path']) {
Stefan Galinski
committed
$templatePath = $configArray['template_path'];
} else {
if (!ExtensionManagementUtility::isLoaded($extensionKey)) {
return;
}
// transform template directory name: your_templates => YourTemplates/
$templateDirectoryParts = GeneralUtility::trimExplode('_', $templateKey);
$templateDirectory = '';
foreach ($templateDirectoryParts as $part) {
$templateDirectory .= \ucfirst($part);
}
$templateDirectory .= '/';
Stefan Galinski
committed
$templatePath = ExtensionManagementUtility::extPath($extensionKey) .
self::DEFAULT_TEMPLATE_PATH . $templateDirectory;
}
if (!\is_dir($templatePath)) {
$templatePath = '';

Torsten Oppermann
committed
}
$description = $configArray['description'];
$subject = $configArray['subject'];
$marker = $configArray['markers'];
$templateContent = $configArray['templateContent'];

Torsten Oppermann
committed
$this->registerArray[$extensionKey][$templateKey] = [

Torsten Oppermann
committed
'templatePath' => $templatePath,
'description' => $description,
'marker' => $marker,
'extension' => $extensionKey,
'templateName' => $templateKey,
'subject' => $subject,
Stefan Galinski
committed
'templateContent' => $templateContent,
'insecureRegistration' => $insecureRegistration

Torsten Oppermann
committed
];

Torsten Oppermann
committed
/**
* 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
*/
$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
Stefan Galinski
committed
* @return string
Stefan Galinski
committed
public function writeRegisterFile($templateKey, $extensionKey, $markers, $subject = '', $description = ''): string {
$configurationLocation = $this->getRegistrationPath();
Stefan Galinski
committed
$registerFolder = GeneralUtility::getFileAbsFileName($configurationLocation);
GeneralUtility::mkdir_deep($registerFolder);
Stefan Galinski
committed
$hashPrefix = md5($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . '|' . $templateKey . '.php');
$registerFile = GeneralUtility::getFileAbsFileName(
$registerFolder . '/' . $hashPrefix . '_' . $templateKey . '.php'
);
$newRegisterArray = [
'extension_key' => $extensionKey,
'template_key' => $templateKey,
'description' => $description,
'subject' => $subject,
'markers' => []
];
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) . ';');
Stefan Galinski
committed
return $registerFile;
/**
* Trims non-allowed characters from the form field marker name
*
* @param string $markerName
* @return string
*/
public static function normalizeFormFieldMarkerName($markerName = '') {
return \preg_replace('/[^a-z0-9\-_]/i', '', $markerName);
}