0

I am trying to add an image uploader in an admin form in magento 2.4, In the form I can see the image uploader but when I upload an image from the upload button I cannot see the preview nor is it saved, however if I upload the image from the gallery I can see the preview.

I put below the code of my custom module in case someone can help me:

Vendor\CompanyLogo\view\adminhtml\ui_component\myform_form.xml

 <field name="logoEmpresa" formElement="imageUploader" sortOrder="99">
        <settings>
            <label translate="true">Logo de empresa</label>
            <componentType>imageUploader</componentType>
        </settings>
        <formElements>
            <imageUploader>
                <settings>
                    <allowedExtensions>jpg jpeg gif png</allowedExtensions>
                    <maxFileSize>2097152</maxFileSize>
                    <previewTmpl>Vendor_CompanyLogo/template/image-preview</previewTmpl>
                    <uploaderConfig>
                        <param xsi:type="string" name="url">companylogo/company/upload</param>
                    </uploaderConfig>
                </settings>
            </imageUploader>
        </formElements>
    </field>

Vendor\CompanyLogo\Controller\Adminhtml\Company

<?php
 
namespace Vendor\CompanyLogo\Controller\Adminhtml\Company;
 
use Exception;
use Vendor\CompanyLogo\Model\Company\ImageUploader;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
 
class Upload extends Action implements HttpPostActionInterface
{
    /**
     * Image uploader
     *
     * @var ImageUploader
     */
    protected $imageUploader;
 
    /**
     * Upload constructor.
     *
     * @param Context $context
     * @param ImageUploader $imageUploader
     */
    public function __construct(
        Context $context,
        ImageUploader $imageUploader
    ) {
        parent::__construct($context);
        $this->imageUploader = $imageUploader;
    }
    /**
     * Upload file controller action
     *
     * @return ResultInterface
     */
    public function execute()
    {
        $imageId = $this->_request->getParam('param_name', 'image');
 
        try {
            $result = $this->imageUploader->saveFileToTmpDir($imageId);
        } catch (Exception $e) {
            $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
        }
        return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
    }
}

Vendor\CompanyLogo\Model\Company

<?php
 
namespace Vendor\CompanyLogo\Model\Company;
 
use Exception;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\File\Uploader;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\UrlInterface;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;
 
/**
 * Feature image uploader
 */
class ImageUploader
{
    const IMAGE_TMP_PATH = 'vendor/tmp/company';
 
    const IMAGE_PATH = 'vendor/company';
    /**
     * Core file storage database
     *
     * @var Database
     */
    protected $coreFileStorageDatabase;
 
    /**
     * Media directory object (writable).
     *
     * @var WriteInterface
     */
    protected $mediaDirectory;
 
    /**
     * Uploader factory
     *
     * @var UploaderFactory
     */
    protected $uploaderFactory;
 
    /**
     * Store manager
     *
     * @var StoreManagerInterface
     */
    protected $storeManager;
 
    /**
     * @var LoggerInterface
     */
    protected $logger;
 
    /**
     * Base tmp path
     *
     * @var string
     */
    protected $baseTmpPath;
 
    /**
     * Base path
     *
     * @var string
     */
    protected $basePath;
 
    /**
     * Allowed extensions
     *
     * @var string
     */
    protected $allowedExtensions;
 
    /**
     * List of allowed image mime types
     *
     * @var string[]
     */
    protected $allowedMimeTypes;
 
    /**
     * ImageUploader constructor
     *
     * @param Database $coreFileStorageDatabase
     * @param Filesystem $filesystem
     * @param UploaderFactory $uploaderFactory
     * @param StoreManagerInterface $storeManager
     * @param LoggerInterface $logger
     * @param string $baseTmpPath
     * @param string $basePath
     * @param string[] $allowedExtensions
     * @param string[] $allowedMimeTypes
     * @throws FileSystemException
     */
    public function __construct(
        Database $coreFileStorageDatabase,
        Filesystem $filesystem,
        UploaderFactory $uploaderFactory,
        StoreManagerInterface $storeManager,
        LoggerInterface $logger,
        $baseTmpPath = self::IMAGE_TMP_PATH,
        $basePath = self::IMAGE_PATH,
        $allowedExtensions = [],
        $allowedMimeTypes = []
    ) {
        $this->coreFileStorageDatabase = $coreFileStorageDatabase;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->uploaderFactory = $uploaderFactory;
        $this->storeManager = $storeManager;
        $this->logger = $logger;
        $this->baseTmpPath = $baseTmpPath;
        $this->basePath = $basePath;
        $this->allowedExtensions = $allowedExtensions;
        $this->allowedMimeTypes = $allowedMimeTypes;
    }
 
    /**
     * Set base tmp path
     *
     * @param string $baseTmpPath
     *
     * @return void
     */
    public function setBaseTmpPath($baseTmpPath)
    {
        $this->baseTmpPath = $baseTmpPath;
    }
 
    /**
     * Set base path
     *
     * @param string $basePath
     *
     * @return void
     */
    public function setBasePath($basePath)
    {
        $this->basePath = $basePath;
    }
 
    /**
     * Set allowed extensions
     *
     * @param string[] $allowedExtensions
     *
     * @return void
     */
    public function setAllowedExtensions($allowedExtensions)
    {
        $this->allowedExtensions = $allowedExtensions;
    }
 
    /**
     * Retrieve base tmp path
     *
     * @return string
     */
    public function getBaseTmpPath()
    {
        return $this->baseTmpPath;
    }
 
    /**
     * Retrieve base path
     *
     * @return string
     */
    public function getBasePath()
    {
        return $this->basePath;
    }
 
    /**
     * Retrieve allowed extensions
     *
     * @return string[]
     */
    public function getAllowedExtensions()
    {
        return $this->allowedExtensions;
    }
 
