Blog

How to create product attribute using data patch in Magento 2

In this tutorial, lets learn how to create a product attribute using data patches in Magento 2.

Data patch is a class that stores instructions for data modification. From Magento 2.3.x, magento introduced a new concept Data patch for add/update magento eav attributes. Previously, Magento 2 uses InstallData and UpgradeData file to use add data in core table or custom table. From Magento 2.3 it is replaced by Data Patch.

How to create product attribute using data patch in Magento 2 :

A data patch is a class that contains data modification instructions. It is defined in a <Vendor>/<Module_Name>/Setup/Patch/Data/<Patch_Name>.php file and implements \Magento\Framework\Setup\Patch\DataPatchInterface.

Data patches have three important methods:

    • getDependencies,
    • getAliases,
    • apply

Let’s understand the process of creating product attribute using data patches :

First of all, Let’s create simple module,

Create the module

Create the registration.php  file in app/code/Thecoachsmb/Productattribute/ for the module

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Thecoachsmb_Productattribute',
__DIR__
);

Create directory app/code/Thecoachsmb/Productattribute/etc

Put this file in it : module.xml

<?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="Thecoachsmb_Productattribute" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

Create Text Field Product Attribute

Now, To create custom product attribute Create ProductAttribute.php file at app/code/Thecoachsmb/Productattribute/Setup/Patch/Data/  and paste the below code :

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

declare (strict_types = 1);

namespace Thecoachsmb\Productattribute\Setup\Patch\Data;

use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

class ProductAttribute implements DataPatchInterface {

    /**
     * ModuleDataSetupInterface
     *
     * @var ModuleDataSetupInterface
     */
    private $moduleDataSetup;

    /**
     * EavSetupFactory
     *
     * @var EavSetupFactory
     */
    private $eavSetupFactory;

    /**
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param EavSetupFactory          $eavSetupFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        EavSetupFactory $eavSetupFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function apply() {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $eavSetup->addAttribute('catalog_product', 'display_on_homepage', [
            'type' => 'text',
            'backend' => '',
            'frontend' => '',
            'label' => 'Display on Home Page',
            'input' => 'text',
            'class' => '',
            'source' => '',
            'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => false,
            'user_defined' => false,
            'default' => '',
            'searchable' => false,
            'filterable' => false,
            'comparable' => false,
            'visible_on_front' => false,
            'used_in_product_listing' => true,
            'unique' => false,
            'apply_to' => '',
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public static function getDependencies() {
        return [];
    }

    /**
     * {@inheritdoc}
     */
    public function getAliases() {
        return [];
    }
}

Here, In this above file there are some new functions available in that file code. So, Let’s understand short details about the use of that functions.

apply() function :- is used to create or update our custom attribute. We need to create an instance of the EavSetupFactory, passing in our moduleDataSetup object, and add our attribute required configuration.

The getDependencies() function :- we can return an array of strings that contains class names of dependencies. This tells Magento to execute the “patches” we define here first, before our setup script. With the help of this function Magento controls the order of how patch scripts are executed.

getAliases() function :- defines aliases for the patch class. Sometimes, When you want to change the class name then it could possible using getAliases() function. If it does, then we should add old class name so, it’s not executed a second time.

getVersion() function :- will return a version of the patch. It’s an optional method.

If the database version number of the module is lower than the version specified in the file, the patch will execute.

Example:

Database Version: 1.0.0
File Version: 1.0.1
Result: 1.0.0 < 1.0.1, patch will execute!

If the database version number of the module is equal to or higher than the version specified in the file, the patch will not execute.

In Last, Now just execute this below command :

php bin/magento s:up && php bin/magento s:s:d -f && php bin/magento c:f

Now, you can see in eav_attribute table that your custom product attribute created successfully using data patch. When you run php bin/magento setup:upgrade command then our data patch is executed and the EAV attribute is created. All patches which are successfully executed, Magento inserts a patch record into the patch_list database table with the value of the class_name field being the value of our patch.

Create MultiSelect Product Attribute

To create a multiselect product attribute in Magento 2, it’s necessary to pass the correct backend model: if you don’t do it your attribute will be created but the values won’t be saved.

Now, To create custom product attribute Create ProductAttriMulti.php file at app/code/Thecoachsmb/Productattribute/Setup/Patch/Data/  and paste the below code :

<?php

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

declare (strict_types = 1);

namespace Thecoachsmb\Productattribute\Setup\Patch\Data;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

class ProductAttriMulti implements DataPatchInterface {

    /**
     * ModuleDataSetupInterface
     *
     * @var ModuleDataSetupInterface
     */
    private $moduleDataSetup;

    /**
     * EavSetupFactory
     *
     * @var EavSetupFactory
     */
    private $eavSetupFactory;

    /**
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param EavSetupFactory          $eavSetupFactory
     */

    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        EavSetupFactory $eavSetupFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * {@inheritdoc}
     */

    public function apply() {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $eavSetup->addAttribute('catalog_product', 'custom_multiselect', [
            'type' => 'text',
            'backend' => 'Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend',
            'frontend' => '',
            'label' => 'Custom Multi Select',
            'input' => 'multiselect',
            'option' => ['values' => [
                'Option 1',
                'Option 2',
                'Option 3',
                ],
            ],
            'unit' => '',
            'class' => '',
            'source' => '',
            'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
            'visible' => true,
            'required' => true,
            'user_defined' => false,
            'default' => '',
            'searchable' => false,
            'filterable' => false,
            'comparable' => false,
            'visible_on_front' => false,
            'used_in_product_listing' => true,
            'unique' => false,
            'apply_to' => '',
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public static function getDependencies() {
        return [];
    }

    /**
     * {@inheritdoc}
     */
    public function getAliases() {
        return [];
    }
}

The 3 important values here are:

  • Type and Input: these 2 values have to go together for a multiselect field. The type ‘text’ is for saving values. In multiselect, values are saved comma separated that’s why it should be text datatype.
  • Display Values In Dropdown. We added them here directly in the function,
   'option' => ['values' => [
               'Option 1',
               'Option 2',
               'Option 3',
           ],
       ],

but could have created your own model or retrieve an existing one.

  • Backend: Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend. This field is very important, as it handles the saving process of the attribute. If you don’t specify it, your attribute will be displayed in the admin product page, but it won’t be saved.

Now just execute this below command :

php bin/magento s:up && php bin/magento s:s:d -f && php bin/magento c:f

When Data Patches are executed

Unlike the declarative schema approach, patches will only be applied once. A list of applied patches is stored in the patch_list database table with the class name (VendorName\ModuleName\Setup\Patch\Data\FileName). Magento compares all the patches with the list of patches present in the table, if the entry is already there, then that particular patch will not be executed again. An unapplied patch will be applied when running the setup:upgrade from the Magento CLI.

I hope this blog is easy to understand about how to create a product attribute using data patches in Magento 2. This is the proper way of creating product attribute in Magento2. Do comment below giving your feedback.

Happy Learning !!

Leave a Reply

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