Magento2-如何在触发checkout_cart_product_add_after后以编程方式将产品添加到购物车


8

考虑有两种产品,即:产品A和产品B。产品B是一种虚拟产品,当将产品A添加到购物车时,我需要将其添加到购物车中。

为此,我正在尝试通过观察事件将产品B添加到购物车checkout_cart_product_add_after。添加产品A后,我将检索为产品A添加的产品数量,并基于此我尝试以编程方式添加产品B。要添加产品B,我编写了以下代码:

<?php
namespace MyModule\Applicationcharges\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class AddCharges implements ObserverInterface
{
    protected $_productRepository;
    protected $_cart;

    public function __construct(\Magento\Catalog\Model\ProductRepository $productRepository, \Magento\Checkout\Model\Cart $cart){
        $this->_productRepository = $productRepository;
        $this->_cart = $cart;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $item=$observer->getEvent()->getData('quote_item');
        $product=$observer->getEvent()->getData('product');
        $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
        $product->getQty();

        $params = array(
            'product' => 2056,
            'qty' => 1
        );

        $_product = $this->_productRepository->getById(2056);
        $this->_cart->addProduct($_product,$params);
        $this->_cart->save();
    }
}

但是,尝试使用添加产品$this->_cart->addProduct()无效。谁能指导如何做到这一点?有什么我想念的吗?

任何指导将不胜感激。

Answers:


8

对于所有将来可能会浪费时间的人,请在下面的答案中注明,这将对您有所帮助。

上面将产品添加到购物车的代码可以正常工作。但是,问题出在逻辑上。我将在下面解释。

首先,我试图在活动中添加产品checkout_cart_product_add_after。将产品添加到购物车时会触发此事件。

如果要执行功能,请进一步研究代码。将产品添加到购物车的代码是:$this->_cart->addProduct($_product,$params);

如果您检查addProduct功能,vendor/module-checkout/Model/Cart.php您将看到正在调度checkout_cart_product_add_after事件的功能。

因此,在我们的情况下,控件将再次返回到观察者文件,后者将再次尝试将产品添加到购物车中。将创建递归,直到您的产品耗尽为止。

一旦数量用完,它将停止。现在我们需要做的是,添加一个条件以停止此递归。条件可以根据您的逻辑。

现在,每次将产品添加到购物车时,$product->getId()都将返回最新添加的产品。您可以使用它来放置条件。

最后,我的代码如下所示:

<?php
namespace MyModule\Applicationcharges\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class AddCharges implements ObserverInterface
{
    protected $_productRepository;
    protected $_cart;
    protected $formKey;

    public function __construct(\Magento\Catalog\Model\ProductRepository $productRepository, \Magento\Checkout\Model\Cart $cart, \Magento\Framework\Data\Form\FormKey $formKey){
        $this->_productRepository = $productRepository;
        $this->_cart = $cart;
        $this->formKey = $formKey;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $item = $observer->getEvent()->getData('quote_item');
        $product = $observer->getEvent()->getData('product');
        $item = ($item->getParentItem() ? $item->getParentItem() : $item);

        // Enter the id of the prouduct which are required to be added to avoid recurrssion
        if($product->getId() != 2056){
            $params = array(
                'product' => 2056,
                'qty' => $product->getQty()
            );
            $_product = $this->_productRepository->getById(2056);
            $this->_cart->addProduct($_product,$params);
            $this->_cart->save();
        }

    }
}

如果用户更新购物车怎么办?您认为这仍会触发吗?
MagePsycho

2
即使从Magento 2.1.0起,这种方法似乎也已被弃用。
MagePsycho

@Dexter如何将具有所需自定义选项的产品添加到购物车?
Shell Suite'5

@MagePsycho我怎么知道你建议使用哪个功能,我的意思是(我正在学习Magento 2),你怎么知道的。在自定义任何功能之前,Mage开发人员必须阅读的所有文档或任何其他内容。
inrsaurabh

$ item = $ observer-> getEvent()-> getData('quote_item'); $ product = $ observer-> getEvent()-> getData('product'); $ item =($ item-> getParentItem()?$ item-> getParentItem():$ item); 如果我打印echo $ item-> getId(); 它为空。我在这里什么都没有。
Dharmesh Hariyani,

0

我为登录的客户和来宾购物车制作了另一个表格

<?php

namespace Ysa\Core\Controller\Api;

use Magento\Framework\App\Action\Action as Action;
use Magento\Framework\App\ResponseInterface;

class Cart extends Action
{
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Magento\Catalog\Model\Product $product,
        \Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface,
        \Magento\Store\Model\Store $store,
        \Magento\Checkout\Model\Session $session,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Quote\Api\CartManagementInterface $quoteManagement
    ) {
        $this->resultPageFactory        = $resultPageFactory;
        $this->_cartRepositoryInterface = $cartRepositoryInterface;
        $this->_store                   = $store;
        $this->_session                 = $session;
        $this->_productFactory          = $productFactory;
        $this->_quoteManagement         = $quoteManagement;

        parent::__construct($context);
    }

    /**
     * @return ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function execute()
    {
        $product_id = $this->getRequest()->getParam('product');
        $product = $this->_productFactory->create();
        $product->load($product_id);

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $customerSession = $objectManager->get('Magento\Customer\Model\Session');

        if ($customerSession->isLoggedIn()) {
            $customer = $customerSession->getCustomer();
            $quoteId = $this->_quoteManagement->createEmptyCartForCustomer($customer->getId());
            $quote = $this->_cartRepositoryInterface->get($quoteId);
            $quote->addProduct($product);
            $this->_cartRepositoryInterface->save($quote);
            $quote->collectTotals();
        } else {
            $quote = $this->_session->getQuote();
            $quote->setStore($this->_store);
            $quote->setCurrency();
            $quote->addProduct($product);
            $quote->save();
            $quote->collectTotals();
            $this->_cartRepositoryInterface->save($quote);
        }
    }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.