| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- <?php
- namespace MailPoet\Cron\Triggers;
- if (!defined('ABSPATH')) exit;
- use MailPoet\Cron\CronHelper;
- use MailPoet\Cron\Workers\AuthorizedSendingEmailsCheck;
- use MailPoet\Cron\Workers\Beamer as BeamerWorker;
- use MailPoet\Cron\Workers\Bounce as BounceWorker;
- use MailPoet\Cron\Workers\InactiveSubscribers;
- use MailPoet\Cron\Workers\KeyCheck\PremiumKeyCheck as PremiumKeyCheckWorker;
- use MailPoet\Cron\Workers\KeyCheck\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
- use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
- use MailPoet\Cron\Workers\SendingQueue\Migration as MigrationWorker;
- use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
- use MailPoet\Cron\Workers\StatsNotifications\AutomatedEmails;
- use MailPoet\Cron\Workers\StatsNotifications\Worker as StatsNotificationsWorker;
- use MailPoet\Cron\Workers\SubscriberLinkTokens;
- use MailPoet\Cron\Workers\SubscribersCountCacheRecalculation;
- use MailPoet\Cron\Workers\SubscribersEngagementScore;
- use MailPoet\Cron\Workers\SubscribersLastEngagement;
- use MailPoet\Cron\Workers\UnsubscribeTokens;
- use MailPoet\Cron\Workers\WooCommercePastOrders;
- use MailPoet\Cron\Workers\WooCommerceSync as WooCommerceSyncWorker;
- use MailPoet\Mailer\MailerLog;
- use MailPoet\Models\ScheduledTask;
- use MailPoet\Services\Bridge;
- use MailPoet\Settings\SettingsController;
- use MailPoet\WP\Functions as WPFunctions;
- class WordPress {
- const SCHEDULED_IN_THE_PAST = 'past';
- const SCHEDULED_IN_THE_FUTURE = 'future';
- const RUN_INTERVAL = -1; // seconds
- const LAST_RUN_AT_SETTING = 'cron_trigger_wordpress.last_run_at';
- private $tasksCounts;
- /** @var CronHelper */
- private $cronHelper;
- /** @var MailPoet */
- private $mailpoetTrigger;
- /** @var SettingsController */
- private $settings;
- /** @var WPFunctions */
- private $wp;
- public function __construct(
- CronHelper $cronHelper,
- MailPoet $mailpoetTrigger,
- SettingsController $settings,
- WPFunctions $wp
- ) {
- $this->mailpoetTrigger = $mailpoetTrigger;
- $this->settings = $settings;
- $this->wp = $wp;
- $this->cronHelper = $cronHelper;
- }
- public function run() {
- if (!$this->checkRunInterval()) {
- return false;
- }
- return ($this->checkExecutionRequirements()) ?
- $this->mailpoetTrigger->run() :
- self::stop();
- }
- private function checkRunInterval() {
- $lastRunAt = (int)$this->settings->get(self::LAST_RUN_AT_SETTING, 0);
- $runInterval = $this->wp->applyFilters('mailpoet_cron_trigger_wordpress_run_interval', self::RUN_INTERVAL);
- $runIntervalElapsed = (time() - $lastRunAt) >= $runInterval;
- if ($runIntervalElapsed) {
- $this->settings->set(self::LAST_RUN_AT_SETTING, time());
- return true;
- }
- return false;
- }
- public static function resetRunInterval() {
- $settings = SettingsController::getInstance();
- $settings->set(self::LAST_RUN_AT_SETTING, 0);
- }
- public function checkExecutionRequirements() {
- $this->loadTasksCounts();
- // migration
- $migrationDisabled = $this->settings->get('cron_trigger.method') === 'none';
- $migrationDueTasks = $this->getTasksCount([
- 'type' => MigrationWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- $migrationCompletedTasks = $this->getTasksCount([
- 'type' => MigrationWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST, self::SCHEDULED_IN_THE_FUTURE],
- 'status' => [ScheduledTask::STATUS_COMPLETED],
- ]);
- $migrationFutureTasks = $this->getTasksCount([
- 'type' => MigrationWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_FUTURE],
- 'status' => [ScheduledTask::STATUS_SCHEDULED],
- ]);
- // sending queue
- $scheduledQueues = SchedulerWorker::getScheduledQueues();
- $runningQueues = SendingQueueWorker::getRunningQueues();
- $sendingLimitReached = MailerLog::isSendingLimitReached();
- $sendingIsPaused = MailerLog::isSendingPaused();
- // sending service
- $mpSendingEnabled = Bridge::isMPSendingServiceEnabled();
- // bounce sync
- $bounceDueTasks = $this->getTasksCount([
- 'type' => BounceWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- $bounceFutureTasks = $this->getTasksCount([
- 'type' => BounceWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_FUTURE],
- 'status' => [ScheduledTask::STATUS_SCHEDULED],
- ]);
- // sending service key check
- $msskeycheckDueTasks = $this->getTasksCount([
- 'type' => SendingServiceKeyCheckWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- $msskeycheckFutureTasks = $this->getTasksCount([
- 'type' => SendingServiceKeyCheckWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_FUTURE],
- 'status' => [ScheduledTask::STATUS_SCHEDULED],
- ]);
- // premium key check
- $premiumKeySpecified = Bridge::isPremiumKeySpecified();
- $premiumKeycheckDueTasks = $this->getTasksCount([
- 'type' => PremiumKeyCheckWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- $premiumKeycheckFutureTasks = $this->getTasksCount([
- 'type' => PremiumKeyCheckWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_FUTURE],
- 'status' => [ScheduledTask::STATUS_SCHEDULED],
- ]);
- // stats notifications
- $statsNotificationsTasks = $this->getTasksCount([
- 'type' => StatsNotificationsWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // stats notifications for auto emails
- $autoStatsNotificationsTasks = $this->getTasksCount([
- 'type' => AutomatedEmails::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // inactive subscribers check
- $inactiveSubscribersTasks = $this->getTasksCount([
- 'type' => InactiveSubscribers::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // unsubscribe tokens check
- $unsubscribeTokensTasks = $this->getTasksCount([
- 'type' => UnsubscribeTokens::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // subscriber link tokens check
- $subscriberLinkTokensTasks = $this->getTasksCount([
- 'type' => SubscriberLinkTokens::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // WooCommerce sync
- $wooCommerceSyncTasks = $this->getTasksCount([
- 'type' => WooCommerceSyncWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // Beamer
- $beamerDueChecks = $this->getTasksCount([
- 'type' => BeamerWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- $beamerFutureChecks = $this->getTasksCount([
- 'type' => BeamerWorker::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_FUTURE],
- 'status' => [ScheduledTask::STATUS_SCHEDULED],
- ]);
- // Authorized email addresses check
- $authorizedEmailAddressesTasks = $this->getTasksCount([
- 'type' => AuthorizedSendingEmailsCheck::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // WooCommerce past orders revenues sync
- $wooCommercePastOrdersTasks = $this->getTasksCount([
- 'type' => WooCommercePastOrders::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // subscriber engagement score
- $subscriberEngagementScoreTasks = $this->getTasksCount([
- 'type' => SubscribersEngagementScore::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // subscriber counts cache recalculation
- $subscribersCountCacheRecalculationTasks = $this->getTasksCount([
- 'type' => SubscribersCountCacheRecalculation::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // subscriber last engagement
- $subscribersLastEngagementTasks = $this->getTasksCount([
- 'type' => SubscribersLastEngagement::TASK_TYPE,
- 'scheduled_in' => [self::SCHEDULED_IN_THE_PAST],
- 'status' => ['null', ScheduledTask::STATUS_SCHEDULED],
- ]);
- // check requirements for each worker
- $sendingQueueActive = (($scheduledQueues || $runningQueues) && !$sendingLimitReached && !$sendingIsPaused);
- $bounceSyncActive = ($mpSendingEnabled && ($bounceDueTasks || !$bounceFutureTasks));
- $sendingServiceKeyCheckActive = ($mpSendingEnabled && ($msskeycheckDueTasks || !$msskeycheckFutureTasks));
- $premiumKeyCheckActive = ($premiumKeySpecified && ($premiumKeycheckDueTasks || !$premiumKeycheckFutureTasks));
- $migrationActive = !$migrationDisabled && ($migrationDueTasks || (!$migrationCompletedTasks && !$migrationFutureTasks));
- $beamerActive = $beamerDueChecks || !$beamerFutureChecks;
- return (
- $migrationActive
- || $sendingQueueActive
- || $bounceSyncActive
- || $sendingServiceKeyCheckActive
- || $premiumKeyCheckActive
- || $statsNotificationsTasks
- || $autoStatsNotificationsTasks
- || $inactiveSubscribersTasks
- || $wooCommerceSyncTasks
- || $authorizedEmailAddressesTasks
- || $beamerActive
- || $wooCommercePastOrdersTasks
- || $unsubscribeTokensTasks
- || $subscriberLinkTokensTasks
- || $subscriberEngagementScoreTasks
- || $subscribersCountCacheRecalculationTasks
- || $subscribersLastEngagementTasks
- );
- }
- public function stop() {
- $cronDaemon = $this->cronHelper->getDaemon();
- if ($cronDaemon) {
- $this->cronHelper->deactivateDaemon($cronDaemon);
- }
- }
- private function loadTasksCounts() {
- $query = sprintf(
- "select
- type,
- status,
- count(*) as count,
- case when scheduled_at <= '%s' then '%s' else '%s' end as scheduled_in
- from %s
- where deleted_at is null
- group by type, status, scheduled_in
- ",
- date('Y-m-d H:i:s', $this->wp->currentTime('timestamp')),
- self::SCHEDULED_IN_THE_PAST,
- self::SCHEDULED_IN_THE_FUTURE,
- ScheduledTask::$_table
- );
- $rows = ScheduledTask::rawQuery($query)->findMany();
- $this->tasksCounts = [];
- foreach ($rows as $r) {
- if (empty($this->tasksCounts[$r->type])) {
- $this->tasksCounts[$r->type] = [];
- }
- if (empty($this->tasksCounts[$r->type][$r->scheduledIn])) {
- $this->tasksCounts[$r->type][$r->scheduledIn] = [];
- }
- $this->tasksCounts[$r->type][$r->scheduledIn][$r->status ?: 'null'] = $r->count;
- }
- }
- private function getTasksCount(array $options) {
- $count = 0;
- $type = $options['type'];
- foreach ($options['scheduled_in'] as $scheduledIn) {
- foreach ($options['status'] as $status) {
- if (! empty($this->tasksCounts[$type][$scheduledIn][$status])) {
- $count += $this->tasksCounts[$type][$scheduledIn][$status];
- }
- }
- }
- return $count;
- }
- }
|