You can create user-defined customer attributes using Patch Data in Magento 2.
If you have some requirement to show customer attributes to only a given website in multi website setup.
This article displays customer attributes for specific website levels.
Let’s hope you have created a simple module,
Just create a new Data Patch file under the path, app/code/<Vendor>/<Modulename>/Setup/Patch/Data/CustomerAttributes.php
We have to create a new attribute called ‘mobile’ and display it on the customer registration page, and customer edit page.
<?php declare(strict_types=1);
namespace Rbj\Blog\Setup\Patch\Data;
use Exception;
use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Customer\Api\Data\AttributeMetadataInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Model\ResourceModel\Attribute as AttributeResource;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Validator\ValidateException;
use Magento\Store\Api\Data\WebsiteInterface;
use Magento\Store\Api\WebsiteRepositoryInterface;
use Psr\Log\LoggerInterface;
class CustomerAttributes implements DataPatchInterface
{
private ?CustomerSetup $customerSetup = null;
private const MOBILE_CUSTOMER_ATTRIBUTE = 'mobile';
public function __construct(
private ModuleDataSetupInterface $moduleDataSetup,
private CustomerSetupFactory $customerSetupFactory,
private AttributeResource $attributeResource,
private WebsiteRepositoryInterface $websiteRepository,
private LoggerInterface $logger
) {
}
public function apply(): self
{
try {
$this->createMobileAttribute();
} catch (Exception $exception) {
$this->logger->error($exception->getMessage());
}
return $this;
}
public static function getDependencies(): array
{
return [];
}
public function getAliases(): array
{
return [];
}
public function createMobileAttribute(): void
{
$this->createAttribute(self::MOBILE_CUSTOMER_ATTRIBUTE);
$this->updateAttribute(self::MOBILE_CUSTOMER_ATTRIBUTE);
}
/**
* Create New Customer Attribute called Mobile
*
* @param string $attributeCode
* @return void
* @throws LocalizedException
* @throws ValidateException
*/
private function createAttribute(string $attributeCode): void
{
$customerAttributeSetup = $this->getCustomerSetup();
$attribute = $customerAttributeSetup->getEavConfig()->getAttribute(Customer::ENTITY, $attributeCode);
if ($attribute && $attribute->getId()) {
return;
}
$customerAttributeSetup->addAttribute(
Customer::ENTITY,
$attributeCode,
[
'type' => 'varchar',
'label' => 'Mobile',
'input' => 'text',
'position' => 70,
'used_in_forms' => ['customer_account_create', 'customer_account_edit'],
AttributeMetadataInterface::REQUIRED => false,
AttributeMetadataInterface::VISIBLE => false,
AttributeMetadataInterface::USER_DEFINED => true,
AttributeMetadataInterface::SYSTEM => 0,
AttributeMetadataInterface::IS_USED_IN_GRID => false,
AttributeMetadataInterface::IS_VISIBLE_IN_GRID => false,
AttributeMetadataInterface::IS_FILTERABLE_IN_GRID => true,
AttributeMetadataInterface::IS_SEARCHABLE_IN_GRID => true
]
);
$attributeGroupId = $customerAttributeSetup->getDefaultAttributeGroupId(
CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER
);
$customerAttributeSetup->addAttributeToSet(
CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER,
(int)$attributeGroupId,
$attributeCode
);
}
/**
* This method used to assigned customer attribute to only specific website only in multiple websites.
*
* @param string $attributeCode
* @return void
* @throws LocalizedException
* @throws AlreadyExistsException
*/
private function updateAttribute(string $attributeCode): void
{
$website = $this->getUsWebsite();
if (!$website) {
return;
}
$customerAttributeUpdateSetup = $this->getCustomerSetup();
$attribute = $customerAttributeUpdateSetup->getEavConfig()
->getAttribute(Customer::ENTITY, $attributeCode)
->loadByCode(Customer::ENTITY, $attributeCode);
if (!$attribute || !$attribute->getId()) {
return;
}
$attribute->setWebsite($website);
$attribute->setData('scope_is_visible', 1);
$usedInForms = ['customer_account_create', 'customer_account_edit'];
$attribute->setData('used_in_forms', $usedInForms);
$this->attributeResource->save($attribute);
}
private function getUsWebsite(): ?WebsiteInterface
{
try {
$website = $this->websiteRepository->get('us_site'); // REPLACE 'us_site' WITH YOUR WEBSITE CODE
} catch (NoSuchEntityException $exception) {
return null;
}
return $website;
}
private function getCustomerSetup(): CustomerSetup
{
if (!$this->customerSetup) {
$this->customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
}
return $this->customerSetup;
}
}
Now, Run the Setup upgrade command to install the customer attribute.
php bin/magento setup:upgrade
