Add an option to restrict coupon to current subscriber
[MAILPOET-6384]
This commit is contained in:
@@ -19,6 +19,7 @@ Module.CouponBlockModel = base.BlockModel.extend({
|
|||||||
return this._getDefaults(
|
return this._getDefaults(
|
||||||
{
|
{
|
||||||
isStandardEmail: App.getNewsletter().isStandardEmail(),
|
isStandardEmail: App.getNewsletter().isStandardEmail(),
|
||||||
|
isAutomationEmail: App.getNewsletter().isAutomationEmail(),
|
||||||
productIds: [], // selected product ids,
|
productIds: [], // selected product ids,
|
||||||
excludedProductIds: [],
|
excludedProductIds: [],
|
||||||
productCategoryIds: [], // selected categories id
|
productCategoryIds: [], // selected categories id
|
||||||
@@ -33,6 +34,10 @@ Module.CouponBlockModel = base.BlockModel.extend({
|
|||||||
minimumAmount: '',
|
minimumAmount: '',
|
||||||
maximumAmount: '',
|
maximumAmount: '',
|
||||||
emailRestrictions: '',
|
emailRestrictions: '',
|
||||||
|
restrictToSubscriber: false,
|
||||||
|
showRestrictToSubscriber:
|
||||||
|
App.getNewsletter().isAutomationEmail() ||
|
||||||
|
App.getNewsletter().isWelcomeEmail(),
|
||||||
styles: {
|
styles: {
|
||||||
block: {
|
block: {
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: '#ffffff',
|
||||||
|
@@ -31,6 +31,7 @@ type State = {
|
|||||||
productCategoryIds: Post[];
|
productCategoryIds: Post[];
|
||||||
excludedProductCategoryIds: Post[];
|
excludedProductCategoryIds: Post[];
|
||||||
emailRestrictions: string;
|
emailRestrictions: string;
|
||||||
|
restrictToSubscriber: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UsageRestriction extends Component<Props, State> {
|
class UsageRestriction extends Component<Props, State> {
|
||||||
@@ -62,6 +63,8 @@ class UsageRestriction extends Component<Props, State> {
|
|||||||
'excludedProductCategoryIds',
|
'excludedProductCategoryIds',
|
||||||
).toJSON() as Post[],
|
).toJSON() as Post[],
|
||||||
emailRestrictions: this.getValueCallback('emailRestrictions') as string,
|
emailRestrictions: this.getValueCallback('emailRestrictions') as string,
|
||||||
|
restrictToSubscriber:
|
||||||
|
(this.getValueCallback('restrictToSubscriber') as boolean) || false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,6 +265,25 @@ class UsageRestriction extends Component<Props, State> {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</PanelRow>
|
</PanelRow>
|
||||||
|
{this.getValueCallback('showRestrictToSubscriber') && (
|
||||||
|
<PanelRow>
|
||||||
|
<ToggleControl
|
||||||
|
checked={this.state.restrictToSubscriber}
|
||||||
|
label={__('Restrict to subscriber email', 'mailpoet')}
|
||||||
|
onChange={(restrictToSubscriber) => {
|
||||||
|
this.setValueCallback(
|
||||||
|
'restrictToSubscriber',
|
||||||
|
restrictToSubscriber,
|
||||||
|
);
|
||||||
|
this.setState({ restrictToSubscriber });
|
||||||
|
}}
|
||||||
|
help={__(
|
||||||
|
'Restrict coupon usage to the subscriber receiving this email.',
|
||||||
|
'mailpoet',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</PanelRow>
|
||||||
|
)}
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
|
@@ -35,6 +35,9 @@ Module.NewsletterModel = SuperModel.extend({
|
|||||||
isStandardEmail: function isStandardEmail() {
|
isStandardEmail: function isStandardEmail() {
|
||||||
return this.get('type') === NewsletterType.Standard;
|
return this.get('type') === NewsletterType.Standard;
|
||||||
},
|
},
|
||||||
|
isWelcomeEmail: function isWelcomeEmail() {
|
||||||
|
return this.get('type') === NewsletterType.Welcome;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Content block view and model handlers for different content types
|
// Content block view and model handlers for different content types
|
||||||
|
@@ -53,7 +53,7 @@ class Preprocessor {
|
|||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
$contentBlocks = $content['blocks'];
|
$contentBlocks = $content['blocks'];
|
||||||
$contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview);
|
$contentBlocks = $this->couponPreProcessor->processCoupons($newsletter, $contentBlocks, $preview, $sendingQueue);
|
||||||
$content['blocks'] = $this->processContainer($newsletter, $contentBlocks, $preview, $sendingQueue);
|
$content['blocks'] = $this->processContainer($newsletter, $contentBlocks, $preview, $sendingQueue);
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
namespace MailPoet\WooCommerce;
|
namespace MailPoet\WooCommerce;
|
||||||
|
|
||||||
use MailPoet\Entities\NewsletterEntity;
|
use MailPoet\Entities\NewsletterEntity;
|
||||||
|
use MailPoet\Entities\SendingQueueEntity;
|
||||||
use MailPoet\Newsletter\NewslettersRepository;
|
use MailPoet\Newsletter\NewslettersRepository;
|
||||||
use MailPoet\Newsletter\Renderer\Blocks\Coupon;
|
use MailPoet\Newsletter\Renderer\Blocks\Coupon;
|
||||||
use MailPoet\NewsletterProcessingException;
|
use MailPoet\NewsletterProcessingException;
|
||||||
@@ -30,12 +31,12 @@ class CouponPreProcessor {
|
|||||||
/**
|
/**
|
||||||
* @throws NewsletterProcessingException
|
* @throws NewsletterProcessingException
|
||||||
*/
|
*/
|
||||||
public function processCoupons(NewsletterEntity $newsletter, array $blocks, bool $preview = false): array {
|
public function processCoupons(NewsletterEntity $newsletter, array $blocks, bool $preview = false, ?SendingQueueEntity $sendingQueue = null): array {
|
||||||
if ($preview) {
|
if ($preview) {
|
||||||
return $blocks;
|
return $blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
$generated = $this->ensureCouponForBlocks($blocks, $newsletter);
|
$generated = $this->ensureCouponForBlocks($blocks, $newsletter, $sendingQueue);
|
||||||
$body = $newsletter->getBody();
|
$body = $newsletter->getBody();
|
||||||
|
|
||||||
if ($generated && $body && $this->shouldPersist($newsletter)) {
|
if ($generated && $body && $this->shouldPersist($newsletter)) {
|
||||||
@@ -54,11 +55,10 @@ class CouponPreProcessor {
|
|||||||
return $blocks;
|
return $blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ensureCouponForBlocks(array &$blocks, NewsletterEntity $newsletter): bool {
|
private function ensureCouponForBlocks(array &$blocks, NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue): bool {
|
||||||
|
|
||||||
foreach ($blocks as &$innerBlock) {
|
foreach ($blocks as &$innerBlock) {
|
||||||
if (isset($innerBlock['blocks']) && !empty($innerBlock['blocks'])) {
|
if (isset($innerBlock['blocks']) && !empty($innerBlock['blocks'])) {
|
||||||
$this->ensureCouponForBlocks($innerBlock['blocks'], $newsletter);
|
$this->ensureCouponForBlocks($innerBlock['blocks'], $newsletter, $sendingQueue);
|
||||||
}
|
}
|
||||||
if (isset($innerBlock['type']) && $innerBlock['type'] === Coupon::TYPE) {
|
if (isset($innerBlock['type']) && $innerBlock['type'] === Coupon::TYPE) {
|
||||||
if (!$this->wcHelper->isWooCommerceActive()) {
|
if (!$this->wcHelper->isWooCommerceActive()) {
|
||||||
@@ -66,7 +66,7 @@ class CouponPreProcessor {
|
|||||||
}
|
}
|
||||||
if ($this->shouldGenerateCoupon($innerBlock)) {
|
if ($this->shouldGenerateCoupon($innerBlock)) {
|
||||||
try {
|
try {
|
||||||
$innerBlock['couponId'] = $this->addOrUpdateCoupon($innerBlock, $newsletter);
|
$innerBlock['couponId'] = $this->addOrUpdateCoupon($innerBlock, $newsletter, $sendingQueue);
|
||||||
$this->generated = true;
|
$this->generated = true;
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw NewsletterProcessingException::create()->withMessage($e->getMessage())->withCode($e->getCode());
|
throw NewsletterProcessingException::create()->withMessage($e->getMessage())->withCode($e->getCode());
|
||||||
@@ -81,10 +81,11 @@ class CouponPreProcessor {
|
|||||||
/**
|
/**
|
||||||
* @param array $couponBlock
|
* @param array $couponBlock
|
||||||
* @param NewsletterEntity $newsletter
|
* @param NewsletterEntity $newsletter
|
||||||
|
* @param SendingQueueEntity|null $sendingQueue
|
||||||
* @return int
|
* @return int
|
||||||
* @throws \WC_Data_Exception|\Exception
|
* @throws \WC_Data_Exception|\Exception
|
||||||
*/
|
*/
|
||||||
private function addOrUpdateCoupon(array $couponBlock, NewsletterEntity $newsletter) {
|
private function addOrUpdateCoupon(array $couponBlock, NewsletterEntity $newsletter, ?SendingQueueEntity $sendingQueue) {
|
||||||
$coupon = $this->wcHelper->createWcCoupon($couponBlock['couponId'] ?? '');
|
$coupon = $this->wcHelper->createWcCoupon($couponBlock['couponId'] ?? '');
|
||||||
if ($this->shouldGenerateCoupon($couponBlock)) {
|
if ($this->shouldGenerateCoupon($couponBlock)) {
|
||||||
$code = isset($couponBlock['code']) && $couponBlock['code'] !== Coupon::CODE_PLACEHOLDER ? $couponBlock['code'] : $this->generateRandomCode();
|
$code = isset($couponBlock['code']) && $couponBlock['code'] !== Coupon::CODE_PLACEHOLDER ? $couponBlock['code'] : $this->generateRandomCode();
|
||||||
@@ -128,7 +129,24 @@ class CouponPreProcessor {
|
|||||||
$coupon->set_product_categories($this->getItemIds($couponBlock['productCategoryIds'] ?? []));
|
$coupon->set_product_categories($this->getItemIds($couponBlock['productCategoryIds'] ?? []));
|
||||||
$coupon->set_excluded_product_categories($this->getItemIds($couponBlock['excludedProductCategoryIds'] ?? []));
|
$coupon->set_excluded_product_categories($this->getItemIds($couponBlock['excludedProductCategoryIds'] ?? []));
|
||||||
|
|
||||||
$coupon->set_email_restrictions(explode(',', $couponBlock['emailRestrictions'] ?? ''));
|
$emailRestrictions = [];
|
||||||
|
if (!empty($couponBlock['emailRestrictions'])) {
|
||||||
|
$emailRestrictions = explode(',', $couponBlock['emailRestrictions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($couponBlock['restrictToSubscriber']) && $sendingQueue && $sendingQueue->getTask()) {
|
||||||
|
$subscribers = $sendingQueue->getTask()->getSubscribers();
|
||||||
|
if (is_iterable($subscribers) && count($subscribers) === 1) { // Only apply to single-subscriber sending queues
|
||||||
|
foreach ($subscribers as $taskSubscriber) {
|
||||||
|
$subscriber = $taskSubscriber->getSubscriber();
|
||||||
|
if ($subscriber && $subscriber->getEmail()) {
|
||||||
|
$emailRestrictions[] = $subscriber->getEmail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$coupon->set_email_restrictions(array_unique(array_filter($emailRestrictions)));
|
||||||
|
|
||||||
// usage limit
|
// usage limit
|
||||||
$coupon->set_usage_limit($couponBlock['usageLimit'] ?? 0);
|
$coupon->set_usage_limit($couponBlock['usageLimit'] ?? 0);
|
||||||
|
Reference in New Issue
Block a user