0

As title says, how can I prevent adding same product to cart more than one time in Magento 2.4.2?

2

This plugin will work for simple and configurable products. You can throw an error or redirect e.g. to cart if product already exists in cart.

di.xml

<type name="Magento\Checkout\Model\Cart">
    <plugin disabled="false" name="Vendor_Module_Plugin_Magento_Checkout_Cart_BeforeAddToCart" type="Vendor\Module\Plugin\Magento\Checkout\Cart\BeforeAddToCart"/>
</type>

vendor/module/Plugin/Magento/Checkout/Cart/BeforeAddToCart.php

    <?php
    declare(strict_types=1);
    
    namespace Vendor\Module\Plugin\Magento\Checkout\Cart;
use Magento\Checkout\Model\Cart;
use Magento\Checkout\Model\Session;
use Magento\Catalog\Model\Product;
use Magento\Checkout\Model\Session\Proxy as SessionProxy;
use Magento\Framework\Message\ManagerInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\UrlInterface;

class BeforeAddToCart {

    private $messageManager;
    private $cartSession;
    private $configurableProduct;
    private $url;
    private $session;

    public function __construct(
        Configurable $configurableProduct,
        ManagerInterface $messageManager,
        SessionProxy $cartSession,
        UrlInterface $url,
        Session $session
    ) {
        $this->messageManager = $messageManager;
        $this->cartSession = $cartSession;
        $this->configurableProduct = $configurableProduct;
        $this->url = $url;
        $this->session = $session;
    }

    public function beforeAddProduct(Cart $subject, $productInfo, $requestInfo=null)
    {
        $enableProductCartControl=true;

        $product = null;
        $parentProduct=null;

        if ($productInfo instanceof Product) {

            $product = $productInfo;
            if (!$product->getId()) {
                throw new \Magento\Framework\Exception\LocalizedException(
                    __("This product wasn't found. Verify the product and try again.")
                );
            }

        }

        if ($product)
        {
            // default product is simple
            //
            if ($product->getTypeId()==='configurable')
            {
                if (isset($requestInfo['super_attribute']))
                {
                    $parentProduct=$product;
                    $childProduct = $this->configurableProduct->getProductByAttributes($requestInfo['super_attribute'] ,$product);
                    // change $product to child
                    $product=$childProduct;
                }
            }

                if ($product && $enableProductCartControl)
                {
                    // check for existence of product in cart...
                    if($this->cartSession->getQuote()->hasProductId($product->getId())){

                        // redirect to cart
                        $this->session->setRedirectUrl($this->url->getUrl('checkout/cart/index'));
                        throw new \Magento\Framework\Exception\LocalizedException(
                            __("[x] This product is already in the cart. Testing, testing : ". $product->getSku())
                        );
                    }

                }


        }

        return [$productInfo, $requestInfo];

    }

    /**
     * Get request for product add to cart procedure
     *
     * @param \Magento\Framework\DataObject|int|array $requestInfo
     * @return \Magento\Framework\DataObject
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    private function _getProductRequest($requestInfo)
    {
        if ($requestInfo instanceof \Magento\Framework\DataObject) {
            $request = $requestInfo;
        } elseif (is_numeric($requestInfo)) {
            $request = new \Magento\Framework\DataObject(['qty' => $requestInfo]);
        } elseif (is_array($requestInfo)) {
            $request = new \Magento\Framework\DataObject($requestInfo);
        } else {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('We found an invalid request for adding product to quote.')
            );
        }
        return $request;
    }
}
17
  • Thanks. I tested it on my store which has only configurable products which all contain 2 simple products and 1 downloadable product inside, but it doesn't work. I cannot add any product to the cart anymore. – KaMZaTa Feb 23 at 16:08
  • Check your logs for errors, the code works fine for me. – paj Feb 23 at 16:17
  • There's nothing on Magento logs. It simply refreshes the page but nothing is added to the cart. – KaMZaTa Feb 23 at 16:23
  • You are implementing this in your own module right? You know "vendor/Module" should be replaced with your own module path? – paj Feb 23 at 16:29
  • Yes, I implemented it in my module. Yes, I replaced Vendor/Module with my own path. – KaMZaTa 2 days ago
1

You can use plugin for that

in you di.xml

<type name="Magento\Checkout\Model\Cart">
<plugin name="prevent_add_to" type="vendor\Module\Plugin\Beforeaddtocart"/>
</type>

vendor\Module\Plugin\Beforeaddtocart.php

<?php

namespace vendor\Module\Plugin;

class Beforeaddtocart{
    
    public function beforeAddProduct(\Magento\Checkout\Model\Cart $subject, $productInfo, $requestInfo=null){
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $session = $objectManager->create('\Magento\Checkout\Model\Session');
        
        $product_id = $requestInfo['product'];
        $quote = $session->getQuote()->hasProductId($product_id);
        if($quote){
            throw new \Magento\Framework\Exception\LocalizedException(
                    __("The product is already in cart you can't add more than 1 qty")
                );
        }
        return [$productInfo, $requestInfo];

    }
}

note: Please don't use objectmanager directly

4
  • This code will not work for variations of configurable products added to cart. – paj Feb 23 at 11:27
  • Thanks, but since my store has only configurable products which contain 2 simple products and 1 downloadable product, how can I adapt it in order to prevent to add just 1 kind of these products and not the whole configurable product? – KaMZaTa Feb 23 at 16:10
  • Anyway, it seems to work for the whole configurable product (but not for the child, as I wrote) – KaMZaTa 2 days ago
  • sorry the code was not tested. but yes that code not work for configurable product – Ronak 2 days ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.