Magento 2 - Gere imagem de personalização na página do produto e adicione-a às opções do produto no carrinho

7

Preciso permitir que os usuários criem uma imagem de personalização na página do produto e anexá-la ao produto quando os usuários adicionam o produto ao carrinho.

Criar um tipo de opção de produto personalizado parece ser muito complicado.

Penso que a solução mais simples é personalizar o modelo do produto, adicionando o construtor de imagens e, em seguida, adicionar a imagem gerada nas opções do produto através de um observador que pega a imagem da solicitação e a coloca nas opções do produto.

Eu sou novo em magento, poderia ser a solução certa? Como posso implementar? Eu sou capaz de criar um módulo.

Alessandro Paterno
fonte
Você achou alguma solução ?
Amit Singh

Respostas:

1

Você pode usar o evento checkout_cart_product_add_afterpara modificar as informações da imagem do produto.

Primeiramente, na página de detalhes do produto, você precisa adicionar um campo oculto no formulário Adicionar ao carrinho, algo como:

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

E usando javascript, adicione o valor ao campo para o URL da imagem gerada pelo usuário, esse valor será salvo nas info_buyRequestopções do item de cotação

Temos que criar o arquivo app/code/Foo/CustomImage/etc/events.xmlpara anexar observadores aos eventos:

  1. checkout_cart_product_add_after : O evento é acionado no Add to Cart
  2. checkout_cart_product_update_after : o evento é acionado na atualização do carrinho (para adicionar ao carrinho da página de edição do carrinho)

<?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>

Agora, para a lógica do observador, criamos um arquivo em 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;
        }
    }
}

Não testei o código, mas devo ajudá-lo a adicionar novos dados à sua opção de produto.

Atish Goswami
fonte
Onde definir a opção personalizada no código acima?
Bhupendra Jadeja
0

Eu estava tendo um problema semelhante e resolvi a parte de mostrar outra imagem como esta. cuidado: pode haver erros, se a proporção / tamanho da imagem real do produto do back-end diferir da imagem personalizada.

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 :-(

    }
}
Alex
fonte