Today we discuss how in Magento 2 ui component image upload.This tutorial is include image upload and show image in edit form,ui components tutorial for image upload,create ui component. This tutorial included the custom image upload, custom image unloader and save image in database.
Step 1: Add Ui component image field
<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-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
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email qaisarssatti@gmail.com
*
*/
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.
<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
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email qaisarssatti@gmail.com
*
*/
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
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email qaisarssatti@gmail.com
*
*/
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 resourceModel reference kindly look into Magento 2 create Custom Model For that you have to provide image ur
In DataProvider
/**
* Simple Hello World Module
*
* @category QaisarSatti
* @package QaisarSatti_HelloWorld
* @author Muhammad Qaisar Satti
* @Email qaisarssatti@gmail.com
*
*/
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.