Add.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. *
  4. * Copyright © Magento, Inc. All rights reserved.
  5. * See COPYING.txt for license details.
  6. */
  7. namespace Magento\Checkout\Controller\Cart;
  8. use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
  9. use Magento\Catalog\Api\ProductRepositoryInterface;
  10. use Magento\Checkout\Model\Cart as CustomerCart;
  11. use Magento\Framework\Exception\NoSuchEntityException;
  12. /**
  13. * Controller for processing add to cart action.
  14. *
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. */
  17. class Add extends \Magento\Checkout\Controller\Cart implements HttpPostActionInterface
  18. {
  19. /**
  20. * @var ProductRepositoryInterface
  21. */
  22. protected $productRepository;
  23. /**
  24. * @param \Magento\Framework\App\Action\Context $context
  25. * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
  26. * @param \Magento\Checkout\Model\Session $checkoutSession
  27. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  28. * @param \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator
  29. * @param CustomerCart $cart
  30. * @param ProductRepositoryInterface $productRepository
  31. * @codeCoverageIgnore
  32. */
  33. public function __construct(
  34. \Magento\Framework\App\Action\Context $context,
  35. \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
  36. \Magento\Checkout\Model\Session $checkoutSession,
  37. \Magento\Store\Model\StoreManagerInterface $storeManager,
  38. \Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator,
  39. CustomerCart $cart,
  40. ProductRepositoryInterface $productRepository
  41. ) {
  42. parent::__construct(
  43. $context,
  44. $scopeConfig,
  45. $checkoutSession,
  46. $storeManager,
  47. $formKeyValidator,
  48. $cart
  49. );
  50. $this->productRepository = $productRepository;
  51. }
  52. /**
  53. * Initialize product instance from request data
  54. *
  55. * @return \Magento\Catalog\Model\Product|false
  56. */
  57. protected function _initProduct()
  58. {
  59. $productId = (int)$this->getRequest()->getParam('product');
  60. if ($productId) {
  61. $storeId = $this->_objectManager->get(
  62. \Magento\Store\Model\StoreManagerInterface::class
  63. )->getStore()->getId();
  64. try {
  65. return $this->productRepository->getById($productId, false, $storeId);
  66. } catch (NoSuchEntityException $e) {
  67. return false;
  68. }
  69. }
  70. return false;
  71. }
  72. /**
  73. * Add product to shopping cart action
  74. *
  75. * @return \Magento\Framework\Controller\Result\Redirect
  76. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  77. */
  78. public function execute()
  79. {
  80. if (!$this->_formKeyValidator->validate($this->getRequest())) {
  81. $this->messageManager->addErrorMessage(
  82. __('Your session has expired')
  83. );
  84. return $this->resultRedirectFactory->create()->setPath('*/*/');
  85. }
  86. $params = $this->getRequest()->getParams();
  87. try {
  88. if (isset($params['qty'])) {
  89. $filter = new \Zend_Filter_LocalizedToNormalized(
  90. ['locale' => $this->_objectManager->get(
  91. \Magento\Framework\Locale\ResolverInterface::class
  92. )->getLocale()]
  93. );
  94. $params['qty'] = $filter->filter($params['qty']);
  95. }
  96. $product = $this->_initProduct();
  97. $related = $this->getRequest()->getParam('related_product');
  98. /**
  99. * Check product availability
  100. */
  101. if (!$product) {
  102. return $this->goBack();
  103. }
  104. $this->cart->addProduct($product, $params);
  105. if (!empty($related)) {
  106. $this->cart->addProductsByIds(explode(',', $related));
  107. }
  108. $this->cart->save();
  109. /**
  110. * @todo remove wishlist observer \Magento\Wishlist\Observer\AddToCart
  111. */
  112. $this->_eventManager->dispatch(
  113. 'checkout_cart_add_product_complete',
  114. ['product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse()]
  115. );
  116. if (!$this->_checkoutSession->getNoCartRedirect(true)) {
  117. if (!$this->cart->getQuote()->getHasError()) {
  118. if ($this->shouldRedirectToCart()) {
  119. $message = __(
  120. 'You added %1 to your shopping cart.',
  121. $product->getName()
  122. );
  123. $this->messageManager->addSuccessMessage($message);
  124. } else {
  125. $this->messageManager->addComplexSuccessMessage(
  126. 'addCartSuccessMessage',
  127. [
  128. 'product_name' => $product->getName(),
  129. 'cart_url' => $this->getCartUrl(),
  130. ]
  131. );
  132. }
  133. }
  134. return $this->goBack(null, $product);
  135. }
  136. } catch (\Magento\Framework\Exception\LocalizedException $e) {
  137. if ($this->_checkoutSession->getUseNotice(true)) {
  138. $this->messageManager->addNoticeMessage(
  139. $this->_objectManager->get(\Magento\Framework\Escaper::class)->escapeHtml($e->getMessage())
  140. );
  141. } else {
  142. $messages = array_unique(explode("\n", $e->getMessage()));
  143. foreach ($messages as $message) {
  144. $this->messageManager->addErrorMessage(
  145. $this->_objectManager->get(\Magento\Framework\Escaper::class)->escapeHtml($message)
  146. );
  147. }
  148. }
  149. $url = $this->_checkoutSession->getRedirectUrl(true);
  150. if (!$url) {
  151. $url = $this->_redirect->getRedirectUrl($this->getCartUrl());
  152. }
  153. return $this->goBack($url);
  154. } catch (\Exception $e) {
  155. $this->messageManager->addExceptionMessage(
  156. $e,
  157. __('We can\'t add this item to your shopping cart right now.')
  158. );
  159. $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
  160. return $this->goBack();
  161. }
  162. }
  163. /**
  164. * Resolve response
  165. *
  166. * @param string $backUrl
  167. * @param \Magento\Catalog\Model\Product $product
  168. * @return $this|\Magento\Framework\Controller\Result\Redirect
  169. */
  170. protected function goBack($backUrl = null, $product = null)
  171. {
  172. if (!$this->getRequest()->isAjax()) {
  173. return parent::_goBack($backUrl);
  174. }
  175. $result = [];
  176. if ($backUrl || $backUrl = $this->getBackUrl()) {
  177. $result['backUrl'] = $backUrl;
  178. } else {
  179. if ($product && !$product->getIsSalable()) {
  180. $result['product'] = [
  181. 'statusText' => __('Out of stock')
  182. ];
  183. }
  184. }
  185. $this->getResponse()->representJson(
  186. $this->_objectManager->get(\Magento\Framework\Json\Helper\Data::class)->jsonEncode($result)
  187. );
  188. }
  189. /**
  190. * Returns cart url
  191. *
  192. * @return string
  193. */
  194. private function getCartUrl()
  195. {
  196. return $this->_url->getUrl('checkout/cart', ['_secure' => true]);
  197. }
  198. /**
  199. * Is redirect should be performed after the product was added to cart.
  200. *
  201. * @return bool
  202. */
  203. private function shouldRedirectToCart()
  204. {
  205. return $this->_scopeConfig->isSetFlag(
  206. 'checkout/cart/redirect_to_cart',
  207. \Magento\Store\Model\ScopeInterface::SCOPE_STORE
  208. );
  209. }
  210. }