Schedule a notification

[MAILPOET-1571]
This commit is contained in:
Pavel Dohnal
2019-01-08 13:31:05 +01:00
parent d346a44974
commit 1d34613b17
5 changed files with 55 additions and 25 deletions

View File

@ -5,6 +5,7 @@ use MailPoet\Cron\CronHelper;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Links; use MailPoet\Cron\Workers\SendingQueue\Tasks\Links;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask; use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask; use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
use MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Logging\Logger; use MailPoet\Logging\Logger;
use MailPoet\Mailer\MailerError; use MailPoet\Mailer\MailerError;
use MailPoet\Mailer\MailerLog; use MailPoet\Mailer\MailerLog;
@ -25,11 +26,15 @@ class SendingQueue {
const BATCH_SIZE = 20; const BATCH_SIZE = 20;
const TASK_BATCH_SIZE = 5; const TASK_BATCH_SIZE = 5;
/** @var StatsNotifications */
public $stats_notifications_worker;
/** @var SendingErrorHandler */ /** @var SendingErrorHandler */
private $error_handler; private $error_handler;
function __construct(SendingErrorHandler $error_handler, $timer = false, $mailer_task = false, $newsletter_task = false) { function __construct(SendingErrorHandler $error_handler, StatsNotifications $stats_notifications_worker, $timer = false, $mailer_task = false, $newsletter_task = false) {
$this->error_handler = $error_handler; $this->error_handler = $error_handler;
$this->stats_notifications_worker = $stats_notifications_worker;
$this->mailer_task = ($mailer_task) ? $mailer_task : new MailerTask(); $this->mailer_task = ($mailer_task) ? $mailer_task : new MailerTask();
$this->newsletter_task = ($newsletter_task) ? $newsletter_task : new NewsletterTask(); $this->newsletter_task = ($newsletter_task) ? $newsletter_task : new NewsletterTask();
$this->timer = ($timer) ? $timer : microtime(true); $this->timer = ($timer) ? $timer : microtime(true);
@ -98,6 +103,7 @@ class SendingQueue {
); );
if($queue->status === ScheduledTaskModel::STATUS_COMPLETED) { if($queue->status === ScheduledTaskModel::STATUS_COMPLETED) {
$this->newsletter_task->markNewsletterAsSent($newsletter, $queue); $this->newsletter_task->markNewsletterAsSent($newsletter, $queue);
$this->stats_notifications_worker->schedule($newsletter);
} }
$this->enforceSendingAndExecutionLimits(); $this->enforceSendingAndExecutionLimits();
} }

View File

