3

How to add an Attribute for a Customer Entity in a custom module using declarative schema in Magento 2.3?

  • You can create custom attribute in normal way also in 2.3. Did you try it? – Rohan Hapani Dec 21 '18 at 8:43
  • Yes i know. but i am asking how to create in declarative approach? – Magento User Dec 22 '18 at 4:31
2

Please use the following code to create Customer's Phone number attribute that will be used in the Registration form too:

<?php
namespace Vendor\Module\Setup\Patch\Data;

use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;

/**
 * Class AddCustomerPhoneNumberAttribute
 * @package Vendor\Module\Setup\Patch\Data
 */
class AddCustomerPhoneNumberAttribute implements DataPatchInterface
{
    /**
     * @var ModuleDataSetupInterface
     */
    protected $moduleDataSetup;

    /**
     * @var CustomerSetupFactory
     */
    protected $customerSetupFactory;

    /**
     * @var AttributeSetFactory
     */
    protected $attributeSetFactory;

    /**
     * AddCustomerPhoneNumberAttribute constructor.
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param CustomerSetupFactory $customerSetupFactory
     * @param AttributeSetFactory $attributeSetFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        CustomerSetupFactory $customerSetupFactory,
        AttributeSetFactory $attributeSetFactory
    ){
        $this->moduleDataSetup = $moduleDataSetup;
        $this->customerSetupFactory = $customerSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }

    /**
     * {@inheritdoc}
     */
    public function apply()
    {
        $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);

        $customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        $attributeSet = $this->attributeSetFactory->create();
        $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

        $customerSetup->addAttribute(
            Customer::ENTITY,
            'phone_number',
            [
                'type' => 'varchar',
                'label' => 'Phone Number',
                'input' => 'text',
                'validate_rules' => '{"max_text_length":255,"min_text_length":1}',
                'required' => false,
                'sort_order' => 120,
                'position' => 120,
                'visible' => true,
                'user_defined' => true,
                'unique' => false,
                'system' => false,
            ]
        );

        $attribute = $customerSetup->getEavConfig()->getAttribute(
            Customer::ENTITY,
            'phone_number'
        );

        $attribute->addData(
            [
                'attribute_set_id' => $attributeSetId,
                'attribute_group_id' => $attributeGroupId,
                'used_in_forms' => ['adminhtml_customer', 'customer_account_create', 'customer_account_edit'],
            ]
        );

        $attribute->save();
    }

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

    /**
     * {@inheritdoc}
     */
    public function getAliases()
    {
        return [];
    }
}
  • I have implemented as explained. When I run setup:upgrade command it shows an error as follow:PHP Fatal error: Uncaught TypeError: Return value of Magento\Framework\Setup\Declaration\Schema\Declaration\SchemaBuilder::processTable() must be an instance of Magento\Framework\Setup\Declaration\Schema\Dto\Table, boolean returned in /var/www/html/magento231/lib/internal/Magento/Framework/Setup/Declaration/Schema/Declaration/SchemaBuilder.php:251 – Bijal Bhavsar Jun 17 at 6:11
1

I have added one customer attribute using Declarative Schema in a custom module.

<?php

namespace vendor_name\module_name\Setup\Patch\Data;

use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchVersionInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Framework\DB\Ddl\Table;

class AddTestAttribute implements DataPatchInterface
{
    protected $_moduleDataSetup;
    protected $_customerSetupFactory;
    protected $_attributeSetFactory;

    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        CustomerSetupFactory $customerSetupFactory,
        AttributeSetFactory $attributeSetFactory
    )
    {
        $this->_moduleDataSetup = $moduleDataSetup;
        $this->_customerSetupFactory = $customerSetupFactory;
        $this->_attributeSetFactory = $attributeSetFactory;
    }

    public function apply()
    {
        $customerSetup = $this->_customerSetupFactory->create(['setup' => $this->_moduleDataSetup]);

        $customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        $attributeSet = $this->_attributeSetFactory->create();
        $attributeSet->getDefaultGroupId($attributeSetId);

        $customerSetup->removeAttribute(Customer::ENTITY, 'test');
        $customerSetup->addAttribute(Customer::ENTITY, 'test', array(
            'type' => Table::TYPE_DECIMAL,
            'label' => 'Test',
            'input' => 'text',
            'required' => 0,
            'default' => 0,
            'visible' => 0,
            'system' => 0
        ));
    }

    public function getAliases()
    {
        return [];
    }

    public static function getDependencies()
    {
        return [

        ];
    }
}
  • 1
    its not displayed on form – Adarsh Shukla Mar 1 at 5:37
  • how can we make it visible on form – Adarsh Shukla Mar 1 at 6:01
  • i have changed visible 0 to 1 still its not visible on admin form – Adarsh Shukla Mar 1 at 6:02
  • @AdarshShukla - To display in form you need to add following code at the end of apply method: $sampleTestAttributeId = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'test'); $sampleTestAttributeId->addData( [ 'attribute_set_id' => $attributeSetId, 'attribute_group_id' => $attributeGroupId, 'used_in_forms' => ['adminhtml_customer', 'customer_account_create', 'customer_account_edit'] ] ); $sampleTestAttributeId->save(); – Bijal Bhavsar Sep 6 at 12:18
0

After reviewing the schema.xsd; I don't see any support for it; but - you can add support for it by updating the schema in your own module and then pointing your file to it while adding support for the additional functionality. (which is alot of work unless you are building several modules and you are doing this within your "core")

Currently this is easily done the previous way via the InstallData.php; I'm not sure if anyone wants this added to declarative at this time; if so; I can put something together as a PR?

  • If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review – Jai Jan 28 at 19:10
  • Upon some research; trying to add/remove attributes via declarative is short of crossing boundaries between the db schema and data patch demarcations. so technically; add/remove attributes should be done via installdata / data patches. Which @Ramanathan recommends. – billandr Jan 29 at 20:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.