From c214372c69d888fcac2a2ae669d3d79c73e1429c Mon Sep 17 00:00:00 2001 From: Tobias Wojtylak Date: Fri, 28 Feb 2025 14:24:38 +0100 Subject: [PATCH 1/2] fix: use longtext & longblob instead of text for mail fields (data truncated error) --- ext_tables.sql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ext_tables.sql b/ext_tables.sql index f9f8e68..8760728 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -12,11 +12,11 @@ CREATE TABLE tx_sentmail_mail ( message_id varchar(255) DEFAULT '' NOT NULL, internal_id varchar(255) DEFAULT '' NOT NULL, is_sent tinyint(1) DEFAULT '0' NOT NULL, - debug text DEFAULT '' NOT NULL, - message text DEFAULT '' NOT NULL, - message_original text DEFAULT '' NOT NULL, - original_message text DEFAULT '' NOT NULL, - envelope_original text DEFAULT '' NOT NULL, - email_serialized text DEFAULT '' NOT NULL, - settings text DEFAULT '' NOT NULL -); \ No newline at end of file + debug longtext DEFAULT '' NOT NULL, + message longtext DEFAULT '' NOT NULL, + message_original longtext DEFAULT '' NOT NULL, + original_message longtext DEFAULT '' NOT NULL, + envelope_original longblob DEFAULT '' NOT NULL, + email_serialized longblob DEFAULT '' NOT NULL, + settings longtext DEFAULT '' NOT NULL +); From b1dc9e37d19daa09debe31d8ef31e3f0adfd2efa Mon Sep 17 00:00:00 2001 From: Tobias Wojtylak Date: Fri, 28 Feb 2025 14:55:40 +0100 Subject: [PATCH 2/2] refactor: prevent EventListener to break page on errors and log them --- .../AfterMailSentEventListener.php | 31 +++------ .../BeforeMailSentEventListener.php | 64 +++++++++++-------- Classes/Repository/MailRepository.php | 6 +- 3 files changed, 49 insertions(+), 52 deletions(-) diff --git a/Classes/EventListener/AfterMailSentEventListener.php b/Classes/EventListener/AfterMailSentEventListener.php index c7f98ee..67caaa7 100644 --- a/Classes/EventListener/AfterMailSentEventListener.php +++ b/Classes/EventListener/AfterMailSentEventListener.php @@ -3,6 +3,7 @@ namespace StudioMitte\SentMails\EventListener; +use StudioMitte\SentMails\Repository\MailRepository; use Symfony\Component\Mime\RawMessage; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; @@ -12,30 +13,33 @@ class AfterMailSentEventListener { + public function __construct(private MailRepository $mailRepository) + { + } public function __invoke(AfterMailerSentMessageEvent $event): void { /** @var Mailer $mailer */ $mailer = $event->getMailer(); - $transport = $mailer->getTransport(); $sentMessage = $mailer->getSentMessage(); if (!$sentMessage) { return; } $originalMessage = $sentMessage->getOriginalMessage(); - $sentMailLogCustomId = $originalMessage->getHeaders()->getHeaderBody('X-SentMail_Custom'); $sentMailLogId = $originalMessage->getHeaders()->getHeaderBody('X-SentMail_ID'); + if (null === $sentMailLogId) { + return; + } + $isReply = get_class($originalMessage) === RawMessage::class; - $logRow = $this->getLogRecord((int)$sentMailLogId, $sentMailLogCustomId); + $logRow = $this->mailRepository->getMailRow((int) $sentMailLogId); - $connection = $this->getConnection(); if ($logRow) { - $connection->update('tx_sentmail_mail', + $this->getConnection()->update('tx_sentmail_mail', [ 'message_id' => $isReply ? '' : $sentMessage->getMessageId(), 'debug' => $sentMessage->getDebug(), - # 'envelope_original' => serialize($sentMessage->getEnvelope()), 'is_sent' => 1, ], [ @@ -43,23 +47,8 @@ public function __invoke(AfterMailerSentMessageEvent $event): void ] ); } - return; } - protected function getLogRecord(int $id, string $customId): array - { - $queryBuilder = $this->getConnection()->createQueryBuilder(); - - return (array)$queryBuilder - ->select('*') - ->from('tx_sentmail_mail') - ->where( - $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($id, Connection::PARAM_INT)), - ) - ->setMaxResults(1) - ->executeQuery() - ->fetchAssociative(); - } private function getConnection(): Connection { diff --git a/Classes/EventListener/BeforeMailSentEventListener.php b/Classes/EventListener/BeforeMailSentEventListener.php index e16c745..b8ae8a3 100644 --- a/Classes/EventListener/BeforeMailSentEventListener.php +++ b/Classes/EventListener/BeforeMailSentEventListener.php @@ -3,6 +3,8 @@ namespace StudioMitte\SentMails\EventListener; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; use Symfony\Component\Mailer\Envelope; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; @@ -13,8 +15,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\StringUtility; -class BeforeMailSentEventListener +class BeforeMailSentEventListener implements LoggerAwareInterface { + use LoggerAwareTrait; private array $blindedConfiguration = [ 'dsn' => '******', @@ -26,36 +29,43 @@ class BeforeMailSentEventListener public function __invoke(BeforeMailerSentMessageEvent $event): void { - /** @var Email $sentMessage */ - $sentMessage = $event->getMessage(); - /** @var Email $originalMessage */ - $originalMessage = $event->getMessage(); + try { + /** @var Email $sentMessage */ + $sentMessage = $event->getMessage(); + /** @var Email $originalMessage */ + $originalMessage = $event->getMessage(); - $customId = StringUtility::getUniqueId('mail_'); + $customId = StringUtility::getUniqueId('mail_'); - $sentMessage->getHeaders()->addTextHeader('X-SentMail_Custom', $customId); + $sentMessage->getHeaders()->addTextHeader('X-SentMail_Custom', $customId); - $isReply = get_class($originalMessage) === RawMessage::class; + $isReply = get_class($originalMessage) === RawMessage::class; - $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_sentmail_mail'); - $connection->insert('tx_sentmail_mail', [ - 'crdate' => time(), - 'subject' => (string)($isReply ? '' : $originalMessage->getHeaders()->getHeaderBody('Subject')), - 'sender' => $this->convertAddresses($originalMessage->getFrom()), - 'receiver' => $this->convertAddresses( $originalMessage->getTo()), - 'bcc' => $this->convertAddresses($originalMessage->getBcc()), - 'cc' => $this->convertAddresses($originalMessage->getCc()), - 'debug' => '', - 'message_id' => $customId, - 'message' => $sentMessage->toString(), - 'original_message' => $originalMessage->toString(), - 'envelope_original' => serialize($event->getEnvelope() ?: Envelope::create($originalMessage)), - 'internal_id' => $customId, - 'email_serialized' => $originalMessage instanceof Email ? serialize($originalMessage) : '', - 'settings' => json_encode($this->getSettings()), - ]); - $sentMessage->getHeaders()->remove('X-SentMail_ID'); - $sentMessage->getHeaders()->addTextHeader('X-SentMail_ID', $connection->lastInsertId('tx_sentmail_mail')); + $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_sentmail_mail'); + $connection->insert('tx_sentmail_mail', [ + 'crdate' => time(), + 'subject' => (string)($isReply ? '' : $originalMessage->getHeaders()->getHeaderBody('Subject')), + 'sender' => $this->convertAddresses($originalMessage->getFrom()), + 'receiver' => $this->convertAddresses( $originalMessage->getTo()), + 'bcc' => $this->convertAddresses($originalMessage->getBcc()), + 'cc' => $this->convertAddresses($originalMessage->getCc()), + 'debug' => '', + 'message_id' => $customId, + 'message' => $sentMessage->toString(), + 'original_message' => $originalMessage->toString(), + 'envelope_original' => serialize($event->getEnvelope() ?: Envelope::create($originalMessage)), + 'internal_id' => $customId, + 'email_serialized' => $originalMessage instanceof Email ? serialize($originalMessage) : '', + 'settings' => json_encode($this->getSettings()), + ]); + $sentMessage->getHeaders()->remove('X-SentMail_ID'); + $sentMessage->getHeaders()->addTextHeader('X-SentMail_ID', $connection->lastInsertId('tx_sentmail_mail')); + + } catch (\Throwable $e) { + $this->logger->warning('[SentMails] Error during BeforeMailSentEventListener: ', [ + $e->getMessage(), + ]); + } } /** diff --git a/Classes/Repository/MailRepository.php b/Classes/Repository/MailRepository.php index b260690..f597aa8 100644 --- a/Classes/Repository/MailRepository.php +++ b/Classes/Repository/MailRepository.php @@ -28,11 +28,9 @@ public function getMails(): array ->executeQuery()->fetchAllAssociative(); } - public function getMailRow(int $id): array + public function getMailRow(int $id): ?array { - $row = BackendUtility::getRecord(self::TABLE_NAME, $id); - - return (array) $row; + return BackendUtility::getRecord(self::TABLE_NAME, $id); } public function getMailsBySearch(string $searchTerm): array