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

View File

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

View File

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

View File

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