    /**
     * Retrieve path
     *
     * @param string $path
     * @param string $imageName
     *
     * @return string
     */
    public function getFilePath($path, $imageName)
    {
        return rtrim($path, '/') . '/' . ltrim($imageName, '/');
    }
 
    /**
     * Checking file for moving and move it
     *
     * @param string $imageName
     *
     * @return string
     *
     * @throws LocalizedException
     */
    public function moveFileFromTmp($imageName)
    {
        $baseTmpPath = $this->getBaseTmpPath();
        $basePath = $this->getBasePath();
 
        $baseImagePath = $this->getFilePath(
            $basePath,
            Uploader::getNewFileName(
                $this->mediaDirectory->getAbsolutePath(
                    $this->getFilePath($basePath, $imageName)
                )
            )
        );
        $baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName);
 
        try {
            $this->coreFileStorageDatabase->copyFile(
                $baseTmpImagePath,
                $baseImagePath
            );
            $this->mediaDirectory->renameFile(
                $baseTmpImagePath,
                $baseImagePath
            );
        } catch (Exception $e) {
            throw new LocalizedException(
                __('Something went wrong while saving the file(s).')
            );
        }
 
        return $imageName;
    }
 
    /**
     * Checking file for save and save it to tmp dir
     *
     * @param string $fileId
     *
     * @return string[]
     *
     * @throws LocalizedException
     */
    public function saveFileToTmpDir($fileId)
    {
        $baseTmpPath = $this->getBaseTmpPath();
 
        /** @var \Magento\MediaStorage\Model\File\Uploader $uploader */
        $uploader = $this->uploaderFactory->create(['fileId' => $fileId]);
        $uploader->setAllowedExtensions($this->getAllowedExtensions());
        $uploader->setAllowRenameFiles(true);
        if (!$uploader->checkMimeType($this->allowedMimeTypes)) {
            throw new LocalizedException(__('File validation failed.'));
        }
        $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath));
        unset($result['path']);
 
        if (!$result) {
            throw new LocalizedException(
                __('File can not be saved to the destination folder.')
            );
        }
 
        /**
         * Workaround for prototype 1.7 methods "isJSON", "evalJSON" on Windows OS
         */
        $result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
        $result['url'] = $this->storeManager
                ->getStore()
                ->getBaseUrl(
                    UrlInterface::URL_TYPE_MEDIA
                ) . $this->getFilePath($baseTmpPath, $result['file']);
        $result['name'] = $result['file'];
 
        if (isset($result['file'])) {
            try {
                $relativePath = rtrim($baseTmpPath, '/') . '/' . ltrim($result['file'], '/');
                $this->coreFileStorageDatabase->saveFile($relativePath);
            } catch (Exception $e) {
                $this->logger->critical($e);
                throw new LocalizedException(
                    __('Something went wrong while saving the file(s).')
                );
            }
        }
 
        return $result;
    }
}

Vendor\CompanyLogo\view\adminhtml\web\template\image-preview.html

<div class="file-uploader-summary">
    <div class="file-uploader-preview image-uploader-preview">
        <a class="image-uploader-preview-link" attr="href: $parent.getFilePreview($file)" target="_blank">
            <div class="file-uploader-spinner image-uploader-spinner" />
            <img
                class="preview-image"
                tabindex="0"
                event="load: $parent.onPreviewLoad.bind($parent)"
                attr="
                    src: $parent.getFilePreview($file),
                    alt: $file.name,
                    title: $file.name">
        </a>
 
        <div class="actions">
            <button
                type="button"
                class="action-remove"
                data-role="delete-button"
                attr="title: $t('Delete image')"
                disable="$parent.disabled"
                click="$parent.removeFile.bind($parent, $file)">
                <span translate="'Delete image'"/>
            </button>
        </div>
    </div>
 
    <div class="file-uploader-filename" text="$file.name"/>
    <div class="file-uploader-meta">
        <text args="$file.previewWidth"/>x<text args="$file.previewHeight"/>
    </div>
</div>

Vendor\CompanyLogo\etc\di.xml

<?xml version="1.0"?>


<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <virtualType name="Vendor\CompanyLogo\ReferenceImageUpload" type="Vendor\CompanyLogo\Model\Company\ImageUploader">
        <arguments>
            <argument name="baseTmpPath" xsi:type="string">vendor/tmp/company</argument>
            <argument name="basePath" xsi:type="string">vendor/company</argument>
            <argument name="allowedExtensions" xsi:type="array">
                <item name="jpg" xsi:type="string">jpg</item>
                <item name="jpeg" xsi:type="string">jpeg</item>
                <item name="gif" xsi:type="string">gif</item>
                <item name="png" xsi:type="string">png</item>
            </argument>
            <argument name="allowedMimeTypes" xsi:type="array">
                <item name="jpg" xsi:type="string">image/jpg</item>
                <item name="jpeg" xsi:type="string">image/jpeg</item>
                <item name="gif" xsi:type="string">image/gif</item>
                <item name="png" xsi:type="string">image/png</item>
            </argument> 
        </arguments>
    </virtualType>
    
    <type name="Vendor\CompanyLogo\Controller\Adminhtml\Company\Upload">
        <arguments>
            <argument name="imageUploader" xsi:type="object">Vendor\CompanyLogo\ReferenceImageUpload</argument>
        </arguments>
    </type>
</config>
2
  • Follow this blog : rohanhapani.com/… Dec 15 '20 at 4:53
  • @RohanHapani in your DataProvider.php you are using RH\Helloworld\Model\ResourceModel\Helloworld\Collection class, where is this class? I will have to follow this blog too?
    – Noty
    Dec 15 '20 at 9:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.