Add NewsletterListingRepository, use it for newsletters data
[MAILPOET-2645]
This commit is contained in:
committed by
Jack Kitterhing
parent
f1e044aa28
commit
51882b43cf
@ -76,6 +76,45 @@ class NewslettersResponseBuilder {
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function buildForListing(NewsletterEntity $newsletter): array {
|
||||
$data = [
|
||||
'id' => (string)$newsletter->getId(), // (string) for BC
|
||||
'hash' => $newsletter->getHash(),
|
||||
'subject' => $newsletter->getSubject(),
|
||||
'type' => $newsletter->getType(),
|
||||
'status' => $newsletter->getStatus(),
|
||||
'sent_at' => ($sentAt = $newsletter->getSentAt()) ? $sentAt->format(self::DATE_FORMAT) : null,
|
||||
'updated_at' => $newsletter->getUpdatedAt()->format(self::DATE_FORMAT),
|
||||
'deleted_at' => ($deletedAt = $newsletter->getDeletedAt()) ? $deletedAt->format(self::DATE_FORMAT) : null,
|
||||
'segments' => [],
|
||||
'queue' => false,
|
||||
'statistics' => false,
|
||||
];
|
||||
|
||||
if ($newsletter->getType() === NewsletterEntity::TYPE_STANDARD) {
|
||||
$data['segments'] = $this->buildSegments($newsletter);
|
||||
$data['statistics'] = $this->newslettersStatsRepository->getStatistics($newsletter)->asArray();
|
||||
$data['queue'] = ($queue = $newsletter->getLatestQueue()) ? $this->buildQueue($queue) : false; // false for BC
|
||||
} elseif (in_array($newsletter->getType(), [NewsletterEntity::TYPE_WELCOME, NewsletterEntity::TYPE_AUTOMATIC], true)) {
|
||||
$data['segments'] = [];
|
||||
$data['statistics'] = $this->newslettersStatsRepository->getStatistics($newsletter)->asArray();
|
||||
$data['options'] = $this->buildOptions($newsletter);
|
||||
$data['total_sent'] = $this->newslettersStatsRepository->getTotalSentCount($newsletter);
|
||||
$data['total_scheduled'] = (int)SendingQueue::findTaskByNewsletterId($newsletter->getId())
|
||||
->where('tasks.status', SendingQueue::STATUS_SCHEDULED)
|
||||
->count();
|
||||
} elseif ($newsletter->getType() === NewsletterEntity::TYPE_NOTIFICATION) {
|
||||
$data['segments'] = $this->buildSegments($newsletter);
|
||||
$data['children_count'] = $this->newslettersStatsRepository->getChildrenCount($newsletter);
|
||||
$data['options'] = $this->buildOptions($newsletter);
|
||||
} elseif ($newsletter->getType() === NewsletterEntity::TYPE_NOTIFICATION_HISTORY) {
|
||||
$data['segments'] = $this->buildSegments($newsletter);
|
||||
$data['statistics'] = $this->newslettersStatsRepository->getStatistics($newsletter)->asArray();
|
||||
$data['queue'] = ($queue = $newsletter->getLatestQueue()) ? $this->buildQueue($queue) : false; // false for BC
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function buildSegments(NewsletterEntity $newsletter) {
|
||||
$output = [];
|
||||
foreach ($newsletter->getNewsletterSegments() as $newsletterSegment) {
|
||||
|
@ -19,6 +19,7 @@ use MailPoet\Models\NewsletterSegment;
|
||||
use MailPoet\Models\NewsletterTemplate;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Newsletter\Listing\NewsletterListingRepository;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\Newsletter\Renderer\Renderer;
|
||||
use MailPoet\Newsletter\Scheduler\PostNotificationScheduler;
|
||||
@ -26,8 +27,8 @@ use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||
use MailPoet\Newsletter\Url as NewsletterUrl;
|
||||
use MailPoet\Services\AuthorizedEmailsController;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Tasks\Sending as SendingTask;
|
||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||
use MailPoet\WooCommerce\Helper as WCHelper;
|
||||
use MailPoet\WP\Emoji;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
@ -43,9 +44,6 @@ class Newsletters extends APIEndpoint {
|
||||
/** @var WPFunctions */
|
||||
private $wp;
|
||||
|
||||
/** @var WCHelper */
|
||||
private $woocommerceHelper;
|
||||
|
||||
/** @var SettingsController */
|
||||
private $settings;
|
||||
|
||||
@ -62,6 +60,9 @@ class Newsletters extends APIEndpoint {
|
||||
/** @var NewslettersRepository */
|
||||
private $newslettersRepository;
|
||||
|
||||
/** @var NewsletterListingRepository */
|
||||
private $newsletterListingRepository;
|
||||
|
||||
/** @var NewslettersResponseBuilder */
|
||||
private $newslettersResponseBuilder;
|
||||
|
||||
@ -84,11 +85,11 @@ class Newsletters extends APIEndpoint {
|
||||
Listing\BulkActionController $bulkAction,
|
||||
Listing\Handler $listingHandler,
|
||||
WPFunctions $wp,
|
||||
WCHelper $woocommerceHelper,
|
||||
SettingsController $settings,
|
||||
CronHelper $cronHelper,
|
||||
AuthorizedEmailsController $authorizedEmailsController,
|
||||
NewslettersRepository $newslettersRepository,
|
||||
NewsletterListingRepository $newsletterListingRepository,
|
||||
NewslettersResponseBuilder $newslettersResponseBuilder,
|
||||
PostNotificationScheduler $postNotificationScheduler,
|
||||
MailerFactory $mailer,
|
||||
@ -99,11 +100,11 @@ class Newsletters extends APIEndpoint {
|
||||
$this->bulkAction = $bulkAction;
|
||||
$this->listingHandler = $listingHandler;
|
||||
$this->wp = $wp;
|
||||
$this->woocommerceHelper = $woocommerceHelper;
|
||||
$this->settings = $settings;
|
||||
$this->cronHelper = $cronHelper;
|
||||
$this->authorizedEmailsController = $authorizedEmailsController;
|
||||
$this->newslettersRepository = $newslettersRepository;
|
||||
$this->newsletterListingRepository = $newsletterListingRepository;
|
||||
$this->newslettersResponseBuilder = $newslettersResponseBuilder;
|
||||
$this->postNotificationScheduler = $postNotificationScheduler;
|
||||
$this->mailer = $mailer;
|
||||
@ -520,51 +521,35 @@ class Newsletters extends APIEndpoint {
|
||||
}
|
||||
|
||||
public function listing($data = []) {
|
||||
$listingData = $this->listingHandler->get('\MailPoet\Models\Newsletter', $data);
|
||||
$definition = $this->listingHandler->getListingDefinition($data);
|
||||
$items = $this->newsletterListingRepository->getData($definition);
|
||||
$count = $this->newsletterListingRepository->getCount($definition);
|
||||
$filters = Newsletter::filters($data);
|
||||
$groups = Newsletter::groups($data);
|
||||
|
||||
$data = [];
|
||||
foreach ($listingData['items'] as $newsletter) {
|
||||
foreach ($items as $newsletter) {
|
||||
$queue = false;
|
||||
|
||||
if ($newsletter->type === Newsletter::TYPE_STANDARD) {
|
||||
$newsletter
|
||||
->withSegments(true)
|
||||
->withSendingQueue()
|
||||
->withStatistics($this->woocommerceHelper);
|
||||
} else if ($newsletter->type === Newsletter::TYPE_WELCOME || $newsletter->type === Newsletter::TYPE_AUTOMATIC) {
|
||||
$newsletter
|
||||
->withOptions()
|
||||
->withTotalSent()
|
||||
->withScheduledToBeSent()
|
||||
->withStatistics($this->woocommerceHelper);
|
||||
} else if ($newsletter->type === Newsletter::TYPE_NOTIFICATION) {
|
||||
$newsletter
|
||||
->withOptions()
|
||||
->withSegments(true)
|
||||
->withChildrenCount();
|
||||
} else if ($newsletter->type === Newsletter::TYPE_NOTIFICATION_HISTORY) {
|
||||
$newsletter
|
||||
->withSegments(true)
|
||||
->withSendingQueue()
|
||||
->withStatistics($this->woocommerceHelper);
|
||||
if (in_array($newsletter->getStatus(), [Newsletter::STATUS_SENT, Newsletter::STATUS_SENDING], true)) {
|
||||
$queue = SendingTask::getByNewsletterId($newsletter->getId());
|
||||
}
|
||||
|
||||
if ($newsletter->status === Newsletter::STATUS_SENT ||
|
||||
$newsletter->status === Newsletter::STATUS_SENDING
|
||||
) {
|
||||
$queue = $newsletter->getQueue();
|
||||
}
|
||||
|
||||
// get preview url
|
||||
$newsletter->previewUrl = NewsletterUrl::getViewInBrowserUrl($newsletter, null, $queue);
|
||||
|
||||
$data[] = $this->wp->applyFilters('mailpoet_api_newsletters_listing_item', $newsletter->asArray());
|
||||
$newsletterData = $this->newslettersResponseBuilder->buildForListing($newsletter);
|
||||
$newsletterData['preview_url'] = NewsletterUrl::getViewInBrowserUrl(
|
||||
(object)[
|
||||
'id' => $newsletter->getId(),
|
||||
'hash' => $newsletter->getHash(),
|
||||
],
|
||||
null,
|
||||
$queue
|
||||
);
|
||||
$data[] = $this->wp->applyFilters('mailpoet_api_newsletters_listing_item', $newsletterData);
|
||||
}
|
||||
|
||||
return $this->successResponse($data, [
|
||||
'count' => $listingData['count'],
|
||||
'filters' => $listingData['filters'],
|
||||
'groups' => $listingData['groups'],
|
||||
'count' => $count,
|
||||
'filters' => $filters,
|
||||
'groups' => $groups,
|
||||
'mta_log' => $this->settings->get('mta_log'),
|
||||
'mta_method' => $this->settings->get('mta.method'),
|
||||
'cron_accessible' => $this->cronHelper->isDaemonAccessible(),
|
||||
|
@ -254,6 +254,7 @@ class ContainerConfigurator implements IContainerConfigurator {
|
||||
// Newsletter
|
||||
$container->autowire(\MailPoet\Newsletter\AutomatedLatestContent::class)->setPublic(true);
|
||||
$container->autowire(\MailPoet\Newsletter\NewslettersRepository::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Listing\NewsletterListingRepository::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Statistics\NewsletterStatisticsRepository::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Scheduler\WelcomeScheduler::class);
|
||||
$container->autowire(\MailPoet\Newsletter\Scheduler\PostNotificationScheduler::class);
|
||||
|
109
lib/Newsletter/Listing/NewsletterListingRepository.php
Normal file
109
lib/Newsletter/Listing/NewsletterListingRepository.php
Normal file
@ -0,0 +1,109 @@
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Newsletter\Listing;
|
||||
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Listing\ListingRepository;
|
||||
use MailPoetVendor\Doctrine\ORM\QueryBuilder;
|
||||
|
||||
class NewsletterListingRepository extends ListingRepository {
|
||||
private static $supportedStatuses = [
|
||||
NewsletterEntity::STATUS_DRAFT,
|
||||
NewsletterEntity::STATUS_SCHEDULED,
|
||||
NewsletterEntity::STATUS_SENDING,
|
||||
NewsletterEntity::STATUS_SENT,
|
||||
NewsletterEntity::STATUS_ACTIVE,
|
||||
];
|
||||
|
||||
private static $supportedTypes = [
|
||||
NewsletterEntity::TYPE_STANDARD,
|
||||
NewsletterEntity::TYPE_WELCOME,
|
||||
NewsletterEntity::TYPE_AUTOMATIC,
|
||||
NewsletterEntity::TYPE_NOTIFICATION,
|
||||
NewsletterEntity::TYPE_NOTIFICATION_HISTORY,
|
||||
];
|
||||
|
||||
protected function applySelectClause(QueryBuilder $queryBuilder) {
|
||||
$queryBuilder->select("PARTIAL n.{id,subject,hash,type,status,sentAt,updatedAt,deletedAt}");
|
||||
}
|
||||
|
||||
protected function applyFromClause(QueryBuilder $queryBuilder) {
|
||||
$queryBuilder->from(NewsletterEntity::class, 'n');
|
||||
}
|
||||
|
||||
protected function applyGroup(QueryBuilder $queryBuilder, string $group) {
|
||||
// include/exclude deleted
|
||||
if ($group === 'trash') {
|
||||
$queryBuilder->andWhere('n.deletedAt IS NOT NULL');
|
||||
} else {
|
||||
$queryBuilder->andWhere('n.deletedAt IS NULL');
|
||||
}
|
||||
|
||||
if (!in_array($group, self::$supportedStatuses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$queryBuilder
|
||||
->andWhere('n.status = :status')
|
||||
->setParameter('status', $group);
|
||||
}
|
||||
|
||||
protected function applySearch(QueryBuilder $queryBuilder, string $search) {
|
||||
$queryBuilder
|
||||
->andWhere('n.subject LIKE :search')
|
||||
->setParameter('search', "%$search%"); // TODO: escape?
|
||||
}
|
||||
|
||||
protected function applyFilters(QueryBuilder $queryBuilder, array $filters) {
|
||||
$segmentId = $filters['segment'] ?? null;
|
||||
if ($segmentId) {
|
||||
$queryBuilder
|
||||
->join('n.newsletterSegments', 'ns')
|
||||
->andWhere('ns.segment = :segmentId')
|
||||
->setParameter('segmentId', $segmentId);
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyParameters(QueryBuilder $queryBuilder, array $parameters) {
|
||||
$type = $parameters['type'] ?? null;
|
||||
$group = $parameters['group'] ?? null;
|
||||
$parentId = $parameters['parent_id'] ?? null;
|
||||
|
||||
if ($type) {
|
||||
$this->applyType($queryBuilder, $type, $group);
|
||||
}
|
||||
|
||||
if ($parentId) {
|
||||
$queryBuilder
|
||||
->andWhere('n.parent = :parentId')
|
||||
->setParameter('parentId', $parentId);
|
||||
}
|
||||
}
|
||||
|
||||
protected function applySorting(QueryBuilder $queryBuilder, string $sortBy, string $sortOrder) {
|
||||
if ($sortBy === 'sentAt') {
|
||||
$queryBuilder->addSelect('CASE WHEN n.sentAt IS NULL THEN 1 ELSE 0 END AS HIDDEN sentAtIsNull');
|
||||
$queryBuilder->addOrderBy('sentAtIsNull', 'DESC');
|
||||
}
|
||||
$queryBuilder->addOrderBy("n.$sortBy", $sortOrder);
|
||||
}
|
||||
|
||||
private function applyType(QueryBuilder $queryBuilder, string $type, string $group = null) {
|
||||
if (!in_array($type, self::$supportedTypes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($type === NewsletterEntity::TYPE_AUTOMATIC && $group) {
|
||||
$queryBuilder
|
||||
->join('n.options', 'o')
|
||||
->join('o.optionField', 'opf')
|
||||
->andWhere('o.value = :group')
|
||||
->setParameter('group', $group)
|
||||
->andWhere('opf.newsletterType = n.type');
|
||||
} else {
|
||||
$queryBuilder
|
||||
->andWhere('n.type = :type')
|
||||
->setParameter('type', $type);
|
||||
}
|
||||
}
|
||||
}
|
@ -24,9 +24,11 @@ use MailPoet\Models\ScheduledTask;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Newsletter\Listing\NewsletterListingRepository;
|
||||
use MailPoet\Newsletter\NewslettersRepository;
|
||||
use MailPoet\Newsletter\Scheduler\PostNotificationScheduler;
|
||||
use MailPoet\Newsletter\Scheduler\Scheduler;
|
||||
use MailPoet\Newsletter\Statistics\NewsletterStatisticsRepository;
|
||||
use MailPoet\Newsletter\Url;
|
||||
use MailPoet\Router\Router;
|
||||
use MailPoet\Services\AuthorizedEmailsController;
|
||||
@ -38,6 +40,7 @@ use MailPoet\WooCommerce\Helper as WCHelper;
|
||||
use MailPoet\WP\Emoji;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
use MailPoetVendor\Carbon\Carbon;
|
||||
use MailPoetVendor\Doctrine\ORM\EntityManager;
|
||||
use MailPoetVendor\Idiorm\ORM;
|
||||
|
||||
class NewslettersTest extends \MailPoetTest {
|
||||
@ -56,7 +59,17 @@ class NewslettersTest extends \MailPoetTest {
|
||||
parent::_before();
|
||||
$this->subscriptionUrlFactory = SubscriptionUrlFactory::getInstance();
|
||||
$this->cronHelper = ContainerWrapper::getInstance()->get(CronHelper::class);
|
||||
$this->endpoint = ContainerWrapper::getInstance()->get(Newsletters::class);
|
||||
$this->endpoint = Stub::copy(
|
||||
ContainerWrapper::getInstance()->get(Newsletters::class),
|
||||
[
|
||||
'newslettersResponseBuilder' => new NewslettersResponseBuilder(
|
||||
new NewsletterStatisticsRepository(
|
||||
$this->diContainer->get(EntityManager::class),
|
||||
$this->makeEmpty(WCHelper::class)
|
||||
)
|
||||
),
|
||||
]
|
||||
);
|
||||
$this->newsletter = Newsletter::createOrUpdate(
|
||||
[
|
||||
'subject' => 'My Standard Newsletter',
|
||||
@ -144,11 +157,11 @@ class NewslettersTest extends \MailPoetTest {
|
||||
ContainerWrapper::getInstance()->get(BulkActionController::class),
|
||||
ContainerWrapper::getInstance()->get(Handler::class),
|
||||
$wp,
|
||||
$this->makeEmpty(WCHelper::class),
|
||||
SettingsController::getInstance(),
|
||||
$this->cronHelper,
|
||||
$this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::never()]),
|
||||
ContainerWrapper::getInstance()->get(NewslettersRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewsletterListingRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class),
|
||||
ContainerWrapper::getInstance()->get(PostNotificationScheduler::class),
|
||||
ContainerWrapper::getInstance()->get(Mailer::class),
|
||||
@ -200,11 +213,11 @@ class NewslettersTest extends \MailPoetTest {
|
||||
ContainerWrapper::getInstance()->get(BulkActionController::class),
|
||||
ContainerWrapper::getInstance()->get(Handler::class),
|
||||
$wp,
|
||||
$this->makeEmpty(WCHelper::class),
|
||||
SettingsController::getInstance(),
|
||||
$this->cronHelper,
|
||||
$this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::once()]),
|
||||
ContainerWrapper::getInstance()->get(NewslettersRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewsletterListingRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class),
|
||||
ContainerWrapper::getInstance()->get(PostNotificationScheduler::class),
|
||||
ContainerWrapper::getInstance()->get(Mailer::class),
|
||||
@ -433,11 +446,11 @@ class NewslettersTest extends \MailPoetTest {
|
||||
ContainerWrapper::getInstance()->get(BulkActionController::class),
|
||||
ContainerWrapper::getInstance()->get(Handler::class),
|
||||
ContainerWrapper::getInstance()->get(WPFunctions::class),
|
||||
$this->makeEmpty(WCHelper::class),
|
||||
SettingsController::getInstance(),
|
||||
$this->cronHelper,
|
||||
$this->make(AuthorizedEmailsController::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewsletterListingRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class),
|
||||
ContainerWrapper::getInstance()->get(PostNotificationScheduler::class),
|
||||
ContainerWrapper::getInstance()->get(Mailer::class),
|
||||
@ -604,11 +617,11 @@ class NewslettersTest extends \MailPoetTest {
|
||||
ContainerWrapper::getInstance()->get(BulkActionController::class),
|
||||
ContainerWrapper::getInstance()->get(Handler::class),
|
||||
$wp,
|
||||
$this->makeEmpty(WCHelper::class),
|
||||
SettingsController::getInstance(),
|
||||
$this->cronHelper,
|
||||
$this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::never()]),
|
||||
ContainerWrapper::getInstance()->get(NewslettersRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewsletterListingRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class),
|
||||
ContainerWrapper::getInstance()->get(PostNotificationScheduler::class),
|
||||
ContainerWrapper::getInstance()->get(Mailer::class),
|
||||
@ -953,11 +966,11 @@ class NewslettersTest extends \MailPoetTest {
|
||||
ContainerWrapper::getInstance()->get(BulkActionController::class),
|
||||
ContainerWrapper::getInstance()->get(Handler::class),
|
||||
$wp,
|
||||
$this->makeEmpty(WCHelper::class),
|
||||
SettingsController::getInstance(),
|
||||
$this->cronHelper,
|
||||
ContainerWrapper::getInstance()->get(AuthorizedEmailsController::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewsletterListingRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class),
|
||||
ContainerWrapper::getInstance()->get(PostNotificationScheduler::class),
|
||||
ContainerWrapper::getInstance()->get(Mailer::class),
|
||||
@ -1066,6 +1079,7 @@ class NewslettersTest extends \MailPoetTest {
|
||||
public function _after() {
|
||||
ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . NewsletterSegment::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . NewsletterOption::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . NewsletterOptionField::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||
ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||
|
Reference in New Issue
Block a user