diff --git a/lib/Newsletter/ViewInBrowser/ViewInBrowserController.php b/lib/Newsletter/ViewInBrowser/ViewInBrowserController.php index e238bd73fc..388953e91f 100644 --- a/lib/Newsletter/ViewInBrowser/ViewInBrowserController.php +++ b/lib/Newsletter/ViewInBrowser/ViewInBrowserController.php @@ -2,9 +2,10 @@ namespace MailPoet\Newsletter\ViewInBrowser; +use MailPoet\Entities\SendingQueueEntity; use MailPoet\Models\Newsletter; -use MailPoet\Models\SendingQueue; use MailPoet\Models\Subscriber; +use MailPoet\Newsletter\Sending\SendingQueuesRepository; use MailPoet\Newsletter\Url as NewsletterUrl; use MailPoet\Subscribers\LinkTokens; use MailPoet\Subscribers\SubscribersRepository; @@ -19,14 +20,19 @@ class ViewInBrowserController { /** @var SubscribersRepository */ private $subscribersRepository; + /** @var SendingQueuesRepository */ + private $sendingQueuesRepository; + public function __construct( LinkTokens $linkTokens, ViewInBrowserRenderer $viewInBrowserRenderer, + SendingQueuesRepository $sendingQueuesRepository, SubscribersRepository $subscribersRepository ) { $this->linkTokens = $linkTokens; $this->viewInBrowserRenderer = $viewInBrowserRenderer; $this->subscribersRepository = $subscribersRepository; + $this->sendingQueuesRepository = $sendingQueuesRepository; } public function view(array $data) { @@ -43,7 +49,7 @@ class ViewInBrowserController { // if queue and subscriber exist, subscriber must have received the newsletter $queue = $this->getQueue($newsletter, $data); - if (!$isPreview && $queue && $subscriber && !$queue->isSubscriberProcessed($subscriber->getId())) { + if (!$isPreview && $queue && $subscriber && !$this->sendingQueuesRepository->isSubscriberProcessed($queue, $subscriber)) { throw new \InvalidArgumentException("Subscriber did not receive the newsletter yet"); } @@ -95,7 +101,7 @@ class ViewInBrowserController { return $subscriber; } - private function getQueue(Newsletter $newsletter, array $data) { + private function getQueue(Newsletter $newsletter, array $data): ?SendingQueueEntity { // queue is optional; try to find it if it's not defined and this is not a welcome email if ($newsletter->type === Newsletter::TYPE_WELCOME) { return null; @@ -106,10 +112,8 @@ class ViewInBrowserController { return null; } - $queue = !empty($data['queue_id']) - ? SendingQueue::findOne($data['queue_id']) - : SendingQueue::where('newsletter_id', $newsletter->id)->findOne(); - - return $queue ?: null; + return !empty($data['queue_id']) + ? $this->sendingQueuesRepository->findOneById($data['queue_id']) + : $this->sendingQueuesRepository->findOneBy(['newsletter' => $newsletter->id]); } } diff --git a/lib/Newsletter/ViewInBrowser/ViewInBrowserRenderer.php b/lib/Newsletter/ViewInBrowser/ViewInBrowserRenderer.php index 52c436c475..3918d42481 100644 --- a/lib/Newsletter/ViewInBrowser/ViewInBrowserRenderer.php +++ b/lib/Newsletter/ViewInBrowser/ViewInBrowserRenderer.php @@ -48,11 +48,16 @@ class ViewInBrowserRenderer { bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, - SendingQueue $queue = null + SendingQueueEntity $queue = null ) { $wpUserPreview = $isPreview; if ($queue && $queue->getNewsletterRenderedBody()) { - $newsletterBody = $queue->getNewsletterRenderedBody('html'); + $body = $queue->getNewsletterRenderedBody(); + if (is_array($body)) { + $newsletterBody = $body['html']; + } else { + $newsletterBody = ''; + } $newsletterBody = $this->emoji->decodeEmojisInBody($newsletterBody); // rendered newsletter body has shortcodes converted to links; we need to // isolate "view in browser", "unsubscribe" and "manage subscription" links @@ -61,7 +66,7 @@ class ViewInBrowserRenderer { if ($wpUserPreview && preg_match(Links::getLinkRegex(), $newsletterBody)) { $newsletterBody = Links::convertHashedLinksToShortcodesAndUrls( $newsletterBody, - $queueId = $queue->id, + $queue->getId(), $convertAll = true ); // remove open tracking link @@ -84,7 +89,7 @@ class ViewInBrowserRenderer { if (!$wpUserPreview && $queue && $subscriber && $this->isTrackingEnabled) { $renderedNewsletter = Links::replaceSubscriberData( $subscriber->getId(), - $queue->id, + $queue->getId(), $renderedNewsletter ); } @@ -93,16 +98,9 @@ class ViewInBrowserRenderer { /** this is here to prepare entities for the shortcodes library, when this whole file uses doctrine, this can be deleted */ private function prepareShortcodes($newsletter, $subscriber, $queue, $wpUserPreview) { - /** @var SendingQueuesRepository $sendingQueueRepository */ - $sendingQueueRepository = ContainerWrapper::getInstance()->get(SendingQueuesRepository::class); /** @var NewslettersRepository $newsletterRepository */ $newsletterRepository = ContainerWrapper::getInstance()->get(NewslettersRepository::class); - /** @var SubscribersRepository $subscribersRepository */ - $subscribersRepository = ContainerWrapper::getInstance()->get(SubscribersRepository::class); - if ($queue instanceof Sending || $queue instanceof SendingQueue) { - $queue = $sendingQueueRepository->findOneById($queue->id); - } if ($queue instanceof SendingQueueEntity) { $this->shortcodes->setQueue($queue); } @@ -112,9 +110,7 @@ class ViewInBrowserRenderer { if ($newsletter instanceof NewsletterEntity) { $this->shortcodes->setNewsletter($newsletter); } - if ($subscriber instanceof Subscriber) { - $subscriber = $subscribersRepository->findOneById($subscriber->id); - } + $this->shortcodes->setWpUserPreview($wpUserPreview); if ($subscriber instanceof SubscriberEntity) { $this->shortcodes->setSubscriber($subscriber); diff --git a/lib/Router/Endpoints/Track.php b/lib/Router/Endpoints/Track.php index 81a0f33b4e..2cbfc34710 100644 --- a/lib/Router/Endpoints/Track.php +++ b/lib/Router/Endpoints/Track.php @@ -110,10 +110,7 @@ class Track { return $data; } // check if the newsletter was sent to the subscriber - $queue = SendingQueue::findOne($data->queue_id); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.NotCamelCaps - if (!$queue instanceof SendingQueue) return false; - - return ($queue->isSubscriberProcessed($data->subscriber->getId())) ? + return ($this->sendingQueuesRepository->isSubscriberProcessed($data->queue, $data->subscriber)) ? $data : false; } diff --git a/tests/integration/Models/SendingQueueTest.php b/tests/integration/Models/SendingQueueTest.php index 958d1a983a..cf410a4f86 100644 --- a/tests/integration/Models/SendingQueueTest.php +++ b/tests/integration/Models/SendingQueueTest.php @@ -26,23 +26,6 @@ class SendingQueueTest extends \MailPoetTest { ]; } - public function testItChecksProcessedSubscribersForOldQueues() { - $subscriberId = 123; - expect($this->queue->isSubscriberProcessed($subscriberId))->false(); - $this->queue->subscribers = ['processed' => [$subscriberId]]; - expect($this->queue->isSubscriberProcessed($subscriberId))->true(); - } - - public function testItChecksProcessedSubscribersForNewQueues() { - $subscriberId = 123; - $queue = SendingTask::create(); - $queue->setSubscribers([$subscriberId]); - $queue->save(); - expect($queue->isSubscriberProcessed($subscriberId))->false(); - $queue->updateProcessedSubscribers([$subscriberId]); - expect($queue->isSubscriberProcessed($subscriberId))->true(); - } - public function testItReadsSerializedRenderedNewsletterBody() { $queue = $this->queue; $data = [ diff --git a/tests/integration/Newsletter/Sending/SendingQueuesRepositoryTest.php b/tests/integration/Newsletter/Sending/SendingQueuesRepositoryTest.php index 85525a4f94..be92c76b55 100644 --- a/tests/integration/Newsletter/Sending/SendingQueuesRepositoryTest.php +++ b/tests/integration/Newsletter/Sending/SendingQueuesRepositoryTest.php @@ -73,11 +73,10 @@ class SendingQueuesRepositoryTest extends \MailPoetTest { $newsletter = new NewsletterEntity(); $newsletter->setType('type'); $newsletter->setSubject('Subject'); - $this->newsletter = $newsletter; $this->entityManager->persist($newsletter); $queue = new SendingQueueEntity(); - $queue->setNewsletter($this->newsletter); + $queue->setNewsletter($newsletter); $queue->setTask($task); $this->entityManager->persist($queue); diff --git a/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserControllerTest.php b/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserControllerTest.php index 9237d793e4..7c38c734a7 100644 --- a/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserControllerTest.php +++ b/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserControllerTest.php @@ -3,15 +3,18 @@ namespace MailPoet\Newsletter\ViewInBrowser; use Codeception\Stub\Expected; +use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\ScheduledTaskEntity; +use MailPoet\Entities\SendingQueueEntity; use MailPoet\Entities\SubscriberEntity; use MailPoet\Models\Newsletter; -use MailPoet\Models\ScheduledTask; use MailPoet\Models\SendingQueue; use MailPoet\Models\Subscriber; +use MailPoet\Newsletter\NewslettersRepository; +use MailPoet\Newsletter\Sending\SendingQueuesRepository; use MailPoet\Subscribers\LinkTokens; use MailPoet\Subscribers\SubscribersRepository; use MailPoet\Tasks\Sending as SendingTask; -use MailPoetVendor\Idiorm\ORM; class ViewInBrowserControllerTest extends \MailPoetTest { /** @var ViewInBrowserController */ @@ -35,11 +38,15 @@ class ViewInBrowserControllerTest extends \MailPoetTest { /** @var mixed[] */ private $browserPreviewData; + /** @var SendingQueuesRepository */ + private $sendingQueuesRepository; + public function _before() { // instantiate class $this->viewInBrowserController = $this->diContainer->get(ViewInBrowserController::class); $this->linkTokens = $this->diContainer->get(LinkTokens::class); $this->subscribersRepository = $this->diContainer->get(SubscribersRepository::class); + $this->sendingQueuesRepository = $this->diContainer->get(SendingQueuesRepository::class); // create newsletter $newsletter = Newsletter::create(); @@ -120,7 +127,7 @@ class ViewInBrowserControllerTest extends \MailPoetTest { public function testItSetsSubscriberToLoggedInWPUserWhenPreviewIsEnabled() { $viewInBrowserRenderer = $this->make(ViewInBrowserRenderer::class, [ - 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueue $queue = null) { + 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueueEntity $queue = null) { assert($subscriber !== null); // PHPStan expect($subscriber)->notNull(); expect($subscriber->getId())->equals(1); @@ -141,10 +148,10 @@ class ViewInBrowserControllerTest extends \MailPoetTest { public function testItGetsQueueByQueueId() { $viewInBrowserRenderer = $this->make(ViewInBrowserRenderer::class, [ - 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueue $queue = null) { + 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueueEntity $queue = null) { assert($queue !== null); // PHPStan expect($queue)->notNull(); - expect($queue->id)->same($this->sendingTask->id); + expect($queue->getId())->equals($this->sendingTask->id); }), ]); @@ -157,10 +164,10 @@ class ViewInBrowserControllerTest extends \MailPoetTest { public function testItGetsQueueByNewsletter() { $viewInBrowserRenderer = $this->make(ViewInBrowserRenderer::class, [ - 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueue $queue = null) { + 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueueEntity $queue = null) { assert($queue !== null); // PHPStan expect($queue)->notNull(); - expect($queue->id)->same($this->sendingTask->queue()->id); + expect($queue->getId())->equals($this->sendingTask->queue()->id); }), ]); @@ -173,7 +180,7 @@ class ViewInBrowserControllerTest extends \MailPoetTest { public function testItResetsQueueForWelcomeEmails() { $viewInBrowserRenderer = $this->make(ViewInBrowserRenderer::class, [ - 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueue $queue = null) { + 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueueEntity $queue = null) { expect($queue)->null(); }), ]); @@ -189,7 +196,7 @@ class ViewInBrowserControllerTest extends \MailPoetTest { public function testItResetsQueueForAutomaticEmailsInPreview() { $viewInBrowserRenderer = $this->make(ViewInBrowserRenderer::class, [ - 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueue $queue = null) { + 'render' => Expected::once(function (bool $isPreview, Newsletter $newsletter, SubscriberEntity $subscriber = null, SendingQueueEntity $queue = null) { expect($queue)->null(); }), ]); @@ -206,10 +213,10 @@ class ViewInBrowserControllerTest extends \MailPoetTest { } public function _after() { - ORM::raw_execute('TRUNCATE ' . Newsletter::$_table); - ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); - ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table); - ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); + $this->truncateEntity(NewsletterEntity::class); + $this->truncateEntity(SubscriberEntity::class); + $this->truncateEntity(ScheduledTaskEntity::class); + $this->truncateEntity(SendingQueueEntity::class); // reset WP user role $wpUser = wp_get_current_user(); $wpUser->add_role('administrator'); @@ -228,6 +235,7 @@ class ViewInBrowserControllerTest extends \MailPoetTest { return new ViewInBrowserController( $this->linkTokens, $viewInBrowserRenderer, + $this->sendingQueuesRepository, $this->subscribersRepository ); } diff --git a/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserRendererTest.php b/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserRendererTest.php index 896e0eb4b2..a8f87faab1 100644 --- a/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserRendererTest.php +++ b/tests/integration/Newsletter/ViewInBrowser/ViewInBrowserRendererTest.php @@ -3,6 +3,10 @@ namespace MailPoet\Newsletter\ViewInBrowser; use Codeception\Stub\Expected; +use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\NewsletterLinkEntity; +use MailPoet\Entities\ScheduledTaskEntity; +use MailPoet\Entities\SendingQueueEntity; use MailPoet\Entities\SubscriberEntity; use MailPoet\Models\Newsletter; use MailPoet\Models\NewsletterLink; @@ -11,6 +15,7 @@ use MailPoet\Models\SendingQueue; use MailPoet\Models\Subscriber; use MailPoet\Newsletter\Links\Links; use MailPoet\Newsletter\Renderer\Renderer; +use MailPoet\Newsletter\Sending\SendingQueuesRepository; use MailPoet\Newsletter\Shortcodes\Shortcodes; use MailPoet\Router\Router; use MailPoet\Settings\SettingsController; @@ -165,22 +170,26 @@ class ViewInBrowserRendererTest extends \MailPoetTest { $this->diContainer->get(Shortcodes::class), $this->diContainer->get(Renderer::class) ); + /** @var SendingQueuesRepository $sendingQueueRepository */ + $sendingQueueRepository = $this->diContainer->get(SendingQueuesRepository::class); $renderedBody = $viewInBrowser->render( $preview = false, $this->newsletter, $this->subscriber, - $this->sendingTask->queue() + $sendingQueueRepository->findOneById($this->sendingTask->queue()->id) ); expect($renderedBody)->regExp('/Newsletter from queue/'); } public function testItConvertsShortcodes() { + /** @var SendingQueuesRepository $sendingQueueRepository */ + $sendingQueueRepository = $this->diContainer->get(SendingQueuesRepository::class); $this->settings->set('tracking.enabled', false); $renderedBody = $this->viewInBrowserRenderer->render( $preview = false, $this->newsletter, $this->subscriber, - $this->sendingTask->queue() + $sendingQueueRepository->findOneById($this->sendingTask->queue()->id) ); expect($renderedBody)->stringContainsString('Hello, First'); expect($renderedBody)->stringContainsString(Router::NAME . '&endpoint=view_in_browser'); @@ -188,8 +197,11 @@ class ViewInBrowserRendererTest extends \MailPoetTest { public function testItRewritesLinksToRouterEndpointWhenTrackingIsEnabled() { $this->settings->set('tracking.enabled', true); - $queue = $this->sendingTask->queue(); - $queue->newsletterRenderedBody = $this->queueRenderedNewsletterWithTracking; + /** @var SendingQueuesRepository $sendingQueueRepository */ + $sendingQueueRepository = $this->diContainer->get(SendingQueuesRepository::class); + $queue = $sendingQueueRepository->findOneById($this->sendingTask->queue()->id); + $this->assertInstanceOf(SendingQueueEntity::class, $queue); + $queue->setNewsletterRenderedBody($this->queueRenderedNewsletterWithTracking); $renderedBody = $this->viewInBrowserRenderer->render( $preview = false, $this->newsletter, @@ -200,8 +212,11 @@ class ViewInBrowserRendererTest extends \MailPoetTest { } public function testItConvertsHashedLinksToUrlsWhenPreviewIsEnabledAndNewsletterWasSent() { - $queue = $this->sendingTask->queue(); - $queue->newsletterRenderedBody = $this->queueRenderedNewsletterWithTracking; + /** @var SendingQueuesRepository $sendingQueueRepository */ + $sendingQueueRepository = $this->diContainer->get(SendingQueuesRepository::class); + $queue = $sendingQueueRepository->findOneById($this->sendingTask->queue()->id); + $this->assertInstanceOf(SendingQueueEntity::class, $queue); + $queue->setNewsletterRenderedBody($this->queueRenderedNewsletterWithTracking); $renderedBody = $this->viewInBrowserRenderer->render( $preview = true, $this->newsletter, @@ -214,8 +229,11 @@ class ViewInBrowserRendererTest extends \MailPoetTest { } public function testRemovesOpenTrackingTagWhenPreviewIsEnabledAndNewsletterWasSent() { - $queue = $this->sendingTask->queue(); - $queue->newsletterRenderedBody = $this->queueRenderedNewsletterWithTracking; + /** @var SendingQueuesRepository $sendingQueueRepository */ + $sendingQueueRepository = $this->diContainer->get(SendingQueuesRepository::class); + $queue = $sendingQueueRepository->findOneById($this->sendingTask->queue()->id); + $this->assertInstanceOf(SendingQueueEntity::class, $queue); + $queue->setNewsletterRenderedBody($this->queueRenderedNewsletterWithTracking); $renderedBody = $this->viewInBrowserRenderer->render( $preview = true, $this->newsletter, @@ -228,10 +246,10 @@ class ViewInBrowserRendererTest extends \MailPoetTest { } public function _after() { - ORM::raw_execute('TRUNCATE ' . Newsletter::$_table); - ORM::raw_execute('TRUNCATE ' . NewsletterLink::$_table); - ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); - ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table); - ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); + $this->truncateEntity(NewsletterEntity::class); + $this->truncateEntity(SubscriberEntity::class); + $this->truncateEntity(ScheduledTaskEntity::class); + $this->truncateEntity(SendingQueueEntity::class); + $this->truncateEntity(NewsletterLinkEntity::class); } } diff --git a/tests/integration/Router/Endpoints/TrackTest.php b/tests/integration/Router/Endpoints/TrackTest.php index 32fbc262fd..7238ce6501 100644 --- a/tests/integration/Router/Endpoints/TrackTest.php +++ b/tests/integration/Router/Endpoints/TrackTest.php @@ -13,6 +13,7 @@ use MailPoet\Models\Newsletter; use MailPoet\Models\NewsletterLink; use MailPoet\Models\SendingQueue; use MailPoet\Models\Subscriber; +use MailPoet\Newsletter\Sending\SendingQueuesRepository; use MailPoet\Router\Endpoints\Track; use MailPoet\Subscribers\LinkTokens; use MailPoet\Tasks\Sending as SendingTask; @@ -106,6 +107,7 @@ class TrackTest extends \MailPoetTest { $this->entityManager->flush(); $track = Stub::make(Track::class, [ 'linkTokens' => new LinkTokens, + 'sendingQueuesRepository' => $this->diContainer->get(SendingQueuesRepository::class), 'terminate' => function($code) { expect($code)->equals(403); }, @@ -131,6 +133,7 @@ class TrackTest extends \MailPoetTest { $this->entityManager->persist($subscriber); $this->entityManager->flush(); $data->subscriber->setId($subscriber->getId()); + $data->subscriber = $subscriber; expect($this->track->_validateTrackData($data))->false(); }