Magento2 - So fügen Sie ein Produkt programmgesteuert in den Warenkorb, wenn checkout_cart_product_add_after ausgelöst wird

8

Bedenken Sie, dass es zwei Produkte gibt, nämlich: Produkt A und Produkt B. Produkt B ist ein virales Produkt, das ich in den Warenkorb legen muss, wenn Produkt A hinzugefügt wird.

Zu diesem Zweck versuche ich, Produkt B in den Warenkorb zu legen, indem ich ein Ereignis beobachte checkout_cart_product_add_after. Sobald Produkt A hinzugefügt wurde, rufe ich die Menge des für Produkt A hinzugefügten Produkts ab und versuche darauf basierend, Produkt B programmgesteuert hinzuzufügen. Um Produkt B hinzuzufügen, habe ich folgenden Code geschrieben:

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

Der Versuch, ein Produkt mit hinzuzufügen, $this->_cart->addProduct()funktioniert jedoch nicht. Kann jemand bitte anleiten, wie dies getan werden kann? Gibt es etwas, was mir fehlt?

Jede Anleitung wird geschätzt.

Dexter
quelle

Antworten:

8

Für alle, die in Zukunft ihren Tag verschwenden könnten, beachten Sie bitte die unten stehende Antwort, die für Sie hilfreich sein wird.

Der obige Code zum Hinzufügen eines Produkts zum Warenkorb funktioniert einwandfrei. Das Problem liegt jedoch in der Logik. Ich werde es unten erklären.

Zuerst habe ich versucht, ein Produkt auf Veranstaltung hinzuzufügen checkout_cart_product_add_after. Dieses Ereignis wird ausgelöst, wenn das Produkt in den Warenkorb gelegt wird.

Weiter in Code graben, wenn Sie die Funktion ausführen müssen. Der Code zum Hinzufügen des Produkts zum Warenkorb lautet:$this->_cart->addProduct($_product,$params);

Wenn Sie die addProductFunktion einchecken vendor/module-checkout/Model/Cart.php, sehen Sie, dass die Funktion das checkout_cart_product_add_afterEreignis auslöst .

In unserem Fall kehrt das Steuerelement daher erneut zur Beobachterdatei zurück, in der erneut versucht wird, das Produkt in den Warenkorb zu legen. Es wird eine Rekursion erstellt, die bis zur Menge unseres Produktabgases läuft.

Sobald die Menge erschöpft ist, hört sie auf. Jetzt müssen wir eine Bedingung hinzufügen, um diese Rekursion zu stoppen. Die Bedingung kann Ihrer Logik entsprechen.

Jedes Mal, wenn ein Produkt in den Warenkorb gelegt $product->getId()wird, wird das zuletzt hinzugefügte Produkt zurückgegeben. Sie können dies verwenden, um eine Bedingung zu setzen.

Am Ende sieht mein Code ungefähr so ​​aus:

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

    }
}
Dexter
quelle
Was passiert, wenn der Benutzer den Warenkorb aktualisiert? Glaubst du, das wird immer noch ausgelöst?
MagePsycho
2
Selbst ab Magento 2.1.0 scheint dieser Ansatz veraltet zu sein.
MagePsycho
@Dexter Wie füge ich ein Produkt mit der erforderlichen benutzerdefinierten Option zum Warenkorb hinzu?
Shell Suite
@MagePsycho Wie kann ich wissen, welche Funktion Sie vorschlagen, dass sie veraltet sein wird? Ich meine (ich lerne Magento 2), woher Sie das wissen. Alle Dokumentationen oder sonstigen Informationen, die ein Mage-Entwickler lesen muss, bevor wir Funktionen anpassen.
Inrsaurabh
$ item = $ Observer-> getEvent () -> getData ('quote_item'); $ product = $ Observer-> getEvent () -> getData ('product'); $ item = ($ item-> getParentItem ()? $ item-> getParentItem (): $ item); Wenn ich echo $ item-> getId () drucke; es ist null. Ich bekomme hier nichts.
Dharmesh Hariyani
0

Ich habe ein anderes Formular für den protokollierten Kunden- und Gastwagen erstellt

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


Israel Guido
quelle