Magento2 - Как программно добавить товар в корзину при запуске checkout_cart_product_add_after

8

Представьте, что есть два продукта, а именно: Продукт A и Продукт B. Продукт B - это вирусный продукт, который мне нужно добавить в корзину, когда Продукт A добавлен в него.

Для этого я пытаюсь добавить продукт B в корзину, наблюдая за событием checkout_cart_product_add_after. После добавления продукта А я извлекаю количество продукта, добавленного для продукта А, и на его основе я пытаюсь добавить продукт Б программно. Чтобы добавить продукт 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
2
Даже из Magento 2.1.0 этот подход кажется устаревшим.
MagePsycho
@Dexter, как добавить товар с необходимой пользовательской опцией в корзину?
Shell Suite
@MagePsycho, как я могу узнать, какая функция, как вы предлагаете, будет устаревшей, я имею в виду (я изучаю Magento 2), как вы это знаете. Любая документация или что-либо еще, что разработчик Mage должен прочитать, прежде чем мы настроим какую-либо функциональность.
Inrsaurabh
$ item = $ наблюдатель-> getEvent () -> getData ('quote_item'); $ product = $ наблюдатель-> getEvent () -> getData ('product'); $ item = ($ item-> getParentItem ()? $ item-> getParentItem (): $ item); Если я печатаю echo $ item-> getId (); это ноль. я ничего здесь не получаю.
Дхармеш Харияни
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);
        }
    }
}

Израиль Гвидо
источник