Skip to content

Commit 1769933

Browse files
committed
Merge branch 'MC-37351' of https://github.com/magento-mpi/magento2ce into PR-09-24-2020
2 parents 2588fac + 239d2fa commit 1769933

35 files changed

+2363
-163
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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\Checkout\Model\StoreSwitcher;
9+
10+
use Magento\Checkout\Model\Session as CheckoutSession;
11+
use Magento\Customer\Model\Session as CustomerSession;
12+
use Magento\Quote\Api\CartRepositoryInterface;
13+
use Magento\Store\Model\StoreSwitcher\ContextInterface;
14+
use Magento\Store\Model\StoreSwitcher\RedirectDataPostprocessorInterface;
15+
use Psr\Log\LoggerInterface;
16+
17+
/**
18+
* Process checkout data redirected from origin store
19+
*
20+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
21+
*/
22+
class RedirectDataPostprocessor implements RedirectDataPostprocessorInterface
23+
{
24+
/**
25+
* @var CartRepositoryInterface
26+
*/
27+
private $quoteRepository;
28+
29+
/**
30+
* @var CustomerSession
31+
*/
32+
private $customerSession;
33+
34+
/**
35+
* @var CheckoutSession
36+
*/
37+
private $checkoutSession;
38+
39+
/**
40+
* @var LoggerInterface
41+
*/
42+
private $logger;
43+
44+
/**
45+
* @param CartRepositoryInterface $quoteRepository
46+
* @param CustomerSession $customerSession
47+
* @param CheckoutSession $checkoutSession
48+
* @param LoggerInterface $logger
49+
*/
50+
public function __construct(
51+
CartRepositoryInterface $quoteRepository,
52+
CustomerSession $customerSession,
53+
CheckoutSession $checkoutSession,
54+
LoggerInterface $logger
55+
) {
56+
$this->quoteRepository = $quoteRepository;
57+
$this->customerSession = $customerSession;
58+
$this->checkoutSession = $checkoutSession;
59+
$this->logger = $logger;
60+
}
61+
62+
/**
63+
* @inheritDoc
64+
*/
65+
public function process(ContextInterface $context, array $data): void
66+
{
67+
if (!empty($data['quote_id'])
68+
&& $this->checkoutSession->getQuoteId() === null
69+
&& !$this->customerSession->isLoggedIn()
70+
) {
71+
try {
72+
$quote = $this->quoteRepository->get((int) $data['quote_id']);
73+
if ($quote
74+
&& $quote->getIsActive()
75+
&& in_array($context->getTargetStore()->getId(), $quote->getSharedStoreIds())
76+
) {
77+
$this->checkoutSession->setQuoteId($quote->getId());
78+
}
79+
} catch (\Throwable $e) {
80+
$this->logger->error($e);
81+
}
82+
}
83+
$quote = $this->checkoutSession->getQuote();
84+
if ($quote->getIsActive()) {
85+
// Update quote items so that product names are updated for current store view
86+
$quote->setStoreId($context->getTargetStore()->getId());
87+
$quote->getItemsCollection(false);
88+
$this->quoteRepository->save($quote);
89+
}
90+
}
91+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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\Checkout\Model\StoreSwitcher;
9+
10+
use Magento\Checkout\Model\Session as CheckoutSession;
11+
use Magento\Customer\Model\Session as CustomerSession;
12+
use Magento\Store\Model\StoreSwitcher\ContextInterface;
13+
use Magento\Store\Model\StoreSwitcher\RedirectDataPreprocessorInterface;
14+
15+
/**
16+
* Collect checkout data to be redirected to target store
17+
*
18+
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
19+
*/
20+
class RedirectDataPreprocessor implements RedirectDataPreprocessorInterface
21+
{
22+
/**
23+
* @var CustomerSession
24+
*/
25+
private $customerSession;
26+
27+
/**
28+
* @var CheckoutSession
29+
*/
30+
private $checkoutSession;
31+
32+
/**
33+
* @param CustomerSession $customerSession
34+
* @param CheckoutSession $checkoutSession
35+
*/
36+
public function __construct(
37+
CustomerSession $customerSession,
38+
CheckoutSession $checkoutSession
39+
) {
40+
$this->customerSession = $customerSession;
41+
$this->checkoutSession = $checkoutSession;
42+
}
43+
/**
44+
* @inheritDoc
45+
*/
46+
public function process(ContextInterface $context, array $data): array
47+
{
48+
if ($this->checkoutSession->getQuoteId() && !$this->customerSession->isLoggedIn()) {
49+
$quote = $this->checkoutSession->getQuote();
50+
if ($quote
51+
&& $quote->getIsActive()
52+
&& in_array($context->getTargetStore()->getId(), $quote->getSharedStoreIds())
53+
) {
54+
$data['quote_id'] = (int) $quote->getId();
55+
}
56+
}
57+
return $data;
58+
}
59+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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\Checkout\Test\Unit\Model\StoreSwitcher;
9+
10+
use Magento\Checkout\Model\Session as CheckoutSession;
11+
use Magento\Checkout\Model\StoreSwitcher\RedirectDataPostprocessor;
12+
use Magento\Customer\Model\Session as CustomerSession;
13+
use Magento\Quote\Api\CartRepositoryInterface;
14+
use Magento\Quote\Model\Quote;
15+
use Magento\Store\Api\Data\StoreInterface;
16+
use Magento\Store\Model\StoreSwitcher\ContextInterface;
17+
use PHPUnit\Framework\MockObject\MockObject;
18+
use PHPUnit\Framework\TestCase;
19+
use Psr\Log\LoggerInterface;
20+
21+
class RedirectDataPostprocessorTest extends TestCase
22+
{
23+
/**
24+
* @var CartRepositoryInterface
25+
*/
26+
private $quoteRepository;
27+
28+
/**
29+
* @var CustomerSession
30+
*/
31+
private $customerSession;
32+
33+
/**
34+
* @var CheckoutSession
35+
*/
36+
private $checkoutSession;
37+
/**
38+
* @var ContextInterface|MockObject
39+
*/
40+
private $context;
41+
/**
42+
* @var RedirectDataPostprocessor
43+
*/
44+
private $model;
45+
46+
/**
47+
* @inheritDoc
48+
*/
49+
protected function setUp(): void
50+
{
51+
parent::setUp();
52+
53+
$this->quoteRepository = $this->createMock(CartRepositoryInterface::class);
54+
$this->customerSession = $this->createMock(CustomerSession::class);
55+
$this->checkoutSession = $this->createMock(CheckoutSession::class);
56+
$logger = $this->createMock(LoggerInterface::class);
57+
$this->model = new RedirectDataPostprocessor(
58+
$this->quoteRepository,
59+
$this->customerSession,
60+
$this->checkoutSession,
61+
$logger
62+
);
63+
64+
$store1 = $this->createConfiguredMock(
65+
StoreInterface::class,
66+
[
67+
'getCode' => 'en',
68+
'getId' => 1,
69+
]
70+
);
71+
$store2 = $this->createConfiguredMock(
72+
StoreInterface::class,
73+
[
74+
'getCode' => 'fr',
75+
'getId' => 2,
76+
]
77+
);
78+
$this->context = $this->createConfiguredMock(
79+
ContextInterface::class,
80+
[
81+
'getFromStore' => $store2,
82+
'getTargetStore' => $store1,
83+
]
84+
);
85+
}
86+
87+
/**
88+
* @dataProvider processDataProvider
89+
* @param array $mock
90+
* @param array $data
91+
* @param bool $isQuoteSet
92+
*/
93+
public function testProcess(array $mock, array $data, bool $isQuoteSet): void
94+
{
95+
$this->customerSession->method('isLoggedIn')
96+
->willReturn($mock['isLoggedIn']);
97+
$this->checkoutSession->method('getQuoteId')
98+
->willReturn($mock['getQuoteId']);
99+
$this->checkoutSession->method('getQuote')
100+
->willReturnCallback(
101+
function () use ($mock) {
102+
return $this->createQuoteMock($mock);
103+
}
104+
);
105+
$this->quoteRepository->method('get')
106+
->willReturnCallback(
107+
function ($id) use ($mock) {
108+
return $this->createQuoteMock(array_merge($mock, ['getQuoteId' => $id]));
109+
}
110+
);
111+
$this->checkoutSession->expects($isQuoteSet ? $this->once() : $this->never())
112+
->method('setQuoteId')
113+
->with($data['quote_id'] ?? null);
114+
115+
$this->model->process($this->context, $data);
116+
}
117+
118+
/**
119+
* @return array
120+
*/
121+
public function processDataProvider(): array
122+
{
123+
return [
124+
[
125+
['isLoggedIn' => false, 'getQuoteId' => 4],
126+
['quote_id' => 2],
127+
false
128+
],
129+
[
130+
['isLoggedIn' => true, 'getQuoteId' => null],
131+
['quote_id' => 2],
132+
false
133+
],
134+
[
135+
['isLoggedIn' => false, 'getQuoteId' => null],
136+
['quote_id' => 1],
137+
false
138+
],
139+
[
140+
['isLoggedIn' => false, 'getQuoteId' => null, 'getIsActive' => false],
141+
['quote_id' => 2],
142+
false
143+
],
144+
[
145+
['isLoggedIn' => false, 'getQuoteId' => null],
146+
['quote_id' => 2],
147+
true
148+
],
149+
];
150+
}
151+
152+
/**
153+
* @param array $mock
154+
* @return Quote
155+
*/
156+
private function createQuoteMock(array $mock): Quote
157+
{
158+
return $this->createConfiguredMock(
159+
Quote::class,
160+
[
161+
'getIsActive' => $mock['getIsActive'] ?? true,
162+
'getId' => $mock['getQuoteId'],
163+
'getSharedStoreIds' => !($mock['getQuoteId'] % 2) ? [1, 2] : [2],
164+
]
165+
);
166+
}
167+
}

0 commit comments

Comments
 (0)