/** * 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; }
/** * Process $buyRequest and sets its options before saving configuration to some product item. * This method is used to attach additional parameters to processed buyRequest. * * $params holds parameters of what operation must be performed: * - '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 inputs, * so they won't intersect with other submitted options * * @param \Magento\Framework\Object|array $buyRequest * @param \Magento\Framework\Object|array $params * @return \Magento\Framework\Object */ public function addParamsToBuyRequest($buyRequest, $params) { if (is_array($buyRequest)) { $buyRequest = new \Magento\Framework\Object($buyRequest); } if (is_array($params)) { $params = new \Magento\Framework\Object($params); } // Ensure that currentConfig goes as \Magento\Framework\Object - for easier work with it later $currentConfig = $params->getCurrentConfig(); if ($currentConfig) { if (is_array($currentConfig)) { $params->setCurrentConfig(new \Magento\Framework\Object($currentConfig)); } elseif (!$currentConfig instanceof \Magento\Framework\Object) { $params->unsCurrentConfig(); } } /* * Notice that '_processing_params' must always be object to protect processing forged requests * where '_processing_params' comes in $buyRequest as array from user input */ $processingParams = $buyRequest->getData('_processing_params'); if (!$processingParams || !$processingParams instanceof \Magento\Framework\Object) { $processingParams = new \Magento\Framework\Object(); $buyRequest->setData('_processing_params', $processingParams); } $processingParams->addData($params->getData()); return $buyRequest; }