Skip to content

Magento 2.4: Save item option value in cart and retrieve it in order success

I have created a button for each product in the cart. Now I want to get the uploaded file URLs of each product from the cart and retrieve it in an email on order success.

My controller:

<?php
namespace MagemechanicLogoUploadControllerCart;

use MagentoFrameworkAppActionContext;
use MagentoFrameworkControllerResultFactory;
use MagentoFrameworkFilesystem;
use MagentoMediaStorageModelFileUploaderFactory;
use MagentoCheckoutModelCart;
use MagentoFrameworkFilesystemDirectoryList;

class Upload extends MagentoFrameworkAppActionAction
{
    protected $cart;
    protected $uploaderFactory;
    protected $filesystem;

    public function __construct(
        Context $context,
        Cart $cart,
        UploaderFactory $uploaderFactory,
        Filesystem $filesystem,
        DirectoryList $directoryList
    ) {
        parent::__construct($context);
        $this->cart = $cart;
        $this->uploaderFactory = $uploaderFactory;
        $this->filesystem = $filesystem;
        $this->directoryList = $directoryList;
    }

    public function execute()
    {
        if ($this->getRequest()->isPost()) {
            try {
                $itemId = $this->getRequest()->getParam('item_id');
                $file = $this->getRequest()->getFiles('logo_upload');
                $mediaDirectory = $this->filesystem->getDirectoryWrite(MagentoFrameworkAppFilesystemDirectoryList::MEDIA);
                $path = $mediaDirectory->getAbsolutePath('logouploads/');
                if (!is_dir($path)) {
                    mkdir($path, 0775, true);
                }

                if ($file && $file['error'] == 0) {
                    $uploader = $this->uploaderFactory->create(['fileId' => 'logo_upload']);
                    $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png', 'pdf']);
                    $uploader->setAllowRenameFiles(true);
                    $uploader->setFilesDispersion(false);
            
                    $result = $uploader->save($path);

                    if ($result['file']) {
                        $logoUrl = $this->_url->getBaseUrl(['_type' => MagentoFrameworkUrlInterface::URL_TYPE_MEDIA]) . 'logouploads/' . $result['file'];
                        $item = $this->cart->getQuote()->getItemById($itemId);
                        $item->addOption([
                            'product_id' => $item->getProductId(),
                            'code' => 'logo_upload',
                            'value' => json_encode(['url' => $logoUrl])
                        ]);
                        $item->save();
                        $this->cart->getQuote()->save();
                        $logoUrl = $this->_url->getBaseUrl(['_type' => MagentoFrameworkUrlInterface::URL_TYPE_MEDIA]) . 'logouploads/' . $result['file'];
                    
                        $this->messageManager->addSuccessMessage(__('Logo uploaded successfully.'));
                    }
                } else {
                    $this->messageManager->addErrorMessage(__('Logo upload error.'));
                }
            } catch (Exception $e) {
                $this->messageManager->addErrorMessage($e->getMessage());
            }
        }

        return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData(['success' => true, 'logo_url' => $logoUrl]);
    }
}

My checkout_onepage_controller_success_action observer:

<?php

namespace MagemechanicLogoUploadObserver;

use MagentoFrameworkEventObserverInterface;
use MagentoFrameworkEventObserver;
use MagentoFrameworkMailTemplateTransportBuilder;
use MagentoSalesModelOrder;
use MagentoFrameworkAppConfigScopeConfigInterface;
use MagentoStoreModelScopeInterface;

class SendFileOnOrderPlace implements ObserverInterface
{
    protected $transportBuilder;
    protected $scopeConfig;
/**
 * @var MagentoCheckoutModelCart
 */
protected $_cartModel;

    public function __construct(
        TransportBuilder $transportBuilder,
        ScopeConfigInterface $scopeConfig,
        MagentoCheckoutModelCart $cartModel
    ) {
        $this->transportBuilder = $transportBuilder;
        $this->scopeConfig = $scopeConfig;
        $this->_cartModel = $cartModel;
    }

