Set newsletter data using Doctrine

[MAILPOET-2900]
This commit is contained in:
Jan Jakeš
2020-05-11 17:15:17 +02:00
committed by Veljko V
parent bb200fce7a
commit 2c784ee036

View File

@@ -3,6 +3,7 @@
namespace MailPoet\Newsletter; namespace MailPoet\Newsletter;
use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterQueueTask; use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterQueueTask;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\InvalidStateException; use MailPoet\InvalidStateException;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterOption; use MailPoet\Models\NewsletterOption;
@@ -13,6 +14,7 @@ use MailPoet\Newsletter\Scheduler\PostNotificationScheduler;
use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\Newsletter\Scheduler\Scheduler;
use MailPoet\Newsletter\Url as NewsletterUrl; use MailPoet\Newsletter\Url as NewsletterUrl;
use MailPoet\NewsletterTemplates\NewsletterTemplatesRepository; use MailPoet\NewsletterTemplates\NewsletterTemplatesRepository;
use MailPoet\NotFoundException;
use MailPoet\Services\AuthorizedEmailsController; use MailPoet\Services\AuthorizedEmailsController;
use MailPoet\Settings\SettingsController; use MailPoet\Settings\SettingsController;
use MailPoet\UnexpectedValueException; use MailPoet\UnexpectedValueException;
@@ -26,6 +28,9 @@ class NewsletterSaveController {
/** @var Emoji */ /** @var Emoji */
private $emoji; private $emoji;
/** @var NewslettersRepository */
private $newslettersRepository;
/** @var NewsletterTemplatesRepository */ /** @var NewsletterTemplatesRepository */
private $newsletterTemplatesRepository; private $newsletterTemplatesRepository;
@@ -41,6 +46,7 @@ class NewsletterSaveController {
public function __construct( public function __construct(
AuthorizedEmailsController $authorizedEmailsController, AuthorizedEmailsController $authorizedEmailsController,
Emoji $emoji, Emoji $emoji,
NewslettersRepository $newslettersRepository,
NewsletterTemplatesRepository $newsletterTemplatesRepository, NewsletterTemplatesRepository $newsletterTemplatesRepository,
PostNotificationScheduler $postNotificationScheduler, PostNotificationScheduler $postNotificationScheduler,
SettingsController $settings, SettingsController $settings,
@@ -48,6 +54,7 @@ class NewsletterSaveController {
) { ) {
$this->authorizedEmailsController = $authorizedEmailsController; $this->authorizedEmailsController = $authorizedEmailsController;
$this->emoji = $emoji; $this->emoji = $emoji;
$this->newslettersRepository = $newslettersRepository;
$this->newsletterTemplatesRepository = $newsletterTemplatesRepository; $this->newsletterTemplatesRepository = $newsletterTemplatesRepository;
$this->postNotificationScheduler = $postNotificationScheduler; $this->postNotificationScheduler = $postNotificationScheduler;
$this->settings = $settings; $this->settings = $settings;
@@ -57,56 +64,41 @@ class NewsletterSaveController {
public function save(array $data = []): array { public function save(array $data = []): array {
$data = $this->wp->applyFilters('mailpoet_api_newsletters_save_before', $data); $data = $this->wp->applyFilters('mailpoet_api_newsletters_save_before', $data);
$segments = [];
if (isset($data['segments'])) {
$segments = $data['segments'];
unset($data['segments']);
}
$options = [];
if (isset($data['options'])) {
$options = $data['options'];
unset($data['options']);
}
if (!empty($data['template_id'])) { if (!empty($data['template_id'])) {
$template = $this->newsletterTemplatesRepository->findOneById($data['template_id']); $template = $this->newsletterTemplatesRepository->findOneById($data['template_id']);
if ($template) { if ($template) {
$data['body'] = json_encode($template->getBody()); $data['body'] = json_encode($template->getBody());
} }
unset($data['template_id']);
} }
$oldNewsletter = null; $oldNewsletterModel = null;
if (isset($data['id'])) { if (isset($data['id'])) {
$fetched = Newsletter::findOne(intval($data['id'])); $fetched = Newsletter::findOne(intval($data['id']));
$oldNewsletter = $fetched instanceof Newsletter ? $fetched : null; $oldNewsletterModel = $fetched instanceof Newsletter ? $fetched : null;
} }
if (!empty($data['body'])) { if (!empty($data['body'])) {
$data['body'] = $this->emoji->encodeForUTF8Column(MP_NEWSLETTERS_TABLE, 'body', $data['body']); $data['body'] = $this->emoji->encodeForUTF8Column(MP_NEWSLETTERS_TABLE, 'body', $data['body']);
} }
$newsletter = Newsletter::createOrUpdate($data);
$errors = $newsletter->getErrors();
if (!empty($errors)) {
throw UnexpectedValueException::create()->withErrors($errors);
}
// Re-fetch newsletter to sync changes made by DB $newsletter = $this->getNewsletter($data);
// updated_at column use CURRENT_TIMESTAMP for update and this change is not updated automatically by ORM $this->updateNewsletter($newsletter, $data);
$newsletter = Newsletter::findOne($newsletter->id);
if (!$newsletter) { // fetch old model for back compatibility
$newsletterModel = Newsletter::findOne((int)$data['id']);
if (!$newsletterModel) {
throw new InvalidStateException(); throw new InvalidStateException();
} }
if (!empty($segments)) { $segments = $data['segments'] ?? [];
NewsletterSegment::where('newsletter_id', $newsletter->id) if ($segments) {
NewsletterSegment::where('newsletter_id', $newsletterModel->id)
->deleteMany(); ->deleteMany();
foreach ($segments as $segment) { foreach ($segments as $segment) {
if (!is_array($segment)) continue; if (!is_array($segment)) continue;
$relation = NewsletterSegment::create(); $relation = NewsletterSegment::create();
$relation->segmentId = (int)$segment['id']; $relation->segmentId = (int)$segment['id'];
$relation->newsletterId = $newsletter->id; $relation->newsletterId = $newsletterModel->id;
$relation->save(); $relation->save();
} }
} }
@@ -119,17 +111,18 @@ class NewsletterSaveController {
]); ]);
} }
if (!empty($options)) { $options = $data['options'] ?? [];
if ($options) {
$optionFields = NewsletterOptionField::where( $optionFields = NewsletterOptionField::where(
'newsletter_type', 'newsletter_type',
$newsletter->type $newsletterModel->type
)->findMany(); )->findMany();
// update newsletter options // update newsletter options
foreach ($optionFields as $optionField) { foreach ($optionFields as $optionField) {
if (isset($options[$optionField->name])) { if (isset($options[$optionField->name])) {
$newsletterOption = NewsletterOption::createOrUpdate( $newsletterOption = NewsletterOption::createOrUpdate(
[ [
'newsletter_id' => $newsletter->id, 'newsletter_id' => $newsletterModel->id,
'option_field_id' => $optionField->id, 'option_field_id' => $optionField->id,
'value' => $options[$optionField->name], 'value' => $options[$optionField->name],
] ]
@@ -137,17 +130,17 @@ class NewsletterSaveController {
} }
} }
// reload newsletter with updated options // reload newsletter with updated options
$newsletter = Newsletter::filter('filterWithOptions', $newsletter->type)->findOne($newsletter->id); $newsletterModel = Newsletter::filter('filterWithOptions', $newsletterModel->type)->findOne($newsletterModel->id);
if (!$newsletter) { if (!$newsletterModel) {
throw new InvalidStateException(); throw new InvalidStateException();
} }
// if this is a post notification, process newsletter options and update its schedule // if this is a post notification, process newsletter options and update its schedule
if ($newsletter->type === Newsletter::TYPE_NOTIFICATION) { if ($newsletterModel->type === Newsletter::TYPE_NOTIFICATION) {
// generate the new schedule from options and get the new "next run" date // generate the new schedule from options and get the new "next run" date
$newsletter->schedule = $this->postNotificationScheduler->processPostNotificationSchedule($newsletter); $newsletterModel->schedule = $this->postNotificationScheduler->processPostNotificationSchedule($newsletterModel);
$nextRunDate = Scheduler::getNextRunDate($newsletter->schedule); $nextRunDate = Scheduler::getNextRunDate($newsletterModel->schedule);
// find previously scheduled jobs and reschedule them using the new "next run" date // find previously scheduled jobs and reschedule them using the new "next run" date
SendingQueue::findTaskByNewsletterId($newsletter->id) SendingQueue::findTaskByNewsletterId($newsletterModel->id)
->where('tasks.status', SendingQueue::STATUS_SCHEDULED) ->where('tasks.status', SendingQueue::STATUS_SCHEDULED)
->findResultSet() ->findResultSet()
->set('scheduled_at', $nextRunDate) ->set('scheduled_at', $nextRunDate)
@@ -155,25 +148,77 @@ class NewsletterSaveController {
} }
} }
$queue = $newsletter->getQueue(); $queue = $newsletterModel->getQueue();
if ($queue && !in_array($newsletter->type, [Newsletter::TYPE_NOTIFICATION, Newsletter::TYPE_NOTIFICATION_HISTORY])) { if ($queue && !in_array($newsletterModel->type, [Newsletter::TYPE_NOTIFICATION, Newsletter::TYPE_NOTIFICATION_HISTORY])) {
// if newsletter was previously scheduled and is now unscheduled, set its status to DRAFT and delete associated queue record // if newsletter was previously scheduled and is now unscheduled, set its status to DRAFT and delete associated queue record
if ($newsletter->status === Newsletter::STATUS_SCHEDULED && isset($options['isScheduled']) && empty($options['isScheduled'])) { if ($newsletterModel->status === Newsletter::STATUS_SCHEDULED && isset($options['isScheduled']) && empty($options['isScheduled'])) {
$queue->delete(); $queue->delete();
$newsletter->status = Newsletter::STATUS_DRAFT; $newsletterModel->status = Newsletter::STATUS_DRAFT;
$newsletter->save(); $newsletterModel->save();
} else { } else {
$queue->newsletterRenderedBody = null; $queue->newsletterRenderedBody = null;
$queue->newsletterRenderedSubject = null; $queue->newsletterRenderedSubject = null;
$newsletterQueueTask = new NewsletterQueueTask(); $newsletterQueueTask = new NewsletterQueueTask();
$newsletterQueueTask->preProcessNewsletter($newsletter, $queue); $newsletterQueueTask->preProcessNewsletter($newsletterModel, $queue);
} }
} }
$this->wp->doAction('mailpoet_api_newsletters_save_after', $newsletter); $this->wp->doAction('mailpoet_api_newsletters_save_after', $newsletterModel);
$this->authorizedEmailsController->onNewsletterUpdate($newsletter, $oldNewsletter); $this->authorizedEmailsController->onNewsletterUpdate($newsletterModel, $oldNewsletterModel);
$previewUrl = NewsletterUrl::getViewInBrowserUrl($newsletter); $previewUrl = NewsletterUrl::getViewInBrowserUrl($newsletterModel);
return [$newsletter->asArray(), ['preview_url' => $previewUrl]]; return [$newsletterModel->asArray(), ['preview_url' => $previewUrl]];
}
private function getNewsletter(array $data): NewsletterEntity {
if (!isset($data['id'])) {
throw new UnexpectedValueException();
}
$newsletter = $this->newslettersRepository->findOneById((int)$data['id']);
if (!$newsletter) {
throw new NotFoundException();
}
return $newsletter;
}
private function updateNewsletter(NewsletterEntity $newsletter, array $data) {
if (array_key_exists('type', $data)) {
$newsletter->setType($data['type']);
}
if (array_key_exists('subject', $data)) {
$newsletter->setSubject($data['subject']);
}
if (array_key_exists('preheader', $data)) {
$newsletter->setPreheader($data['preheader']);
}
if (array_key_exists('body', $data)) {
$newsletter->setBody(json_decode($data['body'], true));
}
if (array_key_exists('ga_campaign', $data)) {
$newsletter->setGaCampaign($data['ga_campaign']);
}
if (array_key_exists('sender_name', $data)) {
$newsletter->setSenderName($data['sender_name'] ?? '');
}
if (array_key_exists('sender_address', $data)) {
$newsletter->setSenderAddress($data['sender_address'] ?? '');
}
if (array_key_exists('reply_to_name', $data)) {
$newsletter->setReplyToName($data['reply_to_name'] ?? '');
}
if (array_key_exists('reply_to_address', $data)) {
$newsletter->setReplyToAddress($data['reply_to_address'] ?? '');
}
$this->newslettersRepository->flush();
} }
} }