Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

Here is full Example

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

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.

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

use json_encode instead of serializer method.

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();}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top