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);
}
