Magento – How to Upload image on Frontend using custom module

image-uploadmagento2

I am trying to upload an image in the frontend. my controller is

public function execute()
{
    /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
    $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
    if (!$this->formKeyValidator->validate($this->getRequest())) {
        $resultRedirect->setUrl($this->_redirect->getRefererUrl());
        return $resultRedirect;
    }

    $data = $this->reviewSession->getFormData(true);
    if ($data) {
        $rating = [];
        if (isset($data['ratings']) && is_array($data['ratings'])) {
            $rating = $data['ratings'];
        }
    } else {
        $data = $this->getRequest()->getPostValue();
        $rating = $this->getRequest()->getParam('ratings', []);
    }
    if (($product = $this->initProduct()) && !empty($data)) {
        /** @var \Magento\Review\Model\Review $review */
        $pathurl = $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'review_module/';
        $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath();
        $mediapath = $this->_mediaBaseDirectory = rtrim($mediaDir, '/');
        $files = $this->getRequest()->getFiles();
        if (isset($data['image']))
        {
          $uploader = $this->_fileUploaderFactory->create(['fileId' => 'image']);
          $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
          $uploader->setAllowRenameFiles(true);
          $path = $mediapath . '/review_module/';
          $data['image'] = $files['image']['name'];
            $result = $uploader->save($path);
        }
        $review = $this->reviewFactory->create()->setData($data);
        $review->unsetData('review_id');

        $validate = $review->validate();
        if ($validate === true) {
            try {
                $review->setEntityId($review->getEntityIdByCode(Review::ENTITY_PRODUCT_CODE))
                    ->setEntityPkValue($product->getId())
                    ->setStatusId(Review::STATUS_PENDING)
                    ->setCustomerId($this->customerSession->getCustomerId())
                    ->setStoreId($this->storeManager->getStore()->getId())
                    ->setStores([$this->storeManager->getStore()->getId()])
                    ->save();

                foreach ($rating as $ratingId => $optionId) {
                    $this->ratingFactory->create()
                        ->setRatingId($ratingId)
                        ->setReviewId($review->getId())
                        ->setCustomerId($this->customerSession->getCustomerId())
                        ->addOptionVote($optionId, $product->getId());
                }

                $review->aggregate();
                $this->messageManager->addSuccess(__('You submitted your review for moderation.'));
            } catch (\Exception $e) {
                $this->reviewSession->setFormData($data);
                $this->messageManager->addError(__('We can\'t post your review right now.'));
            }
        } else {
            $this->reviewSession->setFormData($data);
            if (is_array($validate)) {
                foreach ($validate as $errorMessage) {
                    $this->messageManager->addError($errorMessage);
                }
            } else {
                $this->messageManager->addError(__('We can\'t post your review right now.'));
            }
        }
    }
    $redirectUrl = $this->reviewSession->getRedirectUrl(true);
    $resultRedirect->setUrl($redirectUrl ?: $this->_redirect->getRedirectUrl());
    return $resultRedirect;
}

i am getting this error enter image description here

Best Answer

in controller

namespace Abc\Xyz\Controller\Adminhtml\Index;

 use Exception;
use \Magento\Backend\App\Action;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Filesystem;
use Magento\Framework\UrlInterface;
use Magento\MediaStorage\Model\File\UploaderFactory;
use Abc\Xyz\Model\GuestOffers;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Store\Model\StoreManagerInterface;

class Save extends Action
{
protected $dataProcessor;
protected $dataPersistor;
protected $imageUploader;
protected $model;
/**
 * @var Filesystem
 */
private $_filesystem;

public function __construct(
    Action\Context $context,
    PostDataProcessor $dataProcessor,
    DataPersistorInterface $dataPersistor,
    StoreManagerInterface $storeManager,
    Filesystem $filesystem,
    UploaderFactory $fileUploaderFactory,
    GuestOffers $model

) {
    $this->dataProcessor = $dataProcessor;
    $this->dataPersistor = $dataPersistor;
    $this->_storeManager = $storeManager;
    $this->_filesystem = $filesystem;
    $this->_fileUploaderFactory = $fileUploaderFactory;
    $this->model = $model;
    parent::__construct($context);
}

/**
 * @return ResponseInterface|Redirect|ResultInterface
 */
public function execute()
{
    $resultRedirect = $this->resultRedirectFactory->create();

    $data = $this->getRequest()->getPostValue();

    $files = $this->getRequest()->getFiles(); // we can not get images through $_FILES Global Variable. So Instead we will use this.

    $mediaDir = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath();
    $mediapath = $this->_mediaBaseDirectory = rtrim($mediaDir, '/');

    //check if we got some images or not
    if (isset($files['var_banner']) && !empty($files['var_banner']['name'])) {
        try {
            $uploader = $this->_fileUploaderFactory->create(['fileId' => 'var_banner']);
            $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
            $uploader->setAllowRenameFiles(true);

            $path = $mediapath . '/guest_offers/';  //folder name where images will be moved.

            $data['var_banner'] = str_replace(' ', '_', $files['var_banner']['name']);  //remove space form iamge name and add UNDERSCORE (_).

            $result = $uploader->save($path); //save complete path of image.
        } catch (\Exception $e) {
            $data['var_banner'] = ''; // if image is not uploaded successfully. Save it as null.
            $this->messageManager->addError(__('an error occured while saving image.'));
        }
    }

    $data = $this->dataProcessor->filter($data); //get all other fields posted data.

    $id = $this->getRequest()->getParam('id');
    if ($id) {
        $this->model->load($id);
    }
    $this->model->setData($data);
    $this->_eventManager->dispatch(
        'guestoffers_prepare_save',
        ['sales' => $this->model, 'request' => $this->getRequest()]
    );

    if (!$this->dataProcessor->validate($data)) {
        return $resultRedirect->setPath('*/*/edit', ['id' => $this->model->getId(), '_current' => true]);
    }
    try {
        $this->model->save();
        $this->messageManager->addSuccessMessage(__('You saved the New Guest Offer.'));
        $this->dataPersistor->clear('gestoffers');
        if ($this->getRequest()->getParam('back')) {
            return $resultRedirect->setPath(
                '*/*/edit',
                ['id' => $this->model->getId(),
                    '_current' => true]
            );
        }
        return $resultRedirect->setPath('*/*/edit');
    } catch (LocalizedException $e) {
        $this->messageManager->addErrorMessage($e->getMessage());
    } catch (Exception $e) {
        $this->messageManager->addExceptionMessage($e, __('Something went wrong while saving new offer.'));
    }

    $this->dataPersistor->set('guestoffers', $data);
    return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
}
}