You can focus on achieving your business goals.Wondering who will take care of Magento Support then? The answer is “we” – Get in touch! Let’s talk about how!

Running a successful eCommerce business has a lot to do with the incorporation of minute nuances from the nook and corner of stages like design, development, and implementation. A small hitch in any part of the aspect might have a huge impact on the overall result of the digital business. On that note, not having an essential attribute like File Upload Attribute for Category in Magento 2 made implementation difficult.

There are enough options to upload a File with extensions like JPG, PNG, JPEG, etc in Magento 2, but it was difficult to find the one that could support files with extensions like PDF, TXT, DOC, etc. Enough analyses had to be done to stop this from being a barrier to upload files. Finally, it was sorted out using a code that was exclusively developed for this requirement.

Find the step-by-step code that enables the file upload attribute below.

Migrate To Magento 2

Implementation of File Upload with Magento 2

Step 1:
Create InstallData.php inside your custom Module. 
Here we have a Module in the name of DCKAP/Category

Inside DCKAP/Category/Setup/InstallData.php

namespace DCKAP\Category\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]);         
	                'type' => 'varchar',
                    'label' => 'User Manual Document',
                    'name' => 'User Manual Document',
                    'input' => 'image',
                    'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image',
                    'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                    'visible' => true,
                    'required' => false,
                    'user_defined' => true,
                    'group' => 'General Information'

Here we can use Backend option and Input type as Image itself, we can control that later in UI component and di(Dependency Injection).

Step 2:
Create a category_form.xml file on location DCKAP\Category\view\adminhtml\ui_component

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="content">
        <field name="manual">
            <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">User Manual Document</item>
                    <item name="visible" xsi:type="boolean">true</item>
                    <item name="formElement" xsi:type="string">fileUploader</item>
                    <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</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="dckap_category/category_manual/upload"/>

Step 3:
Add below code in DCKAP/Category/etc/di.xml
Here we can include the file extension types inside allowedExtensions section.

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="DCKAP\Category\Controller\Adminhtml\Category\Manual\Upload">
        <argument name="imageUploader" xsi:type="object">Magento\Catalog\CategoryImageUpload</argument>
<virtualType name="Magento\Catalog\CategoryImageUpload" type="Magento\Catalog\Model\ImageUploader">
        <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="pdf" xsi:type="string">pdf</item>
            <item name="txt" xsi:type="string">txt</item>
            <item name="doc" xsi:type="string">doc</item>
<preference for="Magento\Catalog\Model\Category\DataProvider" type="Ey\Catalog\Model\Category\DataProvider" />

Step 4:
Create Upload.php file on location DCKAP/Category/Controller/Adminhtml/Category/Manual

This is a Controller File Where we need to perform our Custom File Upload action

namespace DCKAP\Category\Controller\Adminhtml\Category\Manual;
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
        ) {
        $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('DCKAP_Category::category');
    * Upload file controller action
    * @return \Magento\Framework\Controller\ResultInterface
    public function execute() {
	        try {
	            $result = $this->imageUploader->saveFileToTmpDir('manual');
            $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);

Step 5:
Finally, create DataProvider.php file on location DCKAP\Category\Model\Category

namespace DCKAP\Category\Model\Category;
class DataProvider extends \Magento\Catalog\Model\Category\DataProvider{
	protected function getFieldsMap()
	    $fields = parent::getFieldsMap();
        $fields['content'][] = 'manual'; // custom image field
        return $fields;

Now it is all done! Once the code is run, an option to upload the file will be included. This is how the exact output looks like.



  • Shajitha Banu

    Shajitha is a Senior Software Engineer at DCKAP and has got 4+ years of experience in Magento. She is interested in solving logical puzzles and Loves to read Thrilling novels. Shajitha also enjoys writing poems in Tamil.


Ready to drive online revenue

Get In Touch

Leave a Reply

Your email address will not be published. Required fields are marked *