diff --git a/lib/Config/Shortcodes.php b/lib/Config/Shortcodes.php
index 846399c942..30dd85b330 100644
--- a/lib/Config/Shortcodes.php
+++ b/lib/Config/Shortcodes.php
@@ -2,10 +2,13 @@
namespace MailPoet\Config;
+use MailPoet\Entities\NewsletterEntity;
+use MailPoet\Entities\ScheduledTaskEntity;
+use MailPoet\Entities\SendingQueueEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Form\Widget;
-use MailPoet\Models\Newsletter;
use MailPoet\Models\Subscriber;
+use MailPoet\Newsletter\NewslettersRepository;
use MailPoet\Newsletter\Url as NewsletterUrl;
use MailPoet\Segments\SegmentSubscribersRepository;
use MailPoet\Subscribers\SubscribersRepository;
@@ -28,18 +31,23 @@ class Shortcodes {
/** @var NewsletterUrl */
private $newsletterUrl;
+ /** @var NewslettersRepository */
+ private $newslettersRepository;
+
public function __construct(
Pages $subscriptionPages,
WPFunctions $wp,
SegmentSubscribersRepository $segmentSubscribersRepository,
SubscribersRepository $subscribersRepository,
- NewsletterUrl $newsletterUrl
+ NewsletterUrl $newsletterUrl,
+ NewslettersRepository $newslettersRepository
) {
$this->subscriptionPages = $subscriptionPages;
$this->wp = $wp;
$this->segmentSubscribersRepository = $segmentSubscribersRepository;
$this->subscribersRepository = $subscribersRepository;
$this->newsletterUrl = $newsletterUrl;
+ $this->newslettersRepository = $newslettersRepository;
}
public function init() {
@@ -110,7 +118,7 @@ class Shortcodes {
$html = '';
- $newsletters = Newsletter::getArchives($segmentIds);
+ $newsletters = $this->newslettersRepository->getArchives($segmentIds);
$subscriber = $this->subscribersRepository->getCurrentWPUser();
$subscriber = $subscriber ? Subscriber::findOne($subscriber->getId()) : null;
@@ -127,10 +135,17 @@ class Shortcodes {
}
$html .= '
';
foreach ($newsletters as $newsletter) {
- $queue = $newsletter->queue()->findOne();
+ $queue = $newsletter->getQueues()->first();
+
+ if ($queue instanceof SendingQueueEntity) {
+ $task = $queue->getTask();
+ } else {
+ $task = null;
+ }
+
$html .= '- ' .
'' .
- $this->wp->applyFilters('mailpoet_archive_date', $newsletter) .
+ $this->wp->applyFilters('mailpoet_archive_date', $task) .
'
' .
$this->wp->applyFilters('mailpoet_archive_subject', $newsletter, $subscriber, $queue) .
@@ -142,18 +157,27 @@ class Shortcodes {
return $html;
}
- public function renderArchiveDate($newsletter) {
+ public function renderArchiveDate($task) {
+ $timestamp = null;
+
+ if ($task instanceof ScheduledTaskEntity) {
+ $processedAt = $task->getProcessedAt();
+ if (!is_null($processedAt)) {
+ $timestamp = $processedAt->getTimestamp();
+ }
+ }
+
return $this->wp->dateI18n(
$this->wp->getOption('date_format'),
- strtotime($newsletter->processedAt)
+ $timestamp
);
}
- public function renderArchiveSubject($newsletter, $subscriber, $queue) {
+ public function renderArchiveSubject(NewsletterEntity $newsletter, $subscriber, SendingQueueEntity $queue) {
$previewUrl = $this->newsletterUrl->getViewInBrowserUrl($newsletter, $subscriber, $queue);
return ''
- . esc_attr($newsletter->newsletterRenderedSubject) .
+ . esc_attr((string)$queue->getNewsletterRenderedSubject()) .
'';
}
}
diff --git a/lib/Models/Newsletter.php b/lib/Models/Newsletter.php
index a0324ca777..39e69318e1 100644
--- a/lib/Models/Newsletter.php
+++ b/lib/Models/Newsletter.php
@@ -506,42 +506,6 @@ class Newsletter extends Model {
->findMany();
}
- public static function getArchives($segmentIds = []) {
- $orm = self::tableAlias('newsletters')
- ->distinct()->select('newsletters.*')
- ->select('newsletter_rendered_subject')
- ->select('task_id')
- ->whereIn('newsletters.type', [
- self::TYPE_STANDARD,
- self::TYPE_NOTIFICATION_HISTORY,
- ])
- ->join(
- MP_SENDING_QUEUES_TABLE,
- 'queues.newsletter_id = newsletters.id',
- 'queues'
- )
- ->join(
- MP_SCHEDULED_TASKS_TABLE,
- 'queues.task_id = tasks.id',
- 'tasks'
- )
- ->where('tasks.status', SendingQueue::STATUS_COMPLETED)
- ->whereNull('newsletters.deleted_at')
- ->select('tasks.processed_at')
- ->orderByDesc('tasks.processed_at')
- ->orderByAsc('task_id');
-
- if (!empty($segmentIds)) {
- $orm->join(
- MP_NEWSLETTER_SEGMENT_TABLE,
- 'newsletter_segments.newsletter_id = newsletters.id',
- 'newsletter_segments'
- )
- ->whereIn('newsletter_segments.segment_id', $segmentIds);
- }
- return $orm->findMany();
- }
-
public static function getByHash($hash) {
return parent::where('hash', $hash)
->findOne();
diff --git a/lib/Newsletter/NewslettersRepository.php b/lib/Newsletter/NewslettersRepository.php
index 1091bd8f0a..794225b5e0 100644
--- a/lib/Newsletter/NewslettersRepository.php
+++ b/lib/Newsletter/NewslettersRepository.php
@@ -129,6 +129,40 @@ class NewslettersRepository extends Repository {
];
}
+ /**
+ * @param array $segmentIds
+ * @return NewsletterEntity[]
+ */
+ public function getArchives(array $segmentIds = []) {
+ $types = [
+ NewsletterEntity::TYPE_STANDARD,
+ NewsletterEntity::TYPE_NOTIFICATION_HISTORY,
+ ];
+
+ $queryBuilder = $this->entityManager
+ ->createQueryBuilder()
+ ->select('n')
+ ->distinct()
+ ->from(NewsletterEntity::class, 'n')
+ ->innerJoin(SendingQueueEntity::class, 'sq', Join::WITH, 'sq.newsletter = n.id')
+ ->innerJoin(ScheduledTaskEntity::class, 'st', Join::WITH, 'st.id = sq.task')
+ ->where('n.type IN (:types)')
+ ->andWhere('st.status = :statusCompleted')
+ ->andWhere('n.deletedAt IS NULL')
+ ->orderBy('st.processedAt', 'DESC')
+ ->addOrderBy('st.id', 'ASC')
+ ->setParameter('types', $types)
+ ->setParameter('statusCompleted', SendingQueueEntity::STATUS_COMPLETED);
+
+ if (!empty($segmentIds)) {
+ $queryBuilder->innerJoin(NewsletterSegmentEntity::class, 'ns', Join::WITH, 'ns.newsletter = n.id')
+ ->andWhere('ns.segment IN (:segmentIds)')
+ ->setParameter('segmentIds', $segmentIds);
+ }
+
+ return $queryBuilder->getQuery()->getResult();
+ }
+
/**
* @return int - number of processed ids
*/
diff --git a/lib/Newsletter/Url.php b/lib/Newsletter/Url.php
index f4b17d1b8a..0e6d0eb8c5 100644
--- a/lib/Newsletter/Url.php
+++ b/lib/Newsletter/Url.php
@@ -2,6 +2,8 @@
namespace MailPoet\Newsletter;
+use MailPoet\Entities\NewsletterEntity;
+use MailPoet\Entities\SendingQueueEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Models\Subscriber as SubscriberModel;
use MailPoet\Router\Endpoints\ViewInBrowser as ViewInBrowserEndpoint;
@@ -45,22 +47,30 @@ class Url {
}
public function createUrlDataObject($newsletter, $subscriber, $queue, $preview) {
+ if ($newsletter instanceof NewsletterEntity) {
+ $newsletterId = (!empty($newsletter->getId())) ? (int)$newsletter->getId() : 0;
+ $newsletterHash = (!empty($newsletter->getHash())) ? $newsletter->getHash() : 0;
+ } else {
+ $newsletterId = (!empty($newsletter->id)) ? (int)$newsletter->id : 0;
+ $newsletterHash = (!empty($newsletter->hash)) ? $newsletter->hash : 0;
+ }
+
+ if ($queue instanceof SendingQueueEntity) {
+ $sendingQueueId = (!empty($queue->getId())) ? (int)$queue->getId() : 0;
+ } else {
+ $sendingQueueId = (!empty($queue->id)) ? (int)$queue->id : 0;
+ }
+
return [
- (!empty($newsletter->id)) ?
- (int)$newsletter->id :
- 0,
- (!empty($newsletter->hash)) ?
- $newsletter->hash :
- 0,
+ $newsletterId,
+ $newsletterHash,
(!empty($subscriber->id)) ?
(int)$subscriber->id :
0,
(!empty($subscriber->token)) ?
$subscriber->token :
0,
- (!empty($queue->id)) ?
- (int)$queue->id :
- 0,
+ $sendingQueueId,
(int)$preview,
];
}
diff --git a/tests/integration/Models/NewsletterTest.php b/tests/integration/Models/NewsletterTest.php
index 334b8053e6..df7f6fbd37 100644
--- a/tests/integration/Models/NewsletterTest.php
+++ b/tests/integration/Models/NewsletterTest.php
@@ -204,93 +204,6 @@ class NewsletterTest extends \MailPoetTest {
expect($newsletter->event)->equals($association->value);
}
- public function testItGetsArchiveNewslettersForSegments() {
- // clear the DB
- $this->_after();
-
- $types = [
- Newsletter::TYPE_STANDARD,
- Newsletter::TYPE_NOTIFICATION_HISTORY,
- ];
- $newsletters = [];
- $sendingQueues[] = [];
- for ($i = 0; $i < count($types); $i++) {
- $newsletters[$i] = Newsletter::createOrUpdate(
- [
- 'subject' => 'My Standard Newsletter',
- 'preheader' => 'Pre Header',
- 'type' => $types[$i],
- ]
- );
- $sendingQueues[$i] = SendingTask::create();
- $sendingQueues[$i]->newsletter_id = $newsletters[$i]->id;
- $sendingQueues[$i]->status = SendingQueue::STATUS_COMPLETED;
- $sendingQueues[$i]->save();
- }
- // set segment association for the last newsletter
- $newsletterSegment = NewsletterSegment::create();
- $newsletterSegment->newsletterId = end($newsletters[1])->id;
- $newsletterSegment->segmentId = 123;
- $newsletterSegment->save();
-
- expect(Newsletter::findMany())->count(2);
-
- // return archives in segment 123
- $results = Newsletter::getArchives([123]);
- expect($results)->count(1);
- expect($results[0]->id)->equals($newsletters[1]->id);
- expect($results[0]->type)->equals(Newsletter::TYPE_NOTIFICATION_HISTORY);
- }
-
- public function testItGetsAllArchiveNewsletters() {
- // clear the DB
- $this->_after();
-
- $types = [
- Newsletter::TYPE_STANDARD,
- Newsletter::TYPE_STANDARD, // should be returned
- Newsletter::TYPE_WELCOME,
- Newsletter::TYPE_AUTOMATIC,
- Newsletter::TYPE_NOTIFICATION,
- Newsletter::TYPE_NOTIFICATION_HISTORY, // should be returned
- Newsletter::TYPE_NOTIFICATION_HISTORY,
- ];
- $newsletters = [];
- $sendingQueues[] = [];
- for ($i = 0; $i < count($types); $i++) {
- $newsletters[$i] = Newsletter::createOrUpdate(
- [
- 'subject' => 'My Standard Newsletter',
- 'preheader' => 'Pre Header',
- 'type' => $types[$i],
- ]
- );
- $sendingQueues[$i] = SendingTask::create();
- $sendingQueues[$i]->newsletter_id = $newsletters[$i]->id;
- $sendingQueues[$i]->status = SendingQueue::STATUS_COMPLETED;
- $sendingQueues[$i]->save();
- }
- // set the sending queue status of the first newsletter to null
- $sendingQueues[0]->status = null;
- $sendingQueues[0]->save();
-
- // trash the last newsletter
- end($newsletters)->trash();
-
- expect(Newsletter::findMany())->count(7);
-
- // archives return only:
- // 1. STANDARD and NOTIFICATION HISTORY newsletters
- // 2. active newsletters (i.e., not trashed)
- // 3. with sending queue records that are COMPLETED
- $results = Newsletter::getArchives();
- expect($results)->count(2);
- expect($results[0]->id)->equals($newsletters[1]->id);
- expect($results[0]->type)->equals(Newsletter::TYPE_STANDARD);
- expect($results[1]->id)->equals($newsletters[5]->id);
- expect($results[1]->type)->equals(Newsletter::TYPE_NOTIFICATION_HISTORY);
- }
-
public function testItGeneratesHashOnNewsletterSave() {
expect(strlen($this->newsletter->hash))
->equals(Security::HASH_LENGTH);
diff --git a/tests/integration/Newsletter/NewsletterRepositoryTest.php b/tests/integration/Newsletter/NewsletterRepositoryTest.php
index 0964605406..5e5df54fe2 100644
--- a/tests/integration/Newsletter/NewsletterRepositoryTest.php
+++ b/tests/integration/Newsletter/NewsletterRepositoryTest.php
@@ -19,8 +19,10 @@ use MailPoet\Entities\StatisticsOpenEntity;
use MailPoet\Entities\StatisticsWooCommercePurchaseEntity;
use MailPoet\Entities\StatsNotificationEntity;
use MailPoet\Entities\SubscriberEntity;
+use MailPoet\Models\Newsletter;
use MailPoet\Newsletter\Sending\ScheduledTaskSubscribersRepository;
use MailPoet\Tasks\Sending as SendingTask;
+use MailPoetVendor\Carbon\Carbon;
class NewsletterRepositoryTest extends \MailPoetTest {
/** @var NewslettersRepository */
@@ -211,8 +213,65 @@ class NewsletterRepositoryTest extends \MailPoetTest {
expect($this->entityManager->find(StatisticsWooCommercePurchaseEntity::class, $statisticsPurchase->getId()))->null();
}
- public function _after() {
- $this->cleanup();
+ public function testItGetsArchiveNewslettersForSegments() {
+ $types = [
+ NewsletterEntity::TYPE_STANDARD,
+ NewsletterEntity::TYPE_NOTIFICATION_HISTORY,
+ ];
+
+ list($newsletters) = $this->createNewslettersAndSendingTasks($types);
+
+ // set segment association for the last newsletter
+ $segment = new SegmentEntity('Segment', SegmentEntity::TYPE_DEFAULT, 'description');
+ $this->entityManager->persist($segment);
+ $newsletterSegment = new NewsletterSegmentEntity($newsletters[1], $segment);
+ $this->entityManager->persist($newsletterSegment);
+ $this->entityManager->flush();
+
+ expect($this->repository->findAll())->count(2);
+
+ // return archives in a given segment
+ $results = $this->repository->getArchives([$segment->getId()]);
+
+ expect($results)->count(1);
+ expect($results[0]->getId())->equals($newsletters[1]->getId());
+ expect($results[0]->getType())->equals(NewsletterEntity::TYPE_NOTIFICATION_HISTORY);
+ }
+
+ public function testItGetsAllArchiveNewsletters() {
+ $types = [
+ Newsletter::TYPE_STANDARD,
+ Newsletter::TYPE_STANDARD, // should be returned
+ Newsletter::TYPE_WELCOME,
+ Newsletter::TYPE_AUTOMATIC,
+ Newsletter::TYPE_NOTIFICATION,
+ Newsletter::TYPE_NOTIFICATION_HISTORY, // should be returned
+ Newsletter::TYPE_NOTIFICATION_HISTORY,
+ ];
+
+ list($newsletters, $sendingQueues) = $this->createNewslettersAndSendingTasks($types);
+
+ // set the sending queue status of the first newsletter to null
+ $sendingQueues[0]->status = null;
+ $sendingQueues[0]->save();
+
+ // trash the last newsletter
+ end($newsletters)->setDeletedAt(new Carbon());
+ $this->entityManager->flush();
+
+ expect($this->repository->findAll())->count(7);
+
+ // archives return only:
+ // 1. STANDARD and NOTIFICATION HISTORY newsletters
+ // 2. active newsletters (i.e., not trashed)
+ // 3. with sending queue records that are COMPLETED
+ $results = $this->repository->getArchives();
+
+ expect($results)->count(2);
+ expect($results[0]->getId())->equals($newsletters[1]->getId());
+ expect($results[0]->getType())->equals(NewsletterEntity::TYPE_STANDARD);
+ expect($results[1]->getId())->equals($newsletters[5]->getId());
+ expect($results[1]->getType())->equals(NewsletterEntity::TYPE_NOTIFICATION_HISTORY);
}
private function createNewsletter(string $type, string $status = NewsletterEntity::STATUS_DRAFT, $parent = null): NewsletterEntity {
@@ -227,6 +286,21 @@ class NewsletterRepositoryTest extends \MailPoetTest {
return $newsletter;
}
+ private function createNewslettersAndSendingTasks(array $types): array {
+ $newsletters = [];
+ $sendingQueues = [];
+ for ($i = 0; $i < count($types); $i++) {
+ $newsletters[$i] = $this->createNewsletter($types[$i]);
+
+ $sendingQueues[$i] = SendingTask::create();
+ $sendingQueues[$i]->newsletter_id = $newsletters[$i]->getId();
+ $sendingQueues[$i]->status = SendingQueueEntity::STATUS_COMPLETED;
+ $sendingQueues[$i]->save();
+ }
+
+ return [$newsletters, $sendingQueues];
+ }
+
private function createQueueWithTaskAndSegmentAndSubscribers(NewsletterEntity $newsletter, $status = ScheduledTaskEntity::STATUS_SCHEDULED): SendingQueueEntity {
$task = new ScheduledTaskEntity();
$task->setType(SendingTask::TASK_TYPE);