Commit e48bdd7b authored by Matthias Adrowski's avatar Matthias Adrowski
Browse files

Merge branch 'master' into 'feature_addFileFromPath'

# Conflicts:
#   Classes/Service/MailTemplateService.php
#   composer.json
#   ext_emconf.php
parents e2f8cf0d e4412a60
<?php
namespace SGalinski\SgMail\Command;
/***************************************************************
* Copyright notice
*
......@@ -26,18 +23,20 @@ namespace SGalinski\SgMail\Command;
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\SgMail\Domain\Model\Mail;
namespace SGalinski\SgMail\Command;
use SGalinski\SgMail\Domain\Repository\MailRepository;
use SGalinski\SgMail\Service\PlaintextService;
use SGalinski\SgMail\Service\MailTemplateService;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use Symfony\Component\Console\Command\Command;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
use TYPO3\CMS\Extbase\Object\Exception;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException;
use TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException;
/**
* Command controller for the mailing feature
......@@ -52,17 +51,10 @@ class SendMailCommandController extends Command {
}
/**
* Execute the command
*
* @param InputInterface $input
* @param OutputInterface $output
* @return int
* @throws \TYPO3\CMS\Extbase\Object\Exception
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\IllegalObjectTypeException
* @throws \TYPO3\CMS\Extbase\Persistence\Exception\UnknownObjectException
* @return MailRepository
* @throws Exception
*/
public function execute(InputInterface $input, OutputInterface $output) {
$sendCount = $input->getArgument('sendCount');
protected function getMailRepository(): MailRepository {
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '10.4.0', '<')) {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
/** @var MailRepository $mailRepository */
......@@ -71,93 +63,25 @@ class SendMailCommandController extends Command {
$mailRepository = GeneralUtility::makeInstance(MailRepository::class);
}
$mailsToSend = $mailRepository->findMailsToSend($sendCount);
foreach ($mailsToSend as $mailToSend) {
/** @var Mail $mailToSend */
$fromAddress = $mailToSend->getFromAddress();
$toAddresses = trim($mailToSend->getToAddress());
$addressesArray = GeneralUtility::trimExplode(',', $toAddresses, TRUE);
if (\count($addressesArray) > 1) {
$toAddresses = $addressesArray;
}
$ccAddresses = GeneralUtility::trimExplode(',', $mailToSend->getCcAddresses(), TRUE);
$bccAddresses = GeneralUtility::trimExplode(',', $mailToSend->getBccAddresses(), TRUE);
$mailSubject = $mailToSend->getMailSubject();
$mailBody = $mailToSend->getMailBody();
$mailToSend->setSendingTime(time());
$mailToSend->setLastSendingTime(time());
if (empty($fromAddress) || empty($toAddresses)) {
continue;
}
$mailRepository->update($mailToSend);
$mailMessage = GeneralUtility::makeInstance(MailMessage::class);
$mailMessage->setFrom($fromAddress, $mailToSend->getFromName());
$mailMessage->setTo($toAddresses);
$mailMessage->setSubject($mailSubject);
if (\count($ccAddresses)) {
$mailMessage->setCc($ccAddresses);
}
if (\count($bccAddresses)) {
$mailMessage->setBcc($bccAddresses);
}
$replyTo = $mailToSend->getReplyTo();
if ($replyTo) {
$mailMessage->setReplyTo($replyTo);
}
$plaintextService = GeneralUtility::makeInstance(PlaintextService::class);
$plaintextBody = $plaintextService->makePlain($mailBody);
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '10.4.0', '<')) {
$mailMessage->setBody($mailBody, 'text/html');
$mailMessage->addPart($plaintextBody, 'text/plain');
} else {
$mailMessage->html($mailBody);
$mailMessage->text($plaintextBody);
}
$attachments = $mailToSend->getAttachments();
if ($attachments->count() > 0) {
foreach ($attachments as $attachment) {
try {
/** @var FileInterface $file */
$file = $attachment->getOriginalResource();
if (!$file) {
continue;
}
$file = $file->getOriginalFile();
if (!$file) {
continue;
}
if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '10.4.0', '<')) {
$mailMessage->attach(
\Swift_Attachment::newInstance(
$file->getContents(), $file->getName(), $file->getMimeType()
)
);
} else {
$mailMessage->attach($file->getContents(), $file->getName(), $file->getMimeType());
}
} catch (\Exception $exception) {
continue;
}
}
}
return $mailRepository;
}
try {
$mailMessage->send();
} catch (\Exception $exception) {
// Ignore that. We can't do much here in a misconfiguration case.
}
}
/**
* Execute the command
*
* @param InputInterface $input
* @param OutputInterface $output
* @return int
* @throws Exception
* @throws IllegalObjectTypeException
* @throws UnknownObjectException
*/
public function execute(InputInterface $input, OutputInterface $output): int {
$sendCount = $input->getArgument('sendCount');
// Important for command controllers that change data
$mailRepository->persist();
$mailsToSend = $this->getMailRepository()->findMailsToSend($sendCount)->toArray();
$mailService = GeneralUtility::makeInstance(MailTemplateService::class);
$mailService->sendMailsFromQueue($mailsToSend);
return 0;
}
}
<?php
/*******************************************************************************
* 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!
******************************************************************************/
namespace SGalinski\SgMail\Controller;
use SGalinski\SgMail\Service\RegisterService;
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use function count;
/**
* Class AbstractController
*
* @package SGalinski\SgMail\Controller
*/
abstract class AbstractController extends ActionController {
public CONST sessionKey = 'sg_mail_controller_session';
public CONST DEFAULT_EXTENSION_KEY = 'sg_mail';
/**
* @var BackendUserAuthentication
*/
protected $backendUserAuthentication;
/**
* @param BackendUserAuthentication $backendUserAuthentication
*/
public function injectBackendUserAuthentication(BackendUserAuthentication $backendUserAuthentication): void {
$this->backendUserAuthentication = $GLOBALS['BE_USER'];
}
/**
* @var RegisterService
*/
protected $registerService;
/**
* @var Site
*/
protected $site;
/**
* @param RegisterService $registerService
*/
public function injectRegisterService(RegisterService $registerService): void {
$this->registerService = $registerService;
}
/**
* Get data from the session
*
* @param string $key
* @return string
*/
protected function getFromSession(string $key): string {
return $this->backendUserAuthentication->getSessionData(self::sessionKey . '_' . $key) ?? '';
}
/**
* Write data to the session
*
* @param string $key
* @param $data
*/
protected function writeToSession(string $key, $data): void {
$this->backendUserAuthentication->setAndSaveSessionData(self::sessionKey . '_' . $key, $data);
}
/**
* Get the mode from session and switch to it if necessary
*
* @throws NoSuchArgumentException
* @throws StopActionException
* @throws UnsupportedRequestTypeException
*/
protected function switchMode(): void {
$mode = $this->getFromSession('mode');
if ($this->request->hasArgument('controller')) {
$mode = $this->request->getArgument('controller');
}
if ($mode) {
$this->writeToSession('mode', $mode);
if ('SGalinski\\SgMail\\Controller\\' . $mode . 'Controller' !== static::class) {
$this->redirect('index', $this->getFromSession('mode'));
}
}
}
/**
* Check if a pid has been set and redirect if there is none
*
* @throws StopActionException
*/
protected function requireSite(): void {
$pid = $this->getPid();
if (!$pid) {
$originalRequest = clone $this->request;
$this->request->setOriginalRequest($originalRequest);
$this->forward('index', 'Site', 'SgMail');
}
try {
$this->site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pid);
} catch (SiteNotFoundException $exception) {
$originalRequest = clone $this->request;
$this->request->setOriginalRequest($originalRequest);
$this->forward('index', 'Site', $this->request->getArguments());
}
}
/**
* Add the message from the request arguments as a flash message
*
* @throws NoSuchArgumentException
*/
protected function addMessage(): void {
if ($this->request->hasArgument('message')) {
$this->addFlashMessage($this->request->getArgument('message'), '', FlashMessage::INFO);
}
}
/**
* Get the page id from get parameters
*
* @return int
*/
protected function getPid(): int {
return (int) GeneralUtility::_GP('id');
}
/**
* Get the selected extension and template from the register
*
* @return array
* @throws NoSuchCacheException
*/
protected function getSelectedExtensionAndTemplateFromRegister(): array {
$pageUid = $this->getPid();
$registerArray = $this->registerService->getNonBlacklistedTemplates($pageUid);
$selectedExtension = '';
$selectedTemplate = '';
if (!empty($registerArray)) {
$selectedExtension = key($registerArray);
}
if (!empty($registerArray[$selectedExtension])) {
$selectedTemplate = key($registerArray[$selectedExtension]);
}
return [$selectedExtension, $selectedTemplate];
}
/**
* Get the selected extension and template from session or register if session is empty
*
* @return array
* @throws NoSuchCacheException
*/
protected function getSelectedExtensionAndTemplate(): array {
if (
$this->getFromSession('selectedTemplate') !== NULL &&
$this->getFromSession('selectedExtension') !== NULL &&
!$this->registerService->isTemplateBlacklisted(
$this->getFromSession('selectedExtension'),
$this->getFromSession('selectedTemplate'),
$this->getPid()
)
) {
return [$this->getFromSession('selectedExtension'), $this->getFromSession('selectedTemplate')];
}
return $this->getSelectedExtensionAndTemplateFromRegister();
}
/**
* This function checks an array of mail addresses on validity and returns false if one of them is invalid
*
* @param array $addresses
* @return bool
*/
protected function checkMailAddresses(array $addresses): bool {
if (count($addresses) > 0) {
foreach ($addresses as $address) {
if (
trim($address) !== '' &&
!filter_var($address, FILTER_VALIDATE_EMAIL) &&
!(
strpos($address, '{') !== FALSE &&
strpos($address, '{') < strpos($address, '}')
)
) {
$message = LocalizationUtility::translate('backend.error_cc', 'sg_mail');
$this->addFlashMessage($message, '', FlashMessage::WARNING);
return FALSE;
}
}
}
return TRUE;
}
/**
* Make the docheader component
*/
protected function makeDocheader(): void {
$pageUid = $this->getPid();
$docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
$pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1));
if ($pageInfo === FALSE) {
$pageInfo = ['uid' => $pageUid];
}
$docHeaderComponent->setMetaInformation($pageInfo);
$this->makeButtons($docHeaderComponent);
$this->view->assign('docHeader', $docHeaderComponent->docHeaderContent());
}
/**
* create buttons for the backend module header
*
* @param DocHeaderComponent $docHeaderComponent
*/
protected function makeButtons(DocHeaderComponent $docHeaderComponent): void {
$buttonBar = $docHeaderComponent->getButtonBar();
/** @var IconFactory $iconFactory */
$iconFactory = GeneralUtility::makeInstance(IconFactory::class);
$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($this->request->getPluginName())
->setGetVariables(
[
'id',
'M'
]
)
->setSetVariables([]);
$buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
}
}
<?php /** @noinspection CallableParameterUseCaseInTypeContextInspection */
namespace SGalinski\SgMail\Controller;
<?php
/***************************************************************
* Copyright notice
*
......@@ -26,67 +23,44 @@ namespace SGalinski\SgMail\Controller;
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use SGalinski\SgMail\Service\BackendService;
use SGalinski\SgMail\Service\RegisterService;
use SGalinski\SgMail\Session\PhpSession;
use TYPO3\CMS\Backend\Template\Components\DocHeaderComponent;
use TYPO3\CMS\Backend\Utility\BackendUtility;
namespace SGalinski\SgMail\Controller;
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\VersionNumberUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
use TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException;
use TYPO3\CMS\Extbase\Object\Exception;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
use function explode;
use function str_getcsv;
use function str_replace;
/**
* Controller for the configuration mode of the backend module
*/
class ConfigurationController extends ActionController {
const DEFAULT_EXTENSION_KEY = 'sg_mail';
/**
* DocHeaderComponent
*
* @var DocHeaderComponent
*/
protected $docHeaderComponent;
/**
* @var \SGalinski\SgMail\Session\PhpSession
*/
protected $session;
class ConfigurationController extends AbstractController {
/**
*
* @param string $mode
* @param string $selectedTemplate
* @param string $selectedExtension
* @param string|null $selectedTemplate
* @param string|null $selectedExtension
* @param array $filters
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException
* @throws NoSuchArgumentException
* @throws NoSuchCacheException
*/
public function indexAction(
$mode = 'new', $selectedTemplate = NULL, $selectedExtension = NULL, array $filters = []
) {
string $mode = 'new', string $selectedTemplate = NULL, string $selectedExtension = NULL, array $filters = []
): void {
if ($this->request->hasArgument('message')) {
$this->addFlashMessage($this->request->getArgument('message'), '', FlashMessage::ERROR);
}
$pageUid = (int) GeneralUtility::_GP('id');
$registerArray = BackendService::getNonBlacklistedTemplates($pageUid);
if ($selectedTemplate === NULL || $selectedTemplate === '') {
if (!empty($registerArray)) {
$selectedExtension = \key($registerArray);
}
if (!empty($registerArray)) {
$selectedTemplate = \key($registerArray[$selectedExtension]);
}
[$selectedExtension, $selectedTemplate] = $this->getSelectedExtensionAndTemplate();
}
$this->view->assign('extensionKey', self::DEFAULT_EXTENSION_KEY);
$this->view->assign('mode', $mode);
if ($mode === 'edit') {
$registerArray = $this->registerService->getNonBlacklistedTemplates($this->getPid());
$templateToEdit = $registerArray[$selectedExtension][$selectedTemplate];
$editableMarkers = [];
foreach ($templateToEdit['marker'] as $arr) {
......@@ -115,18 +89,10 @@ class ConfigurationController extends ActionController {
);
}
// make docheader
$this->docHeaderComponent = GeneralUtility::makeInstance(DocHeaderComponent::class);
$pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1));
if ($pageInfo === FALSE) {
$pageInfo = ['uid' => $pageUid];
}
$this->docHeaderComponent->setMetaInformation($pageInfo);
BackendService::makeButtons($this->docHeaderComponent, $this->request);
$this->makeDocheader();
$this->view->assignMultiple(
[
'docHeader' => $this->docHeaderComponent->docHeaderContent(),
'extensionKey' => self::DEFAULT_EXTENSION_KEY,
'selectedTemplateFilter' => $filters['filterTemplate'],
'selectedExtensionFilter' => $filters['filterExtension'],
'selectedTemplateKey' => $selectedTemplate,
......@@ -139,12 +105,12 @@ class ConfigurationController extends ActionController {
/**
* Create the template or display errors that occured
*
* @throws NoSuchArgumentException
* @throws NoSuchCacheException
* @throws StopActionException
* @throws UnsupportedRequestTypeException
* @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
* @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException
* @throws Exception
*/
public function createAction() {
public function createAction(): void {
if (!$this->request->hasArgument('configuration')) {
$this->redirect(
'index', 'Configuration', NULL,
......@@ -154,16 +120,13 @@ class ConfigurationController extends ActionController {
/** @var array $configuration */
$configuration = $this->request->getArgument('configuration');
$templateName = $configuration['templateName'];
$extensionKey = $configuration['extensionKey'];
$csv = \str_replace("\r", '', $configuration['csv']);
$csv = str_replace("\r", '', $configuration['csv']);
$subject = $configuration['subject'];
$description = $configuration['description'];
$markersCsv = \explode("\n", $csv);
$markersCsv = explode("\n", $csv);
$markers = [];
foreach ($markersCsv as $markerCsv) {
$rowArray = str_getcsv($markerCsv, ';');
if (!$rowArray[0]) {
......@@ -180,33 +143,13 @@ class ConfigurationController extends ActionController {
'markerLabel' => $markerLabel
];
}