Context.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Store\App\Action\Plugin;
  7. use Magento\Framework\App\Http\Context as HttpContext;
  8. use Magento\Framework\Exception\NoSuchEntityException;
  9. use Magento\Framework\Exception\NotFoundException;
  10. use Magento\Store\Api\Data\StoreInterface;
  11. use Magento\Store\Api\StoreCookieManagerInterface;
  12. use Magento\Store\Model\StoreManagerInterface;
  13. use Magento\Framework\App\Action\AbstractAction;
  14. use Magento\Framework\App\RequestInterface;
  15. /**
  16. * Class ContextPlugin
  17. */
  18. class Context
  19. {
  20. /**
  21. * @var \Magento\Framework\Session\SessionManagerInterface
  22. */
  23. protected $session;
  24. /**
  25. * @var \Magento\Framework\App\Http\Context
  26. */
  27. protected $httpContext;
  28. /**
  29. * @var \Magento\Store\Model\StoreManagerInterface
  30. */
  31. protected $storeManager;
  32. /**
  33. * @var StoreCookieManagerInterface
  34. */
  35. protected $storeCookieManager;
  36. /**
  37. * @param \Magento\Framework\Session\SessionManagerInterface $session
  38. * @param \Magento\Framework\App\Http\Context $httpContext
  39. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  40. * @param StoreCookieManagerInterface $storeCookieManager
  41. */
  42. public function __construct(
  43. \Magento\Framework\Session\SessionManagerInterface $session,
  44. \Magento\Framework\App\Http\Context $httpContext,
  45. \Magento\Store\Model\StoreManagerInterface $storeManager,
  46. StoreCookieManagerInterface $storeCookieManager
  47. ) {
  48. $this->session = $session;
  49. $this->httpContext = $httpContext;
  50. $this->storeManager = $storeManager;
  51. $this->storeCookieManager = $storeCookieManager;
  52. }
  53. /**
  54. * Set store and currency to http context.
  55. *
  56. * @param AbstractAction $subject
  57. * @param RequestInterface $request
  58. * @return void
  59. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  60. */
  61. public function beforeDispatch(
  62. AbstractAction $subject,
  63. RequestInterface $request
  64. ) {
  65. if ($this->isAlreadySet()) {
  66. //If required store related value were already set for
  67. //HTTP processors then just continuing as we were.
  68. return;
  69. }
  70. /** @var string|array|null $storeCode */
  71. $storeCode = $request->getParam(
  72. \Magento\Store\Model\StoreManagerInterface::PARAM_NAME,
  73. $this->storeCookieManager->getStoreCodeFromCookie()
  74. );
  75. if (is_array($storeCode)) {
  76. if (!isset($storeCode['_data']['code'])) {
  77. $this->processInvalidStoreRequested();
  78. }
  79. $storeCode = $storeCode['_data']['code'];
  80. }
  81. if ($storeCode === '') {
  82. //Empty code - is an invalid code and it was given explicitly
  83. //(the value would be null if the code wasn't found).
  84. $this->processInvalidStoreRequested();
  85. }
  86. try {
  87. $currentStore = $this->storeManager->getStore($storeCode);
  88. } catch (NoSuchEntityException $exception) {
  89. $this->processInvalidStoreRequested($exception);
  90. }
  91. $this->updateContext($currentStore);
  92. }
  93. /**
  94. * Take action in case of invalid store requested.
  95. *
  96. * @param \Throwable|null $previousException
  97. * @return void
  98. * @throws NotFoundException
  99. */
  100. private function processInvalidStoreRequested(
  101. \Throwable $previousException = null
  102. ) {
  103. $store = $this->storeManager->getStore();
  104. $this->updateContext($store);
  105. throw new NotFoundException(
  106. $previousException
  107. ? __($previousException->getMessage())
  108. : __('Invalid store requested.'),
  109. $previousException
  110. );
  111. }
  112. /**
  113. * Update context accordingly to the store found.
  114. *
  115. * @param StoreInterface $store
  116. * @return void
  117. */
  118. private function updateContext(StoreInterface $store)
  119. {
  120. $this->httpContext->setValue(
  121. StoreManagerInterface::CONTEXT_STORE,
  122. $store->getCode(),
  123. $this->storeManager->getDefaultStoreView()->getCode()
  124. );
  125. /** @var StoreInterface $defaultStore */
  126. $defaultStore = $this->storeManager->getWebsite()->getDefaultStore();
  127. $this->httpContext->setValue(
  128. HttpContext::CONTEXT_CURRENCY,
  129. $this->session->getCurrencyCode()
  130. ?: $store->getDefaultCurrencyCode(),
  131. $defaultStore->getDefaultCurrencyCode()
  132. );
  133. }
  134. /**
  135. * Check if there is a need to find the current store.
  136. *
  137. * @return bool
  138. */
  139. private function isAlreadySet(): bool
  140. {
  141. $storeKey = StoreManagerInterface::CONTEXT_STORE;
  142. return $this->httpContext->getValue($storeKey) !== null;
  143. }
  144. }