Magento2-checkout_cart_product_add_afterが発生したときにプログラムでカートに商品を追加する方法


8

製品Aと製品Bの2つの製品があるとします。製品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()して製品を追加しようとしても機能しません。誰でもこれをどのように行うことができるかを案内できますか?足りないものはありますか?

どんなガイダンスもいただければ幸いです。

回答:


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 2016

2
Magento 2.1.0からでも、このアプローチは推奨されないようです。
MagePsycho 2016

@Dexter必要なカスタムオプションの商品をカートに追加する方法
Shell Suite

@MagePsychoどの機能が非推奨になることを示唆していることをどのように知ることができるか、つまり、私はMagento 2を学んでいることを意味します。ドキュメントやその他のMage開発者は、機能をカスタマイズする前に読む必要があります。
inrsaurabh 2018年

$ item = $ observer-> getEvent()-> getData( 'quote_item'); $ product = $ observer-> getEvent()-> getData( 'product'); $ item =($ item-> getParentItem()?$ item-> getParentItem():$ item); エコーを出力する場合$ item-> getId(); それはnullです。ここには何もありません。
Dharmesh Hariyani 2018年

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.