Use doctrine in stats notifications for auto emails
[MAILPOET-2439]
This commit is contained in:
committed by
Jack Kitterhing
parent
5a2edff9fe
commit
95564cfa32
@ -5,11 +5,14 @@ namespace MailPoet\Cron\Workers\StatsNotifications;
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Config\Renderer;
|
||||
use MailPoet\Cron\Workers\SimpleWorker;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Features\FeaturesController;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Mailer\MetaInfo;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\ScheduledTask;
|
||||
use MailPoet\Newsletter\Statistics\NewsletterStatistics;
|
||||
use MailPoet\Newsletter\Statistics\NewsletterStatisticsRepository;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\WooCommerce\Helper as WCHelper;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
@ -26,20 +29,24 @@ class AutomatedEmails extends SimpleWorker {
|
||||
/** @var Renderer */
|
||||
private $renderer;
|
||||
|
||||
/** @var WCHelper */
|
||||
private $woocommerce_helper;
|
||||
|
||||
/** @var MetaInfo */
|
||||
private $mailerMetaInfo;
|
||||
|
||||
/** @var float */
|
||||
public $timer;
|
||||
|
||||
/** @var StatsNotificationsRepository */
|
||||
private $repository;
|
||||
|
||||
/** @var NewsletterStatisticsRepository */
|
||||
private $newsletter_statistics_repository;
|
||||
|
||||
function __construct(
|
||||
Mailer $mailer,
|
||||
Renderer $renderer,
|
||||
SettingsController $settings,
|
||||
WCHelper $woocommerce_helper,
|
||||
StatsNotificationsRepository $repository,
|
||||
NewsletterStatisticsRepository $newsletter_statistics_repository,
|
||||
MetaInfo $mailerMetaInfo,
|
||||
$timer = false
|
||||
) {
|
||||
@ -47,9 +54,10 @@ class AutomatedEmails extends SimpleWorker {
|
||||
$this->mailer = $mailer;
|
||||
$this->settings = $settings;
|
||||
$this->renderer = $renderer;
|
||||
$this->woocommerce_helper = $woocommerce_helper;
|
||||
$this->mailerMetaInfo = $mailerMetaInfo;
|
||||
$this->timer = $timer ?: microtime(true);
|
||||
$this->repository = $repository;
|
||||
$this->newsletter_statistics_repository = $newsletter_statistics_repository;
|
||||
}
|
||||
|
||||
function checkProcessingRequirements() {
|
||||
@ -107,44 +115,37 @@ class AutomatedEmails extends SimpleWorker {
|
||||
}
|
||||
|
||||
protected function getNewsletters() {
|
||||
$newsletters = Newsletter
|
||||
::whereNull('deleted_at')
|
||||
->whereIn('type', [Newsletter::TYPE_AUTOMATIC, Newsletter::TYPE_WELCOME])
|
||||
->where('status', Newsletter::STATUS_ACTIVE)
|
||||
->orderByAsc('subject')
|
||||
->findMany();
|
||||
foreach ($newsletters as $newsletter) {
|
||||
$newsletter
|
||||
->withSendingQueue()
|
||||
->withTotalSent()
|
||||
->withStatistics($this->woocommerce_helper);
|
||||
}
|
||||
$result = [];
|
||||
$newsletters = $this->repository->getDueAutomatedNewsletters();
|
||||
foreach ($newsletters as $newsletter) {
|
||||
if ($newsletter->total_sent) {
|
||||
$result[] = $newsletter;
|
||||
$statistics = $this->newsletter_statistics_repository->getStatistics($newsletter);
|
||||
if ($statistics->getTotalSentCount()) {
|
||||
$result[] = [
|
||||
'statistics' => $statistics,
|
||||
'newsletter' => $newsletter,
|
||||
];
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Newsletter[] $newsletters
|
||||
* @return array
|
||||
*/
|
||||
private function prepareContext(array $newsletters) {
|
||||
$context = [
|
||||
'linkSettings' => WPFunctions::get()->getSiteUrl(null, '/wp-admin/admin.php?page=mailpoet-settings#basics'),
|
||||
'newsletters' => [],
|
||||
];
|
||||
foreach ($newsletters as $newsletter) {
|
||||
$clicked = ($newsletter->statistics['clicked'] * 100) / $newsletter->total_sent;
|
||||
$opened = ($newsletter->statistics['opened'] * 100) / $newsletter->total_sent;
|
||||
foreach ($newsletters as $row) {
|
||||
/** @var NewsletterStatistics $statistics */
|
||||
$statistics = $row['statistics'];
|
||||
/** @var NewsletterEntity $newsletter */
|
||||
$newsletter = $row['newsletter'];
|
||||
$clicked = ($statistics->getClickCount() * 100) / $statistics->getTotalSentCount();
|
||||
$opened = ($statistics->getOpenCount() * 100) / $statistics->getTotalSentCount();
|
||||
$context['newsletters'][] = [
|
||||
'linkStats' => WPFunctions::get()->getSiteUrl(null, '/wp-admin/admin.php?page=mailpoet-newsletters#/stats/' . $newsletter->id),
|
||||
'linkStats' => WPFunctions::get()->getSiteUrl(null, '/wp-admin/admin.php?page=mailpoet-newsletters#/stats/' . $newsletter->getId()),
|
||||
'clicked' => $clicked,
|
||||
'opened' => $opened,
|
||||
'subject' => $newsletter->subject,
|
||||
'subject' => $newsletter->getSubject(),
|
||||
];
|
||||
}
|
||||
return $context;
|
||||
|
@ -4,6 +4,7 @@ namespace MailPoet\Cron\Workers\StatsNotifications;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Doctrine\Repository;
|
||||
use MailPoet\Entities\NewsletterEntity;
|
||||
use MailPoet\Entities\ScheduledTaskEntity;
|
||||
use MailPoet\Entities\StatsNotificationEntity;
|
||||
|
||||
@ -56,5 +57,24 @@ class StatsNotificationsRepository extends Repository {
|
||||
}
|
||||
return $query->getQuery()->getResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NewsletterEntity[]
|
||||
*/
|
||||
public function getDueAutomatedNewsletters() {
|
||||
return $this->entity_manager
|
||||
->createQueryBuilder()
|
||||
->select('n')
|
||||
->from(NewsletterEntity::class, 'n')
|
||||
->where('n.status = :status')
|
||||
->setParameter(':status', NewsletterEntity::STATUS_ACTIVE)
|
||||
->andWhere('n.deleted_at is null')
|
||||
->andWhere('n.type IN (:types)')
|
||||
->setParameter('types', [NewsletterEntity::TYPE_AUTOMATIC, NewsletterEntity::TYPE_WELCOME])
|
||||
->orderBy('n.subject')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,15 @@ class WorkersFactory {
|
||||
|
||||
/** @return StatsNotificationsWorkerForAutomatedEmails */
|
||||
function createStatsNotificationsWorkerForAutomatedEmails($timer) {
|
||||
return new StatsNotificationsWorkerForAutomatedEmails($this->mailer, $this->renderer, $this->settings, $this->woocommerce_helper, $this->mailerMetaInfo, $timer);
|
||||
return new StatsNotificationsWorkerForAutomatedEmails(
|
||||
$this->mailer,
|
||||
$this->renderer,
|
||||
$this->settings,
|
||||
$this->stats_notifications_repository,
|
||||
$this->newsletter_statistics_repository,
|
||||
$this->mailerMetaInfo,
|
||||
$timer
|
||||
);
|
||||
}
|
||||
|
||||
/** @return SendingServiceKeyCheckWorker */
|
||||
|
@ -3,10 +3,15 @@
|
||||
namespace MailPoet\Cron\Workers\StatsNotifications;
|
||||
|
||||
use MailPoet\Config\Renderer;
|
||||
use MailPoet\DI\ContainerWrapper;
|
||||
use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Mailer\MetaInfo;
|
||||
use MailPoet\Models\Newsletter;
|
||||
use MailPoet\Models\ScheduledTask;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\StatisticsClicks;
|
||||
use MailPoet\Models\StatisticsOpens;
|
||||
use MailPoet\Newsletter\Statistics\NewsletterStatisticsRepository;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\WooCommerce\Helper as WCHelper;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
@ -28,6 +33,7 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
function _before() {
|
||||
parent::_before();
|
||||
\ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table);
|
||||
\ORM::raw_execute('TRUNCATE ' . Newsletter::$_table);
|
||||
ScheduledTask::createOrUpdate([
|
||||
'type' => AutomatedEmails::TASK_TYPE,
|
||||
'status' => null,
|
||||
@ -37,17 +43,15 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
$this->mailer = $this->createMock(Mailer::class);
|
||||
$this->renderer = $this->createMock(Renderer::class);
|
||||
$this->settings = new SettingsController();
|
||||
$this->stats_notifications = $this->getMockBuilder(AutomatedEmails::class)
|
||||
->enableOriginalConstructor()
|
||||
->setConstructorArgs([
|
||||
$this->mailer,
|
||||
$this->renderer,
|
||||
$this->settings,
|
||||
$this->makeEmpty(WCHelper::class),
|
||||
new MetaInfo,
|
||||
])
|
||||
->setMethods(['getNewsletters'])
|
||||
->getMock();
|
||||
$this->stats_notifications = new AutomatedEmails(
|
||||
$this->mailer,
|
||||
$this->renderer,
|
||||
$this->settings,
|
||||
ContainerWrapper::getInstance()->get(StatsNotificationsRepository::class),
|
||||
ContainerWrapper::getInstance()->get(NewsletterStatisticsRepository::class),
|
||||
new MetaInfo
|
||||
);
|
||||
|
||||
$this->settings->set(Worker::SETTINGS_KEY, [
|
||||
'automated' => true,
|
||||
'address' => 'email@example.com',
|
||||
@ -76,15 +80,11 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
expect($this->stats_notifications->checkProcessingRequirements())->equals(false);
|
||||
}
|
||||
|
||||
function testItDoesntWorkIfEnabled() {
|
||||
function testItDoesWorkIfEnabled() {
|
||||
expect($this->stats_notifications->checkProcessingRequirements())->equals(true);
|
||||
}
|
||||
|
||||
function testItDoesntRenderIfNoNewslettersFound() {
|
||||
$this->stats_notifications
|
||||
->expects($this->once())
|
||||
->method('getNewsletters')
|
||||
->will($this->returnValue([]));
|
||||
$this->renderer->expects($this->never())
|
||||
->method('render');
|
||||
$this->mailer->expects($this->never())
|
||||
@ -96,20 +96,15 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItRenders() {
|
||||
$newsletter1 = Newsletter::create();
|
||||
$newsletter1->hydrate([
|
||||
'id' => 8765,
|
||||
Newsletter::createOrUpdate([
|
||||
'id' => 8763,
|
||||
'subject' => 'Subject',
|
||||
'total_sent' => 10,
|
||||
'statistics' => [
|
||||
'clicked' => 5,
|
||||
'opened' => 2,
|
||||
],
|
||||
'type' => 'welcome',
|
||||
'status' => 'active',
|
||||
]);
|
||||
$this->stats_notifications
|
||||
->expects($this->once())
|
||||
->method('getNewsletters')
|
||||
->will($this->returnValue([$newsletter1]));
|
||||
$this->createQueue(8763, 10);
|
||||
$this->createClicks(8763, 5);
|
||||
$this->createOpens(8763, 2);
|
||||
$this->renderer->expects($this->exactly(2))
|
||||
->method('render');
|
||||
$this->renderer->expects($this->at(0))
|
||||
@ -129,20 +124,16 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItSends() {
|
||||
$newsletter1 = Newsletter::create();
|
||||
$newsletter1->hydrate([
|
||||
'id' => 8765,
|
||||
Newsletter::createOrUpdate([
|
||||
'id' => 8763,
|
||||
'subject' => 'Subject',
|
||||
'total_sent' => 10,
|
||||
'statistics' => [
|
||||
'clicked' => 5,
|
||||
'opened' => 2,
|
||||
],
|
||||
'type' => 'welcome',
|
||||
'status' => 'active',
|
||||
]);
|
||||
$this->stats_notifications
|
||||
->expects($this->once())
|
||||
->method('getNewsletters')
|
||||
->will($this->returnValue([$newsletter1]));
|
||||
$this->createQueue(8763, 10);
|
||||
$this->createClicks(8763, 5);
|
||||
$this->createOpens(8763, 2);
|
||||
|
||||
|
||||
$this->renderer->expects($this->exactly(2))
|
||||
->method('render');
|
||||
@ -163,20 +154,15 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItPreparesContext() {
|
||||
$newsletter1 = Newsletter::create();
|
||||
$newsletter1->hydrate([
|
||||
'id' => 8765,
|
||||
Newsletter::createOrUpdate([
|
||||
'id' => 8764,
|
||||
'subject' => 'Subject',
|
||||
'total_sent' => 10,
|
||||
'statistics' => [
|
||||
'clicked' => 5,
|
||||
'opened' => 2,
|
||||
],
|
||||
'type' => 'welcome',
|
||||
'status' => 'active',
|
||||
]);
|
||||
$this->stats_notifications
|
||||
->expects($this->once())
|
||||
->method('getNewsletters')
|
||||
->will($this->returnValue([$newsletter1]));
|
||||
$this->createClicks(8764, 5);
|
||||
$this->createOpens(8764, 2);
|
||||
$this->createQueue(8764, 10);
|
||||
$this->renderer->expects($this->exactly(2)) // html + text template
|
||||
->method('render')
|
||||
->with(
|
||||
@ -189,20 +175,16 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
}
|
||||
|
||||
function testItAddsNewsletterStatsToContext() {
|
||||
$newsletter1 = Newsletter::create();
|
||||
$newsletter1->hydrate([
|
||||
Newsletter::createOrUpdate([
|
||||
'id' => 8765,
|
||||
'subject' => 'Subject',
|
||||
'total_sent' => 10,
|
||||
'statistics' => [
|
||||
'clicked' => 5,
|
||||
'opened' => 2,
|
||||
],
|
||||
'type' => 'welcome',
|
||||
'status' => 'active',
|
||||
]);
|
||||
$this->stats_notifications
|
||||
->expects($this->once())
|
||||
->method('getNewsletters')
|
||||
->will($this->returnValue([$newsletter1]));
|
||||
$this->createClicks(8765, 5);
|
||||
$this->createOpens(8765, 2);
|
||||
$this->createQueue(8765, 10);
|
||||
|
||||
$this->renderer->expects($this->exactly(2)) // html + text template
|
||||
->method('render')
|
||||
->with(
|
||||
@ -217,4 +199,39 @@ class AutomatedEmailsTest extends \MailPoetTest {
|
||||
$this->stats_notifications->process();
|
||||
}
|
||||
|
||||
private function createClicks($newsletter_id, $count) {
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
StatisticsClicks::createOrUpdate([
|
||||
'newsletter_id' => $newsletter_id,
|
||||
'subscriber_id' => $i + 1,
|
||||
'queue_id' => 5,
|
||||
'link_id' => 4,
|
||||
'count' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createOpens($newsletter_id, $count) {
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
StatisticsOpens::createOrUpdate([
|
||||
'newsletter_id' => $newsletter_id,
|
||||
'subscriber_id' => $i + 1,
|
||||
'queue_id' => 5,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createQueue($newsletter_id, $count_processed) {
|
||||
$sending_task = ScheduledTask::createOrUpdate([
|
||||
'type' => 'sending',
|
||||
'status' => ScheduledTask::STATUS_COMPLETED,
|
||||
]);
|
||||
SendingQueue::createOrUpdate([
|
||||
'newsletter_rendered_subject' => 'Email Subject',
|
||||
'task_id' => $sending_task->id,
|
||||
'newsletter_id' => $newsletter_id,
|
||||
'count_processed' => $count_processed,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user