cancel
Showing results for 
Search instead for 
Did you mean: 

Add file upload in existing module

Add file upload in existing module

Hi Guys,

 

I am adding file upload field in my existing event  module. Below is my code. File upload not working and not showing any error in log file, After investigation I found file upload filed name in browser source show as event_data[event_homepdf] but my code I am using only event_homepdf

form.xml file upload field is below

<field name="event_homepdf">
            <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">Event</item>
                    <item name="label" xsi:type="string" translate="true">Home PDF</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">Magento_Catalog/image-preview</item>
                    <item name="required" xsi:type="boolean">false</item>
                    <item name="uploaderConfig" xsi:type="array">
                        <item name="url" xsi:type="url" path="eventmanager/event/upload"/>
                    </item>                  
                </item>
            </argument>
        </field>

Controller code is below

<?php 
namespace Webkul\EventManager\Controller\Adminhtml\Event;
use Magento\Framework\Controller\ResultFactory;

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

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

    public function _isAllowed()
    {
        return $this->_authorization->isAllowed('Webkul_EventManager::Event');
    }

    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('event_homepdf'); 		
						
            $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);
    }
}
?>

Model code is bewlo

<?php

namespace Webkul\EventManager\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 = "event/tmp/pdf/";
        $this->basePath = "event/pdf/";
        $this->allowedExtensions= ['jpg', 'jpeg', 'gif', 'png','pdf'];
    }

    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));
		
		$this->logger->alert($result);
		
        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("upload pdf error=".$e);
                throw new \Magento\Framework\Exception\LocalizedException(
                    __('Something went wrong while saving the file(s).')
                );
            }
        }
        return $result;
    }
}

How can i give straight name of file upload field event_data[event_homepdf] to event_homepdf

 

Any one can help me!!!

 

 

Thanks

Sanjeev

 

2 REPLIES 2

Re: Add file upload in existing module

To Add file upload follow the following steps:

create [Namespace]\[Module]\Block\Adminhtml\[Entity]\Helper\Image 
class

<?php
namespace [Namespace]\[Module]\Block\Adminhtml\[Entity]\Helper;
use Magento\Framework\Data\Form\Element\Image as ImageField;
use Magento\Framework\Data\Form\Element\Factory as ElementFactory;
use Magento\Framework\Data\Form\Element\CollectionFactory as ElementCollectionFactory;
use Magento\Framework\Escaper;
use [Namespace]\[Module]\Model\[Entity]\Image as [Entity]Image;
use Magento\Framework\UrlInterface;

/**
 * @method string getValue()
 */
class Image extends ImageField
{
    /**
     * image model
     *
     * @var \[Namespace]\[Module]\Model\[Entity]\Image
     */
    protected $imageModel;

    /**
     * @param [Entity]Image $imageModel
     * @param ElementFactory $factoryElement
     * @param ElementCollectionFactory $factoryCollection
     * @param Escaper $escaper
     * @param UrlInterface $urlBuilder
     * @param array $data
     */
    public function __construct(        [Entity]Image $imageModel,
        ElementFactory $factoryElement,
        ElementCollectionFactory $factoryCollection,
        Escaper $escaper,
        UrlInterface $urlBuilder,
        $data = []
    )
    {
        $this->imageModel = $imageModel;
        parent::__construct($factoryElement, $factoryCollection, $escaper, $urlBuilder, $data);
    }
    /**
     * Get image preview url
     *
     * @return string
     */
    protected function _getUrl()
    {
        $url = false;
        if ($this->getValue()) {
            $url = $this->imageModel->getBaseUrl().$this->getValue();
        }
        return $url;
    }
}

create the class that will help you retrieve the image upload path and upload dir

<?php
namespace [Namespace]\[Module]\Model\[Entity];
use Magento\Framework\UrlInterface;
use Magento\Framework\Filesystem;
use Magento\Framework\App\Filesystem\DirectoryList;
class Image
{
    /**
     * media sub folder
     * @var string
     */
    protected $subDir = '[namespace]/[module]/[entity]';
    /**
     * url builder
     *
     * @var \Magento\Framework\UrlInterface
     */
    protected $urlBuilder;
    /**
     * @var \Magento\Framework\Filesystem
     */
    protected $fileSystem;
    /**
     * @param UrlInterface $urlBuilder
     * @param Filesystem $fileSystem
     */
    public function __construct(        UrlInterface $urlBuilder,
        Filesystem $fileSystem
    )
    {
        $this->urlBuilder = $urlBuilder;
        $this->fileSystem = $fileSystem;
    }
    /**
     * get images base url
     *
     * @return string
     */
    public function getBaseUrl()
    {
        return $this->urlBuilder->getBaseUrl(['_type' => UrlInterface::URL_TYPE_MEDIA]).$this->subDir.'/image';
    }
    /**
     * get base image dir
     *
     * @return string
     */
    public function getBaseDir()
    {
        return $this->fileSystem->getDirectoryWrite(DirectoryList::MEDIA)->getAbsolutePath($this->subDir.'/image');
    }
}

now in your edit for tab add this in the method _prepareForm right after declaring the fieldset

$fieldset->addType('image', '\[Namespace]\[Module]\Block\Adminhtml\[Entity]\Helper\Image');

and add your image field like this

$fieldset->addField(
    'image_field_name',
    'image',
    [
        'name'        => 'image_field_name',
        'label'       => __('Image field Label'),
        'title'       => __('Image field Label'),
    ]
);

In the controller that saves your entity you need to inject in the constructor the following classes
Magento\MediaStorage\Model\File\UploaderFactory and [Namespace]\[Module]\Model\[Entity]\Image 
So make your class look like this

<?php
use Magento\Framework\Exception\LocalizedException as FrameworkException;

class ....

protected $uploaderFactory;
protected $imageModel;

public function __construct(
    ....
    \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
    \[Namespace]\[Module]\Model\[Entity]\Image $imageModel,
    ....
){
    ...
    $this->uploaderFactory = $uploaderFactory;
    $this->imageModel = $imageModel;
    ...
}

Now, in the same controller add this, before calling $[entity]->save()

$imageName = $this->uploadFileAndGetName('image_field_name', $this->imageModel->getBaseDir(), $data);
$[entity]->setImageFieldName($imageName);

and create this method:

public function uploadFileAndGetName($input, $destinationFolder, $data){
    try {
        if (isset($data[$input]['delete'])) {
            return '';
        } else {
            $uploader = $this->uploaderFactory->create(['fileId' => $input]);
            $uploader->setAllowRenameFiles(true);
            $uploader->setFilesDispersion(true);
            $uploader->setAllowCreateFolders(true);
            $result = $uploader->save($destinationFolder);
            return $result['file'];
        }
    } catch (\Exception $e) {
        if ($e->getCode() != \Magento\Framework\File\Uploader::TMP_NAME_EMPTY) {
            throw new FrameworkException($e->getMessage());
        } else {
            if (isset($data[$input]['value'])) {
                return $data[$input]['value'];
            }
        }
    }
    return '';
}

A full example on how to create an entity that supports image and file upload (it's a bit different than described here as it contains an extra class for upload) can be found here

Re: Add file upload in existing module

Adding file upload functionality to an existing module in a software project can vary greatly depending on the programming language, framework, and technology stack you are using. However, I can provide you with a general overview of the steps involved in adding file upload functionality to an existing module. You can also visit https://converra.com/converter/azw3/fb2 for more details of conversion.