Magento – How to upload image file on product edit page in backend

magento-2.1

I have added custom field-set to product edit page and trying to upload multiple (more than 8) images.

To add custom field-set I have added layout file in my custom module –

/view/adminhtml/layout/catalog_product_new.xml

<referenceBlock name="product_form">
            <block class="Myvendor\Newtab\Block\Adminhtml\Product\Edit\Tab\Welcome" name="product.welcome" as="custom-tab" >
                <arguments>
                    <argument name="config" xsi:type="array">
                        <item name="label" xsi:type="string" translate="true">Design Tool Options</item>
                        <item name="collapsible" xsi:type="boolean">true</item>
                        <item name="opened" xsi:type="boolean">true</item>
                        <item name="sortOrder" xsi:type="string">2</item>
                        <item name="canShow" xsi:type="boolean">true</item>
                        <item name="componentType" xsi:type="string">fieldset</item>
                    </argument>
                </arguments>
            </block>
        </referenceBlock>

and created following template file to add custom file type fields

/view/adminhtml/templates/catalog/product/edit/welcome.phtml

<input type="file" data-form-part="product_form" name="thumb">

To save data created

/Controller/Adminhtml/Rewrite/Product/Save.php

 namespace Myvendor\Newtab\Controller\Adminhtml\Rewrite\Product;
    use Magento\Framework\App\Filesystem\DirectoryList;
    use Magento\Backend\App\Action;

    class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Save
    {

        public function __construct(
            \Magento\Backend\App\Action\Context $context,
            \Magento\Catalog\Controller\Adminhtml\Product\Builder $pbuilder, 
            \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $initializationHelper,
            \Magento\Catalog\Model\Product\Copier $productCopier,
            \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager,
            \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
            \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory)
        {
            $this->_fileUploaderFactory = $fileUploaderFactory;
            parent::__construct($context,$pbuilder,$initializationHelper,$productCopier,$productTypeManager,$productRepository);
        }

        public function execute()
        {  
            $uploader = $this->_fileUploaderFactory->create(['fileId' => 'thumb']);
            $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
            $uploader->setAllowRenameFiles(false);
            $uploader->setFilesDispersion(false);
            $path = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath('images/');
            $uploader->save($path);
}
}

I am getting following exception –

1 exception(s): Exception #0 (Exception): $_FILES array is empty

Best Answer

Include this code into your class:

class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Save
{
     /**
     * @var \Magento\Framework\Image\AdapterFactory
     */
     protected $adapterFactory;

     /**
     * @var \Magento\MediaStorage\Model\File\UploaderFactory
     */
     protected $uploader;
     /**
 * \Magento\Backend\Helper\Js $jsHelper
 * @param Action\Context $context
 */
 public function __construct(        
    \Magento\Backend\Helper\Js $jsHelper,
    \Magento\Framework\Image\AdapterFactory $adapterFactory,
    \Magento\MediaStorage\Model\File\UploaderFactory $uploader,
    \Magento\Framework\Filesystem $filesystem,
    Context $context
) {
    $this->_jsHelper = $jsHelper;
    $this->adapterFactory = $adapterFactory;
    $this->uploader = $uploader;
    $this->filesystem = $filesystem;
    parent::__construct($context);
}

/**
 * Save action
 *
 * @return \Magento\Framework\Controller\ResultInterface
 */
public function execute()
{
   ...
    $path = $this->filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)

->getAbsolutePath('images/');            

    if(isset($_FILES['thumb']['name']) && $_FILES['thumb']['name'] != '') {
            try {                    
                $uploader = $this->uploader->create(['fileId' => 'thumb']);
                $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
                $imageAdapter = $this->adapterFactory->create();
                $uploader->addValidateCallback('thumb', $imageAdapter, 'validateUploadFile');
                $uploader->setAllowRenameFiles(true);
                $uploader->setFilesDispersion(true);
                $result = $uploader->save($path);
                $data['thumb'] = 'images'.$result['file'];

            } catch (Exception $e) {
                $data['thumb'] = $_FILES['thumb']['name'];
            }
        }
        else{
            $data['thumb'] = $data['thumb']['value'];
        }

        $model->setData($data);
        try {
             $model->save();
             ...
         }
      }
   }

And for multiple images just put that code into loop, Hope it works for you.

Related Topic