    public function execute(Observer $observer)
    {

        $writer = new Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
        $logger = new Zend_Log();
        $logger->addWriter($writer);
        $logger->info('chekcout event triiggered');

        $order = $observer->getEvent()->getOrder();
        $items = $order->getAllItems();
        $attachments = [];
        // $quote = $this->_cartModel->getQuote();
        // $cartAllItems = $quote->getAllItems();
        // foreach ($cartAllItems as $item) {
        //     $options = $item->getProduct()->getTypeInstance(true)
        //     ->getOrderOptions($item->getProduct());
        //     foreach ($options as $option) {
        //         $itemOptions = $option;
        //         // $logger->info('Item ID: ');
        //         $logger->info('Order Item Options: ' . json_encode($itemOptions));
    
        //         //itemOptions contain all the custom option of an item
        //     }
        // }
        foreach ($items as $item) {
            $writer = new Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
            $logger = new Zend_Log();
            $logger->addWriter($writer);
            $logger->info('Item ID: ');
            $logger->info($item->getId());
            // $option1 = $item->getOptionByCode('logo_upload');
            // $logger->info(print_r($option1->getData(), true));
            
            $option = $item->getProductOptionByCode('logo_upload');
            if ($option) {
                $logger->info(print_r($option, true));

                $attachments[] = json_decode($option['value'], true);
            }
        // }

        // foreach ($items as $item) {
        //     $options = $item->getProductOptions();

            // if (isset($options['info_buyRequest'])) {
                // $writer = new Zend_Log_Writer_Stream(BP . '/var/log/custom2.log');
                // $logger = new Zend_Log();
                // $logger->addWriter($writer);
                // $logger->info(print_r($options['info_buyRequest'], true));

                // foreach ($options['info_buyRequest'] as $option) {
                    // if ($option['label'] === 'logo_upload') {
                        // $logoUploadValue = json_decode($option['value'], true);
                        // $logoUrl = $logoUploadValue['url'];
                        // $writer = new Zend_Log_Writer_Stream(BP . '/var/log/custom2.log');
                        // $logger = new Zend_Log();
                        // $logger->addWriter($writer);
                        // $logger->info(print_r($option, true));
                        // $logger->info('logoUploadValue ');
                        // $logger->info($logoUploadValue->getData());

                        // Log the logo URL (or handle it as needed)
                        // $this->logger->info('Logo URL: ' . $logoUrl);
                    // }
                // }

                // if (isset($options['options'])) {
                    // foreach ($options['options'] as $option) {
                    //     if ($option['code'] === 'logo_upload') { // Use 'code' instead of 'label'
                    //         $logoUploadValue = json_decode($option['value'], true);
                    //         $logoUrl = $logoUploadValue['url'];
    
                    //         // Log the logo URL (or handle it as needed)
                    //         $this->logger->info('Logo URL: ' . $logoUrl);
                    //     }
                    // }
                // }
            // }
        // }

        if (!empty($attachments)) {
            $adminEmail = $this->scopeConfig->getValue(
                'trans_email/ident_general/email',
                ScopeInterface::SCOPE_STORE
            );

            $templateVars = [
                'order' => $order,
                'attachments' => $attachments
            ];

            $transport = $this->transportBuilder
                ->setTemplateIdentifier('order_logo_attachment_email_template')
                ->setTemplateOptions([
                    'area' => MagentoFrameworkAppArea::AREA_FRONTEND,
                    'store' => $order->getStoreId(),
                ])
                ->setTemplateVars($templateVars)
                ->setFrom([
                    'email' => $adminEmail,
                    'name' => 'Admin'
                ])
                ->addTo($adminEmail)
                ->getTransport();

            $transport->sendMessage();
        }
    }
}

I am not able to retrieve the URLs in the order success observer.
Any help would be appreciated.