Skip to content

Magento2.4.2: How to create two images field in admin form?

I want to one more image field in my custom admin form
enter image description here

This is my custom admin form
and i want to add one more image field and my code is this

vendor/PromotionsPopUpBox/view/adminhtml/ui_component/promotions_form.xml

<fieldset name="promotions_popup_box">
        <settings>
            <label translate="true">PopUpBox Form</label>
        </settings>
        <field name="title">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Title</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">title</item>
                </item>
            </argument>
        </field>
        <field name="description">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Description</item>
                    <item name="formElement" xsi:type="string">textarea</item>
                    <item name="dataScope" xsi:type="string">description</item>
                </item>
            </argument>
        </field>

        <field name="image">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">string</item>
                    <item name="label" xsi:type="string" translate="true">Image</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">ui/form/element/uploader/preview</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                    <item name="required" xsi:type="boolean">true</item>
                    <item name="allowedExtensions" xsi:type="string">jpg jpeg gif png svg</item>
                    <item name="uploaderConfig" xsi:type="array">
                        <item name="url" xsi:type="url" path="promotions/form/tempUpload"/>
                    </item>
                    <item name="notice" xsi:type="string"><![CDATA[Allowed file types:jpg, jpeg, png.]]></item>
                </item>
            </argument>
        </field>
        <field name="category_link">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Category Link</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="dataScope" xsi:type="string">category_link</item>
                </item>
            </argument>
        </field>
        <field name="timer" formElement="date">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="source" xsi:type="string">timer</item>
                </item>
            </argument>
            <settings>
                <validation>
                    <rule name="validate-date" xsi:type="boolean">true</rule>
                </validation>
                <dataType>text</dataType>
                <label translate="true">Timer</label>
                <visible>true</visible>
                <dataScope>timer</dataScope>
            </settings>
        </field>
    </fieldset>
    

VendorModuleControllerAdminhtmlFormTempUpload.php

<?php

namespace VendorModuleControllerAdminhtmlForm;

use Exception;
use MagentoBackendAppAction;
use MagentoBackendAppActionContext;
use MagentoFrameworkAppFilesystemDirectoryList;
use MagentoFrameworkAppResponseInterface;
use MagentoFrameworkControllerResultJson;
use MagentoFrameworkControllerResultFactory;
use MagentoFrameworkControllerResultInterface;
use MagentoFrameworkExceptionFileSystemException;
use MagentoFrameworkExceptionLocalizedException;
use MagentoFrameworkFilesystem;
use MagentoFrameworkUrlInterface as UrlInterfaceAlias;
use MagentoMediaStorageModelFileUploaderFactory;
use MagentoStoreModelStoreManagerInterface;

class TempUpload extends Action
{

    /**
     *
     * @var UploaderFactory
     */
    protected UploaderFactory $uploaderFactory;

    /**
     * @var FilesystemDirectoryWriteInterface
     */
    protected FilesystemDirectoryWriteInterface $mediaDirectory;

    /**
     * @var StoreManagerInterface
     */
    protected StoreManagerInterface $storeManager;

    /**
     * @throws FileSystemException
     */
    public function __construct(
        Context $context,
        UploaderFactory $uploaderFactory,
        Filesystem $filesystem,
        StoreManagerInterface $storeManager
    ) {
        parent::__construct($context);
        $this->uploaderFactory = $uploaderFactory;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->storeManager = $storeManager;
    }

