How to Create Custom Image Uploader Attribute in Category with Drag & Drop Option
Create registration.php file inside app/code/Webcreta/CustomImage folder
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Webcreta_CustomImage', __DIR__ );
Create module.xml file inside app/code/Webcreta/CustomImage/etc folder
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Webcreta_CustomImage" setup_version="1.0.0" /> </config>
Create InstallData.php file inside app/code/Webcreta/CustomImage/Setup folder
<?php namespace Webcreta\CustomImage\Setup; use Magento\Eav\Setup\EavSetup; use Magento\Eav\Setup\EavSetupFactory; use Magento\Framework\Setup\InstallDataInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface; /** * @codeCoverageIgnore */ class InstallData implements InstallDataInterface { /** * EAV setup factory. * * @var EavSetupFactory */ private $_eavSetupFactory; protected $categorySetupFactory; /** * Init. * * @param EavSetupFactory $eavSetupFactory */ public function __construct(EavSetupFactory $eavSetupFactory, \Magento\Catalog\Setup\CategorySetupFactory $categorySetupFactory) { $this->_eavSetupFactory = $eavSetupFactory; $this->categorySetupFactory = $categorySetupFactory; } /** * {@inheritdoc} * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function install( ModuleDataSetupInterface $setup, ModuleContextInterface $context ) { /** @var EavSetup $eavSetup */ $eavSetup = $this->_eavSetupFactory->create(['setup' => $setup]); $setup = $this->categorySetupFactory->create(['setup' => $setup]); $setup->addAttribute( \Magento\Catalog\Model\Category::ENTITY, 'custom_image', [ 'type' => 'varchar', 'label' => 'Custom Image', 'input' => 'image', 'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image', 'required' => false, 'sort_order' => 9, 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE, 'group' => 'General Information', ] ); } }
Create a category_form.xml file inside app/code/Webcreta/CustomImage/view/adminhtml/ui_component folder
<?xml version="1.0" encoding="UTF-8"?> <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> <fieldset name="content"> <field name="custom_image"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="dataType" xsi:type="string">string</item> <item name="source" xsi:type="string">category</item> <item name="label" xsi:type="string" translate="true">Custom Image</item> <item name="visible" xsi:type="boolean">true</item> <item name="formElement" xsi:type="string">imageUploader</item> <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item> <item name="previewTmpl" xsi:type="string">Magento_Catalog/image-preview</item> <item name="required" xsi:type="boolean">false</item> <item name="sortOrder" xsi:type="number">40</item> <item name="uploaderConfig" xsi:type="array"> <item name="url" xsi:type="url" path="customimage/category_image/upload"/> </item> </item> </argument> </field> </fieldset> </form>
Create di.xml file inside app/code/Webcreta/CustomImage/etc folder
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Webcreta\CustomImage\Controller\Adminhtml\Category\Image\Upload"> <arguments> <argument name="imageUploader" xsi:type="object">Magento\Catalog\CategoryImageUpload</argument> </arguments> </type> <virtualType name="Magento\Catalog\CategoryImageUpload" type="Magento\Catalog\Model\ImageUploader"> <arguments> <argument name="baseTmpPath" xsi:type="string">catalog/tmp/category</argument> <argument name="basePath" xsi:type="string">catalog/category</argument> <argument name="allowedExtensions" xsi:type="array"> <item name="jpg" xsi:type="string">jpg</item> <item name="jpeg" xsi:type="string">jpeg</item> <item name="gif" xsi:type="string">gif</item> <item name="png" xsi:type="string">png</item> </argument> </arguments> </virtualType> <preference for="Magento\Catalog\Model\Category\DataProvider" type="Webcreta\CustomImage\Model\Category\DataProvider" /> </config> create routes.xml file inside app/code/Webcreta/CustomImage/etc/adminhtml folder <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="admin"> <route id="customimage" frontName="customimage"> <module name="Webcreta_CustomImage" before="Magento_Backend" /> </route> </router> </config>
Create Upload.php file inside app/code/Webcreta/CustomImage/Controller/Adminhtml/Category/Image folder
<?php namespace Webcreta\CustomImage\Controller\Adminhtml\Category\Image; use Magento\Framework\Controller\ResultFactory; /** * Agorae Adminhtml Category Image Upload Controller */ class Upload extends \Magento\Backend\App\Action { /** * Image uploader * * @var \Magento\Catalog\Model\ImageUploader */ protected $imageUploader; /** * Uploader factory * * @var \Magento\MediaStorage\Model\File\UploaderFactory */ private $uploaderFactory; /** * Media directory object (writable). * * @var \Magento\Framework\Filesystem\Directory\WriteInterface */ protected $mediaDirectory; /** * Store manager * * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; /** * Core file storage database * * @var \Magento\MediaStorage\Helper\File\Storage\Database */ protected $coreFileStorageDatabase; /** * @var \Psr\Log\LoggerInterface */ protected $logger; /** * Upload constructor. * * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Catalog\Model\ImageUploader $imageUploader */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Catalog\Model\ImageUploader $imageUploader, \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory, \Magento\Framework\Filesystem $filesystem, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase, \Psr\Log\LoggerInterface $logger ) { parent::__construct($context); $this->imageUploader = $imageUploader; $this->uploaderFactory = $uploaderFactory; $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); $this->storeManager = $storeManager; $this->coreFileStorageDatabase = $coreFileStorageDatabase; $this->logger = $logger; } /** * Check admin permissions for this controller * * @return boolean */ protected function _isAllowed() { return $this->_authorization->isAllowed('Webcreta_CustomImage::category'); } /** * Upload file controller action * * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { try { $result = $this->imageUploader->saveFileToTmpDir('custom_image'); $result['cookie'] = [ 'name' => $this->_getSession()->getName(), 'value' => $this->_getSession()->getSessionId(), 'lifetime' => $this->_getSession()->getCookieLifetime(), 'path' => $this->_getSession()->getCookiePath(), 'domain' => $this->_getSession()->getCookieDomain(), ]; } catch (\Exception $e) { $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result); } }
Create DataProvider.php file inside app/code/Webcreta/CustomImage/Model/Category folder
<?php namespace Webcreta\CustomImage\Model\Category; class DataProvider extends \Magento\Catalog\Model\Category\DataProvider { protected function getFieldsMap() { $fields = parent::getFieldsMap(); $fields['content'][] = 'custom_image'; // custom image field return $fields; } }
Create di.xml file inside app/code/Webcreta/CustomImage/etc/adminhtml folder
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Catalog\Controller\Adminhtml\Category\Save"> <plugin name="webcreta_image_preprocessing" type="Webcreta\CustomImage\Plugin\Catalog\Controller\Adminhtml\Category\SavePlugin" /> </type> </config>
Create SavePlugin.php file inside app/code/Webcreta/CustomImage/Plugin/Catalog/Controller/Adminhtml/Category folder
<?php namespace Webcreta\CustomImage\Plugin\Catalog\Controller\Adminhtml\Category; use Magento\Catalog\Controller\Adminhtml\Category\Save as SaveController; class SavePlugin { /** * Add additional images * * @param SaveController $subject * @param array $data * @return array */ public function beforeImagePreprocessing(SaveController $subject, $data) { foreach ($this->getAdditionalImages() as $imageType) { if (empty($data[$imageType])) { unset($data[$imageType]); $data[$imageType]['delete'] = true; } } return [$data]; } /** * Get additional Images * * @return array */ protected function getAdditionalImages() { return ['custom_image']; } }