Skip to content

Commit fbd3813

Browse files
committed
MC-37351: Cart contents lost after switching to different store with different domain
- Add customer ID in ContextInterface - Move error handling from cache serializer
1 parent d35dd1c commit fbd3813

File tree

7 files changed

+96
-39
lines changed

7 files changed

+96
-39
lines changed

app/code/Magento/Customer/Model/StoreSwitcher/RedirectDataPostprocessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function process(ContextInterface $context, array $data): void
6565
}
6666
} catch (NoSuchEntityException $e) {
6767
$this->logger->error($e);
68-
throw new LocalizedException(__('The requested customer does not exist.'), $e);
68+
throw new LocalizedException(__('Failed to sign into the customer account.'), $e);
6969
} catch (LocalizedException $e) {
7070
$this->logger->error($e);
7171
throw new LocalizedException(__('There was an error retrieving the customer record.'), $e);

app/code/Magento/Store/Controller/Store/Redirect.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\Store\Controller\Store;
99

10+
use Magento\Authorization\Model\UserContextInterface;
1011
use Magento\Framework\App\Action\Action;
1112
use Magento\Framework\App\Action\Context;
1213
use Magento\Framework\App\Action\HttpGetActionInterface;
@@ -59,6 +60,10 @@ class Redirect extends Action implements HttpGetActionInterface, HttpPostActionI
5960
* @var ContextInterfaceFactory|null
6061
*/
6162
private $contextFactory;
63+
/**
64+
* @var UserContextInterface|null
65+
*/
66+
private $userContext;
6267

6368
/**
6469
* @param Context $context
@@ -70,7 +75,9 @@ class Redirect extends Action implements HttpGetActionInterface, HttpPostActionI
7075
* @param StoreManagerInterface|null $storeManager
7176
* @param RedirectDataGenerator|null $redirectDataGenerator
7277
* @param ContextInterfaceFactory|null $contextFactory
78+
* @param UserContextInterface|null $userContext
7379
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
80+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
7481
*/
7582
public function __construct(
7683
Context $context,
@@ -81,7 +88,8 @@ public function __construct(
8188
HashGenerator $hashGenerator,
8289
StoreManagerInterface $storeManager = null,
8390
?RedirectDataGenerator $redirectDataGenerator = null,
84-
?ContextInterfaceFactory $contextFactory = null
91+
?ContextInterfaceFactory $contextFactory = null,
92+
?UserContextInterface $userContext = null
8593
) {
8694
parent::__construct($context);
8795
$this->storeRepository = $storeRepository;
@@ -92,6 +100,8 @@ public function __construct(
92100
?: ObjectManager::getInstance()->get(RedirectDataGenerator::class);
93101
$this->contextFactory = $contextFactory
94102
?: ObjectManager::getInstance()->get(ContextInterfaceFactory::class);
103+
$this->userContext = $userContext
104+
?: ObjectManager::getInstance()->get(UserContextInterface::class);
95105
}
96106

97107
/**
@@ -122,7 +132,10 @@ public function execute()
122132
[
123133
'fromStore' => $fromStore,
124134
'targetStore' => $targetStore,
125-
'redirectUrl' => $this->_redirect->getRedirectUrl()
135+
'redirectUrl' => $this->_redirect->getRedirectUrl(),
136+
'customerId' => $this->userContext->getUserType() === UserContextInterface::USER_TYPE_CUSTOMER ?
137+
(int) $this->userContext->getUserId()
138+
: null
126139
]
127140
)
128141
);

app/code/Magento/Store/Model/StoreSwitcher/Context.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,27 @@ class Context implements ContextInterface
2626
* @var string
2727
*/
2828
private $redirectUrl;
29+
/**
30+
* @var int|null
31+
*/
32+
private $customerId;
2933

3034
/**
3135
* @param StoreInterface $fromStore
3236
* @param StoreInterface $targetStore
3337
* @param string $redirectUrl
38+
* @param int|null $customerId
3439
*/
3540
public function __construct(
3641
StoreInterface $fromStore,
3742
StoreInterface $targetStore,
38-
string $redirectUrl
43+
string $redirectUrl,
44+
?int $customerId = null
3945
) {
4046
$this->fromStore = $fromStore;
4147
$this->targetStore = $targetStore;
4248
$this->redirectUrl = $redirectUrl;
49+
$this->customerId = $customerId;
4350
}
4451

4552
/**
@@ -65,4 +72,12 @@ public function getRedirectUrl(): string
6572
{
6673
return $this->redirectUrl;
6774
}
75+
76+
/**
77+
* @inheritDoc
78+
*/
79+
public function getCustomerId(): ?int
80+
{
81+
return $this->customerId;
82+
}
6883
}

app/code/Magento/Store/Model/StoreSwitcher/ContextInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,11 @@ public function getTargetStore(): StoreInterface;
3434
* @return string
3535
*/
3636
public function getRedirectUrl(): string;
37+
38+
/**
39+
* The logged in customer ID
40+
*
41+
* @return int
42+
*/
43+
public function getCustomerId(): ?int;
3744
}

app/code/Magento/Store/Model/StoreSwitcher/HashProcessor.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77

88
namespace Magento\Store\Model\StoreSwitcher;
99

10+
use Magento\Authorization\Model\UserContextInterface;
1011
use Magento\Framework\App\RequestInterface;
1112
use Magento\Framework\Exception\LocalizedException;
1213
use Magento\Framework\Message\ManagerInterface;
1314
use Magento\Store\Api\Data\StoreInterface;
1415
use Magento\Store\Model\StoreSwitcherInterface;
16+
use Psr\Log\LoggerInterface;
1517

1618
/**
1719
* Process one time token and build redirect url
@@ -49,6 +51,14 @@ class HashProcessor implements StoreSwitcherInterface
4951
* @var RedirectDataValidator
5052
*/
5153
private $dataValidator;
54+
/**
55+
* @var LoggerInterface
56+
*/
57+
private $logger;
58+
/**
59+
* @var UserContextInterface
60+
*/
61+
private $userContext;
5262

5363
/**
5464
* @param RequestInterface $request
@@ -58,6 +68,8 @@ class HashProcessor implements StoreSwitcherInterface
5868
* @param ContextInterfaceFactory $contextFactory
5969
* @param RedirectDataInterfaceFactory $dataFactory
6070
* @param RedirectDataValidator $dataValidator
71+
* @param LoggerInterface $logger
72+
* @param UserContextInterface $userContext
6173
*/
6274
public function __construct(
6375
RequestInterface $request,
@@ -66,7 +78,9 @@ public function __construct(
6678
ManagerInterface $messageManager,
6779
ContextInterfaceFactory $contextFactory,
6880
RedirectDataInterfaceFactory $dataFactory,
69-
RedirectDataValidator $dataValidator
81+
RedirectDataValidator $dataValidator,
82+
LoggerInterface $logger,
83+
UserContextInterface $userContext
7084
) {
7185
$this->request = $request;
7286
$this->postprocessor = $postprocessor;
@@ -75,6 +89,8 @@ public function __construct(
7589
$this->contextFactory = $contextFactory;
7690
$this->dataFactory = $dataFactory;
7791
$this->dataValidator = $dataValidator;
92+
$this->logger = $logger;
93+
$this->userContext = $userContext;
7894
}
7995

8096
/**
@@ -91,11 +107,15 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s
91107
$timestamp = (int) $this->request->getParam('time_stamp');
92108
$signature = (string) $this->request->getParam('signature');
93109
$data = (string) $this->request->getParam('data');
110+
$customerId = $this->userContext->getUserType() === UserContextInterface::USER_TYPE_CUSTOMER ?
111+
(int) $this->userContext->getUserId()
112+
: null;
94113
$context = $this->contextFactory->create(
95114
[
96115
'fromStore' => $fromStore,
97116
'targetStore' => $targetStore,
98-
'redirectUrl' => $redirectUrl
117+
'redirectUrl' => $redirectUrl,
118+
'customerId' => $customerId
99119
]
100120
);
101121
$redirectDataObject = $this->dataFactory->create(
@@ -116,6 +136,11 @@ public function switch(StoreInterface $fromStore, StoreInterface $targetStore, s
116136
}
117137
} catch (LocalizedException $exception) {
118138
$this->messageManager->addErrorMessage($exception->getMessage());
139+
} catch (\Throwable $exception) {
140+
$this->logger->error($exception);
141+
$this->messageManager->addErrorMessage(
142+
__('Something went wrong while switching to the store.')
143+
);
119144
}
120145

121146
return $redirectUrl;

app/code/Magento/Store/Model/StoreSwitcher/RedirectDataCacheSerializer.php

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
namespace Magento\Store\Model\StoreSwitcher;
99

10+
use http\Exception\InvalidArgumentException;
1011
use Magento\Framework\App\CacheInterface;
1112
use Magento\Framework\Math\Random;
1213
use Magento\Framework\Serialize\Serializer\Json;
13-
use Psr\Log\LoggerInterface;
1414

1515
/**
1616
* Store switcher redirect data cache serializer
@@ -33,45 +33,30 @@ class RedirectDataCacheSerializer implements RedirectDataSerializerInterface
3333
* @var Random
3434
*/
3535
private $random;
36-
/**
37-
* @var LoggerInterface
38-
*/
39-
private $logger;
4036

4137
/**
4238
* @param Json $json
4339
* @param Random $random
4440
* @param CacheInterface $cache
45-
* @param LoggerInterface $logger
4641
*/
4742
public function __construct(
4843
Json $json,
4944
Random $random,
50-
CacheInterface $cache,
51-
LoggerInterface $logger
45+
CacheInterface $cache
5246
) {
5347
$this->cache = $cache;
5448
$this->json = $json;
5549
$this->random = $random;
56-
$this->logger = $logger;
5750
}
5851

5952
/**
6053
* @inheritDoc
6154
*/
6255
public function serialize(array $data): string
6356
{
64-
$token = '';
65-
try {
66-
if ($data) {
67-
$token = $this->random->getRandomString(self::CACHE_ID_LENGTH);
68-
$cacheKey = self::CACHE_KEY_PREFIX . $token;
69-
$this->cache->save($this->json->serialize($data), $cacheKey, [], self::CACHE_LIFE_TIME);
70-
}
71-
} catch (\Throwable $exception) {
72-
$this->logger->error($exception);
73-
$token = '';
74-
}
57+
$token = $this->random->getRandomString(self::CACHE_ID_LENGTH);
58+
$cacheKey = self::CACHE_KEY_PREFIX . $token;
59+
$this->cache->save($this->json->serialize($data), $cacheKey, [], self::CACHE_LIFE_TIME);
7560

7661
return $token;
7762
}
@@ -81,18 +66,17 @@ public function serialize(array $data): string
8166
*/
8267
public function unserialize(string $data): array
8368
{
84-
$result = [];
85-
try {
86-
if (strlen($data) === self::CACHE_ID_LENGTH) {
87-
$cacheKey = self::CACHE_KEY_PREFIX . $data;
88-
$json = $this->cache->load($cacheKey);
89-
$result = $this->json->unserialize($json);
90-
$this->cache->remove($cacheKey);
91-
}
92-
} catch (\Throwable $exception) {
93-
$this->logger->error($exception);
94-
$result = [];
69+
if (strlen($data) !== self::CACHE_ID_LENGTH) {
70+
throw new InvalidArgumentException("Invalid cache key '$data' supplied.");
71+
}
72+
73+
$cacheKey = self::CACHE_KEY_PREFIX . $data;
74+
$json = $this->cache->load($cacheKey);
75+
if (!$json) {
76+
throw new InvalidArgumentException('Couldn\'t retrieve data from cache.');
9577
}
78+
$result = $this->json->unserialize($json);
79+
$this->cache->remove($cacheKey);
9680

9781
return $result;
9882
}

app/code/Magento/Store/Model/StoreSwitcher/RedirectDataGenerator.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\Store\Model\StoreSwitcher;
99

1010
use Magento\Framework\Encryption\Encryptor;
11+
use Psr\Log\LoggerInterface;
1112

1213
/**
1314
* Store switcher redirect data collector
@@ -30,23 +31,30 @@ class RedirectDataGenerator
3031
* @var Encryptor
3132
*/
3233
private $encryptor;
34+
/**
35+
* @var LoggerInterface
36+
*/
37+
private $logger;
3338

3439
/**
3540
* @param Encryptor $encryptor
3641
* @param RedirectDataPreprocessorInterface $preprocessor
3742
* @param RedirectDataSerializerInterface $serializer
3843
* @param RedirectDataInterfaceFactory $dataFactory
44+
* @param LoggerInterface $logger
3945
*/
4046
public function __construct(
4147
Encryptor $encryptor,
4248
RedirectDataPreprocessorInterface $preprocessor,
4349
RedirectDataSerializerInterface $serializer,
44-
RedirectDataInterfaceFactory $dataFactory
50+
RedirectDataInterfaceFactory $dataFactory,
51+
LoggerInterface $logger
4552
) {
4653
$this->preprocessor = $preprocessor;
4754
$this->serializer = $serializer;
4855
$this->dataFactory = $dataFactory;
4956
$this->encryptor = $encryptor;
57+
$this->logger = $logger;
5058
}
5159

5260
/**
@@ -58,7 +66,12 @@ public function __construct(
5866
public function generate(ContextInterface $context): RedirectDataInterface
5967
{
6068
$data = $this->preprocessor->process($context, []);
61-
$dataStr = $this->serializer->serialize($data);
69+
try {
70+
$dataStr = $this->serializer->serialize($data);
71+
} catch (\Throwable $exception) {
72+
$this->logger->error($exception);
73+
$dataStr = '';
74+
}
6275
$timestamp = time();
6376
$token = implode(
6477
',',

0 commit comments

Comments
 (0)