-
Georgi Mateev authoredGeorgi Mateev authored
BackendService.php 14.77 KiB
<?php
namespace SGalinski\SgMail\Service;
/***************************************************************
* Copyright notice
*
* (c) sgalinski Internet Services (https://www.sgalinski.de)
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\SgMail\Domain\Model\Template;
use SGalinski\SgMail\Domain\Repository\MailRepository;
use SGalinski\SgMail\Domain\Repository\TemplateRepository;
use SGalinski\SgMail\Utility\ExtensionUtility;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
use TYPO3\CMS\Extbase\Mvc\Request;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
/**
* Backend Service class
*/
class BackendService {
// options for the queue search filter
public const SENDER_FILTER_OPTION = 0;
public const RECIPIENT_FILTER_OPTION = 1;
public const SUBJECT_FILTER_OPTION = 2;
public const MAILTEXT_FILTER_OPTION = 3;
public const CC_FILTER_OPTION = 4;
public const BCC_FILTER_OPTION = 5;
public const FROM_NAME_FILTER_OPTION = 6;
public const REPLY_TO_NAME_FILTER_OPTION = 7;
// constants for deetermining the backend mode
public const BACKEND_MODE_EDITOR = 'editor';
public const BACKEND_MODE_EDITOR_CONTROLLER = 'Mail';
public const BACKEND_MODE_QUEUE = 'queue';
public const BACKEND_MODE_QUEUE_CONTROLLER = 'Queue';
/**
* Get all pages the be user has access to
*
* @return array
* @throws \InvalidArgumentException
*/
public static function getPages(): array {
$out = [];
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
$queryBuilder = $connectionPool->getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
$queryBuilder->select('*')
->from('pages')
->where(
$queryBuilder->expr()->eq(
'is_siteroot',
1
)
);
if (!version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) {
$queryBuilder->andWhere(
$queryBuilder->expr()->eq(
'sys_language_uid',
0
)
);
}
$rows = $queryBuilder->execute()->fetchAll();
foreach ($rows as $row) {
$pageInfo = BackendUtility::readPageAccess($row['uid'], $GLOBALS['BE_USER']->getPagePermsClause(1));
if ($pageInfo) {
$rootline = BackendUtility::BEgetRootLine($pageInfo['uid'], '', TRUE);
ksort($rootline);
$path = '/root';
foreach ($rootline as $page) {
$path .= '/p' . dechex($page['uid']);
}
$pageInfo['path'] = $path;
$out[] = $pageInfo;
}
}
return $out;
}
/**
* create buttons for the backend module header
*
* @param DocHeaderComponent $docHeaderComponent
* @param Request $request
* @throws \InvalidArgumentException
* @throws \UnexpectedValueException
*/
public static function makeButtons($docHeaderComponent, $request): void {
/** @var ButtonBar $buttonBar */
$buttonBar = $docHeaderComponent->getButtonBar();
/** @var IconFactory $iconFactory */
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9.0.0', '<')) {
$locallangPath = 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:';
} else {
$locallangPath = 'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:';
}
// Refresh
$refreshButton = $buttonBar->makeLinkButton()
->setHref(GeneralUtility::getIndpEnv('REQUEST_URI'))
->setTitle(
LocalizationUtility::translate(
$locallangPath . 'labels.reload'
)
)
->setIcon($iconFactory->getIcon('actions-refresh', Icon::SIZE_SMALL));
$buttonBar->addButton($refreshButton, ButtonBar::BUTTON_POSITION_RIGHT);
// shortcut button
$shortcutButton = $buttonBar->makeShortcutButton()
->setModuleName($request->getPluginName())
->setGetVariables(
[
'id',
'M'
]
)
->setSetVariables([]);
$buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
}
/**
* Retrieves the next site root in the page hierarchy from the current page
*
* @param int $currentPid
* @return int
*/
public static function getSiteRoot($currentPid): int {
$rootLine = BackendUtility::BEgetRootLine((int) $currentPid);
$siteRoot = ['uid' => 0];
foreach ($rootLine as $page) {
if ((int) $page['is_siteroot'] === 1) {
$siteRoot = $page;
break;
}
}
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
): array {
$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
*
* @return array
* @throws \InvalidArgumentException
*/
public static function getLanguages(): array {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_language');
$rows = $queryBuilder->select('*')
->from('sys_language')->execute()->fetchAll();
$languages = [];
// adding default language
$languages[] = ['isocode' => MailTemplateService::DEFAULT_LANGUAGE, 'name' => LocalizationUtility::translate(
'backend.language_default', 'SgMail'
)];
foreach ($rows as $language) {
$languages[] = ['isocode' => $language['language_isocode'],
'name' => $language['title']];
}
return $languages;
}
/**
* get an array of all the labels for the activated languages
*
* @param array $languages
* @return array
* @throws \InvalidArgumentException
*/
public static function getLanguageLabels(array $languages): array {
$languageLabels = [];
foreach ($languages as $language) {
$languageLabels[$language['isocode']] = $language['name'];
}
return $languageLabels;
}
/**
* Get the languages in an array suitable for filtering
*
* @return array
* @throws \InvalidArgumentException
*/
public static function getLanguagesForFilter(): array {
$languages = self::getLanguages();
array_unshift($languages, ['isocode' => '', 'name' => '']);
$filterLanguages = [];
if (\count($languages) > 0) {
foreach ($languages as $language) {
$filterLanguages[$language['isocode']] = $language['name'];
}
}
return $filterLanguages;
}
/**
* Get the template keys in an array suitable for filtering
*
* @param int $pageUid
* @return array
* @throws \InvalidArgumentException
* @throws \BadFunctionCallException
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
*/
public static function getTemplatesForFilter($pageUid): array {
$pageUid = (int) $pageUid;
$registerArray = self::getNonBlacklistedTemplates($pageUid);
$templates = [];
$registerService = GeneralUtility::makeInstance(RegisterService::class);
foreach ($registerArray as $extensions) {
foreach ($extensions as $template => $key) {
$templates[$key['extension']][] = [
'name' => $key['templateName'],
'is_manual' => $registerService->isManuallyRegisteredTemplate($key['templateName']),
];
}
}
array_unshift($templates, '');
return $templates;
}
/**
* Save or update the template in the DB, depending if it already exists or not
*
* @param int $pid
* @param string $selectedExtension
* @param string $selectedTemplate
* @param string $language
* @param array $templateData
* @return Template $template
* @throws \InvalidArgumentException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
*/
public static function saveTemplate($pid, $selectedExtension, $selectedTemplate, $language, $templateData
): Template {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$templateRepository = $objectManager->get(TemplateRepository::class);
/** @var Template $template */
$template = $templateRepository->findOneByTemplate(
$selectedExtension, $selectedTemplate, $language, $pid
);
$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);
}
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$persistenceManager = $objectManager->get(PersistenceManager::class);
$persistenceManager->persistAll();
return $template;
}
/**
* Generate a csv string from the queues, respecting the given filters
*
* @param array $filters
* @return string
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException
* @throws \InvalidArgumentException
*/
public static function getCsvFromQueue(array $filters = []): string {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var MailRepository $mailRepository */
$mailRepository = $objectManager->get(MailRepository::class);
$pageUid = (int) GeneralUtility::_GP('id');
/** @var array $queue */
$queue = $mailRepository->findAllEntries($pageUid, 0, $filters);
$totalQueueSize = \count($queue);
$exportString = '';
if ($totalQueueSize && $queue) {
$ignoreFields = ['uid', 'pid', 'tstamp',
'password', 'starttime', 'endtime', 'deleted', 'sent', 'priority', 'crdate', 'cruser_id', 'hidden'];
$dateFields = ['tstamp', 'starttime', 'endtime', 'crdate'];
$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;
}
}
return trim(preg_replace('/\s\s+/', ' ', strip_tags($exportString)));
}
/**
* Filter the register array to have only whitelisted templates for this domain
*
* @param int $siteRootId
* @throws \InvalidArgumentException
* @throws \BadFunctionCallException
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @return array
*/
public static function getNonBlacklistedTemplates($siteRootId): array {
$siteRootId = (int) $siteRootId;
$registerService = GeneralUtility::makeInstance(RegisterService::class);
$registerArray = $registerService->getRegisterArray();
$extensionConfiguration = ExtensionUtility::getExtensionConfiguration();
if (isset($extensionConfiguration['excludeTemplates']) && $extensionConfiguration['excludeTemplates'] !== '') {
$excludedTemplatesWithSiteId = GeneralUtility::trimExplode(
';', $extensionConfiguration['excludeTemplates'], TRUE
);
foreach ($excludedTemplatesWithSiteId as $currentSite) {
$currentSiteBlacklist = GeneralUtility::trimExplode(',', $currentSite, TRUE);
if ((int) $currentSiteBlacklist[0] === $siteRootId) {
foreach ($currentSiteBlacklist as $excludedTemplate) {
[$extensionKey, $templateName] = GeneralUtility::trimExplode('.', $excludedTemplate);
if ($extensionKey && $templateName && isset($registerArray[$extensionKey][$templateName])) {
unset($registerArray[$extensionKey][$templateName]);
}
}
}
}
}
// filter out excluded templates from all domains
if (isset($extensionConfiguration['excludeTemplatesAllDomains']) &&
$extensionConfiguration['excludeTemplatesAllDomains'] !== ''
) {
$excludedTemplates = GeneralUtility::trimExplode(
',', $extensionConfiguration['excludeTemplatesAllDomains'], TRUE
);
foreach ($excludedTemplates as $excludedTemplate) {
[$extensionKey, $templateName] = GeneralUtility::trimExplode('.', $excludedTemplate);
if ($extensionKey && $templateName && isset($registerArray[$extensionKey][$templateName])) {
unset($registerArray[$extensionKey][$templateName]);
}
}
}
return $registerArray;
}
}