diff --git a/lib/API/JSON/v1/Newsletters.php b/lib/API/JSON/v1/Newsletters.php index 013265c051..c4d9b004b2 100644 --- a/lib/API/JSON/v1/Newsletters.php +++ b/lib/API/JSON/v1/Newsletters.php @@ -8,14 +8,13 @@ use MailPoet\API\JSON\Response; use MailPoet\API\JSON\ResponseBuilders\NewslettersResponseBuilder; use MailPoet\Config\AccessControl; use MailPoet\Cron\CronHelper; -use MailPoet\DI\ContainerWrapper; +use MailPoet\Doctrine\Validator\ValidationException; use MailPoet\Entities\NewsletterEntity; use MailPoet\Entities\NewsletterOptionFieldEntity; use MailPoet\Entities\SendingQueueEntity; +use MailPoet\InvalidStateException; use MailPoet\Listing; use MailPoet\Models\Newsletter; -use MailPoet\Models\NewsletterOption; -use MailPoet\Models\NewsletterOptionField; use MailPoet\Newsletter\Listing\NewsletterListingRepository; use MailPoet\Newsletter\NewsletterSaveController; use MailPoet\Newsletter\NewslettersRepository; @@ -24,7 +23,6 @@ use MailPoet\Newsletter\Preview\SendPreviewException; use MailPoet\Newsletter\Scheduler\PostNotificationScheduler; use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\Newsletter\Url as NewsletterUrl; -use MailPoet\NewsletterTemplates\NewsletterTemplatesRepository; use MailPoet\Settings\SettingsController; use MailPoet\UnexpectedValueException; use MailPoet\Util\License\Features\Subscribers as SubscribersFeature; @@ -191,7 +189,11 @@ class Newsletters extends APIEndpoint { $task->getScheduledAt() <= Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) && $task->getStatus() === SendingQueueEntity::STATUS_SCHEDULED ) { - $task->setScheduledAt(Carbon::createFromFormat('Y-m-d H:i:s', $nextRunDate)); + $nextRunDate = $nextRunDate ? Carbon::createFromFormat('Y-m-d H:i:s', $nextRunDate) : null; + if ($nextRunDate === false) { + throw InvalidStateException::create()->withMessage('Invalid next run date generated'); + } + $task->setScheduledAt($nextRunDate); } } $this->postNotificationScheduler->createPostNotificationSendingTask($newsletter); @@ -370,69 +372,13 @@ class Newsletters extends APIEndpoint { } public function create($data = []) { - $options = []; - if (isset($data['options'])) { - $options = $data['options']; - unset($data['options']); - } - - $newsletter = Newsletter::createOrUpdate($data); - $errors = $newsletter->getErrors(); - - if (!empty($errors)) { - return $this->badRequest($errors); - } else { - // try to load template data - $templateId = (isset($data['template']) ? (int)$data['template'] : false); - $template = ContainerWrapper::getInstance()->get(NewsletterTemplatesRepository::class)->findOneById($templateId); - if ($template) { - $newsletter->body = json_encode($template->getBody()); - } else { - $newsletter->body = []; - } - } - - $newsletter->save(); - $errors = $newsletter->getErrors(); - if (!empty($errors)) { - return $this->badRequest($errors); - } else { - if (!empty($options)) { - $optionFields = NewsletterOptionField::where( - 'newsletter_type', $newsletter->type - )->findArray(); - - foreach ($optionFields as $optionField) { - if (isset($options[$optionField['name']])) { - $relation = NewsletterOption::create(); - $relation->newsletterId = $newsletter->id; - $relation->optionFieldId = $optionField['id']; - $relation->value = $options[$optionField['name']]; - $relation->save(); - } - } - } - - if ( - empty($data['id']) - && - isset($data['type']) - && - $data['type'] === Newsletter::TYPE_NOTIFICATION - ) { - $newsletter = Newsletter::filter('filterWithOptions', $data['type'])->findOne($newsletter->id); - assert($newsletter instanceof Newsletter); - $newsletterEntity = $this->newslettersRepository->findOneById($newsletter->id); - assert($newsletterEntity instanceof NewsletterEntity); - $this->postNotificationScheduler->processPostNotificationSchedule($newsletterEntity); - } - - $newsletter = Newsletter::findOne($newsletter->id); - if(!$newsletter instanceof Newsletter) return $this->errorResponse(); - return $this->successResponse( - $newsletter->asArray() - ); + try { + $newsletter = $this->newsletterSaveController->save($data); + } catch (ValidationException $exception) { + return $this->badRequest(['Please specify a type.']); } + $response = $this->newslettersResponseBuilder->build($newsletter); + return $this->successResponse($response); } /** @return NewsletterEntity|null */ diff --git a/lib/Newsletter/NewsletterSaveController.php b/lib/Newsletter/NewsletterSaveController.php index 882eac6c2c..87abea81f2 100644 --- a/lib/Newsletter/NewsletterSaveController.php +++ b/lib/Newsletter/NewsletterSaveController.php @@ -21,6 +21,7 @@ use MailPoet\NotFoundException; use MailPoet\Services\AuthorizedEmailsController; use MailPoet\Settings\SettingsController; use MailPoet\UnexpectedValueException; +use MailPoet\Util\Security; use MailPoet\WP\Emoji; use MailPoetVendor\Carbon\Carbon; use MailPoetVendor\Doctrine\ORM\EntityManager; @@ -59,6 +60,9 @@ class NewsletterSaveController { /** @var SettingsController */ private $settings; + /** @var Security */ + private $security; + public function __construct( AuthorizedEmailsController $authorizedEmailsController, Emoji $emoji, @@ -70,7 +74,8 @@ class NewsletterSaveController { NewsletterTemplatesRepository $newsletterTemplatesRepository, PostNotificationScheduler $postNotificationScheduler, ScheduledTasksRepository $scheduledTasksRepository, - SettingsController $settings + SettingsController $settings, + Security $security ) { $this->authorizedEmailsController = $authorizedEmailsController; $this->emoji = $emoji; @@ -83,6 +88,7 @@ class NewsletterSaveController { $this->postNotificationScheduler = $postNotificationScheduler; $this->scheduledTasksRepository = $scheduledTasksRepository; $this->settings = $settings; + $this->security = $security; } public function save(array $data = []): NewsletterEntity { @@ -97,10 +103,11 @@ class NewsletterSaveController { $data['body'] = $this->emoji->encodeForUTF8Column(MP_NEWSLETTERS_TABLE, 'body', $data['body']); } - $newsletter = $this->getNewsletter($data); + $newsletter = isset($data['id']) ? $this->getNewsletter($data) : $this->createNewsletter($data); $oldSenderAddress = $newsletter->getSenderAddress(); $this->updateNewsletter($newsletter, $data); + $this->newslettersRepository->flush(); if (!empty($data['segments'])) { $this->updateSegments($newsletter, $data['segments']); } @@ -140,6 +147,29 @@ class NewsletterSaveController { return $newsletter; } + private function createNewsletter(array $data): NewsletterEntity { + $newsletter = new NewsletterEntity(); + $newsletter->setUnsubscribeToken($this->security->generateUnsubscribeTokenByEntity($newsletter)); + $newsletter->setHash(Security::generateHash()); + // set default sender based on settings + if (empty($data['sender'])) { + $sender = $this->settings->get('sender', []); + $data['sender_name'] = $sender['name'] ?? ''; + $data['sender_address'] = $sender['address'] ?? ''; + } + + // set default reply_to based on settings + if (empty($data['reply_to'])) { + $replyTo = $this->settings->get('reply_to', []); + $data['reply_to_name'] = $replyTo['name'] ?? ''; + $data['reply_to_address'] = $replyTo['address'] ?? ''; + } + + $this->updateNewsletter($newsletter, $data); + $this->newslettersRepository->persist($newsletter); + return $newsletter; + } + private function updateNewsletter(NewsletterEntity $newsletter, array $data) { if (array_key_exists('type', $data)) { $newsletter->setType($data['type']); @@ -176,8 +206,6 @@ class NewsletterSaveController { if (array_key_exists('reply_to_address', $data)) { $newsletter->setReplyToAddress($data['reply_to_address'] ?? ''); } - - $this->newslettersRepository->flush(); } private function updateSegments(NewsletterEntity $newsletter, array $segments) {