@ -3,6 +3,7 @@
namespace MailPoet\Cron\Workers; namespace MailPoet\Cron\Workers;
use Carbon\Carbon; use Carbon\Carbon;
use MailPoet\Models\Newsletter;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Models\ScheduledTask; use MailPoet\Models\ScheduledTask;
use MailPoet\Models\Setting; use MailPoet\Models\Setting;
@ -11,8 +12,7 @@ use MailPoet\Models\StatsNotification;
/** /**
* TODO: * TODO:
* - finish stats_notifications table, test if it is working and the migration is creating the table * - only schedule for post notification and standard, need to do check here
* - when sending of post notification or a standard newsletter is finished call schedule
* - add processing of this task to Daemon * - add processing of this task to Daemon
* - check JIRA what to do next and how to send the newsletter * - check JIRA what to do next and how to send the newsletter
* - see \MailPoet\Subscribers\NewSubscriberNotificationMailer how to send an email, now with DI everything should be easy * - see \MailPoet\Subscribers\NewSubscriberNotificationMailer how to send an email, now with DI everything should be easy
@ -29,8 +29,8 @@ class StatsNotifications {
*/ */
const HOURS_TO_SEND_AFTER_NEWSLETTER = 24; const HOURS_TO_SEND_AFTER_NEWSLETTER = 24;
function schedule($newsletter_id) { function schedule(Newsletter $newsletter) {
if(!$this->shouldSchedule($newsletter_id)) { if(!$this->shouldSchedule($newsletter)) {
return false; return false;
} }
@ -41,7 +41,7 @@ class StatsNotifications {
$task->save(); $task->save();
$stats_notifications = StatsNotification::create(); $stats_notifications = StatsNotification::create();
$stats_notifications->newsletter_id = $newsletter_id; $stats_notifications->newsletter_id = $newsletter->id;
$stats_notifications->task_id = $task->id; $stats_notifications->task_id = $task->id;
$stats_notifications->save(); $stats_notifications->save();
} }
@ -50,11 +50,11 @@ class StatsNotifications {
} }
private function shouldSchedule($newsletter_id) { private function shouldSchedule(Newsletter $newsletter) {
if($this->isDisabled()) { if($this->isDisabled()) {
return false; return false;
} }
if($this->isTaskScheduled($newsletter_id)) { if($this->isTaskScheduled($newsletter->id)) {
return false; return false;
} }
return true; return true;

View File

@ -54,6 +54,8 @@ class ContainerConfigurator implements IContainerConfigurator {
// Cron // Cron
$container->autowire(\MailPoet\Cron\Daemon::class)->setPublic(true); $container->autowire(\MailPoet\Cron\Daemon::class)->setPublic(true);
$container->autowire(\MailPoet\Cron\DaemonHttpRunner::class)->setPublic(true); $container->autowire(\MailPoet\Cron\DaemonHttpRunner::class)->setPublic(true);
$container->autowire(\MailPoet\Cron\Workers\WorkersFactory::class)->setPublic(true);
$container->autowire(\MailPoet\Cron\Workers\SendingQueue\SendingErrorHandler::class)->setPublic(true);
// Listing // Listing
$container->autowire(\MailPoet\Listing\BulkActionController::class)->setPublic(true); $container->autowire(\MailPoet\Listing\BulkActionController::class)->setPublic(true);
$container->autowire(\MailPoet\Listing\Handler::class)->setPublic(true); $container->autowire(\MailPoet\Listing\Handler::class)->setPublic(true);

View File

@ -12,6 +12,7 @@ use MailPoet\Cron\Workers\SendingQueue\SendingErrorHandler;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker; use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask; use MailPoet\Cron\Workers\SendingQueue\Tasks\Mailer as MailerTask;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask; use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterTask;
use MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Mailer\MailerLog; use MailPoet\Mailer\MailerLog;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterLink; use MailPoet\Models\NewsletterLink;
@ -36,6 +37,9 @@ class SendingQueueTest extends \MailPoetTest {
/** @var SendingErrorHandler */ /** @var SendingErrorHandler */
private $sending_error_handler; private $sending_error_handler;
/** @var StatsNotifications */
private $stats_notifications_worker;
function _before() { function _before() {
$wp_users = get_users(); $wp_users = get_users();
wp_set_current_user($wp_users[0]->ID); wp_set_current_user($wp_users[0]->ID);
@ -76,7 +80,8 @@ class SendingQueueTest extends \MailPoetTest {
$this->newsletter_link->hash = 'abcde'; $this->newsletter_link->hash = 'abcde';
$this->newsletter_link->save(); $this->newsletter_link->save();
$this->sending_error_handler = new SendingErrorHandler(); $this->sending_error_handler = new SendingErrorHandler();
$this->sending_queue_worker = new SendingQueueWorker($this->sending_error_handler); $this->stats_notifications_worker = new StatsNotifications();
$this->sending_queue_worker = new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker);
} }
private function getDirectUnsubscribeURL() { private function getDirectUnsubscribeURL() {
@ -106,20 +111,20 @@ class SendingQueueTest extends \MailPoetTest {
// constructor accepts timer argument // constructor accepts timer argument
$timer = microtime(true) - 5; $timer = microtime(true) - 5;
$sending_queue_worker = new SendingQueueWorker($this->sending_error_handler, $timer); $sending_queue_worker = new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker, $timer);
expect($sending_queue_worker->timer)->equals($timer); expect($sending_queue_worker->timer)->equals($timer);
} }
function testItEnforcesExecutionLimitsBeforeQueueProcessing() { function testItEnforcesExecutionLimitsBeforeQueueProcessing() {
$sending_queue_worker = Stub::make( $sending_queue_worker = Stub::make(
new SendingQueueWorker($this->sending_error_handler), new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker),
array( array(
'processQueue' => Expected::never(), 'processQueue' => Expected::never(),
'enforceSendingAndExecutionLimits' => Expected::exactly(1, function() { 'enforceSendingAndExecutionLimits' => Expected::exactly(1, function() {
throw new \Exception(); throw new \Exception();
}) })
), $this); ), $this);
$sending_queue_worker->__construct($this->sending_error_handler); $sending_queue_worker->__construct($this->sending_error_handler, $this->stats_notifications_worker);
try { try {
$sending_queue_worker->process(); $sending_queue_worker->process();
self::fail('Execution limits function was not called.'); self::fail('Execution limits function was not called.');
@ -130,12 +135,13 @@ class SendingQueueTest extends \MailPoetTest {
function testItEnforcesExecutionLimitsAfterSendingWhenQueueStatusIsNotSetToComplete() { function testItEnforcesExecutionLimitsAfterSendingWhenQueueStatusIsNotSetToComplete() {
$sending_queue_worker = Stub::make( $sending_queue_worker = Stub::make(
new SendingQueueWorker($this->sending_error_handler), new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker),
array( array(
'enforceSendingAndExecutionLimits' => Expected::exactly(1) 'enforceSendingAndExecutionLimits' => Expected::exactly(1)
), $this); ), $this);
$sending_queue_worker->__construct( $sending_queue_worker->__construct(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -164,12 +170,13 @@ class SendingQueueTest extends \MailPoetTest {
$queue = $this->queue; $queue = $this->queue;
$queue->status = SendingQueue::STATUS_COMPLETED; $queue->status = SendingQueue::STATUS_COMPLETED;
$sending_queue_worker = Stub::make( $sending_queue_worker = Stub::make(
new SendingQueueWorker($this->sending_error_handler), new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker),
array( array(
'enforceSendingAndExecutionLimits' => Expected::never() 'enforceSendingAndExecutionLimits' => Expected::never()
), $this); ), $this);
$sending_queue_worker->__construct( $sending_queue_worker->__construct(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -193,7 +200,7 @@ class SendingQueueTest extends \MailPoetTest {
function testItEnforcesExecutionLimitsAfterQueueProcessing() { function testItEnforcesExecutionLimitsAfterQueueProcessing() {
$sending_queue_worker = Stub::make( $sending_queue_worker = Stub::make(
new SendingQueueWorker($this->sending_error_handler), new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker),
array( array(
'processQueue' => function() { 'processQueue' => function() {
// this function returns a queue object // this function returns a queue object
@ -201,7 +208,7 @@ class SendingQueueTest extends \MailPoetTest {
}, },
'enforceSendingAndExecutionLimits' => Expected::exactly(2) 'enforceSendingAndExecutionLimits' => Expected::exactly(2)
), $this); ), $this);
$sending_queue_worker->__construct($this->sending_error_handler); $sending_queue_worker->__construct($this->sending_error_handler, $this->stats_notifications_worker);
$sending_queue_worker->process(); $sending_queue_worker->process();
} }
@ -225,6 +232,7 @@ class SendingQueueTest extends \MailPoetTest {
$directUnsubscribeURL = $this->getDirectUnsubscribeURL(); $directUnsubscribeURL = $this->getDirectUnsubscribeURL();
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -246,6 +254,7 @@ class SendingQueueTest extends \MailPoetTest {
$trackedUnsubscribeURL = $this->getTrackedUnsubscribeURL(); $trackedUnsubscribeURL = $this->getTrackedUnsubscribeURL();
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -265,6 +274,7 @@ class SendingQueueTest extends \MailPoetTest {
function testItCanProcessSubscribersOneByOne() { function testItCanProcessSubscribersOneByOne() {
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -309,6 +319,7 @@ class SendingQueueTest extends \MailPoetTest {
function testItCanProcessSubscribersInBulk() { function testItCanProcessSubscribersInBulk() {
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -356,6 +367,7 @@ class SendingQueueTest extends \MailPoetTest {
function testItProcessesStandardNewsletters() { function testItProcessesStandardNewsletters() {
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -410,6 +422,7 @@ class SendingQueueTest extends \MailPoetTest {
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::makeEmpty(new MailerTask(), array(), $this) Stub::makeEmpty(new MailerTask(), array(), $this)
); );
@ -425,6 +438,7 @@ class SendingQueueTest extends \MailPoetTest {
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -591,9 +605,10 @@ class SendingQueueTest extends \MailPoetTest {
'updateProcessedSubscribers' => false 'updateProcessedSubscribers' => false
)); ));
$sending_task->id = 100; $sending_task->id = 100;
$sending_queue_worker = Stub::make(new SendingQueueWorker($this->sending_error_handler)); $sending_queue_worker = Stub::make(new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker));
$sending_queue_worker->__construct( $sending_queue_worker->__construct(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -627,6 +642,7 @@ class SendingQueueTest extends \MailPoetTest {
function testItDoesNotUpdateNewsletterHashDuringSending() { function testItDoesNotUpdateNewsletterHashDuringSending() {
$sending_queue_worker = new SendingQueueWorker( $sending_queue_worker = new SendingQueueWorker(
$this->sending_error_handler, $this->sending_error_handler,
$this->stats_notifications_worker,
$timer = false, $timer = false,
Stub::make( Stub::make(
new MailerTask(), new MailerTask(),
@ -650,7 +666,7 @@ class SendingQueueTest extends \MailPoetTest {
return $custom_batch_size_value; return $custom_batch_size_value;
}; };
Hooks::addFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter); Hooks::addFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter);
$sending_queue_worker = new SendingQueueWorker($this->sending_error_handler); $sending_queue_worker = new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker);
expect($sending_queue_worker->batch_size)->equals($custom_batch_size_value); expect($sending_queue_worker->batch_size)->equals($custom_batch_size_value);
Hooks::removeFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter); Hooks::removeFilter('mailpoet_cron_worker_sending_queue_batch_size', $filter);
} }

View File

@ -2,8 +2,8 @@
namespace MailPoet\Test\Cron\Workers; namespace MailPoet\Test\Cron\Workers;
use Carbon\Carbon;
use MailPoet\Cron\Workers\StatsNotifications; use MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Models\Newsletter;
use MailPoet\Models\ScheduledTask; use MailPoet\Models\ScheduledTask;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Models\Setting; use MailPoet\Models\Setting;
@ -24,7 +24,8 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldSchedule() { function testShouldSchedule() {
$newsletter_id = 5; $newsletter_id = 5;
$this->stats_notifications->schedule($newsletter_id); $newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id]);
$this->stats_notifications->schedule($newsletter);
$notification = StatsNotification::where('newsletter_id', $newsletter_id)->findOne(); $notification = StatsNotification::where('newsletter_id', $newsletter_id)->findOne();
expect($notification)->isInstanceOf(StatsNotification::class); expect($notification)->isInstanceOf(StatsNotification::class);
$task = ScheduledTask::where('id', $notification->task_id)->findOne(); $task = ScheduledTask::where('id', $notification->task_id)->findOne();
@ -37,7 +38,8 @@ class StatsNotificationsTest extends \MailPoetTest {
'enabled' => false, 'enabled' => false,
'address' => 'email@example.com' 'address' => 'email@example.com'
]); ]);
$this->stats_notifications->schedule($newsletter_id); $newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id]);
$this->stats_notifications->schedule($newsletter);
$queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne(); $queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne();
expect($queue)->isEmpty(); expect($queue)->isEmpty();
} }
@ -45,7 +47,8 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldNotScheduleIfSettingsMissing() { function testShouldNotScheduleIfSettingsMissing() {
$newsletter_id = 7; $newsletter_id = 7;
Setting::setValue(StatsNotifications::SETTINGS_KEY, []); Setting::setValue(StatsNotifications::SETTINGS_KEY, []);
$this->stats_notifications->schedule($newsletter_id); $newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id]);
$this->stats_notifications->schedule($newsletter);
$queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne(); $queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne();
expect($queue)->isEmpty(); expect($queue)->isEmpty();
} }
@ -55,7 +58,8 @@ class StatsNotificationsTest extends \MailPoetTest {
Setting::setValue(StatsNotifications::SETTINGS_KEY, [ Setting::setValue(StatsNotifications::SETTINGS_KEY, [
'enabled' => true, 'enabled' => true,
]); ]);
$this->stats_notifications->schedule($newsletter_id); $newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id]);
$this->stats_notifications->schedule($newsletter);
$queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne(); $queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne();
expect($queue)->isEmpty(); expect($queue)->isEmpty();
} }
@ -66,7 +70,8 @@ class StatsNotificationsTest extends \MailPoetTest {
'enabled' => true, 'enabled' => true,
'address' => ' ' 'address' => ' '
]); ]);
$this->stats_notifications->schedule($newsletter_id); $newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id]);
$this->stats_notifications->schedule($newsletter);
$queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne(); $queue = SendingQueue::where('newsletter_id', $newsletter_id)->findOne();
expect($queue)->isEmpty(); expect($queue)->isEmpty();
} }
@ -82,7 +87,8 @@ class StatsNotificationsTest extends \MailPoetTest {
'newsletter_id' => $newsletter_id, 'newsletter_id' => $newsletter_id,
'task_id' => $existing_task->id, 'task_id' => $existing_task->id,
]); ]);
$this->stats_notifications->schedule($newsletter_id); $newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id]);
$this->stats_notifications->schedule($newsletter);
$queues = SendingQueue::where('newsletter_id', $newsletter_id)->findMany(); $queues = SendingQueue::where('newsletter_id', $newsletter_id)->findMany();
expect($queues)->count(1); expect($queues)->count(1);
$tasks = ScheduledTask::where('id', $queues[0]->task_id)->findMany(); $tasks = ScheduledTask::where('id', $queues[0]->task_id)->findMany();