Magento2里循环添加同一个产品到购物车
Magento2里循环添加同一个产品到购物车
需要重写 MagentoCheckoutControllerCartAdd
在插件的etc/di.xml里定义
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nOnamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="MagentoCheckoutControllerCartAdd" type="ZouTestRewriteCheckoutControllerCartAdd" /> </config>
ZouTestRewriteCheckoutControllerCartAdd.php 里的核心代码如下:
<?php namespace ZouTestRewriteCheckoutControllerCart; use MagentoCatalogApiProductRepositoryInterface; use MagentoCheckoutModelCart as CustomerCart; use MagentoFrameworkExceptionNoSuchEntityException; class Add extends MagentoCheckoutControllerCartAdd { public function execute() { .... $productCartInfo = []; //if($params['qty'] > 1 && $product->getTypeId() == GiftCard::TYPE_GIFTCARD_PRODUCT){ if($params['qty'] > 1{ //$amGiftcardRecipientNames = array_values($params['am_giftcard_recipient_name']); $amGiftcardRecipientNames = $params['am_giftcard_recipient_name']; foreach ($amGiftcardRecipientNames as $name) { $newParams = $params; $newParams['am_giftcard_recipient_name'] = $name; $newParams['qty'] = 1; //$newParams['giftcard_store_id'] = $email; $productCartInfo[] = $newParams; } }else{ $params['am_giftcard_recipient_name'] = current($params['am_giftcard_recipient_name']); $params['qty'] = 1; $productCartInfo = [$params]; } //print_r($productCartInfo);die; //var_dump($params);die; foreach ($productCartInfo as $params) { $request->setParams($params); $product = clone $product; //$cart = clone $this->cart; $this->_checkoutSession->setGiftcardStoreId($params['giftcard_store_id']); $this->cart->addProduct($product, $params); // if (!empty($related)) { // $this->cart->addProductsByIds(explode(',', $related)); // } /** * @todo remove wishlist observer MagentoWishlistObserverAddToCart */ $this->_eventManager->dispatch('checkout_cart_add_product_complete',['product' => $product, 'request' => $request, 'response' => $this->getResponse()]); //$this->_checkoutSession->resetCheckout(); } $this->cart->save(); ... } } }
重点:
1,需要$product = clone $product;不然的话 自动合并成一个产品了 不是独立分开的
2,$this->cart->save(); 需要在循环外面进行save,不然价格就有问题(除第1个外 其他的价格为0)。
MagentoQuoteModelQuote 里有判断产品是否重复
public function addProduct( MagentoCatalogModelProduct $product, $request = null, $processMode = MagentoCatalogModelProductTypeAbstractType::PROCESS_MODE_FULL ) { ... $cartCandidates = $product->getTypeInstance()->prepareForCartAdvanced($request, $product, $processMode); 。。。 $item = $this->getItemByProduct($candidate); if (!$item) { $item = $this->itemProcessor->init($candidate, $request); $item->setQuote($this); $item->setOptions($candidate->getCustomOptions()); $item->setProduct($candidate); // Add only item that is not in quote already $this->addItem($item); } }
MagentoQuoteModelQuoteItem里进行比对
public function representProduct($product) { $itemProduct = $this->getProduct(); if (!$product || $itemProduct->getId() != $product->getId()) { return false; } /** * Check maybe product is planned to be a child of some quote item - in this case we limit search * only within same parent item */ $stickWithinParent = $product->getStickWithinParent(); if ($stickWithinParent) { if ($this->getParentItem() !== $stickWithinParent) { return false; } } // Check options $itemOptions = $this->getOptionsByCode(); $productOptions = $product->getCustomOptions(); if (!$this->compareOptions($itemOptions, $productOptions)) { return false; } if (!$this->compareOptions($productOptions, $itemOptions)) { return false; } return true; }
只要product的custom options里有不一样的option,就会认为不是同一个产品。
至于如何设置product的custom options,需要在对应产品类型的ProductType里去设置
protected function _prepareProduct(DataObject $buyRequest, $product, $processMode) { 。。。 $product->addCustomOption('am_giftcard_amount', $amount, $product); }