_orderFactory = $orderFactory; $this->_customerSession = $customerSession; $this->quoteRepository = $quoteRepository; $this->_remoteAddress = $remoteAddress; $this->_eventManager = $eventManager; $this->_storeManager = $storeManager; $this->customerRepository = $customerRepository; $this->quoteIdMaskFactory = $quoteIdMaskFactory; $this->quoteFactory = $quoteFactory; parent::__construct( $request, $sidResolver, $sessionConfig, $saveHandler, $validator, $storage, $cookieManager, $cookieMetadataFactory, $appState ); } /** * Set customer data. * * @param CustomerInterface|null $customer * @return \Magento\Checkout\Model\Session * @codeCoverageIgnore */ public function setCustomerData($customer) { $this->_customer = $customer; return $this; } /** * Check whether current session has quote * * @return bool * @codeCoverageIgnore */ public function hasQuote() { return isset($this->_quote); } /** * Set quote to be loaded even if inactive * * @param bool $load * @return $this * @codeCoverageIgnore */ public function setLoadInactive($load = true) { $this->_loadInactive = $load; return $this; } /** * Get checkout quote instance by current session * * @return Quote * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function getQuote() { $this->_eventManager->dispatch('custom_quote_process', ['checkout_session' => $this]); if ($this->_quote === null) { $quote = $this->quoteFactory->create(); if ($this->getQuoteId()) { try { if ($this->_loadInactive) { $quote = $this->quoteRepository->get($this->getQuoteId()); } else { $quote = $this->quoteRepository->getActive($this->getQuoteId()); } /** * If current currency code of quote is not equal current currency code of store, * need recalculate totals of quote. It is possible if customer use currency switcher or * store switcher. */ if ($quote->getQuoteCurrencyCode() != $this->_storeManager->getStore()->getCurrentCurrencyCode()) { $quote->setStore($this->_storeManager->getStore()); $this->quoteRepository->save($quote->collectTotals()); /* * We mast to create new quote object, because collectTotals() * can to create links with other objects. */ $quote = $this->quoteRepository->get($this->getQuoteId()); } } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { $this->setQuoteId(null); } } if (!$this->getQuoteId()) { if ($this->_customerSession->isLoggedIn() || $this->_customer) { $customerId = $this->_customer ? $this->_customer->getId() : $this->_customerSession->getCustomerId(); try { $quote = $this->quoteRepository->getActiveForCustomer($customerId); $this->setQuoteId($quote->getId()); } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { } } else { $quote->setIsCheckoutCart(true); $this->_eventManager->dispatch('checkout_quote_init', ['quote' => $quote]); } } if ($this->_customer) { $quote->setCustomer($this->_customer); } elseif ($this->_customerSession->isLoggedIn()) { $quote->setCustomer($this->customerRepository->getById($this->_customerSession->getCustomerId())); } $quote->setStore($this->_storeManager->getStore()); $this->_quote = $quote; } if (!$this->isQuoteMasked() && !$this->_customerSession->isLoggedIn() && $this->getQuoteId()) { $quoteId = $this->getQuoteId(); /** @var $quoteIdMask \Magento\Quote\Model\QuoteIdMask */ $quoteIdMask = $this->quoteIdMaskFactory->create()->load($quoteId, 'quote_id'); if ($quoteIdMask->getMaskedId() === null) { $quoteIdMask->setQuoteId($quoteId)->save(); } $this->setIsQuoteMasked(true); } $remoteAddress = $this->_remoteAddress->getRemoteAddress(); if ($remoteAddress) { $this->_quote->setRemoteIp($remoteAddress); $xForwardIp = $this->request->getServer('HTTP_X_FORWARDED_FOR'); $this->_quote->setXForwardedFor($xForwardIp); } return $this->_quote; } /** * @return string * @codeCoverageIgnore */ protected function _getQuoteIdKey() { return 'quote_id_' . $this->_storeManager->getStore()->getWebsiteId(); } /** * @param int $quoteId * @return void * @codeCoverageIgnore */ public function setQuoteId($quoteId) { $this->storage->setData($this->_getQuoteIdKey(), $quoteId); } /** * @return int * @codeCoverageIgnore */ public function getQuoteId() { return $this->getData($this->_getQuoteIdKey()); } /** * Load data for customer quote and merge with current quote * * @return $this */ public function loadCustomerQuote() { if (!$this->_customerSession->getCustomerId()) { return $this; } $this->_eventManager->dispatch('load_customer_quote_before', ['checkout_session' => $this]); try { $customerQuote = $this->quoteRepository->getForCustomer($this->_customerSession->getCustomerId()); } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { $customerQuote = $this->quoteFactory->create(); } $customerQuote->setStoreId($this->_storeManager->getStore()->getId()); if ($customerQuote->getId() && $this->getQuoteId() != $customerQuote->getId()) { if ($this->getQuoteId()) { $this->quoteRepository->save( $customerQuote->merge($this->getQuote())->collectTotals() ); } $this->setQuoteId($customerQuote->getId()); if ($this->_quote) { $this->quoteRepository->delete($this->_quote); } $this->_quote = $customerQuote; } else { $this->getQuote()->getBillingAddress(); $this->getQuote()->getShippingAddress(); $this->getQuote()->setCustomer($this->_customerSession->getCustomerDataObject()) ->setTotalsCollectedFlag(false) ->collectTotals(); $this->quoteRepository->save($this->getQuote()); } return $this; } /** * @param string $step * @param array|string $data * @param bool|string|null $value * @return $this */ public function setStepData($step, $data, $value = null) { $steps = $this->getSteps(); if ($value === null) { if (is_array($data)) { $steps[$step] = $data; } } else { if (!isset($steps[$step])) { $steps[$step] = []; } if (is_string($data)) { $steps[$step][$data] = $value; } } $this->setSteps($steps); return $this; } /** * @param string|null $step * @param string|null $data * @return array|string|bool */ public function getStepData($step = null, $data = null) { $steps = $this->getSteps(); if ($step === null) { return $steps; } if (!isset($steps[$step])) { return false; } if ($data === null) { return $steps[$step]; } if (!is_string($data) || !isset($steps[$step][$data])) { return false; } return $steps[$step][$data]; } /** * Destroy/end a session * Unset all data associated with object * * @return $this */ public function clearQuote() { $this->_eventManager->dispatch('checkout_quote_destroy', ['quote' => $this->getQuote()]); $this->_quote = null; $this->setQuoteId(null); $this->setLastSuccessQuoteId(null); return $this; } /** * Unset all session data and quote * * @return $this */ public function clearStorage() { parent::clearStorage(); $this->_quote = null; return $this; } /** * Clear misc checkout parameters * * @return void */ public function clearHelperData() { $this->setRedirectUrl(null)->setLastOrderId(null)->setLastRealOrderId(null)->setAdditionalMessages(null); } /** * @return $this * @codeCoverageIgnore */ public function resetCheckout() { $this->setCheckoutState(self::CHECKOUT_STATE_BEGIN); return $this; } /** * @param Quote $quote * @return $this */ public function replaceQuote($quote) { $this->_quote = $quote; $this->setQuoteId($quote->getId()); return $this; } /** * Get order instance based on last order ID * * @return \Magento\Sales\Model\Order */ public function getLastRealOrder() { $orderId = $this->getLastRealOrderId(); if ($this->_order !== null && $orderId == $this->_order->getIncrementId()) { return $this->_order; } $this->_order = $this->_orderFactory->create(); if ($orderId) { $this->_order->loadByIncrementId($orderId); } return $this->_order; } /** * Restore last active quote * * @return bool True if quote restored successfully, false otherwise */ public function restoreQuote() { /** @var \Magento\Sales\Model\Order $order */ $order = $this->getLastRealOrder(); if ($order->getId()) { try { $quote = $this->quoteRepository->get($order->getQuoteId()); $quote->setIsActive(1)->setReservedOrderId(null); $this->quoteRepository->save($quote); $this->replaceQuote($quote)->unsLastRealOrderId(); $this->_eventManager->dispatch('restore_quote', ['order' => $order, 'quote' => $quote]); return true; } catch (\Magento\Framework\Exception\NoSuchEntityException $e) { } } return false; } /** * @param $isQuoteMasked bool * @return void * @codeCoverageIgnore */ protected function setIsQuoteMasked($isQuoteMasked) { $this->isQuoteMasked = $isQuoteMasked; } /** * @return bool|null * @codeCoverageIgnore */ protected function isQuoteMasked() { return $this->isQuoteMasked; } }