:::: MENU ::::
Posts tagged with: image upload

Magento 2 ui component image upload

Today we discuss how in Magento 2 ui component image upload.This tutorial is include image upload and show image in edit form. This tutorial included the custom image upload, custom image unloader and save image in database.

Step 1: Add Ui component image field

<field name="logo">
            <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">helloworld</item>
                    <item name="label" xsi:type="string" translate="true">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">QaisarSatti_HelloWorld/image-preview</item>
                    <item name="required" xsi:type="boolean">false</item>
                    <item name="uploaderConfig" xsi:type="array">
                        <item name="url" xsi:type="url" path="helloworld/index/upload"/>
                    </item>
                </item>
            </argument>
   </field>

Step 2: Create template file

Create file name image-preview.html in directory.

QaisarSatti/HelloWorld/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>

Step 2: Create Image uploader

Create ImageUploader.php in following directory

QaisarSatti\HelloWorld\Model

<?php
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email [email protected]
*
*/

namespace QaisarSatti\HelloWorld\Model;

/**
 * Catalog image uploader
 */

class ImageUploader
{
    /**
     * Core file storage database
     *
     * @var \Magento\MediaStorage\Helper\File\Storage\Database
     */

    protected $coreFileStorageDatabase;

    /**
     * Media directory object (writable).
     *
     * @var \Magento\Framework\Filesystem\Directory\WriteInterface
     */

    protected $mediaDirectory;

    /**
     * Uploader factory
     *
     * @var \Magento\MediaStorage\Model\File\UploaderFactory
     */

    private $uploaderFactory;

    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */

    protected $storeManager;

    /**
     * @var \Psr\Log\LoggerInterface
     */

    protected $logger;

    /**
     * Base tmp path
     *
     * @var string
     */

    protected $baseTmpPath;

    /**
     * Base path
     *
     * @var string
     */

    protected $basePath;

    /**
     * Allowed extensions
     *
     * @var string
     */

    protected $allowedExtensions;

    /**
     * ImageUploader constructor
     *
     * @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase
     * @param \Magento\Framework\Filesystem $filesystem
     * @param \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Psr\Log\LoggerInterface $logger
     * @param string $baseTmpPath
     * @param string $basePath
     * @param string[] $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,
        $baseTmpPath,
        $basePath,
        $allowedExtensions
    ) {
        $this->coreFileStorageDatabase = $coreFileStorageDatabase;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
        $this->uploaderFactory = $uploaderFactory;
        $this->storeManager = $storeManager;
        $this->logger = $logger;
        $this->baseTmpPath = $baseTmpPath;
        $this->basePath = $basePath;
        $this->allowedExtensions = $allowedExtensions;
    }

    /**
     * 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 base path
     *
     * @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 \Magento\Framework\Exception\LocalizedException
     */

    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;
    }

    /**
     * Checking file for save and save it to tmp dir
     *
     * @param string $fileId
     *
     * @return string[]
     *
     * @throws \Magento\Framework\Exception\LocalizedException
     */

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

        /**
         * Workaround for prototype 1.7 methods "isJSON", "evalJSON" on Windows OS
         */

        $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;
    }
}

Step 4: Image Configuration

Now add your image configuration in di.xml. These configuration include upload base path and upload base temp path for image upload. Type will be your upload controller.

QaisarSatti\HelloWorld\etc\

Now adding the configuration in di.xml.

<virtualType name="QaisarSatti\HelloWorld\HelloWorldImageUpload" type="QaisarSatti\HelloWorld\Model\ImageUploader">
    <arguments>
            <argument name="baseTmpPath" xsi:type="string">test/tmp</argument>
            <argument name="basePath" xsi:type="string">test</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>
</virtualType>
<type name="QaisarSatti\HelloWorld\Controller\Adminhtml\Index\Upload">
    <arguments>
            <argument name="imageUploader" xsi:type="object">QaisarSatti\HelloWorld\HelloWorldImageUpload</argument>
    </arguments>
</type>

Step 5: Controller Upload Image

<?php
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email [email protected]
*
*/

namespace QaisarSatti\HelloWorld\Controller\Adminhtml\Index;

use Magento\Framework\Controller\ResultFactory;

/**
 * Class Upload
 */

class Upload extends \Magento\Backend\App\Action
{
    /**
     * Image uploader
     *
     * @var \Magento\Catalog\Model\ImageUploader
     */

    protected $imageUploader;

