Refactor Stats notifications to spearate classes

[MAILPOET-1571]
This commit is contained in:
Pavel Dohnal
2019-01-09 10:28:50 +01:00
parent 6452e83476
commit 96f2f79d48
7 changed files with 120 additions and 43 deletions

View File

@@ -23,6 +23,7 @@ class Daemon {
$this->executeMigrationWorker();
$this->executeScheduleWorker();
$this->executeQueueWorker();
$this->executeStatsNotificationsWorker();
$this->executeSendingServiceKeyCheckWorker();
$this->executePremiumKeyCheckWorker();
$this->executeBounceWorker();
@@ -43,6 +44,11 @@ class Daemon {
return $queue->process();
}
function executeStatsNotificationsWorker() {
$worker = $this->workers_factory->createStatsNotificationsWorker($this->timer);
return $worker->process();
}
function executeSendingServiceKeyCheckWorker() {
$worker = $this->workers_factory->createSendingServiceKeyCheckWorker($this->timer);
return $worker->process();

View File

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

View File

@@ -1,25 +1,14 @@
<?php
namespace MailPoet\Cron\Workers;
namespace MailPoet\Cron\Workers\StatsNotifications;
use Carbon\Carbon;
use MailPoet\Models\Newsletter;
use MailPoet\Models\SendingQueue;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\Setting;
use MailPoet\Models\StatsNotification;
/**
* TODO:
* - 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
*/
class StatsNotifications {
const TASK_TYPE = 'stats_notification';
const SETTINGS_KEY = 'stats_notifications';
class Scheduler {
/**
* How many hours after the newsletter will be the stats notification sent
@@ -33,7 +22,7 @@ class StatsNotifications {
}
$task = ScheduledTask::create();
$task->type = self::TASK_TYPE;
$task->type = Worker::TASK_TYPE;
$task->status = ScheduledTask::STATUS_SCHEDULED;
$task->scheduled_at = $this->getNextRunDate();
$task->save();
@@ -44,10 +33,6 @@ class StatsNotifications {
$stats_notifications->save();
}
function process() {
}
private function shouldSchedule(Newsletter $newsletter) {
if($this->isDisabled()) {
return false;
@@ -62,7 +47,7 @@ class StatsNotifications {
}
private function isDisabled() {
$settings = Setting::getValue(self::SETTINGS_KEY);
$settings = Setting::getValue(Worker::SETTINGS_KEY);
if(!is_array($settings)) {
return true;
}
@@ -81,7 +66,7 @@ class StatsNotifications {
private function isTaskScheduled($newsletter_id) {
$existing = ScheduledTask::table_alias('tasks')
->join(StatsNotification::$_table, 'tasks.id = notification.task_id', 'notification')
->where('tasks.type', self::TASK_TYPE)
->where('tasks.type', Worker::TASK_TYPE)
->where('notification.newsletter_id', $newsletter_id)
->findMany();
return (bool)$existing;

View File

@@ -0,0 +1,79 @@
<?php
namespace MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Config\Renderer;
use MailPoet\Cron\CronHelper;
use MailPoet\Mailer\Mailer;
use MailPoet\Models\Setting;
/**
* TODO:
* - 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
*/
class Worker {
const TASK_TYPE = 'stats_notification';
const SETTINGS_KEY = 'stats_notifications';
const SENDER_EMAIL_PREFIX = 'wordpress@';
/** @var float */
public $timer;
/** @var Renderer */
private $renderer;
/** @var \MailPoet\Mailer\Mailer */
private $mailer;
function __construct(Mailer $mailer, Renderer $renderer, $timer = false) {
$this->timer = $timer ?: microtime(true);
$this->renderer = $renderer;
$this->mailer = $mailer;
}
/** @throws \Exception */
function process() {
$settings = Setting::getValue(self::SETTINGS_KEY);
try {
$this->mailer->getSenderNameAndAddress($this->constructSenderEmail());
$this->mailer->send($this->constructNewsletter(), $settings['address']);
} catch(\Exception $e) {
if(WP_DEBUG) {
throw $e;
}
}
CronHelper::enforceExecutionLimit($this->timer);
}
private function constructSenderEmail() {
$url_parts = parse_url(home_url());
$site_name = strtolower($url_parts['host']);
if(strpos($site_name, 'www.') === 0) {
$site_name = substr($site_name, 4);
}
return [
'address' => self::SENDER_EMAIL_PREFIX . $site_name,
'name' => self::SENDER_EMAIL_PREFIX . $site_name,
];
}
private function constructNewsletter() {
$context = [
'link_settings' => get_site_url(null, '/wp-admin/admin.php?page=mailpoet-settings'),
'link_premium' => get_site_url(null, '/wp-admin/admin.php?page=mailpoet-premium'),
];
return [
'subject' => sprintf(__('New subscriber to ', 'mailpoet')),
'body' => [
'html' => $this->renderer->render('emails/newSubscriberNotification.html', $context),
'text' => $this->renderer->render('emails/newSubscriberNotification.txt', $context),
],
];
}
}

View File

@@ -2,9 +2,11 @@
namespace MailPoet\Cron\Workers;
use MailPoet\Config\Renderer;
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
use MailPoet\Cron\Workers\SendingQueue\Migration as MigrationWorker;
use MailPoet\Cron\Workers\StatsNotifications\Worker as StatsNotificationsWorker;
use MailPoet\Cron\Workers\Bounce as BounceWorker;
use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
@@ -26,11 +28,17 @@ class WorkersFactory {
/** @return SendingQueueWorker */
function createQueueWorker($timer) {
return new SendingQueueWorker($this->sending_error_handler, $this->createStatsNotificationsWorker(), $timer);
return new SendingQueueWorker($this->sending_error_handler, $this->createStatsNotificationsWorker($timer), $timer);
}
function createStatsNotificationsWorker() {
return new StatsNotifications();
function createStatsNotificationsWorker($timer) {
//TODO get those from DI
$caching = !WP_DEBUG;
$debugging = WP_DEBUG;
$this->renderer = new Renderer($caching, $debugging);
$this->mailer = new \MailPoet\Mailer\Mailer();
return new StatsNotificationsWorker($this->mailer, $this->renderer, $timer);
}
/** @return SendingServiceKeyCheckWorker */

View File

@@ -12,7 +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\Cron\Workers\StatsNotifications\Scheduler as StatsNotificationsScheduler;
use MailPoet\Mailer\MailerLog;
use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterLink;
@@ -37,7 +37,7 @@ class SendingQueueTest extends \MailPoetTest {
/** @var SendingErrorHandler */
private $sending_error_handler;
/** @var StatsNotifications */
/** @var Scheduler */
private $stats_notifications_worker;
function _before() {
@@ -80,7 +80,7 @@ class SendingQueueTest extends \MailPoetTest {
$this->newsletter_link->hash = 'abcde';
$this->newsletter_link->save();
$this->sending_error_handler = new SendingErrorHandler();
$this->stats_notifications_worker = new StatsNotifications();
$this->stats_notifications_worker = new StatsNotificationsScheduler();
$this->sending_queue_worker = new SendingQueueWorker($this->sending_error_handler, $this->stats_notifications_worker);
}

View File

@@ -1,21 +1,20 @@
<?php
namespace MailPoet\Test\Cron\Workers;
namespace MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Models\Newsletter;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\Setting;
use MailPoet\Models\StatsNotification;
class StatsNotificationsTest extends \MailPoetTest {
class SchedulerTest extends \MailPoetTest {
/** @var StatsNotifications */
/** @var Scheduler */
private $stats_notifications;
function _before() {
$this->stats_notifications = new StatsNotifications();
Setting::setValue(StatsNotifications::SETTINGS_KEY, [
$this->stats_notifications = new Scheduler();
Setting::setValue(Worker::SETTINGS_KEY, [
'enabled' => true,
'address' => 'email@example.com'
]);
@@ -33,7 +32,7 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldNotScheduleIfDisabled() {
$newsletter_id = 6;
Setting::setValue(StatsNotifications::SETTINGS_KEY, [
Setting::setValue(Worker::SETTINGS_KEY, [
'enabled' => false,
'address' => 'email@example.com'
]);
@@ -45,7 +44,7 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldNotScheduleIfSettingsMissing() {
$newsletter_id = 7;
Setting::setValue(StatsNotifications::SETTINGS_KEY, []);
Setting::setValue(Worker::SETTINGS_KEY, []);
$newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id, 'type' => Newsletter::TYPE_STANDARD]);
$this->stats_notifications->schedule($newsletter);
$notification = StatsNotification::where('newsletter_id', $newsletter_id)->findOne();
@@ -54,7 +53,7 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldNotScheduleIfEmailIsMissing() {
$newsletter_id = 8;
Setting::setValue(StatsNotifications::SETTINGS_KEY, [
Setting::setValue(Worker::SETTINGS_KEY, [
'enabled' => true,
]);
$newsletter = Newsletter::createOrUpdate(['id' => $newsletter_id, 'type' => Newsletter::TYPE_STANDARD]);
@@ -65,7 +64,7 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldNotScheduleIfEmailIsEmpty() {
$newsletter_id = 9;
Setting::setValue(StatsNotifications::SETTINGS_KEY, [
Setting::setValue(Worker::SETTINGS_KEY, [
'enabled' => true,
'address' => ' '
]);
@@ -78,7 +77,7 @@ class StatsNotificationsTest extends \MailPoetTest {
function testShouldNotScheduleIfAlreadyScheduled() {
$newsletter_id = 10;
$existing_task = ScheduledTask::createOrUpdate([
'type' => StatsNotifications::TASK_TYPE,
'type' => Worker::TASK_TYPE,
'status' => ScheduledTask::STATUS_SCHEDULED,
'scheduled_at' => '2017-01-02 12:13:14',
]);