/** * Add wishlist item to shopping cart and remove from wishlist * * If Product has required options - item removed from wishlist and redirect * to product view page with message about needed defined required options * * @return ResponseInterface * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function execute() { $itemId = (int) $this->getRequest()->getParam('item'); /* @var $item \Magento\Wishlist\Model\Item */ $item = $this->itemFactory->create()->load($itemId); if (!$item->getId()) { return $this->_redirect('*/*'); } $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId()); if (!$wishlist) { return $this->_redirect('*/*'); } // Set qty $qty = $this->getRequest()->getParam('qty'); if (is_array($qty)) { if (isset($qty[$itemId])) { $qty = $qty[$itemId]; } else { $qty = 1; } } $qty = $this->quantityProcessor->process($qty); if ($qty) { $item->setQty($qty); } $redirectUrl = $this->_url->getUrl('*/*'); $configureUrl = $this->_url->getUrl('*/*/configure/', ['id' => $item->getId(), 'product_id' => $item->getProductId()]); try { /** @var \Magento\Wishlist\Model\Resource\Item\Option\Collection $options */ $options = $this->optionFactory->create()->getCollection()->addItemFilter([$itemId]); $item->setOptions($options->getOptionsByItem($itemId)); $buyRequest = $this->productHelper->addParamsToBuyRequest($this->getRequest()->getParams(), ['current_config' => $item->getBuyRequest()]); $item->mergeBuyRequest($buyRequest); $item->addToCart($this->cart, true); $this->cart->save()->getQuote()->collectTotals(); $wishlist->save(); if (!$this->cart->getQuote()->getHasError()) { $message = __('You added %1 to your shopping cart.', $this->escaper->escapeHtml($item->getProduct()->getName())); $this->messageManager->addSuccess($message); } if ($this->cart->getShouldRedirectToCart()) { $redirectUrl = $this->cart->getCartUrl(); } else { $refererUrl = $this->_redirect->getRefererUrl(); if ($refererUrl && $refererUrl != $configureUrl) { $redirectUrl = $refererUrl; } } } catch (ProductException $e) { $this->messageManager->addError(__('This product(s) is out of stock.')); } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addNotice($e->getMessage()); $redirectUrl = $configureUrl; } catch (\Exception $e) { $this->messageManager->addException($e, __('Cannot add item to shopping cart')); } $this->helper->calculate(); return $this->getResponse()->setRedirect($redirectUrl); }
/** * Update wishlist Item and set data from request * * The $params sets how current item configuration must be taken into account and additional options. * It's passed to \Magento\Catalog\Helper\Product->addParamsToBuyRequest() to compose resulting buyRequest. * * Basically it can hold * - 'current_config', \Magento\Framework\Object or array - current buyRequest that configures product in this item, * used to restore currently attached files * - 'files_prefix': string[a-z0-9_] - prefix that was added at frontend to names of file options (file inputs), * so they won't intersect with other submitted options * * For more options see \Magento\Catalog\Helper\Product->addParamsToBuyRequest() * * @param int|Item $itemId * @param \Magento\Framework\Object $buyRequest * @param null|array|\Magento\Framework\Object $params * @return $this * @throws Exception * * @see \Magento\Catalog\Helper\Product::addParamsToBuyRequest() */ public function updateItem($itemId, $buyRequest, $params = null) { $item = null; if ($itemId instanceof Item) { $item = $itemId; } else { $item = $this->getItem((int) $itemId); } if (!$item) { throw new Exception(__('We can\'t specify a wish list item.')); } $product = $item->getProduct(); $productId = $product->getId(); if ($productId) { if (!$params) { $params = new \Magento\Framework\Object(); } else { if (is_array($params)) { $params = new \Magento\Framework\Object($params); } } $params->setCurrentConfig($item->getBuyRequest()); $buyRequest = $this->_catalogProduct->addParamsToBuyRequest($buyRequest, $params); $product->setWishlistStoreId($item->getStoreId()); $items = $this->getItemCollection(); $isForceSetQuantity = true; foreach ($items as $_item) { /* @var $_item Item */ if ($_item->getProductId() == $product->getId() && $_item->representProduct($product) && $_item->getId() != $item->getId()) { // We do not add new wishlist item, but updating the existing one $isForceSetQuantity = false; } } $resultItem = $this->addNewItem($product, $buyRequest, $isForceSetQuantity); /** * Error message */ if (is_string($resultItem)) { throw new Exception(__($resultItem)); } if ($resultItem->getId() != $itemId) { if ($resultItem->getDescription() != $item->getDescription()) { $resultItem->setDescription($item->getDescription())->save(); } $item->isDeleted(true); $this->setDataChanges(true); } else { $resultItem->setQty($buyRequest->getQty() * 1); $resultItem->setOrigData('qty', 0); } } else { throw new Exception(__('The product does not exist.')); } return $this; }
/** * Updates quote item with new configuration * * $params sets how current item configuration must be taken into account and additional options. * It's passed to \Magento\Catalog\Helper\Product->addParamsToBuyRequest() to compose resulting buyRequest. * * Basically it can hold * - 'current_config', \Magento\Framework\Object or array - current buyRequest that configures product in this item, * used to restore currently attached files * - 'files_prefix': string[a-z0-9_] - prefix that was added at frontend to names of file options (file inputs), * so they won't intersect with other submitted options * * For more options see \Magento\Catalog\Helper\Product->addParamsToBuyRequest() * * @param int $itemId * @param \Magento\Framework\Object $buyRequest * @param null|array|\Magento\Framework\Object $params * @return \Magento\Quote\Model\Quote\Item * @throws \Magento\Framework\Exception\LocalizedException * * @see \Magento\Catalog\Helper\Product::addParamsToBuyRequest() * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function updateItem($itemId, $buyRequest, $params = null) { $item = $this->getItemById($itemId); if (!$item) { throw new \Magento\Framework\Exception\LocalizedException(__('This is the wrong quote item id to update configuration.')); } $productId = $item->getProduct()->getId(); //We need to create new clear product instance with same $productId //to set new option values from $buyRequest $product = clone $this->productRepository->getById($productId, false, $this->getStore()->getId()); if (!$params) { $params = new \Magento\Framework\Object(); } elseif (is_array($params)) { $params = new \Magento\Framework\Object($params); } $params->setCurrentConfig($item->getBuyRequest()); $buyRequest = $this->_catalogProduct->addParamsToBuyRequest($buyRequest, $params); $buyRequest->setResetCount(true); $resultItem = $this->addProduct($product, $buyRequest); if (is_string($resultItem)) { throw new \Magento\Framework\Exception\LocalizedException(__($resultItem)); } if ($resultItem->getParentItem()) { $resultItem = $resultItem->getParentItem(); } if ($resultItem->getId() != $itemId) { /** * Product configuration didn't stick to original quote item * It either has same configuration as some other quote item's product or completely new configuration */ $this->removeItem($itemId); $items = $this->getAllItems(); foreach ($items as $item) { if ($item->getProductId() == $productId && $item->getId() != $resultItem->getId()) { if ($resultItem->compare($item)) { // Product configuration is same as in other quote item $resultItem->setQty($resultItem->getQty() + $item->getQty()); $this->removeItem($item->getId()); break; } } } } else { $resultItem->setQty($buyRequest->getQty()); } return $resultItem; }