Skip to content

Commit 5f7bad7

Browse files
author
Oleksandr Iegorov
committed
MC-18270: When persistent cart is disabled, logged in users still have a persistent cart session
1 parent 72f72dd commit 5f7bad7

File tree

3 files changed

+71
-7
lines changed

3 files changed

+71
-7
lines changed

app/code/Magento/Persistent/Observer/CheckExpirePersistentQuoteObserver.php

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Persistent\Observer;
77

88
use Magento\Framework\Event\ObserverInterface;
9+
use Magento\Quote\Model\Quote;
910

1011
/**
1112
* Observer of expired session
@@ -68,6 +69,11 @@ class CheckExpirePersistentQuoteObserver implements ObserverInterface
6869
*/
6970
private $checkoutPagePath = 'checkout';
7071

72+
/**
73+
* @var Quote
74+
*/
75+
private $quote;
76+
7177
/**
7278
* @param \Magento\Persistent\Helper\Session $persistentSession
7379
* @param \Magento\Persistent\Helper\Data $persistentData
@@ -100,30 +106,81 @@ public function __construct(
100106
*
101107
* @param \Magento\Framework\Event\Observer $observer
102108
* @return void
109+
* @throws \Magento\Framework\Exception\LocalizedException
110+
* @throws \Magento\Framework\Exception\NoSuchEntityException
103111
*/
104112
public function execute(\Magento\Framework\Event\Observer $observer)
105113
{
106114
if (!$this->_persistentData->canProcess($observer)) {
107115
return;
108116
}
109117

118+
//clear persistent when persistent data is disabled
119+
if ($this->isPersistentQuoteOutdated()) {
120+
$this->_eventManager->dispatch('persistent_session_expired');
121+
$this->quoteManager->expire();
122+
$this->_checkoutSession->clearQuote();
123+
return;
124+
}
125+
110126
if ($this->_persistentData->isEnabled() &&
111127
!$this->_persistentSession->isPersistent() &&
112128
!$this->_customerSession->isLoggedIn() &&
113129
$this->_checkoutSession->getQuoteId() &&
114130
!$this->isRequestFromCheckoutPage($this->request) &&
115131
// persistent session does not expire on onepage checkout page
116-
(
117-
$this->_checkoutSession->getQuote()->getIsPersistent() ||
118-
$this->_checkoutSession->getQuote()->getCustomerIsGuest()
119-
)
132+
$this->isNeedToExpireSession()
120133
) {
121134
$this->_eventManager->dispatch('persistent_session_expired');
122135
$this->quoteManager->expire();
123136
$this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
124137
}
125138
}
126139

140+
/**
141+
* Checks if current quote marked as persistent and Persistence Functionality is disabled.
142+
*
143+
* @return bool
144+
* @throws \Magento\Framework\Exception\LocalizedException
145+
* @throws \Magento\Framework\Exception\NoSuchEntityException
146+
*/
147+
private function isPersistentQuoteOutdated(): bool
148+
{
149+
if ((!$this->_persistentData->isEnabled() || !$this->_persistentData->isShoppingCartPersist())
150+
&& !$this->_customerSession->isLoggedIn()
151+
&& $this->_checkoutSession->getQuoteId()) {
152+
return (bool)$this->getQuote()->getIsPersistent();
153+
}
154+
return false;
155+
}
156+
157+
/**
158+
* Condition checker
159+
*
160+
* @return bool
161+
* @throws \Magento\Framework\Exception\LocalizedException
162+
* @throws \Magento\Framework\Exception\NoSuchEntityException
163+
*/
164+
private function isNeedToExpireSession(): bool
165+
{
166+
return $this->getQuote()->getIsPersistent() || $this->getQuote()->getCustomerIsGuest();
167+
}
168+
169+
/**
170+
* Getter for Quote with micro optimization
171+
*
172+
* @return Quote
173+
* @throws \Magento\Framework\Exception\LocalizedException
174+
* @throws \Magento\Framework\Exception\NoSuchEntityException
175+
*/
176+
private function getQuote(): Quote
177+
{
178+
if ($this->quote === null) {
179+
$this->quote = $this->_checkoutSession->getQuote();
180+
}
181+
return $this->quote;
182+
}
183+
127184
/**
128185
* Check current request is coming from onepage checkout page.
129186
*

app/code/Magento/Persistent/Test/Unit/Observer/CheckExpirePersistentQuoteObserverTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public function testExecuteWhenPersistentIsNotEnabled()
116116
->method('canProcess')
117117
->with($this->observerMock)
118118
->willReturn(true);
119-
$this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn(false);
119+
$this->persistentHelperMock->expects($this->exactly(2))->method('isEnabled')->willReturn(false);
120120
$this->eventManagerMock->expects($this->never())->method('dispatch');
121121
$this->model->execute($this->observerMock);
122122
}
@@ -144,7 +144,9 @@ public function testExecuteWhenPersistentIsEnabled(
144144
->method('canProcess')
145145
->with($this->observerMock)
146146
->willReturn(true);
147-
$this->persistentHelperMock->expects($this->once())->method('isEnabled')->willReturn(true);
147+
$this->persistentHelperMock->expects($this->atLeastOnce())
148+
->method('isEnabled')
149+
->willReturn(true);
148150
$this->sessionMock->expects($this->once())->method('isPersistent')->willReturn(false);
149151
$this->checkoutSessionMock
150152
->method('getQuote')

dev/tests/integration/testsuite/Magento/Braintree/Controller/Paypal/PlaceOrderTest.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ protected function setUp()
4747

4848
$this->session = $this->getMockBuilder(Session::class)
4949
->disableOriginalConstructor()
50-
->setMethods(['getQuote', 'setLastOrderStatus', 'unsLastBillingAgreementReferenceId'])
50+
->setMethods(['getQuote', 'setLastOrderStatus', 'unsLastBillingAgreementReferenceId', 'getQuoteId'])
5151
->getMock();
5252

5353
$adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class)
@@ -76,6 +76,9 @@ protected function tearDown()
7676
/**
7777
* Tests a negative scenario for a place order flow when exception throws after placing an order.
7878
*
79+
*
80+
* @magentoAppArea frontend
81+
* @magentoAppIsolation enabled
7982
* @magentoDataFixture Magento/Braintree/Fixtures/paypal_quote.php
8083
*/
8184
public function testExecuteWithFailedOrder()
@@ -85,6 +88,8 @@ public function testExecuteWithFailedOrder()
8588

8689
$this->session->method('getQuote')
8790
->willReturn($quote);
91+
$this->session->method('getQuoteId')
92+
->willReturn($quote->getId());
8893

8994
$this->adapter->method('sale')
9095
->willReturn($this->getTransactionStub('authorized'));

0 commit comments

Comments
 (0)