    /**
     * Upload constructor.
     *
     * @param \Magento\Backend\App\Action\Context $context
     * @param \Magento\Catalog\Model\ImageUploader $imageUploader
     */

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

    /**
     * Check admin permissions for this controller
     *
     * @return boolean
     */

    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('QaisarSatti_HelloWorld::helloworld1');
    }

    /**
     * Upload file controller action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */

    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('logo');

            $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);
    }
}

Step 5: Controller Save Image

<?php
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email [email protected]
*
*/

namespace QaisarSatti\HelloWorld\Controller\Adminhtml\Index;

use Magento\Backend\App\Action;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Exception\LocalizedException;

class Save extends \Magento\Backend\App\Action
{
   
    const ADMIN_RESOURCE = 'QaisarSatti_HelloWorld::helloworld';    
    protected $dataProcessor;    
    protected $dataPersistor;
    protected $imageUploader;


    public function __construct(
        Action\Context $context,
        PostDataProcessor $dataProcessor,
        DataPersistorInterface $dataPersistor
    ) {
        $this->dataProcessor = $dataProcessor;
        $this->dataPersistor = $dataPersistor;
        parent::__construct($context);
    }

    public function execute()
    {
       
        $data = $this->getRequest()->getPostValue();
     

        $resultRedirect = $this->resultRedirectFactory->create();
        if ($data) {



       

            if (isset($data['logo'][0]['name']) && isset($data['logo'][0]['tmp_name'])) {
                $data['image'] =$data['logo'][0]['name'];
                $this->imageUploader = \Magento\Framework\App\ObjectManager::getInstance()->get(
                'QaisarSatti\HelloWorld\HelloWorldImageUpload'
            );
                $this->imageUploader->moveFileFromTmp($data['image']);
            } elseif (isset($data['logo'][0]['image']) && !isset($data['logo'][0]['tmp_name'])) {
                $data['image'] = $data['logo'][0]['image'];
            } else {
                $data['image'] = null;
            }


        return $resultRedirect->setPath('*/*/');
    }
}

Step 5: Edit Form Showing Image

Now we will add data to show image on edit form. For that you have to provide image ur

In DataProvider

<?php
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email [email protected]
*
*/

namespace QaisarSatti\HelloWorld\Model\HelloWorld;

use QaisarSatti\HelloWorld\Model\ResourceModel\HelloWorld\CollectionFactory;
use Magento\Framework\App\Request\DataPersistorInterface;

/**
 * Class DataProvider
 */

class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
    /**
     * @var \Magento\Cms\Model\ResourceModel\Block\Collection
     */

    protected $collection;

    /**
     * @var DataPersistorInterface
     */

    protected $dataPersistor;

    /**
     * @var array
     */

    public    $_storeManager;    

    protected $loadedData;

    /**
     * Constructor
     *
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $blockCollectionFactory
     * @param DataPersistorInterface $dataPersistor
     * @param array $meta
     * @param array $data
     */

    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $helloworldCollectionFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        DataPersistorInterface $dataPersistor,
        array $meta = [],
        array $data = []
    ) {
        $this->collection = $helloworldCollectionFactory->create();
        $this->dataPersistor = $dataPersistor;
        $this->_storeManager=$storeManager;
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    }

    /**
     * Get data
     *
     * @return array
     */

    public function getData()
    {
        $baseurl =  $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        $items = $this->collection->getItems();
        /** @var \Magento\Cms\Model\Block $block */
        foreach ($items as $helloworld) {
             $temp = $helloworld>getData();
             if($temp['image']):
            $img = [];
            $img[0]['image'] = $temp['image'];
            $img[0]['url'] = $baseurl.'test/'.$temp['image'];
            $temp['logo'] = $img;
            endif;
           

        $data = $this->dataPersistor->get('helloworld');
        if (!empty($data)) {
            $helloworld = $this->collection->getNewEmptyItem();
            $helloworld>setData($data);
            $this->loadedData[$helloworld->getLabelId()] = $helloworld->getData();
            $this->dataPersistor->clear('helloworld');
        }else {
            if($items):
            if ($helloworld->getData('image') != null) {

                $t2[$helloworld>getId()] = $temp;    
                 
                return $t2;
            } else {                
                 
           
               return $this->loadedData;
               
            }
            endif;
          }


        return $this->loadedData;
    }
}

Note: You can follow this for multiple image too. Just repeat the process for every Image you want to add.

Author: Qaisar Satti
Category: Magento 2
Last Modified: July 12, 2018