How to Add a Customer Attribute Programmatically using Data Patch in Magento 2

add_customer_attribute_programmatically_data_patch_magento_2_new

In Magento 2.3.x, Magento has introduced the Data Patch interface Magento\Framework\Setup\Patch\DataPatchInterface to add or modify the EAV data.

In Magento 2.2 and 2.1 we were using InstallData or UpgradeData script to add a customer attribute programmatically. Though these scripts are still working in Magento 2.3.x for backward compatibility. But as a professional developer one should use data patch class to add or modify EAV data.

In this post, we will see how to add a customer attribute programmatically using a data patch in Magento 2.

Add a Customer Attribute Programmatically

To add a customer attribute using data patch create patch file MyCustomerAttribute.php under app/code/Vendor/Module/Setup/Patch/Data directory and add below code.

<?php


namespace Vendor\Module\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Customer\Setup\CustomerSetup;

class MyCustomerAttribute implements DataPatchInterface, PatchRevertableInterface
{

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

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

    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        $this->moduleDataSetup->getConnection()->startSetup();
        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
        $customerSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            'customer_pan_number',
            [
                'type' => 'varchar',
                'label' => 'Customer Pan Number',
                'input' => 'text',
                'source' => '',
                'required' => false,
                'visible' => true,
                'position' => 500,
                'system' => false,
                'backend' => ''
            ]
        );
        
        $attribute = $customerSetup->getEavConfig()->getAttribute('customer', 'customer_pan_number')->addData([
            'used_in_forms' => [
                'adminhtml_customer'
            ]
        ]);
        $attribute->save();

        $this->moduleDataSetup->getConnection()->endSetup();
    }

    public function revert()
    {
        $this->moduleDataSetup->getConnection()->startSetup();
        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
        $customerSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'customer_pan_number');

        $this->moduleDataSetup->getConnection()->endSetup();
    }

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

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

Here customer_pan_number is our customer attribute. In line number 63 we have passed used_in_forms array value adminhtml_customer that means it is available in admin customer edit form.

As per requirement you can pass used_in_forms array

'used_in_forms' => [
'adminhtml_checkout',
'adminhtml_customer',
'adminhtml_customer_address',
'customer_account_edit',
'customer_address_edit',
'customer_register_address',
'customer_account_create'
];

After adding this class into your module please run below command to create customer attribute in database.
php bin/magento setup:upgrade

Hope this post helps you.To receive update about this type of code snippet, please like us on Facebook and follow us on Twitter.

Leave a Comment

(5 Comments)

  • Fernando Torres

    $attribute->save(); is deprecated… what would be the new approach?

  • Fernando Torres

    after all this, the ‘customer_pan_number’ attribute is not added to the table ‘customer_entity’. how can I get the ‘customer_pan_number’ saved in the data base?

    • Chirag

      customer_pan_number is the customer attribute and follows the EAV database structure. It will automatically saved when you save a customer from the backend.

  • rajnikant

    Warning: call_user_func() expects parameter 1 to be a valid callback, class ‘Rbj\AddressAttribute\Setup\Patch\Data\MyCustomerAttribute’ not found

    • Chirag

      Make sure you have created the file at the correct path and in the correct Magento 2 version.

  • All the comments are goes into moderation before approval. Irrelevant comment with links directly goes to spam. Your email address will not be published.

    Was this post helpful? Please support Us!

    Follow us on twitter or Like us on facebook.

     


    Subscribe Here
    SUBSCRIBE NOW

    Want to Increase your Magento 2 Development Knowledge?

    If Yes! Then Subscribe to our newsletter and receive step-by-step tutorials, code snippets once a week!!
    close-link

    To Avoid Spam Downloads, We Want Your Email

    We will send you download link right
    away. Please submit form below.
    SEND ME DOWNLOAD LINK
    Close