    /**
     * @return ResponseInterface|Json|ResultInterface
     */
    public function execute()
    {
        $jsonResult = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        try {
            $fileUploader = $this->uploaderFactory->create(['fileId' => 'image']);
            $fileUploader->setAllowedExtensions(['jpg', 'jpeg', 'png']);
            $fileUploader->setAllowRenameFiles(true);
            $fileUploader->setAllowCreateFolders(true);
            $fileUploader->setFilesDispersion(false);
            $fileUploader->validateFile();
            $result = $fileUploader->save($this->mediaDirectory->getAbsolutePath('tmp/imageUploader/images'));
            $result['url'] = $this->storeManager->getStore()->getBaseUrl(UrlInterfaceAlias::URL_TYPE_MEDIA)
                . 'tmp/imageUploader/images/' . ltrim(str_replace('\', '/', $result['file']), '/');
            return $jsonResult->setData($result);
        } catch (LocalizedException $e) {
            return $jsonResult->setData(['errorcode' => 0, 'error' => $e->getMessage()]);
        } catch (Exception $e) {
            error_log($e->getMessage());
            error_log($e->getTraceAsString());
            return $jsonResult->setData([
                'errorcode' => 0,
                'error' => __(
                    'An error occurred, please try again later.'
                )
            ]);
        }
    }
}
VendorModuleControllerAdminhtmlFormSave.php
<?php
declare(strict_types=1);

namespace VendorModuleControllerAdminhtmlForm;

use Exception;
use MagentoBackendAppAction;
use MagentoBackendAppActionContext;
use MagentoFrameworkAppFilesystemDirectoryList;
use MagentoFrameworkAppResponseInterface;
use MagentoFrameworkExceptionCouldNotSaveException;
use MagentoFrameworkExceptionFileSystemException;
use MagentoFrameworkExceptionLocalizedException;
use MagentoFrameworkFilesystem;
use MagentoFrameworkValidationValidationException;
use MagentoMediaStorageModelFileUploaderFactory;
use VendorModuleApiDataFormInterfaceFactory;
use VendorModuleApiFormRepositoryInterface;

class Save extends Action
{
    /**
     * @var FormInterfaceFactory
     */
    protected FormInterfaceFactory $formInterfaceFactory;

    /**
     * @var FormRepositoryInterface
     */
    protected FormRepositoryInterface $formRepositoryInterface;

    /**
     * @var UploaderFactory
     */
    protected UploaderFactory $uploaderFactory;

    /**
     * @var FilesystemDirectoryWriteInterface
     */
    protected FilesystemDirectoryWriteInterface $mediaDirectory;

    /**
     * @param Context $context
     * @param UploaderFactory $uploaderFactory
     * @param Filesystem $filesystem
     * @param FormRepositoryInterface $formRepositoryInterface
     * @param FormInterfaceFactory $formInterfaceFactory
     * @throws FileSystemException
     */
    public function __construct(
        Context $context,
        UploaderFactory $uploaderFactory,
        Filesystem $filesystem,
        FormRepositoryInterface $formRepositoryInterface,
        FormInterfaceFactory $formInterfaceFactory
    ) {
        parent::__construct($context);
        $this->uploaderFactory = $uploaderFactory;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->formInterfaceFactory = $formInterfaceFactory;
        $this->formRepositoryInterface = $formRepositoryInterface;
    }

    /**
     * @return ResponseInterface
     * @throws Exception
     */
    public function execute(): ResponseInterface
    {
        try {
            if ($this->getRequest()->getMethod() !== 'POST'
                || !$this->_formKeyValidator->validate($this->getRequest())) {
                throw new LocalizedException(__('Invalid Request'));
            }

            $params = $this->getRequest()->getParams();
            if (isset($params['entity_id'])) {
                $imageName = $params['image'][0];
                $data = $this->formRepositoryInterface->getById($params['entity_id']);
                if (isset($imageName['tmp_name'])) {
                    $info = $this->validateImage($params);
                    $this->saveRow($info, $params, $data);
                } else {
                    $data->setTitle($params['title']);
                    $data->setDescription($params['description']);
                    $data->setCategoryLink($params['category_link']);
                    $data->setTimer($params['timer']);
                    $this->formRepositoryInterface->save($data);
                    return $this->_redirect('*/*/form/entity_id/1/');
                }
            } else {
                $info = $this->validateImage($params);
                $image = $this->formInterfaceFactory->create();
                $this->saveRow($info, $params, $image);
            }
        } catch (LocalizedException $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
            return $this->_redirect('*/*/form/entity_id/1/');
        } catch (Exception $e) {
            error_log($e->getMessage());
            error_log($e->getTraceAsString());
            $this->messageManager->addErrorMessage(__('An error occurred, please try again later.'));
            return $this->_redirect('*/*/form/entity_id/1/');
        }
        return $this->_redirect('*/*/form/entity_id/1/');
    }

    /**
     * @throws Exception
     */
    public function validateImage($params)
    {
        try {
            $fileUploader = null;
            $imageId = 'image';
            if (isset($params['image']) && count($params['image'])) {
                $imageId = $params['image'][0];
                if (!file_exists($imageId['tmp_name'])) {
                    $imageId['tmp_name'] = $imageId['path'] . '/' . $imageId['file'];
                }
            }
            $fileUploader = $this->uploaderFactory->create(['fileId' => $imageId]);
            $fileUploader->setAllowedExtensions(['jpg', 'jpeg', 'png']);
            $fileUploader->setAllowRenameFiles(true);
            $fileUploader->setAllowCreateFolders(true);
            $fileUploader->validateFile();
            return $fileUploader->save($this->mediaDirectory->getAbsolutePath('imageUploader/images'));
        } catch (ValidationException $e) {
            throw new
            LocalizedException(__(
                'Image extension is not supported. Only extensions allowed are jpg, jpeg and png'
            ));
        } catch (Exception $e) {
            //if an except is thrown, no image has been uploaded
            throw new LocalizedException(__('Image is required'));
        }
    }

    /**
     * @throws CouldNotSaveException
     * @throws LocalizedException
     */
    public function saveRow($info, $params, $data): ResponseInterface
    {
        try {

            $data->setTitle($params['title']);
            $data->setDescription($params['description']);
            $data->setImage($this->mediaDirectory->getRelativePath('imageUploader/images') . '/' . $info['file']);
            $data->setCategoryLink($params['category_link']);
            $data->setTimer($params['timer']);
            $data->setStatus($params['status']);

            $this->formRepositoryInterface->save($data);
            $this->messageManager->addSuccessMessage(__('Promotions saved successfully'));
            return $this->_redirect('*/*/form/entity_id/1/');
        } catch (Exception $e) {
            //if an except is thrown, no image has been uploaded
            throw new LocalizedException(__("Form didn't save"));
        }
    }
}

If i follow the same approach i followed for one image then there will be two much duplicated code.
and there is enough duplicate code in this