10

I want to add product to cart with some additional data. My code adds the product to cart,but the additional info is not saved properly.
I want to display the additional content in cart like custom option http://i.prntscr.com/KzmHQqaNSYGhOt3buzlK1A.png

Here is my code

    namespace Namespace\Module\Controller\Index;

use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\App\Action\Context;

class Post extends \Magento\Framework\App\Action\Action
{

    protected $resultPageFactory;
    protected $_productRepository;
    protected $_cart;
    protected $formKey;
    private $serializer;


    public function __construct(
        Context $context,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        \Magento\Checkout\Model\Cart $cart, 
        \Magento\Framework\Data\Form\FormKey $formKey,
        \Magento\Framework\Serialize\SerializerInterface $serializer,
        PageFactory $resultPageFactory
    ) {
        $this->resultPageFactory = $resultPageFactory;
        $this->_productRepository = $productRepository;
        $this->_cart = $cart;
        $this->formKey = $formKey;
        $this->serializer = $serializer;
        parent::__construct($context);
    }    

    public function execute()
    {    
        $post = $this->getRequest()->getPostValue();
        $additionalOptions['print_style'] = [
            'label' => 'Print Style',
            'value' => 'Test',
        ];
        $params = array(
                'product' => 4,
                'qty' => 1,
                'options' => array('additional_options'=>$this->serializer->serialize($additionalOptions)) 
            );
            $_product = $this->_productRepository->getById(4);
            $this->_cart->addProduct($_product,$params);
            $this->_cart->save();

        echo 'success';



    }
}

How can I do it?

6
  • I have used below code but getting error Error > Fatal error: Uncaught TypeError: Argument 2 passed to > [Vendor_Name][Module_Name]\Controller\Index\Addplan::__construct() > must be an instance of Magento\Catalog\Model\ProductRepository, > instance of Magento\Checkout\Model\ResourceModel\Cart given, called in > /var/generation/[Vendor_Name]/[Module_Name]/Controller/Index/Addplan/Interceptor.php > on line 14 and defined in > /app/code/[Vendor_Name]/[Module_Name]/Controller/Index/Addplan.php:15 > Stack trace: #0 > /var/generation/[Vendor_Name]/[Module_Name]/Controller/Index/Addplan/Interceptor.
    – Jack
    Nov 29, 2017 at 5:48
  • I trying to use that code in magento version 2.2.4 but after add to cart showing this error '1 exception(s): Exception #0 (InvalidArgumentException): Unable to unserialize value.' please help me for that issue , Thanks
    – Sandeep V
    Aug 1, 2018 at 12:40
  • This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review Aug 1, 2018 at 13:02
  • If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review
    – Priyank
    Aug 1, 2018 at 13:25
  • I got Unable to unserialize value. when used that extension. plz help me
    – Sandeep V
    Aug 1, 2018 at 13:34

6 Answers 6

5

The following code works.
http://i.prntscr.com/cFUE8nuRQC2Veg4i3xo9OQ.png

        $productId = 4;
        $additionalOptions['print_style'] = [
            'label' => 'Print Style',
            'value' => 'Test'
        ];

        $params = array(
                'product' => $productId,
                'qty' => 1
            );
        $_product = $this->_productRepository->getById($productId);
        $_product->addCustomOption('additional_options', $this->serializer->serialize($additionalOptions));
        $this->_cart->addProduct($_product, $params);
        $this->_cart->save();
6
  • I have used your code but getting error
    – Jack
    Nov 29, 2017 at 5:45
  • how to update additional options
    – sivakumar
    Apr 17, 2018 at 12:50
  • Please check "Web Spider"'s Answer. Apr 19, 2018 at 5:53
  • @JancyAbraham : so will this effect on all sections like checkout summary,admin order section.Means we need to just add only in cart and will reflect all other sections? Mar 1, 2019 at 6:19
  • Yes,it will display Apr 11, 2019 at 5:32
2

You may use 2 approaches here

1) You may use setOptions() method to set the custom options before adding product to cart Your approach will be like

$customOptionFactory = $objectManager->create('Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory');

$additionalOptions['print_style'] = [
        'label' => 'Print Style',
        'value' => 'Test',
    ];
$customOptions = [];

foreach ($additionalOptions['print_style'] as $option) {
    $customOption = $customOptionFactory->create(['data' => $option]);
    $customOption->setProductSku($_product->getSku());
    $customOptions[] = $customOption;
}
$_product->setOptions($customOptions);
$this->_cart->addProduct($_product,$params);
$this->_cart->save();

for this approach you may take dev/tests/integration/testsuite/Magento/Catalog/_files/product_with_options.php as reference

2) You may use addCustomOption() method on $_product In this case your approach will be

 $additionalOptions['print_style'] = [
        'label' => 'Print Style',
        'value' => 'Test',
    ];
 $_product->addCustomOption('additional_options',serialize($additionalOptions));

P.S. Just in case you're curious to know how addCustomOption() is working , take a quick look on file

vendor/magento/module-catalog/Model/Product.php
1
1

You need to use Observer checkout_cart_product_add_after to add custom data in additional_options

Here is full Example

1
  • Sorry, I want to use the code in my custom controller. :-( Sep 20, 2017 at 6:20
1

This code works here : add products to cart with customizable options

$product = $productFactory->create();
$product->setStoreId(1)->load($product->getIdBySku($sku));
$params = new \Magento\Framework\DataObject();
$params->setQty($qty);
foreach ($product->getOptions() as $o) {
foreach ($o->getValues() as $value) {
if ($value["sku"] == 'RED') { //add this if to search for your custom option by sku or the value name etc.
$options[$value['option_id']] = $value['option_type_ id'];
$params->setOptions($options); //set the customizable option to the product

}
}
}
try {
$quote1->addProduct($product, $params); //add to cart 🙂
} catch (Exception $e) {echo $e->getMessage();}
0

This can be implemented using the event observer. You can add following files in your module Namespace/Module/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_product_add_after">
        <observer name="namespace_module_checkout_cart_product_add_after" instance="Namespace\Module\Observer\CheckoutCartProductAddAfterObserver" />
    </event>
</config>

Namespace/Module/Observer/CheckoutCartProductAddAfterObserver.php

namespace Namespace\Module\Observer;

use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\RequestInterface;

class CheckoutCartProductAddAfterObserver implements ObserverInterface {

    protected $_request;

    public function __construct(RequestInterface $request) {
        $this->_request = $request;
    }

    public function execute(EventObserver $observer) {
        $item = $observer->getQuoteItem();
        $additionalOptions = array();

        if ($additionalOption = $item->getOptionByCode('additional_options')) {
            $additionalOptions = (array) unserialize($additionalOption->getValue());
        }

       // $post = $this->_request->getParam('print_style'); // Your data added here
    $post = array('Print Style' = > 'Test');

        if (is_array($post)) {
            foreach ($post as $key => $value) {
                if ($key == '' || $value == '') {
                    continue;
                }

                $additionalOptions[] = array(
                    'label' => $key,
                    'value' => $value
                );
            }
        }

        if (count($additionalOptions) > 0) {
            $item->addOption(array(
                'product_id' => $item->getProductId(),
                'code' => 'additional_options',
                'value' => serialize($additionalOptions)
            ));
        }

    }

}

Hope this will help you.

0
0

If the method "$this->serializer->serialize" not works then

use json_encode instead of serializer method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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