diff --git a/src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php b/src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php index 12d45c30..f5154563 100644 --- a/src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php +++ b/src/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandler.php @@ -5,6 +5,7 @@ namespace PhpList\Core\Domain\Messaging\MessageHandler; use Doctrine\ORM\EntityManagerInterface; +use PhpList\Core\Domain\Configuration\Service\UserPersonalizer; use PhpList\Core\Domain\Messaging\Exception\MessageSizeLimitExceededException; use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; use PhpList\Core\Domain\Messaging\Message\SyncCampaignProcessorMessage; @@ -56,6 +57,7 @@ public function __construct( private readonly EventLogManager $eventLogManager, private readonly MessageDataManager $messageDataManager, private readonly MessagePrecacheService $precacheService, + private readonly UserPersonalizer $userPersonalizer, ?int $maxMailSize = null, ) { $this->maxMailSize = $maxMailSize ?? 0; @@ -159,6 +161,8 @@ private function handleEmailSending( Message\MessageContent $precachedContent, ): void { $processed = $this->messagePreparator->processMessageLinks($campaign->getId(), $precachedContent, $subscriber); + $processed->setText($this->userPersonalizer->personalize($processed->getText(), $subscriber->getEmail())); + $processed->setFooter($this->userPersonalizer->personalize($processed->getFooter(), $subscriber->getEmail())); try { $email = $this->mailer->composeEmail($campaign, $subscriber, $processed); diff --git a/src/Domain/Messaging/Service/MessageProcessingPreparator.php b/src/Domain/Messaging/Service/MessageProcessingPreparator.php index aee1d9e7..549a439e 100644 --- a/src/Domain/Messaging/Service/MessageProcessingPreparator.php +++ b/src/Domain/Messaging/Service/MessageProcessingPreparator.php @@ -5,8 +5,6 @@ namespace PhpList\Core\Domain\Messaging\Service; use PhpList\Core\Domain\Analytics\Service\LinkTrackService; -use PhpList\Core\Domain\Configuration\Service\UserPersonalizer; -use PhpList\Core\Domain\Messaging\Model\Message; use PhpList\Core\Domain\Messaging\Model\Message\MessageContent; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; use PhpList\Core\Domain\Subscription\Model\Subscriber; @@ -24,7 +22,6 @@ public function __construct( private readonly MessageRepository $messageRepository, private readonly LinkTrackService $linkTrackService, private readonly TranslatorInterface $translator, - private readonly UserPersonalizer $userPersonalizer, ) { } @@ -78,16 +75,14 @@ public function processMessageLinks( $htmlText = $content->getText(); $footer = $content->getFooter(); - // todo: check other configured data that should be used in mail formatting/creation + // todo: check if getTextMessage should replace links as well if ($htmlText !== null) { $htmlText = $this->replaceLinks($savedLinks, $htmlText); - $htmlText = $this->userPersonalizer->personalize($htmlText, $subscriber->getEmail()); $content->setText($htmlText); } if ($footer !== null) { $footer = $this->replaceLinks($savedLinks, $footer); - $footer = $this->userPersonalizer->personalize($footer, $subscriber->getEmail()); $content->setFooter($footer); } diff --git a/src/Domain/Messaging/Service/RateLimitedCampaignMailer.php b/src/Domain/Messaging/Service/RateLimitedCampaignMailer.php index de2b73c1..97027d16 100644 --- a/src/Domain/Messaging/Service/RateLimitedCampaignMailer.php +++ b/src/Domain/Messaging/Service/RateLimitedCampaignMailer.php @@ -20,23 +20,26 @@ public function __construct(MailerInterface $mailer, SendRateLimiter $limiter) $this->limiter = $limiter; } - public function composeEmail(Message $processed, Subscriber $subscriber, Message\MessageContent $content): Email - { + public function composeEmail( + Message $message, + Subscriber $subscriber, + Message\MessageContent $processedContent, + ): Email { $email = new Email(); - if ($processed->getOptions()->getFromField() !== '') { - $email->from($processed->getOptions()->getFromField()); + if ($message->getOptions()->getFromField() !== '') { + $email->from($message->getOptions()->getFromField()); } - if ($processed->getOptions()->getReplyTo() !== '') { - $email->replyTo($processed->getOptions()->getReplyTo()); + if ($message->getOptions()->getReplyTo() !== '') { + $email->replyTo($message->getOptions()->getReplyTo()); } return $email ->to($subscriber->getEmail()) - ->subject($content->getSubject()) + ->subject($processedContent->getSubject()) // todo: check HTML2Text functionality - ->text($content->getTextMessage()) - ->html($content->getText()); + ->text($processedContent->getTextMessage()) + ->html($processedContent->getText()); } /** diff --git a/tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php b/tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php index a565f558..0e61d5dd 100644 --- a/tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php +++ b/tests/Unit/Domain/Messaging/MessageHandler/CampaignProcessorMessageHandlerTest.php @@ -7,6 +7,7 @@ use Doctrine\ORM\EntityManagerInterface; use Exception; use PhpList\Core\Domain\Configuration\Service\Manager\EventLogManager; +use PhpList\Core\Domain\Configuration\Service\UserPersonalizer; use PhpList\Core\Domain\Messaging\Message\CampaignProcessorMessage; use PhpList\Core\Domain\Messaging\MessageHandler\CampaignProcessorMessageHandler; use PhpList\Core\Domain\Messaging\Model\Message; @@ -57,10 +58,18 @@ protected function setUp(): void $requeueHandler = $this->createMock(RequeueHandler::class); $this->translator = $this->createMock(Translator::class); $this->precacheService = $this->createMock(MessagePrecacheService::class); + $userPersonalizer = $this->createMock(UserPersonalizer::class); $timeLimiter->method('start'); $timeLimiter->method('shouldStop')->willReturn(false); + // Ensure personalization returns original text so assertions on replaced links remain valid + $userPersonalizer + ->method('personalize') + ->willReturnCallback(function (string $text) { + return $text; + }); + $this->handler = new CampaignProcessorMessageHandler( mailer: $this->mailer, entityManager: $this->entityManager, @@ -77,6 +86,7 @@ protected function setUp(): void eventLogManager: $this->createMock(EventLogManager::class), messageDataManager: $this->createMock(MessageDataManager::class), precacheService: $this->precacheService, + userPersonalizer: $userPersonalizer, maxMailSize: 0, ); } @@ -166,6 +176,8 @@ public function testInvokeWithValidSubscriberEmail(): void { $campaign = $this->createMock(Message::class); $content = $this->createContentMock(); + $content->method('getText')->willReturn('
Test HTML message
'); + $content->method('getFooter')->willReturn('Test footer message
'); $campaign->method('getContent')->willReturn($content); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); @@ -225,6 +237,8 @@ public function testInvokeWithMailerException(): void { $campaign = $this->createMock(Message::class); $content = $this->createContentMock(); + $content->method('getText')->willReturn('Test HTML message
'); + $content->method('getFooter')->willReturn('Test footer message
'); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getContent')->willReturn($content); $campaign->method('getMetadata')->willReturn($metadata); @@ -278,6 +292,8 @@ public function testInvokeWithMultipleSubscribers(): void { $campaign = $this->createCampaignMock(); $content = $this->createContentMock(); + $content->method('getText')->willReturn('Test HTML message
'); + $content->method('getFooter')->willReturn('Test footer message
'); $metadata = $this->createMock(MessageMetadata::class); $campaign->method('getMetadata')->willReturn($metadata); $campaign->method('getId')->willReturn(1); diff --git a/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php b/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php index b7530895..9ba29c46 100644 --- a/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php +++ b/tests/Unit/Domain/Messaging/Service/MessageProcessingPreparatorTest.php @@ -6,7 +6,6 @@ use PhpList\Core\Domain\Analytics\Model\LinkTrack; use PhpList\Core\Domain\Analytics\Service\LinkTrackService; -use PhpList\Core\Domain\Configuration\Service\UserPersonalizer; use PhpList\Core\Domain\Messaging\Model\Message\MessageContent; use PhpList\Core\Domain\Messaging\Repository\MessageRepository; use PhpList\Core\Domain\Messaging\Service\MessageProcessingPreparator; @@ -23,7 +22,6 @@ class MessageProcessingPreparatorTest extends TestCase private SubscriberRepository&MockObject $subscriberRepository; private MessageRepository&MockObject $messageRepository; private LinkTrackService&MockObject $linkTrackService; - private UserPersonalizer&MockObject $userPersonalizer; private OutputInterface&MockObject $output; private MessageProcessingPreparator $preparator; @@ -32,13 +30,6 @@ protected function setUp(): void $this->subscriberRepository = $this->createMock(SubscriberRepository::class); $this->messageRepository = $this->createMock(MessageRepository::class); $this->linkTrackService = $this->createMock(LinkTrackService::class); - $this->userPersonalizer = $this->createMock(UserPersonalizer::class); - // Ensure personalization returns original text so assertions on replaced links remain valid - $this->userPersonalizer - ->method('personalize') - ->willReturnCallback(function (string $text) { - return $text; - }); $this->output = $this->createMock(OutputInterface::class); $this->preparator = new MessageProcessingPreparator( @@ -46,7 +37,6 @@ protected function setUp(): void messageRepository: $this->messageRepository, linkTrackService: $this->linkTrackService, translator: new Translator('en'), - userPersonalizer: $this->userPersonalizer, ); }