Image upload in Magento 2 using a custom module?

Custom module how to upload the image from the frontend or backend?

Magento 2 Custom Module Image Upload

Magento 2 Custom Module Image Upload

For image upload, I am assuming first that you have a form ready with enctype='multipart/form-data' the image field. For this tutorial, I am using the same module which I am using in every post. So for me, the module will be Vky_Test

Now in our module open Vky/Test/view/frontend/templates/test.phtml
First of all, add enctype='multipart/form-data'in the <form> tag
Then add input for the image file to upload. So add below inside the form wherever you want.

<div class="field image">
            <label class="label" for="image"><span>Image</span></label>
            <div class="control">
                <input name="image" id="image" title="Image" value="" class="input-file" type="file">
            </div>
        </div>

So for me, our edited Vky/Test/view/frontend/templates/test.phtmlwill be like below

<form class="" action="<?php echo $block->getBaseUrl().'test/index/save'; ?>" id="vky-test-form" method="post" enctype='multipart/form-data'>
    <fieldset class="fieldset">
        <legend class="legend"><span>Test Form For Vky_Test Module</span></legend><br>
        <div class="field note no-label">Write here anything you want.</div>
        <div class="field title">
            <label class="label" for="title"><span>Title</span></label>
            <div class="control">
                <input name="title" id="title" title="Name" value="" class="input-text" type="text">
            </div>
        </div>
        <div class="field author">
            <label class="label" for="author"><span>Author</span></label>
            <div class="control">
                <input name="author" id="author" title="Author" value="" class="input-text" type="text">
            </div>
        </div>
        <div class="field content">
            <label class="label" for="content"><span>Content</span></label>
            <div class="control">
                <textarea name="content" id="content" title="Content" class="input-text" cols="5" rows="3"></textarea>
            </div>
        </div>
        <div class="field image">
            <label class="label" for="image"><span>Image</span></label>
            <div class="control">
                <input name="image" id="image" title="Image" value="" class="input-file" type="file">
            </div>
        </div>
    </fieldset>
    <div class="actions-toolbar">
        <div class="primary">
            <button type="submit" title="Submit" class="action submit primary">
                <span>Submit</span>
            </button>
        </div>
    </div>
</form>

Now open the Vky/Test/Controller/Index/Save.php
You can use this same controller code to upload the image from the admin controller make sure your controller action extends \Magento\Backend\App\Action

Right now what we have in the file is

<?php

namespace Vky\Test\Controller\Index;

use Magento\Framework\App\Action\Context;
use Vky\Test\Model\TestFactory;
class Save extends \Magento\Framework\App\Action\Action
{
	/**
     * @var Test
     */
    protected $_test;

	public function __construct(
		Context $context,
        TestFactory $test
    ) {
        $this->_test = $test;
        parent::__construct($context);
    }
	public function execute()
    {
    	$test = $this->_test->create();
        $test->setData($data);
        if($test->save()){
            $this->messageManager->addSuccessMessage(__('You saved the data.'));
        }else{
            $this->messageManager->addErrorMessage(__('Data was not saved.'));
        }
        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('test/index/index');
        return $resultRedirect;
    }
}

We will need to add few things in this file.
Edited Vky/Test/Controller/Index/Save.php

<?php

namespace Vky\Test\Controller\Index;

use Magento\Framework\App\Action\Context;
use Vky\Test\Model\TestFactory;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Magento\Framework\Image\AdapterFactory;
use Magento\Framework\Filesystem;
class Save extends \Magento\Framework\App\Action\Action
{
    protected $_test;
    protected $uploaderFactory;
    protected $adapterFactory;
    protected $filesystem;

    public function __construct(
        Context $context,
        TestFactory $test,
        UploaderFactory $uploaderFactory,
        AdapterFactory $adapterFactory,
        Filesystem $filesystem
    ) {
        $this->_test = $test;
        $this->uploaderFactory = $uploaderFactory;
        $this->adapterFactory = $adapterFactory;
        $this->filesystem = $filesystem;
        parent::__construct($context);
    }
    public function execute()
    {
        $data = $this->getRequest()->getParams();
        if(isset($_FILES['image']['name']) && $_FILES['image']['name'] != '') {
            try{
                $uploaderFactory = $this->uploaderFactory->create(['fileId' => 'image']);
                $uploaderFactory->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
                $imageAdapter = $this->adapterFactory->create();
                $uploaderFactory->addValidateCallback('custom_image_upload',$imageAdapter,'validateUploadFile');
                $uploaderFactory->setAllowRenameFiles(true);
                $uploaderFactory->setFilesDispersion(true);
                $mediaDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
                $destinationPath = $mediaDirectory->getAbsolutePath('vky/test');
                $result = $uploaderFactory->save($destinationPath);
                if (!$result) {
                    throw new LocalizedException(
                        __('File cannot be saved to path: $1', $destinationPath)
                    );
                }
                $imagePath = 'vky/test'.$result['file'];
                $data['image'] = $imagePath;
            } catch (\Exception $e) {
            }
        }
        $test = $this->_test->create();
        $test->setData($data);
        if($test->save()){
            $this->messageManager->addSuccessMessage(__('You saved the data.'));
        }else{
            $this->messageManager->addErrorMessage(__('Data was not saved.'));
        }
        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('test');
        return $resultRedirect;
    }
}

Here 'image' is the input name and also the field name of my database table.
The image file will be saved at pub/media/vky/test
And $data['image'] = $imagePath; the value of $imagePath will be saved in the field(image is the field name for me) of your database table.

No Comments

Post A Comment