7

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 '16 at 5:54
1

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

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

<?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      
        $this->processOptions($item);       
        return $this;
    }//end execute()


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

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

            $extensibleAttribute->setCustomOptions($options);
            $productOption->setExtensionAttributes($extensibleAttribute);
            $cartItem->setProductOption($productOption);
        }
    }

    /**
     * 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();
            $option->setOptionId($optionId);
            if (is_array($optionValue)) {
                $optionValue = implode(',', $optionValue);
            }
            $option->setOptionValue($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? – Bhupendra Jadeja Jul 13 '16 at 12:06
0

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.

di.xml

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

RendererPlugin.php

<?php

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

    $result->setImageUrl($previewImageUrl);

    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, privacy policy and cookie policy

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