3

I am quite new to Magento and have the requirement to add a predetermined free product to the shopping cart each time the customer adds something else. So far I have added an observer to watch for the 'checkout_cart_product_add_after' event.

I have used the following code in my observer but when I add a product to the cart, a message is displayed saying

"We can't add this product to the basket right now"

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\View\Result\PageFactory;

class AddProduct implements ObserverInterface
{
    protected $resultPageFactory;
    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,
        PageFactory $resultPageFactory
    )
    {
        $this->resultPageFactory = $resultPageFactory;
        $this->_productRepository = $productRepository;
        $this->_cart = $cart;
        $this->formKey = $formKey;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $productId =10;

        $params = array(
            'form_key' => $this->formKey->getFormKey(),
            'product' => $productId, //product Id
            'qty'   =>1 //quantity of product
        );
        //Load the product based on productID
        $_product = $this->product->load($productId);
        $this->cart->addProduct($_product, $params);
        $this->cart->save();

    }

}

I hope somebody is able to explain what is going wrong here or point me in a different direction if this approach will not work. I am using version 2.2 of Magento.

Many thanks

2
  • product id with 10 is configurable product or simple? Feb 21, 2018 at 12:51
  • I can not see any issue in your approach. Please check that there is enough quantity of product available to add it in cart and it is not out of stock. Also if it is configurable product then you have to pass Attributes too in Parameters array
    – Khushbu
    Feb 20, 2019 at 8:16

3 Answers 3

2
protected $formKey;   
protected $cart;
protected $product;

public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\Data\Form\FormKey $formKey,
\Magento\Checkout\Model\Cart $cart,
\Magento\Catalog\Model\Product $product,
array $data = []) {
    $this->formKey = $formKey;
    $this->cart = $cart;
    $this->product = $product;      
    parent::__construct($context);
}

public function execute()
 { 
  $productId =10;
  $params = array(
                'form_key' => $this->formKey->getFormKey(),
                'product' => $productId, //product Id
                'qty'   =>1 //quantity of product                
            );              
    //Load the product based on productID   
    $_product = $this->product->load($productId);       
    $this->cart->addProduct($_product, $params);
    $this->cart->save();
 }
1
  • Please post answers with little explanation.. it would help better Nov 3, 2020 at 9:35
2

according to the docblock of Magento\Quote\Model\Quote::AddProduct(), $params should have to convert into \Magento\Framework\DataObject

<?php
namespace Vendor\Extension\Controller\Index;

use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;
use Magento\Checkout\Model\Session;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Data\Form\FormKey;
use Magento\Framework\DataObject\Factory;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Quote\Api\CartRepositoryInterface;

class Post extends Action
{
    protected $formKey;
    private $checkoutSession;
    private $productRepository;
    private $dataObjectFactory;
    private $cartRepository;

    public function __construct(
        Context $context,
        FormKey $formKey,
        Session $checkoutSession,
        ProductRepository $productRepository,
        Factory $dataObjectFactory,
        CartRepositoryInterface $cartRepository
    ) {
        $this->formKey = $formKey;
        $this->checkoutSession = $checkoutSession;
        $this->productRepository = $productRepository;
        $this->dataObjectFactory = $dataObjectFactory;
        $this->cartRepository = $cartRepository;
        parent::__construct($context);
    }
    public function execute()
    {
        $productId =10;
        $params = [
            'form_key' => $this->formKey->getFormKey(),
            'product' => $productId,
            'qty'   =>1
        ];
        try {
            $product = $this->productRepository->getById($productId);
            $cart = $this->checkoutSession->getQuote();
            $cart->addProduct(
                $product,
                $this->dataObjectFactory->create($params)
            );
            $this->cartRepository->save($cart);
        } catch (NoSuchEntityException $e) {
            //@todo no product with given ID
        } catch (LocalizedException $e) {
            //@todo error during addProduct or local during saving cart
        } catch (CouldNotSaveException $e) {
            //@todo unable to save cart
        } catch (\Exception $e) {
            //@todo there could be more type of exceptions than stated above
        }
    }
}

also:

  • use repository if possible
  • get cart from checkout session
1

try below code

<?php
    namespace Vendor\Extension\Controller\Index;
    use Magento\Framework\App\Action\Action;
    use Magento\Framework\App\Action\Context;
    use Magento\Framework\Data\Form\FormKey;
    use Magento\Checkout\Model\Cart;
    use Magento\Catalog\Model\Product;
    class Post extends Action
    {
        protected $formKey;   
        protected $cart;
        protected $product;
        public function __construct(
            Context $context,
            FormKey $formKey,
            Cart $cart,
            Product $product) {
                $this->formKey = $formKey;
                $this->cart = $cart;
                $this->product = $product;      
                parent::__construct($context);
        }
        public function execute()
         { 
            $productId =10;
            $params = array(
                        'form_key' => $this->formKey->getFormKey(),
                        'product' => $productId, 
                        'qty'   =>1
                    );              
            $product = $this->product->load($productId);       
            $this->cart->addProduct($product, $params);
            $this->cart->save();
         }
    }

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.