1

I'm trying to add a new Custom attribute to the Magento customer model, and I think that I've set everything up correctly from what I've been able to scour off of this website & google, but I'm just not having any luck with it.

Essentially, the project is about overloading some of the functionality for the Magento Customer module, we want to execute some custom code in & around the Customer saving, loading and authentication functionality.

I'm building all of my interceptors into a custom module which I've successfully vendored into my Dev instance.

This module has an InstallData.php script which does successfully create my Custom Attribute:

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(
            Customer::ENTITY,
            'MSISDN',
            [
                'type'         => 'varchar',
                'label'        => 'MSISDN',
                'input'        => 'text',
                'required'     => true,
                'visible'      => true,
                'user_defined' => true,
                'position'     => 999,
                'system'       => 0
            ]
        );
        $msisdnAttribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'MSISDN');
        $msisdnAttribute->setData(
            'used_in_forms',
            ['adminhtml_customer']

        );
        $msisdnAttribute->save();
    }

Once I've run composer update & php bin/magento setup:upgrade, I can confirm that the custom attribute has been created in the database.

However, when I try to register a new customer using the REST API, following request:
{ "customer": { "group_id": 1, "default_billing": "", "default_shipping": "", "created_at": "2019-02-05 12:12:12", "updated_at": "2019-02-05 12:12:12", "created_in": "dev_store", "dob": "1981-03-01", "email": "[email protected]", "firstname": "User", "lastname": "Name", "middlename": "X", "prefix": "B", "suffix": "A", "gender": 1, "store_id": 1, "taxvat": "string", "website_id": 1, "custom_attributes": [ {
"attribute_code": "MSISDN", "value": "121314151617" }
]
},
"password": "TestPassword1234" }

I get the Error response:

{"message":"\"MSISDN\" is a required value."}

Ultimately, I want to be able to intercept this value before the Customer data model gets saved so that I can execute custom validations & a few other tasks.

Please let me know if I can provide any other info.

Thanks in advance for the help.

2
  • Have you cross verified this attribute is created in backend Commented Feb 7, 2019 at 17:03
  • I can confirm that the attribute is being shown on the admin form, but that form gives the same error, stating that the MSISDN is a required value, even when that form field is filled in.
    – DuncanA
    Commented Feb 8, 2019 at 12:20

2 Answers 2

0

You need to add attribute in customer registration form as well

customer_register_address

use below code:

$msisdnAttribute->setData(
    'used_in_forms',
     ['adminhtml_customer', 'customer_register_address']    
);

Note: You have added this attribute in install script, now you need to create upgrade data script and first remove attribute and reinstall it in upgrade script.

You can remove attribute using below code:

$customerSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY,'attribute_code');
2
  • Thank you for the feedback, I've tried making that change to the attribute, but I'm still getting the same error. Is there anywhere that I could see a list of the valid options for that setData() method? I've tried googling it, but I'm not finding anything.
    – DuncanA
    Commented Feb 8, 2019 at 9:00
  • habe you checked attribute is visible on backend customer edit page? Commented Feb 8, 2019 at 15:10
0

For anybody that smashes their head into this problem like I did, hopefully the following will help.

I ended up tweaking & updating my InstallData.php from info I scraped up out of other people's queries about similar issues, and I've eventually landed on the following:

<?php

namespace MyModule\Customer\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Indexer\IndexerRegistry;
use Magento\Eav\Model\Config;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetupFactory;

class InstallData implements InstallDataInterface
{
/**
 * Customer setup factory
 *
 * @var CustomerSetupFactory
 */
protected $customerSetupFactory;

/**
 * @var IndexerRegistry
 */
protected $indexerRegistry;

/**
 * @var \Magento\Eav\Model\Config
 */
protected $eavConfig;

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

/**
 * @var EavSetupFactory
 */
private $eavSetupFactory;


/**
 * @param CustomerSetupFactory $customerSetupFactory
 * @param IndexerRegistry $indexerRegistry
 * @param Config $eavConfig
 * @param EavSetupFactory $eavSetupFactory
 * @param AttributeSetFactory $attributeSetFactory
 */
public function __construct(
    CustomerSetupFactory $customerSetupFactory,
    IndexerRegistry $indexerRegistry,
    Config $eavConfig,
    EavSetupFactory $eavSetupFactory,
    AttributeSetFactory $attributeSetFactory
)
{
    $this->customerSetupFactory = $customerSetupFactory;
    $this->indexerRegistry = $indexerRegistry;
    $this->eavConfig = $eavConfig;
    $this->eavSetupFactory = $eavSetupFactory;
    $this->attributeSetFactory = $attributeSetFactory;
}

public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    $setup->startSetup();
    /** @var CustomerSetup $customerSetup */
    $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);

    $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
    $attributeSetId = $customerEntity->getDefaultAttributeSetId();

    /** @var $attributeSet AttributeSet */
    $attributeSet = $this->attributeSetFactory->create();
    $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

    $customerSetup->addAttribute(
        Customer::ENTITY,
        'msisdn',
        [
            'type'         => 'varchar',
            'label'        => 'msisdn',
            'input'        => 'text',
            'required'     => true,
            'visible'      => true,
            'user_defined' => true,
            'position'     => 999,
            'system'       => 0
        ]
    );
    $msisdnAttribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'msisdn');

    $msisdnAttribute->addData([
            'attribute_set_id' => $attributeSetId,
            'attribute_group_id' => $attributeGroupId,
            'used_in_forms' => [ 'customer_account_create' ,'customer_account_edit', 'adminhtml_customer', 'adminhtml_checkout', 'customer_register_address', 'customer_register']
            ]);
    $msisdnAttribute->save();

    $indexer = $this->indexerRegistry->get(Customer::CUSTOMER_GRID_INDEXER_ID);
    $indexer->reindexAll();
    $this->eavConfig->clear();
    $setup->endSetup();     
}
}

And after doing the whole process of reinstalling the module, Magento is now finally able to read the custom attribute from my JSON Request & save it to the database.

Disclaimer: The above install script has been created by using a "throw-everything at-the-wall-and-see-what-sticks" approach, so I'm sure that some coding guidelines & best practices are being violated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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