6

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

HungryDB
  • 896
  • 2
  • 12
  • 37

2 Answers2

3

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.

Ronak Chauhan
  • 6,183
  • 2
  • 28
  • 65
1

Use this method in block to create form :

/**
 * Prepare form before rendering HTML
 *
 * @return $this
 * @SuppressWarnings(PHPMD.NPathComplexity)
 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
 */
protected function _prepareForm()
{
    $model = $this->getModel();


    /** @var \Magento\Framework\Data\Form $form */
    $form = $this->_formFactory->create(
        ['data' => ['id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post']]
    );

    $fieldset = $form->addFieldset(
        'base_fieldset',
        ['legend' => __('Banner Information'), 'class' => 'fieldset-wide']
    );

    if ($model->getGridpart2templateId()) {
        $fieldset->addField('id', 'hidden', ['name' => 'id', 'value' => $model->getGridpart2templateId()]);
    }

    $fieldset->addField(
        'banner_title',
        'text',
        [
            'name' => 'banner_title',
            'label' => __('Title'),
            'title' => __('Title'),
            'required' => true,
            'value' => $model->getBannerTitle()
        ]
    );

    $fieldset->addField(
        'banner_image',
        'image',
        [
            'name' => 'banner_image',
            'label' => __('Image'),
            'title' => __('Image'),
            'required' => true,
            'path'=> 'sliderbanner/view/frontend/web/images'. $model->getImagePath(),
            'value' => $model->getImagePath()
        ]
    );

    $fieldset->addField(
         'validfrom',
         'date',
         [
             'name' => 'validfrom',
             'label' => __('Valid From'),
             'title' => __('Valid From'),
             'required' => true,
             'class' => '',
             'singleClick'=> true,
             'date_format' => 'yyyy-MM-dd', 
             'time'=>false,
             'value'=> $model->getValidfrom()
            //'format' =>$this->_localeDate->getDateFormat(\IntlDateFormatter::LONG)
         ]
     );

    $fieldset->addField(
         'validto',
         'date',
         [
             'name' => 'validto',
             'label' => __('Valid To'),
             'title' => __('Valid To'),
             'required' => true,
             'class' => '',
             'singleClick'=> true,
             'date_format' => 'yyyy-MM-dd', 
             'time'=>false,
             'value'=> $model->getValidto()
            //'format' =>$this->_localeDate->getDateFormat(\IntlDateFormatter::LONG)
         ]
     );

    $form->setAction($this->getUrl('*/*/save'));
    $form->setUseContainer(true);
    $this->setForm($form);

    return parent::_prepareForm();
}

And use this line to fetch form code into phtml file :

<form action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" id="gridpart2_template_edit_form" enctype="multipart/form-data">
     <?php /* @escapeNotVerified */ echo $block->getForm() ?>
</form>
Ronak Chauhan
  • 6,183
  • 2
  • 28
  • 65