I need to let users create a customization image in product page and than attach that image to product when users add product in cart.

Create a custom product option type seems to be very tricky.

I think that the simpliest solution is to customize product template adding the image builder and then add generated image in product options through an observer that take the image from request and put it in product options.

I'm new in magento, it could be the right solution? How can I implement? I'm able to create a module.

  • Did you find any solution ?
    – Amit Singh
    Nov 26, 2016 at 5:54

2 Answers 2


You can use the event checkout_cart_product_add_after to modify the product image information.

Firstly in your product detail page you need to add a hidden field in the add to cart form something like:

<input type="hidden" name="[option][front_designurl]" id="front_designurl"/>

And using javascript add the value to the field for the generated image url by the user, this value gets saved in the info_buyRequest of the quote item options

We have to create the file app/code/Foo/CustomImage/etc/events.xml to attach observers to the events:

  1. checkout_cart_product_add_after: Event is fired on Add to Cart
  2. checkout_cart_product_update_after: Event is fired on Cart Update (For add to cart from cart edit page)

<?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="foo_customimage_observer_set_price_for_item_add" instance="Foo\CustomImage\Model\Observer\SetImageForItem"/>
    <event name="checkout_cart_product_update_after">
        <observer name="foo_customimage_observer_set_price_for_item_update" instance="Foo\CustomImage\Model\Observer\SetImageForItem"/>

Now for the observer logic we create a file at app/code/Foo/CustomImage/Model/Observer/SetImageForItem.php


namespace Foo\CustomImage\Model\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Quote\Model\Quote\ProductOptionFactory;
use Magento\Quote\Api\Data\ProductOptionExtensionFactory;
use Magento\Catalog\Model\CustomOptions\CustomOptionFactory;

class SetImageForItem implements ObserverInterface
    /** @var \Magento\Quote\Model\Quote\ProductOptionFactory  */
    protected $productOptionFactory;

    /** @var \Magento\Quote\Api\Data\ProductOptionExtensionFactory  */
    protected $extensionFactory;

    /** @var CustomOptionFactory  */
    protected $customOptionFactory;

     * @param ProductOptionFactory $productOptionFactory
     * @param ProductOptionExtensionFactory $extensionFactory
     * @param CustomOptionFactory $customOptionFactory
    public function __construct(
        ProductOptionFactory $productOptionFactory,
        ProductOptionExtensionFactory $extensionFactory
        CustomOptionFactory $customOptionFactory
    ) {
        $this->productOptionFactory = $productOptionFactory;
        $this->extensionFactory = $extensionFactory;
        $this->customOptionFactory = $customOptionFactory;

    public function execute(Observer $observer)
        /** @var $item \Magento\Quote\Model\Quote\Item */
        $item    = $observer->getEvent()->getQuoteItem();//Gets the Quote Item Instance
        $request = $item->getBuyRequest(); // Gets the posted data sent to "Add to cart" controller action      
        return $this;
    }//end execute()

     * @inheritDoc
    public function processOptions(CartItemInterface $cartItem)
        $options = $this->getOptions($cartItem);
        if (!empty($options) && is_array($options)) {
            $productOption = $cartItem->getProductOption()
                ? $cartItem->getProductOption()
                : $this->productOptionFactory->create();

            /** @var  \Magento\Quote\Api\Data\ProductOptionExtensionInterface $extensibleAttribute */
            $extensibleAttribute = $productOption->getExtensionAttributes()
                ? $productOption->getExtensionAttributes()
                : $this->extensionFactory->create();


     * Receive custom option from buy request
     * @param CartItemInterface $cartItem
     * @return array
    protected function getOptions(CartItemInterface $cartItem)
        $buyRequest = !empty($cartItem->getOptionByCode('info_buyRequest'))
            ? unserialize($cartItem->getOptionByCode('info_buyRequest')->getValue())
            : null;
        return is_array($buyRequest) && isset($buyRequest['options'])
            ? $buyRequest['options']
            : [];

     * Update options values
     * @param array $options
     * @return null
    protected function updateOptionsValues(array &$options)
        foreach ($options as $optionId => &$optionValue) {
            /** @var \Magento\Catalog\Model\CustomOptions\CustomOption $option */
            $option = $this->customOptionFactory->create();
            if (is_array($optionValue)) {
                $optionValue = implode(',', $optionValue);
            $optionValue = $option;

I have not tried out the code, but should help you add new data to your product option.

  • Where to set custom option in above code? Jul 13, 2016 at 12:06

I was having a similar problem and solved the part of showing another image like this. beware: It might have bugs, if the aspect ratio / size of the actual product image from backend differs from the customized one.


<type name="Magento\Checkout\Block\Cart\Item\Renderer">
    <plugin sortOrder="1" name="foo" type="Foo\Bar\Plugin\Block\Cart\Item\RendererPlugin"/>



namespace Foo\Bar\Plugin\Block\Cart\Item;

class RendererPlugin
     * Override cart image, if designer product
     * @param \Magento\Checkout\Block\Cart\Item\Renderer $subject
     * @param \Magento\Catalog\Block\Product\Image $result
     * @see \Magento\Checkout\Block\Cart\Item\Renderer::getImage
    public function afterGetImage(\Magento\Checkout\Block\Cart\Item\Renderer $subject, $result)
    $item = $subject->getItem();
    $optionId = $this->options->getDesignerCodeOptionId($subject->getProduct());
    $designCode = $item->getOptionByCode('option_' . $optionId)->getValue();
    $design = $this->design->getByDesignCode($designCode);

    $previewImageUrl = $design->getData('preview_image_url');


    return $result; // recreate, to calculate aspect ratio an -- possible BUG: does not recalculate aspect ratio :-(


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.