phpmagento2custom-attributes

Add Customer Custom Attribute to front store


I need to add a Customer custom attribute. Here is snippet of my code:

         $customerSetup->addAttribute(Customer::ENTITY, 'customer_mobile', [
            'type' => 'varchar',
            'label' => 'Customer Mobile',
            'input' => 'text',
            'required' => false,
            'visible' => true,
            'user_defined' => true,
            'sort_order' => 85,
            'position' => 999,
            'system' => 0,
            'visible_on_front' => true
        ]);

        $attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'customer_mobile')
            ->addData([
                'attribute_set_id' => $attributeSetId,
                'attribute_group_id' => $attributeGroupId,
                'used_in_forms' => ['adminhtml_customer', 'customer_account_edit'],
            ]);

        $attribute->save();

It successfully adds 'customer_mobile' in the admin. But it does not show on the front store, in edit user form. I check on the table customer_form_attribute and there are 2 rows with my new custom attribute with 2 forms. Do I need to override the customer_account_edit.xml to display? I try to work on this for 2 days, but no hope. Can anyone help me.

Thank you very much!


Solution

  • Thank to Charmi Patel, I found the answer here. I'll summarize it:

    1. Create customer attribute on below path Vendor\Module\Setup\Patch\Data\AddCustomerMobileAttribute.php
    <?php
    
    namespace Vendor\Module\Setup\Patch\Data;
    
    use Magento\Customer\Model\Customer;
    use Magento\Customer\Model\ResourceModel\Attribute;
    use Magento\Eav\Model\Config;
    use Magento\Eav\Setup\EavSetupFactory;
    use Magento\Framework\Setup\ModuleDataSetupInterface;
    use Magento\Framework\Setup\Patch\DataPatchInterface;
    use Magento\Framework\Setup\Patch\PatchRevertableInterface;
    use Psr\Log\LoggerInterface;
    
    /**
     * Create Customer Attribute
     */
    class AddCustomerMobileAttribute implements DataPatchInterface, PatchRevertableInterface
    {
        /**
         * @var ModuleDataSetupInterface
         */
        private $moduleDataSetup;
    
        /**
         * @var EavSetupFactory
         */
        private $eavSetupFactory;
    
        /**
         * @var LoggerInterface
         */
        private $logger;
    
        /**
         * @var Config
         */
        private $eavConfig;
    
        /**
         * @var Attribute
         */
        private $attributeResource;
    
        /**
         * CustomerAttribute Constructor
         *
         * @param EavSetupFactory $eavSetupFactory
         * @param Config $eavConfig
         * @param LoggerInterface $logger
         * @param Attribute $attributeResource
         * @param ModuleDataSetupInterface $moduleDataSetup
         */
        public function __construct(
            EavSetupFactory                                   $eavSetupFactory,
            Config                                            $eavConfig,
            LoggerInterface                                   $logger,
            Attribute                                         $attributeResource,
            ModuleDataSetupInterface                          $moduleDataSetup
        ) {
            $this->eavSetupFactory = $eavSetupFactory;
            $this->eavConfig = $eavConfig;
            $this->logger = $logger;
            $this->attributeResource = $attributeResource;
            $this->moduleDataSetup = $moduleDataSetup;
        }
    
        /**
         * @inheritdoc
         */
        public function apply()
        {
            $this->moduleDataSetup->getConnection()->startSetup();
            $this->addOnlineStoreAttribute();
            $this->moduleDataSetup->getConnection()->endSetup();
        }
    
        /**
         * @throws \Magento\Framework\Exception\AlreadyExistsException
         * @throws \Magento\Framework\Exception\LocalizedException
         * @throws \Zend_Validate_Exception
         */
        public function addOnlineStoreAttribute()
        {
            $eavSetup = $this->eavSetupFactory->create();
            $eavSetup->addAttribute(
                Customer::ENTITY,
                'phone_number',
                [
                    'type' => 'varchar',
                    'label' => 'Online Stores',
                    'input' => 'text',
                    'required' => true,
                    'visible' => true,
                    'user_defined' => true,
                    'system' => false,
                    'is_visible_in_grid' => true,
                    'is_used_in_grid' => true,
                    'is_filterable_in_grid' => true,
                    'is_searchable_in_grid' => true,
                    'position' => 10,
                    'nullable' => true
                ]
            );
    
            $attributeSetId = $eavSetup->getDefaultAttributeSetId(Customer::ENTITY);
            $attributeGroupId = $eavSetup->getDefaultAttributeGroupId(Customer::ENTITY);
    
            $attribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'phone_number');
            $attribute->setData('attribute_set_id', $attributeSetId);
            $attribute->setData('attribute_group_id', $attributeGroupId);
    
            $attribute->setData('used_in_forms', [
                'adminhtml_customer',
                'adminhtml_customer_address',
                'customer_account_edit',
                'customer_address_edit',
                'customer_register_address',
                'customer_account_create'
            ]);
    
            $this->attributeResource->save($attribute);
        }
    
        /**
         * @inheritdoc
         */
        public static function getDependencies()
        {
            return [];
        }
    
        /**
         * @inheritdoc
         */
        public function revert()
        {
        }
    
        /**
         * @inheritdoc
         */
        public function getAliases()
        {
            return [];
        }
    }
    
    1. Create customer_account_edit.xml file on Vendor/Module/view/frontend/layout/customer_account_edit.xml
    <?xml version="1.0"?>
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
        <body>
            <referenceBlock name="form.additional.info">
                <block class="Vendor\Module\Block\Index" name="phone_number"
                       template="Vendor_Module::index.phtml"/>
            </referenceBlock>
        </body>
    </page>
    
    1. Create block file for your logic on path Vendor\Module\Block\Index.php
    <?php
    namespace Vendor\Module\Block;
    
    use Magento\Framework\View\Element\Template;
    use Magento\Customer\Model\Session;
    use Magento\Customer\Api\CustomerRepositoryInterface;
    
    class Index extends Template
    {
        protected $customerSession;
        protected $customerRepository;
    
        public function __construct(
            Template\Context $context,
            Session $customerSession,
            CustomerRepositoryInterface $customerRepository,
            array $data = []
        ) {
            $this->customerSession = $customerSession;
            $this->customerRepository = $customerRepository;
            parent::__construct($context, $data);
        }
    
        public function getPhoneNumber()
        {
            $customerId = $this->customerSession->getCustomerId();
            $customer = $this->customerRepository->getById($customerId);
            return $customer->getCustomAttribute('phone_number') ? $customer->getCustomAttribute('phone_number')->getValue() : '';
        }
    }
    
    1. Create phtml file on path Vendor/Module/view/frontend/templates/index.phtml
    <div class="field phone">
        <label class="label" for="phone_number"><span><?php echo __('Phone Number'); ?></span></label>
        <div class="control">
            <input type="text" name="phone_number" id="phone_number" value="<?php echo $block->escapeHtml($block->getPhoneNumber()); ?>" title="<?php echo __('Phone Number'); ?>" class="input-text"/>
        </div>
    </div>