Magento – Magento 2: Image not uploading in grid “Attention: File was not uploaded”

magento2magento2.2.2uicomponent

Created a custom module using Ui_Component,facing problem during image upload.

Error (On alert) :

Attention: File was not uploaded

Ui_Component Form Code for Upload:

    <field name="icon">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="dataType" xsi:type="string">string</item>
                <item name="source" xsi:type="string">Item</item>
                <item name="label" xsi:type="string" translate="true">Group Image</item>
                <item name="visible" xsi:type="boolean">true</item>
                <item name="formElement" xsi:type="string">fileUploader</item>
                <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
                <item name="previewTmpl" xsi:type="string">Testing_Test/image-preview</item>
                <item name="required" xsi:type="boolean">false</item>
                <item name="sortOrder" xsi:type="number">40</item>
                <item name="uploaderConfig" xsi:type="array">
                    <item name="url" xsi:type="url" path="testing/item/upload"/>
                </item>
            </item>
        </argument>
    </field> 

image-preview.html (Path: Testing/Test/view/adminhtml/web/template)

<div class="file-uploader-summary">
    <div class="file-uploader-preview">
        <a attr="href: $parent.getFilePreview($file)" target="_blank">
            <img
                class="preview-image"
                tabindex="0"
                event="load: $parent.onPreviewLoad.bind($parent)"
                attr="
                    src: $parent.getFilePreview($file),
                    alt: $file.name">
        </a>

        <div class="actions">
            <button
                type="button"
                class="action-remove"
                data-role="delete-button"
                attr="title: $t('Delete image')"
                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>

Upload.php (Path: Testing/Test/Controller/Adminhtml/Item)

<?php
namespace Testing\Test\Controller\Adminhtml\Item;

use Magento\Framework\Controller\ResultFactory;

class Upload extends \Magento\Backend\App\Action
{
public $imageUploader;

public function __construct(
    \Magento\Backend\App\Action\Context $context,
    \Vendor\Module\Model\ImageUploader $imageUploader
) {
    parent::__construct($context);
    $this->imageUploader = $imageUploader;
}

public function execute()
{
    try {
        $result = $this->imageUploader->saveFileToTmpDir('icon');
        $result['cookie'] = [
            'name' => $this->_getSession()->getName(),
            'value' => $this->_getSession()->getSessionId(),
            'lifetime' => $this->_getSession()->getCookieLifetime(),
            'path' => $this->_getSession()->getCookiePath(),
            'domain' => $this->_getSession()->getCookieDomain(),
        ];
    } catch (\Exception $e) {
        $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
    }
    return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
}

}

ImageUploader.php (Path: Testing\Test\Model)

namespace Testing\Test\Model;

class ImageUploader
{
    private $coreFileStorageDatabase;
    private $mediaDirectory;
    private $uploaderFactory;
    private $storeManager;
    private $logger;
    public $baseTmpPath;
    public $basePath;
    public $allowedExtensions;

    public function __construct(
        \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->coreFileStorageDatabase = $coreFileStorageDatabase;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
        $this->uploaderFactory = $uploaderFactory;
        $this->storeManager = $storeManager;
        $this->logger = $logger;
        $this->baseTmpPath = "item/tmp/icon";
        $this->basePath = "item/icon";
        $this->allowedExtensions= ['jpg', 'jpeg', 'gif', 'png'];
    }

    public function setBaseTmpPath($baseTmpPath)
    {
        $this->baseTmpPath = $baseTmpPath;
    }

    public function setBasePath($basePath)
    {
        $this->basePath = $basePath;
    }

    public function setAllowedExtensions($allowedExtensions)
    {
        $this->allowedExtensions = $allowedExtensions;
    }

    public function getBaseTmpPath()
    {
        return $this->baseTmpPath;
    }

    public function getBasePath()
    {
        return $this->basePath;
    }

    public function getAllowedExtensions()
    {
        return $this->allowedExtensions;
    }

    public function getFilePath($path, $imageName)
    {
        return rtrim($path, '/') . '/' . ltrim($imageName, '/');
    }

    public function moveFileFromTmp($imageName)
    {
        $baseTmpPath = $this->getBaseTmpPath();
        $basePath = $this->getBasePath();
        $baseImagePath = $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 \Magento\Framework\Exception\LocalizedException(
                __('Something went wrong while saving the file(s).')
            );
        }
        return $imageName;
    }

    public function saveFileToTmpDir($fileId)
    {
        $baseTmpPath = $this->getBaseTmpPath();
        $uploader = $this->uploaderFactory->create(['fileId' => $fileId]);
        $uploader->setAllowedExtensions($this->getAllowedExtensions());
        $uploader->setAllowRenameFiles(true);
        $result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath));
        if (!$result) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('File can not be saved to the destination folder.')
            );
        }

        $result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
        $result['path'] = str_replace('\\', '/', $result['path']);
        $result['url'] = $this->storeManager
                ->getStore()
                ->getBaseUrl(
                    \Magento\Framework\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 \Magento\Framework\Exception\LocalizedException(
                    __('Something went wrong while saving the file(s).')
                );
            }
        }
        return $result;
    }
}

di.xml

<type name="Testing\Test\Model\ImageUploader">
        <arguments>

            <argument name="baseTmpPath" xsi:type="string">item/tmp/icon</argument>
            <argument name="basePath" xsi:type="string">item/icon</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>
        </arguments>
    </type>

Done with all this:

php bin/magento setup:upgrade

php bin/magento setup:di:compile php

bin/magento setup:static-content:deploy

Anything missing in this code ?

Best Answer

Looking at your last comment, and giving a look at documentation, I am not sure why are you using Factory for that model

https://devdocs.magento.com/guides/v2.3/extension-dev-guide/factories.html

Factories are service classes that instantiate non-injectable classes, that is, models that represent a database entity. They create a layer of abstraction between the ObjectManager and business code.

So, I think you should use just \Magento\MediaStorage\Model\File\Uploader in \Testing\Test\Model\ImageUploader constructor