JezK
Edit File: StatusController.php
<?php declare(strict_types = 1); namespace MailPoet\Newsletter; if (!defined('ABSPATH')) exit; use MailPoet\Entities\NewsletterEntity; use MailPoet\Entities\NewsletterOptionFieldEntity; use MailPoet\Entities\ScheduledTaskEntity; use MailPoet\Entities\SendingQueueEntity; use MailPoet\InvalidStateException; use MailPoet\Newsletter\Scheduler\PostNotificationScheduler; use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\Services\AuthorizedEmailsController; use MailPoet\Util\License\Features\Subscribers as SubscribersFeature; use MailPoetVendor\Carbon\Carbon; /** * Centralized newsletter status-toggle (active/draft) flow used by the REST * endpoint at `PUT mailpoet/v1/newsletters/{id}/status`. * * Lifts the status change, paused-queue resume, post-notification reschedule, * and authorized-sender gating into one place so the REST endpoint can stay a * thin HTTP adapter. */ class StatusController { /** @var NewslettersRepository */ private $newslettersRepository; /** @var SubscribersFeature */ private $subscribersFeature; /** @var AuthorizedEmailsController */ private $authorizedEmailsController; /** @var NewsletterValidator */ private $newsletterValidator; /** @var Scheduler */ private $scheduler; /** @var PostNotificationScheduler */ private $postNotificationScheduler; public function __construct( NewslettersRepository $newslettersRepository, SubscribersFeature $subscribersFeature, AuthorizedEmailsController $authorizedEmailsController, NewsletterValidator $newsletterValidator, Scheduler $scheduler, PostNotificationScheduler $postNotificationScheduler ) { $this->newslettersRepository = $newslettersRepository; $this->subscribersFeature = $subscribersFeature; $this->authorizedEmailsController = $authorizedEmailsController; $this->newsletterValidator = $newsletterValidator; $this->scheduler = $scheduler; $this->postNotificationScheduler = $postNotificationScheduler; } /** * @throws BulkActionException */ public function setStatus(NewsletterEntity $newsletter, string $status): NewsletterEntity { if ($status === NewsletterEntity::STATUS_ACTIVE && $this->subscribersFeature->check()) { throw new BulkActionException( __('Subscribers limit reached.', 'mailpoet'), 'mailpoet_newsletters_subscribers_limit', 403 ); } if ($status === NewsletterEntity::STATUS_ACTIVE && !$this->authorizedEmailsController->isSenderAddressValid($newsletter)) { throw new BulkActionException( __('The sender address is not an authorized sender domain.', 'mailpoet'), 'mailpoet_newsletters_unauthorized_sender', 403 ); } if ($status === NewsletterEntity::STATUS_ACTIVE) { $validationError = $this->newsletterValidator->validate($newsletter); if ($validationError !== null) { throw new BulkActionException( $validationError, 'mailpoet_newsletters_validation_failed', 403 ); } } $this->newslettersRepository->prefetchOptions([$newsletter]); $newsletter->setStatus($status); if ($newsletter->getStatus() === NewsletterEntity::STATUS_ACTIVE) { // Unpause any tasks that were halted by an earlier deactivation so a // toggle-off/on cycle resumes rather than orphaning the queue. foreach ($newsletter->getUnfinishedQueues() as $queue) { $task = $queue->getTask(); if ($task && $task->getStatus() === ScheduledTaskEntity::STATUS_PAUSED) { $task->setStatus(ScheduledTaskEntity::STATUS_SCHEDULED); } } } // Past-due post notifications need their next run date computed and a // new sending task scheduled; otherwise re-activation would silently // miss the next interval. if ($newsletter->getType() === NewsletterEntity::TYPE_NOTIFICATION && $status === NewsletterEntity::STATUS_ACTIVE) { $scheduleOption = $newsletter->getOption(NewsletterOptionFieldEntity::NAME_SCHEDULE); if ($scheduleOption === null) { throw new BulkActionException( __('This email has incorrect state.', 'mailpoet'), 'mailpoet_newsletters_missing_schedule', 400 ); } $nextRunDate = $this->scheduler->getNextRunDate($scheduleOption->getValue()); foreach ($newsletter->getQueues() as $queue) { $task = $queue->getTask(); if ( $task && $task->getScheduledAt() <= Carbon::now()->millisecond(0) && $task->getStatus() === SendingQueueEntity::STATUS_SCHEDULED ) { $parsedDate = $nextRunDate ? Carbon::createFromFormat('Y-m-d H:i:s', $nextRunDate) : null; if ($parsedDate === false) { throw InvalidStateException::create()->withMessage('Invalid next run date generated'); } $task->setScheduledAt($parsedDate); } } $this->postNotificationScheduler->createPostNotificationSendingTask($newsletter); } $this->newslettersRepository->flush(); return $newsletter; } }