Add Customer Attributes Programmatically in Magento 2

In this article we’ll see what’re customer attributes and how we add them programmatically in Magento 2. So we’ll proceed with following points :

1. What’re customer attributes
2. Why we need to add them programmatically
3. Steps to create customer attribute.

1. What’re customer attributes

In Magento, fields which are used in registration, login and filling customer address are basically customer attributes. They’re further divided into customer attributes and customer address attributes. Now if attributes used in customer registration / login are customer attributes and attribute used in address information for customers are customer address attributes. Some examples of customer attributes are below :

a. Customer Attributes
– First Name, Last Name, DOB etc
b. Customer Address Attributes
– Zip, City, Street, Country, Region/State etc

2. Why we need to add them programmatically

Magento by default didn’t provide functionality to add customer attributes in CE and sometime our project requirement have to add some extra fields(customer attributes) in registration form or address form. To do so we need to add them programmatically or through third party modules.

3. Steps to create customer attribute.

Let see how we can create customer attributes programmatically in Magento 2 step by step :-

Step 1: Create setup file InstallData.php

Firstly, we will create the InstallData.php file:
File: Excellence/Customerattr/Setup/InstallData.php

<?php
namespace Excellence\Customerattr\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;

class InstallData implements InstallDataInterface
{
	private $eavSetupFactory;

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

}

In this class, we define the EAV setup model which will be use to interact with Magento 2 attribute.

Step 2: Define the install() method

After that, we have to define the install() method and create eav setup model:

	
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
	{
		$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
		$eavSetup->addAttribute(
			\Magento\Customer\Model\Customer::ENTITY,
			'gst_number',
			[
				'type'         => 'varchar',
				'label'        => 'GST Number',
				'input'        => 'text',
				'required'     => false,
				'visible'      => true,
				'user_defined' => true,
				'position'     => 100,
				'system'       => 0,
			]
		);
}

Step 3: Create custom attribute

Finally, we need to set the forms in which the attributes will be used. In this step, we need define the eavConfig object which allow us to call the attribute back and set the data for it and the full code to create customer attribute is:

Now our final InstallData.php looks like below :-

<?php

namespace Excellence\Customerattr\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\Config;
use Magento\Customer\Model\Customer;

class InstallData implements InstallDataInterface
{
	private $eavSetupFactory;

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

	public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
	{
		$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
		$eavSetup->addAttribute(
			\Magento\Customer\Model\Customer::ENTITY,
			'gst_number',
			[
				'type'         => 'varchar',
				'label'        => 'GST Number',
				'input'        => 'text',
				'required'     => false,
				'visible'      => true,
				'user_defined' => true,
				'position'     => 999,
				'system'       => 0,
			]
		);
		$attribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'gst_number');

		//  used_in_forms are of these types you can use forms key according to your need ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address', 'customer_account_create']
		
               $attribute->setData(
			'used_in_forms',
			['adminhtml_customer', 'customer_account_create']

		);
		$attribute->save();
	}
}

Step 4: Show Customer Attribute in Register form
For showing this customer attribute on the registration page, we need to do following things :

We will add our phtml files to ‘form.additional.info’ reference name using Excellence/Customerattr/view/frontend/layout/customer_account_create.xml

<page 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="form.additional.info">
            <block class="Magento\Framework\View\Element\Template" name="mobile_number" template="Excellence_MobileLogin::mobile.phtml"/>
        </referenceContainer>
    </body>
</page>

Explaination : we’re not overriding the entire vendor/magento/module-customer/view/frontend/templates/form/register.phtml file. Instead we used container name form.additional.info as reference and adding a new block to it. ‘form.additional.info’ is being called in register.phtml using this code getChildHtml(‘form_additional_info’); ?>

So by above xml we can simply add new attribute fields with editing register.phtml of core or without overriding it and getChildHtml(‘form_additional_info’); ?> automatically read content of ‘form.additional.info’ child block.

That’s all for adding customer attribute programmatically.