diff --git a/vendor/magento/module-quote/Model/QuoteRepository.php b/vendor/magento/module-quote/Model/QuoteRepository.php index c836578bcc2..db5d1a551a4 100644 --- a/vendor/magento/module-quote/Model/QuoteRepository.php +++ b/vendor/magento/module-quote/Model/QuoteRepository.php @@ -12,6 +12,7 @@ use Magento\Framework\Api\SearchCriteria\CollectionProcessor; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\App\RequestSafetyInterface; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\ObjectManager\ResetAfterRequestInterface; @@ -96,6 +97,11 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter */ private $cartFactory; + /** + * @var RequestSafetyInterface + */ + private $requestSafety; + /** * Constructor * @@ -107,6 +113,7 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter * @param CollectionProcessorInterface|null $collectionProcessor * @param QuoteCollectionFactory|null $quoteCollectionFactory * @param CartInterfaceFactory|null $cartFactory + * @param RequestSafetyInterface|null $requestSafety * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( @@ -117,7 +124,8 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter JoinProcessorInterface $extensionAttributesJoinProcessor, CollectionProcessorInterface $collectionProcessor = null, QuoteCollectionFactory $quoteCollectionFactory = null, - CartInterfaceFactory $cartFactory = null + CartInterfaceFactory $cartFactory = null, + RequestSafetyInterface $requestSafety = null ) { $this->quoteFactory = $quoteFactory; $this->storeManager = $storeManager; @@ -128,6 +136,7 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter $this->quoteCollectionFactory = $quoteCollectionFactory ?: ObjectManager::getInstance() ->get(QuoteCollectionFactory::class); $this->cartFactory = $cartFactory ?: ObjectManager::getInstance()->get(CartInterfaceFactory::class); + $this->requestSafety = $requestSafety ?: ObjectManager::getInstance()->get(RequestSafetyInterface::class); } /** @@ -178,6 +187,7 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter */ public function getActive($cartId, array $sharedStoreIds = []) { + $this->validateCachedActiveQuote((int)$cartId); $quote = $this->get($cartId, $sharedStoreIds); if (!$quote->getIsActive()) { throw NoSuchEntityException::singleField('cartId', $cartId); @@ -185,11 +195,33 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter return $quote; } + /** + * Validates if cached quote is still active. + * + * @param int $cartId + * @return void + * @throws NoSuchEntityException + */ + private function validateCachedActiveQuote(int $cartId): void + { + if (isset($this->quotesById[$cartId]) && !$this->requestSafety->isSafeMethod()) { + $quote = $this->cartFactory->create(); + if (is_callable([$quote, 'setSharedStoreIds'])) { + $quote->setSharedStoreIds(['*']); + } + $quote->loadActive($cartId); + if (!$quote->getIsActive()) { + throw NoSuchEntityException::singleField('cartId', $cartId); + } + } + } + /** * @inheritdoc */ public function getActiveForCustomer($customerId, array $sharedStoreIds = []) { + $this->validateCachedCustomerActiveQuote((int)$customerId); $quote = $this->getForCustomer($customerId, $sharedStoreIds); if (!$quote->getIsActive()) { throw NoSuchEntityException::singleField('customerId', $customerId); @@ -197,6 +229,28 @@ class QuoteRepository implements CartRepositoryInterface, ResetAfterRequestInter return $quote; } + /** + * Validates if cached customer quote is still active. + * + * @param int $customerId + * @return void + * @throws NoSuchEntityException + */ + private function validateCachedCustomerActiveQuote(int $customerId): void + { + if (isset($this->quotesByCustomerId[$customerId]) && !$this->requestSafety->isSafeMethod()) { + $quoteId = $this->quotesByCustomerId[$customerId]->getId(); + $quote = $this->cartFactory->create(); + if (is_callable([$quote, 'setSharedStoreIds'])) { + $quote->setSharedStoreIds(['*']); + } + $quote->loadActive($quoteId); + if (!$quote->getIsActive()) { + throw NoSuchEntityException::singleField('customerId', $customerId); + } + } + } + /** * @inheritdoc */ diff --git a/vendor/magento/module-quote/i18n/en_US.csv b/vendor/magento/module-quote/i18n/en_US.csv index 6563651ba5a..65c12c26fc6 100644 --- a/vendor/magento/module-quote/i18n/en_US.csv +++ b/vendor/magento/module-quote/i18n/en_US.csv @@ -69,6 +69,7 @@ Carts,Carts "Validated Country Code","Validated Country Code" "Validated Vat Number","Validated Vat Number" "Invalid Quote Item id %1","Invalid Quote Item id %1" +"The cart is locked for processing. Please try again later.","The cart is locked for processing. Please try again later." "Invalid quote address id %1","Invalid quote address id %1" "Number above 0 is required for the limit","Number above 0 is required for the limit" "Please select a valid rate limit period in seconds: %1.","Please select a valid rate limit period in seconds: %1."