From 7ced42a4942b0b1c8d12f2f2f5cfc78a0482091f Mon Sep 17 00:00:00 2001 From: Sam Najian Date: Fri, 20 Jan 2023 17:15:39 +0100 Subject: [PATCH] Fix bug when duplicated newsletter uses the source's coupon On duplication, the sensitive data of the coupon were inherited from the source [MAILPOET-4678] --- mailpoet/lib/DI/ContainerConfigurator.php | 1 + mailpoet/lib/Newsletter/NewsletterCoupon.php | 45 ++++++++++++++++++ .../Newsletter/NewsletterSaveController.php | 8 +++- .../Editor/NewsletterCouponTest.php | 47 +++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 mailpoet/lib/Newsletter/NewsletterCoupon.php create mode 100644 mailpoet/tests/unit/Newsletter/Editor/NewsletterCouponTest.php diff --git a/mailpoet/lib/DI/ContainerConfigurator.php b/mailpoet/lib/DI/ContainerConfigurator.php index 085b69e725..28d1ac5067 100644 --- a/mailpoet/lib/DI/ContainerConfigurator.php +++ b/mailpoet/lib/DI/ContainerConfigurator.php @@ -481,6 +481,7 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\Newsletter\Sending\SendingQueuesRepository::class)->setPublic(true); $container->autowire(\MailPoet\Newsletter\ViewInBrowser\ViewInBrowserController::class)->setPublic(true); $container->autowire(\MailPoet\Newsletter\ViewInBrowser\ViewInBrowserRenderer::class)->setPublic(true); + $container->autowire(\MailPoet\Newsletter\NewsletterCoupon::class)->setPublic(true); $container->autowire(\MailPoet\Statistics\GATracking::class)->setPublic(true); // Newsletter templates $container->autowire(\MailPoet\NewsletterTemplates\NewsletterTemplatesRepository::class)->setPublic(true); diff --git a/mailpoet/lib/Newsletter/NewsletterCoupon.php b/mailpoet/lib/Newsletter/NewsletterCoupon.php new file mode 100644 index 0000000000..e088847c6d --- /dev/null +++ b/mailpoet/lib/Newsletter/NewsletterCoupon.php @@ -0,0 +1,45 @@ +getBody(); + if (!is_array($body) || empty($body['content'])) { + return $newsletter; + } + $cleanBlocks = $this->cleanupCouponBlocks($body['content']['blocks']); + $updatedBody = array_merge( + $body, + [ + 'content' => array_merge( + $body['content'], + ['blocks' => $cleanBlocks] + ), + ] + ); + + $newsletter->setBody($updatedBody); + return $newsletter; + } + + private function cleanupCouponBlocks(array &$blocks): array { + foreach ($blocks as &$block) { + if (isset($block['blocks']) && !empty($block['blocks'])) { + $this->cleanupCouponBlocks($block['blocks']); + } + + if (isset($block['type']) && $block['type'] === Coupon::TYPE) { + if (isset($block['code'])) + unset($block['code']); + + if(isset($block['couponId'])) + unset($block['couponId']); + } + } + return $blocks; + } +} diff --git a/mailpoet/lib/Newsletter/NewsletterSaveController.php b/mailpoet/lib/Newsletter/NewsletterSaveController.php index 90051865eb..fd94ca9d81 100644 --- a/mailpoet/lib/Newsletter/NewsletterSaveController.php +++ b/mailpoet/lib/Newsletter/NewsletterSaveController.php @@ -74,6 +74,9 @@ class NewsletterSaveController { /** @var Scheduler */ private $scheduler; + /*** @var NewsletterCoupon */ + private $newsletterCoupon; + public function __construct( AuthorizedEmailsController $authorizedEmailsController, Emoji $emoji, @@ -89,7 +92,8 @@ class NewsletterSaveController { Security $security, WPFunctions $wp, ApiDataSanitizer $dataSanitizer, - Scheduler $scheduler + Scheduler $scheduler, + NewsletterCoupon $newsletterCoupon ) { $this->authorizedEmailsController = $authorizedEmailsController; $this->emoji = $emoji; @@ -106,6 +110,7 @@ class NewsletterSaveController { $this->wp = $wp; $this->dataSanitizer = $dataSanitizer; $this->scheduler = $scheduler; + $this->newsletterCoupon = $newsletterCoupon; } public function save(array $data = []): NewsletterEntity { @@ -182,6 +187,7 @@ class NewsletterSaveController { // reset sent at date $duplicate->setSentAt(null); + $duplicate = $this->newsletterCoupon->cleanupSensitiveData($duplicate); $this->newslettersRepository->persist($duplicate); $this->newslettersRepository->flush(); diff --git a/mailpoet/tests/unit/Newsletter/Editor/NewsletterCouponTest.php b/mailpoet/tests/unit/Newsletter/Editor/NewsletterCouponTest.php new file mode 100644 index 0000000000..d5e8c34de0 --- /dev/null +++ b/mailpoet/tests/unit/Newsletter/Editor/NewsletterCouponTest.php @@ -0,0 +1,47 @@ + 'any', + 'blocks' => [ + [ + 'type' => Coupon::TYPE, + 'couponId' => '100', + 'code' => 'asdasjdkkjaskljdasd', + ], + [ + 'type' => 'any', + 'blocks' => [ + [ + 'type' => Coupon::TYPE, + 'couponId' => '100', + 'code' => 'asdasjdkkjaskljdasd', + ], + ], + ], + ], + ], + [ + 'type' => Coupon::TYPE, + 'couponId' => '100', + 'code' => 'asdasjdkkjaskljdasd', + ], + ]; + $newsletter->setBody(['content' => ['blocks' => $blocks]]); + $result = $newsletterCoupon->cleanupSensitiveData($newsletter); + $body = (array)$result->getBody(); + expect($body['content']['blocks'][0]['blocks'][0])->equals(['type' => Coupon::TYPE]); + expect($body['content']['blocks'][0]['blocks'][1]['blocks'][0])->equals(['type' => Coupon::TYPE]); + expect($body['content']['blocks'][1])->equals(['type' => Coupon::TYPE]); + } +}