Set newsletter option data using Doctrine

[MAILPOET-2900]
This commit is contained in:
Jan Jakeš
2020-05-12 15:13:13 +02:00
committed by Veljko V
parent 0e5e95310f
commit e1819d4334
7 changed files with 100 additions and 48 deletions

View File

@ -169,7 +169,11 @@ class NewslettersResponseBuilder {
private function buildOptions(NewsletterEntity $newsletter) { private function buildOptions(NewsletterEntity $newsletter) {
$output = []; $output = [];
foreach ($newsletter->getOptions() as $option) { foreach ($newsletter->getOptions() as $option) {
$output[$option->getOptionField()->getName()] = $option->getValue(); $optionField = $option->getOptionField();
if (!$optionField) {
continue;
}
$output[$optionField->getName()] = $option->getValue();
} }
// convert 'afterTimeNumber' string to integer // convert 'afterTimeNumber' string to integer

View File

@ -267,6 +267,8 @@ class ContainerConfigurator implements IContainerConfigurator {
$container->autowire(\MailPoet\Newsletter\NewsletterSaveController::class)->setPublic(true); $container->autowire(\MailPoet\Newsletter\NewsletterSaveController::class)->setPublic(true);
$container->autowire(\MailPoet\Newsletter\NewslettersRepository::class)->setPublic(true); $container->autowire(\MailPoet\Newsletter\NewslettersRepository::class)->setPublic(true);
$container->autowire(\MailPoet\Newsletter\Listing\NewsletterListingRepository::class)->setPublic(true); $container->autowire(\MailPoet\Newsletter\Listing\NewsletterListingRepository::class)->setPublic(true);
$container->autowire(\MailPoet\Newsletter\Options\NewsletterOptionsRepository::class)->setPublic(true);
$container->autowire(\MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository::class)->setPublic(true);
$container->autowire(\MailPoet\Newsletter\Preview\SendPreviewController::class); $container->autowire(\MailPoet\Newsletter\Preview\SendPreviewController::class);
$container->autowire(\MailPoet\Newsletter\Segment\NewsletterSegmentRepository::class); $container->autowire(\MailPoet\Newsletter\Segment\NewsletterSegmentRepository::class);
$container->autowire(\MailPoet\Newsletter\Statistics\NewsletterStatisticsRepository::class); $container->autowire(\MailPoet\Newsletter\Statistics\NewsletterStatisticsRepository::class);

View File

@ -33,10 +33,15 @@ class NewsletterOptionEntity {
/** /**
* @ORM\ManyToOne(targetEntity="MailPoet\Entities\NewsletterOptionFieldEntity") * @ORM\ManyToOne(targetEntity="MailPoet\Entities\NewsletterOptionFieldEntity")
* @var NewsletterOptionFieldEntity * @var NewsletterOptionFieldEntity|null
*/ */
private $optionField; private $optionField;
public function __construct(NewsletterEntity $newsletter, NewsletterOptionFieldEntity $optionField) {
$this->newsletter = $newsletter;
$this->optionField = $optionField;
}
/** /**
* @return string|null * @return string|null
*/ */
@ -60,24 +65,10 @@ class NewsletterOptionEntity {
} }
/** /**
* @param NewsletterEntity $newsletter * @return NewsletterOptionFieldEntity|null
*/
public function setNewsletter($newsletter) {
$this->newsletter = $newsletter;
}
/**
* @return NewsletterOptionFieldEntity
*/ */
public function getOptionField() { public function getOptionField() {
$this->safelyLoadToOneAssociation('optionField'); $this->safelyLoadToOneAssociation('optionField');
return $this->optionField; return $this->optionField;
} }
/**
* @param NewsletterOptionFieldEntity $optionField
*/
public function setOptionField($optionField) {
$this->optionField = $optionField;
}
} }

View File

@ -4,13 +4,14 @@ 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\Entities\NewsletterEntity;
use MailPoet\Entities\NewsletterOptionEntity;
use MailPoet\Entities\NewsletterSegmentEntity; use MailPoet\Entities\NewsletterSegmentEntity;
use MailPoet\Entities\SegmentEntity; use MailPoet\Entities\SegmentEntity;
use MailPoet\InvalidStateException; use MailPoet\InvalidStateException;
use MailPoet\Models\Newsletter; use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterOption;
use MailPoet\Models\NewsletterOptionField;
use MailPoet\Models\SendingQueue; use MailPoet\Models\SendingQueue;
use MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository;
use MailPoet\Newsletter\Options\NewsletterOptionsRepository;
use MailPoet\Newsletter\Scheduler\PostNotificationScheduler; use MailPoet\Newsletter\Scheduler\PostNotificationScheduler;
use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\Newsletter\Scheduler\Scheduler;
use MailPoet\Newsletter\Segment\NewsletterSegmentRepository; use MailPoet\Newsletter\Segment\NewsletterSegmentRepository;
@ -37,6 +38,12 @@ class NewsletterSaveController {
/** @var NewslettersRepository */ /** @var NewslettersRepository */
private $newslettersRepository; private $newslettersRepository;
/** @var NewsletterOptionsRepository */
private $newsletterOptionsRepository;
/** @var NewsletterOptionFieldsRepository */
private $newsletterOptionFieldsRepository;
/** @var NewsletterSegmentRepository */ /** @var NewsletterSegmentRepository */
private $newsletterSegmentRepository; private $newsletterSegmentRepository;
@ -57,6 +64,8 @@ class NewsletterSaveController {
Emoji $emoji, Emoji $emoji,
EntityManager $entityManager, EntityManager $entityManager,
NewslettersRepository $newslettersRepository, NewslettersRepository $newslettersRepository,
NewsletterOptionsRepository $newsletterOptionsRepository,
NewsletterOptionFieldsRepository $newsletterOptionFieldsRepository,
NewsletterSegmentRepository $newsletterSegmentRepository, NewsletterSegmentRepository $newsletterSegmentRepository,
NewsletterTemplatesRepository $newsletterTemplatesRepository, NewsletterTemplatesRepository $newsletterTemplatesRepository,
PostNotificationScheduler $postNotificationScheduler, PostNotificationScheduler $postNotificationScheduler,
@ -67,6 +76,8 @@ class NewsletterSaveController {
$this->emoji = $emoji; $this->emoji = $emoji;
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->newslettersRepository = $newslettersRepository; $this->newslettersRepository = $newslettersRepository;
$this->newsletterOptionsRepository = $newsletterOptionsRepository;
$this->newsletterOptionFieldsRepository = $newsletterOptionFieldsRepository;
$this->newsletterSegmentRepository = $newsletterSegmentRepository; $this->newsletterSegmentRepository = $newsletterSegmentRepository;
$this->newsletterTemplatesRepository = $newsletterTemplatesRepository; $this->newsletterTemplatesRepository = $newsletterTemplatesRepository;
$this->postNotificationScheduler = $postNotificationScheduler; $this->postNotificationScheduler = $postNotificationScheduler;
@ -97,9 +108,10 @@ class NewsletterSaveController {
$newsletter = $this->getNewsletter($data); $newsletter = $this->getNewsletter($data);
$this->updateNewsletter($newsletter, $data); $this->updateNewsletter($newsletter, $data);
$this->updateSegments($newsletter, $data['segments'] ?? []); $this->updateSegments($newsletter, $data['segments'] ?? []);
$this->updateOptions($newsletter, $data['options'] ?? []);
// fetch old model for back compatibility // fetch model with updated options (for back compatibility)
$newsletterModel = Newsletter::findOne((int)$data['id']); $newsletterModel = Newsletter::filter('filterWithOptions', $newsletter->getType())->findOne($newsletter->getId());
if (!$newsletterModel) { if (!$newsletterModel) {
throw new InvalidStateException(); throw new InvalidStateException();
} }
@ -114,27 +126,6 @@ class NewsletterSaveController {
$options = $data['options'] ?? []; $options = $data['options'] ?? [];
if ($options) { if ($options) {
$optionFields = NewsletterOptionField::where(
'newsletter_type',
$newsletterModel->type
)->findMany();
// update newsletter options
foreach ($optionFields as $optionField) {
if (isset($options[$optionField->name])) {
$newsletterOption = NewsletterOption::createOrUpdate(
[
'newsletter_id' => $newsletterModel->id,
'option_field_id' => $optionField->id,
'value' => $options[$optionField->name],
]
);
}
}
// reload newsletter with updated options
$newsletterModel = Newsletter::filter('filterWithOptions', $newsletterModel->type)->findOne($newsletterModel->id);
if (!$newsletterModel) {
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 ($newsletterModel->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
@ -253,4 +244,34 @@ class NewsletterSaveController {
$this->entityManager->flush(); $this->entityManager->flush();
} }
private function updateOptions(NewsletterEntity $newsletter, array $options) {
if (!$options) {
return;
}
$optionFields = $this->newsletterOptionFieldsRepository->findBy(['newsletterType' => $newsletter->getType()]);
foreach ($optionFields as $optionField) {
if (!isset($options[$optionField->getName()])) {
continue;
}
$option = $this->newsletterOptionsRepository->findOneBy([
'newsletter' => $newsletter,
'optionField' => $optionField,
]);
if (!$option) {
$option = new NewsletterOptionEntity($newsletter, $optionField);
$this->newsletterOptionsRepository->persist($option);
}
$option->setValue($options[$optionField->getName()]);
if (!$newsletter->getOptions()->contains($option)) {
$newsletter->getOptions()->add($option);
}
}
$this->entityManager->flush();
}
} }

View File

@ -0,0 +1,19 @@
<?php
namespace MailPoet\Newsletter\Options;
use MailPoet\Doctrine\Repository;
use MailPoet\Entities\NewsletterOptionFieldEntity;
/**
* @method NewsletterOptionFieldEntity[] findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null)
* @method NewsletterOptionFieldEntity|null findOneBy(array $criteria, array $orderBy = null)
* @method NewsletterOptionFieldEntity|null findOneById(mixed $id)
* @method void persist(NewsletterOptionFieldEntity $entity)
* @method void remove(NewsletterOptionFieldEntity $entity)
*/
class NewsletterOptionFieldsRepository extends Repository {
protected function getEntityClassName() {
return NewsletterOptionFieldEntity::class;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace MailPoet\Newsletter\Options;
use MailPoet\Doctrine\Repository;
use MailPoet\Entities\NewsletterOptionEntity;
/**
* @method NewsletterOptionEntity[] findBy(array $criteria, array $orderBy = null, int $limit = null, int $offset = null)
* @method NewsletterOptionEntity|null findOneBy(array $criteria, array $orderBy = null)
* @method NewsletterOptionEntity|null findOneById(mixed $id)
* @method void persist(NewsletterOptionEntity $entity)
* @method void remove(NewsletterOptionEntity $entity)
*/
class NewsletterOptionsRepository extends Repository {
protected function getEntityClassName() {
return NewsletterOptionEntity::class;
}
}

View File

@ -143,9 +143,7 @@ class NewsletterListingRepositoryTest extends \MailPoetTest {
$newsletter1->setSubject('Automatic email 1'); $newsletter1->setSubject('Automatic email 1');
$this->entityManager->persist($newsletter1); $this->entityManager->persist($newsletter1);
$newsletter1Option = new NewsletterOptionEntity(); $newsletter1Option = new NewsletterOptionEntity($newsletter1, $newsletterOptionField);
$newsletter1Option->setNewsletter($newsletter1);
$newsletter1Option->setOptionField($newsletterOptionField);
$newsletter1Option->setValue('woocommerce'); $newsletter1Option->setValue('woocommerce');
$this->entityManager->persist($newsletter1Option); $this->entityManager->persist($newsletter1Option);
@ -154,9 +152,7 @@ class NewsletterListingRepositoryTest extends \MailPoetTest {
$newsletter2->setSubject('Automatic email 2'); $newsletter2->setSubject('Automatic email 2');
$this->entityManager->persist($newsletter2); $this->entityManager->persist($newsletter2);
$newsletter2Option = new NewsletterOptionEntity(); $newsletter2Option = new NewsletterOptionEntity($newsletter2, $newsletterOptionField);
$newsletter2Option->setNewsletter($newsletter2);
$newsletter2Option->setOptionField($newsletterOptionField);
$newsletter2Option->setValue('unicorns'); $newsletter2Option->setValue('unicorns');
$this->entityManager->persist($newsletter2Option); $this->entityManager->persist($newsletter2Option);