Skip to content

Commit d030b9a

Browse files
committed
MC-29102: [2.4.x] [Magento Cloud] Customer receives newsletter unsubscription email after registering for new account
1 parent d001f7b commit d030b9a

File tree

7 files changed

+276
-0
lines changed

7 files changed

+276
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Newsletter\Controller\Ajax;
7+
8+
use Magento\Framework\App\Action\Context;
9+
use Magento\Framework\Controller\ResultFactory;
10+
use Magento\Framework\Exception\LocalizedException;
11+
use Magento\Framework\Validator\EmailAddress as EmailAddressValidator;
12+
use Magento\Newsletter\Model\GuestSubscriptionChecker;
13+
use Psr\Log\LoggerInterface;
14+
15+
/**
16+
* Newsletter subscription status verification controller.
17+
*/
18+
class Status extends \Magento\Framework\App\Action\Action
19+
{
20+
/**
21+
* @var EmailAddressValidator
22+
*/
23+
private $emailAddressValidator;
24+
25+
/**
26+
* @var GuestSubscriptionChecker
27+
*/
28+
private $guestSubscriptionChecker;
29+
30+
/**
31+
* @var LoggerInterface
32+
*/
33+
private $logger;
34+
35+
/**
36+
* @param Context $context
37+
* @param EmailAddressValidator $emailAddressValidator
38+
* @param GuestSubscriptionChecker $guestSubscriptionChecker
39+
* @param LoggerInterface $logger
40+
*/
41+
public function __construct(
42+
Context $context,
43+
EmailAddressValidator $emailAddressValidator,
44+
GuestSubscriptionChecker $guestSubscriptionChecker,
45+
LoggerInterface $logger
46+
) {
47+
parent::__construct($context);
48+
$this->emailAddressValidator = $emailAddressValidator;
49+
$this->guestSubscriptionChecker = $guestSubscriptionChecker;
50+
$this->logger = $logger;
51+
}
52+
53+
/**
54+
* @inheritdoc
55+
*/
56+
public function execute()
57+
{
58+
$email = (string)$this->getRequest()->getParam('email');
59+
60+
$response = [
61+
'subscribed' => false,
62+
'errors' => false,
63+
];
64+
try {
65+
if (!empty($email) && $this->emailAddressValidator->isValid($email)) {
66+
$response['subscribed'] = $this->guestSubscriptionChecker->isSubscribed($email);
67+
}
68+
} catch (LocalizedException $exception) {
69+
$response = [
70+
'errors' => true,
71+
'message' => $exception->getMessage(),
72+
];
73+
} catch (\Throwable $exception) {
74+
$response = [
75+
'errors' => true,
76+
'message' => __('Something went wrong.'),
77+
];
78+
}
79+
80+
/** @var \Magento\Framework\Controller\Result\Json $resultJson */
81+
$resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
82+
83+
return $resultJson->setData($response);
84+
}
85+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Newsletter\Model;
9+
10+
use Magento\Framework\App\ResourceConnection;
11+
use Magento\Store\Model\StoreManagerInterface;
12+
13+
/**
14+
* Checks guest subscription by email.
15+
*/
16+
class GuestSubscriptionChecker
17+
{
18+
/**
19+
* @var ResourceConnection
20+
*/
21+
private $resourceConnection;
22+
/**
23+
* @var StoreManagerInterface
24+
*/
25+
private $storeManager;
26+
27+
/**
28+
* @param ResourceConnection $resourceConnection
29+
* @param StoreManagerInterface $storeManager
30+
*/
31+
public function __construct(ResourceConnection $resourceConnection, StoreManagerInterface $storeManager)
32+
{
33+
$this->resourceConnection = $resourceConnection;
34+
$this->storeManager = $storeManager;
35+
}
36+
37+
/**
38+
* @param string $subscriberEmail
39+
* @return bool
40+
*/
41+
public function isSubscribed(string $subscriberEmail): bool
42+
{
43+
if (!empty($subscriberEmail)) {
44+
$storeIds = $this->storeManager->getWebsite()->getStoreIds();
45+
$connection = $this->resourceConnection->getConnection();
46+
$select = $connection
47+
->select()
48+
->from($this->resourceConnection->getTableName('newsletter_subscriber'))
49+
->where('subscriber_email = ?', $subscriberEmail)
50+
->where('store_id IN (?)', $storeIds)
51+
->where('customer_id = 0')
52+
->limit(1);
53+
54+
$result = (bool)$connection->fetchOne($select);
55+
56+
return $result;
57+
}
58+
59+
return false;
60+
}
61+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
9+
<body>
10+
<referenceBlock name="customer_form_register">
11+
<block name="customer.form.register.newsletter" template="Magento_Newsletter::form/register/newsletter.phtml"/>
12+
</referenceBlock>
13+
</body>
14+
</page>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
var config = {
7+
map: {
8+
'*': {
9+
subscriptionStatusResolver: 'Magento_Newsletter/js/subscription-status-resolver',
10+
newsletterSignUp: 'Magento_Newsletter/js/newsletter-sign-up'
11+
}
12+
}
13+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
?>
7+
<script type="text/x-magento-init">
8+
{
9+
"#email_address": {
10+
"newsletterSignUp": {
11+
"signUpElement": "#is_subscribed",
12+
"submitButton": ".form-create-account button[type='submit']"
13+
}
14+
}
15+
}
16+
</script>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'jquery',
8+
'uiElement',
9+
'mage/storage',
10+
'mage/url',
11+
'subscriptionStatusResolver',
12+
'mage/validation',
13+
], function ($, Component, storage, urlBuilder, subscriptionStatusResolver) {
14+
'use strict';
15+
16+
return Component.extend({
17+
18+
defaults: {
19+
signUpElement: '',
20+
submitButton: '',
21+
element: null
22+
},
23+
24+
/** @inheritdoc */
25+
initialize: function (config, element) {
26+
this._super();
27+
this.element = element;
28+
$(element).on('change', $.proxy(this.updateSignUpStatus, this));
29+
this.updateSignUpStatus();
30+
},
31+
32+
/**
33+
* Send status request and update subscription element according to result.
34+
*/
35+
updateSignUpStatus: function() {
36+
let element = $(this.element),
37+
email = element.val(),
38+
self = this,
39+
newsletterSubscription;
40+
41+
if ($(self.signUpElement).is(':checked')) {
42+
return;
43+
}
44+
45+
if (!email || !$.validator.methods['validate-email'].call(this, email, element)) {
46+
return;
47+
}
48+
49+
newsletterSubscription = $.Deferred();
50+
51+
$(self.submitButton).prop('disabled', true);
52+
53+
subscriptionStatusResolver(email, newsletterSubscription);
54+
55+
$.when(newsletterSubscription).done(function (isSubscribed) {
56+
$(self.signUpElement).prop('checked', isSubscribed);
57+
}).always(function () {
58+
$(self.submitButton).prop('disabled', false);
59+
});
60+
}
61+
});
62+
});
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'jquery',
8+
'mage/storage',
9+
'mage/url',
10+
], function ($, storage, urlBuilder) {
11+
'use strict';
12+
13+
return function(email, deferred) {
14+
return $.getJSON(
15+
urlBuilder.build('newsletter/ajax/status'),
16+
{
17+
email: email
18+
}
19+
).done(function (response) {
20+
deferred.resolve(response.subscribed);
21+
}).fail(function () {
22+
deferred.reject();
23+
});
24+
}
25+
});

0 commit comments

Comments
 (0)