<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Checkout\Model;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteIdMaskFactory;
/**
* @api
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @since 100.0.2
*/
class Session extends \Magento\Framework\Session\SessionManager
{
/**
* Checkout state begin
*/
const CHECKOUT_STATE_BEGIN = 'begin';
/**
* Quote instance
*
* @var Quote
*/
protected $_quote;
/**
* Customer Data Object
*
* @var CustomerInterface|null
*/
protected $_customer;
/**
* Whether load only active quote
*
* @var bool
*/
protected $_loadInactive = false;
/**
* Loaded order instance
*
* @var \Magento\Sales\Model\Order
*/
protected $_order;
/**
* @var \Magento\Sales\Model\OrderFactory
*/
protected $_orderFactory;
/**
* @var \Magento\Customer\Model\Session
*/
protected $_customerSession;
/**
* @var \Magento\Quote\Api\CartRepositoryInterface
*/
protected $quoteRepository;
/**
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress
*/
protected $_remoteAddress;
/**
* @var \Magento\Framework\Event\ManagerInterface
*/
protected $_eventManager;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $_storeManager;
/**
* @var \Magento\Customer\Api\CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* @param QuoteIdMaskFactory
*/
protected $quoteIdMaskFactory;
/**
* @param bool
*/
protected $isQuoteMasked;
/**
* @var \Magento\Quote\Model\QuoteFactory
*/
protected $quoteFactory;
/**
* @param \Magento\Framework\App\Request\Http $request
* @param \Magento\Framework\Session\SidResolverInterface $sidResolver
* @param \Magento\Framework\Session\Config\ConfigInterface $sessionConfig
* @param \Magento\Framework\Session\SaveHandlerInterface $saveHandler
* @param \Magento\Framework\Session\ValidatorInterface $validator
* @param \Magento\Framework\Session\StorageInterface $storage
* @param \Magento\Framework\Stdlib\CookieManagerInterface $cookieManager
* @param \Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory
* @param \Magento\Framework\App\State $appState
* @param \Magento\Sales\Model\OrderFactory $orderFactory
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository
* @param \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
* @param QuoteIdMaskFactory $quoteIdMaskFactory
* @param \Magento\Quote\Model\QuoteFactory $quoteFactory
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Framework\App\Request\Http $request,
\Magento\Framework\Session\SidResolverInterface $sidResolver,
\Magento\Framework\Session\Config\ConfigInterface $sessionConfig,
\Magento\Framework\Session\SaveHandlerInterface $saveHandler,
\Magento\Framework\Session\ValidatorInterface $validator,
\Magento\Framework\Session\StorageInterface $storage,
\Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
\Magento\Framework\App\State $appState,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Magento\Customer\Model\Session $customerSession,
\Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress,
\Magento\Framework\Event\ManagerInterface $eventManager,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
QuoteIdMaskFactory $quoteIdMaskFactory,
\Magento\Quote\Model\QuoteFactory $quoteFactory
) {
$this->_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;
}
}
|