4

I would like to create a customer account programmatically in Magento 2.0.4.

I just have one problem. I don't know how to persist custom attributes. With following code, I got response that my required custom attribute (xxx_test) is not set.

 class Register extends \Magento\Framework\App\Action\Action {

    protected $storeManager;

    /**
     * @var \Magento\Customer\Model\CustomerFactory
     */
    protected $customerFactory;

    /**
     * @param \Magento\Framework\App\Action\Context      $context
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Customer\Model\CustomerFactory    $customerFactory
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Customer\Model\CustomerFactory $customerFactory
    ) {
        $this->storeManager     = $storeManager;
        $this->customerFactory  = $customerFactory;

        parent::__construct($context);
    }

    public function execute()
    {
        // Get Website ID
        $websiteId  = $this->storeManager->getWebsite()->getWebsiteId();

        // Instantiate object (this is the most important part)
        $customer = $this->customerFactory->create();

        $customer->setWebsiteId($websiteId);
        $customer->setEmail("test@mail.com");
        $customer->setFirstname("First Name");
        $customer->setLastname("Last name");
        $customer->setPassword("password");
        $customer->setPrefix("Herr");

        $customer->setAddresses(null);

        $storeId = $this->storeManager->getWebsite($websiteId)->getDefaultStore()->getId();
        $customer->setStoreId($storeId);

        $storeName = $this->storeManager->getStore($customer->getStoreId())->getName();
        $customer->setCreatedIn($storeName);

        /* 
         * TODO
         * Problem with custom attributes
         */

        $customerData = $customer->getDataModel();
        $customerData->setCustomAttribute("xxx_test", "N/A");
        $customer->updateData($customerData);

        $customer->save();
        $customer->sendNewAccountEmail();
    }


}

Could anybody please help?

1
  • I followed the same, but still facing the same issue. I used setData() instead of setCustomAttribute(), but no use. Feb 20, 2017 at 7:44

2 Answers 2

2

To persist data in your customer attribute, you must first register that attribute in the database using an InstallData script. Since the Customer model is an EAV type, you do it like this:

Create file \app\code\Vendor\Module\Setup\InstallData.php with contents as follows

<?php

namespace Vendor\Module\Setup;


use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{
    private $customerSetupFactory;

    public function __construct(
        CustomerSetupFactory $customerSetupFactory
    )
    {
        $this->customerSetupFactory = $customerSetupFactory;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        $customerEntity = Customer::ENTITY;

        /** @var CustomerSetup $customerSetup */
        $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);

        $customerSetup->addAttribute(
            $customerEntity,
            'xxx_test',
            ['type' => 'varchar']
        );

        $setup->endSetup();
    }
}

Choose the data type that corresponds to your attribute (int, text, date, varchar etc...). For this example I used 'varchar'.

To run this script, you use the magento CLI command setup:upgrade. The InstallData script only runs the first time setup:upgrade is used against your module. If your module has already had this command run against it, you can delete it's entry in the setup_module database table and then the install script(s) will be run again.

Now that your attribute exists, you can set it programmatically like this:

$customer->setXxxTest('test data');

or

$customer->setData('xxx_test', 'test data');
2
  • thanks, i have created the custom attribute correct. but i missed the setData () function. now it works thx!
    – Umfi
    Jul 18, 2016 at 9:44
  • @AaronAllen, I have used the same(setData()), still its not saving the data of custom attributes. Could you please help me. Feb 22, 2017 at 5:44
0

Bellow code can work standalone

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $customerSetupFactory = $objectManager->create('Magento\Customer\Setup\CustomerSetupFactory');

        $setupInterface = $objectManager->create('Magento\Framework\Setup\ModuleDataSetupInterface');

        $customerSetup = $customerSetupFactory->create(['setup' => $setupInterface]);

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

        $attributeSetFactory = $objectManager->create('Magento\Eav\Model\Entity\Attribute\SetFactory');

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

        $customerSetup->addAttribute(\Magento\Customer\Model\Customer::ENTITY, 'attribute_code', [
            'type' => 'varchar',
            'label' => 'Attribute Title',
            'input' => 'text',
            'required' => false,
            'visible' => true,
            'user_defined' => true,
            'sort_order' => 1000,
            'position' => 1000,
            'system' => 0,
        ]);
        //add attribute to attribute set
        $attribute = $customerSetup->getEavConfig()->getAttribute(\Magento\Customer\Model\Customer::ENTITY, 'attribute_code')
        ->addData([
            'attribute_set_id' => $attributeSetId,
            'attribute_group_id' => $attributeGroupId,
            'used_in_forms' => ['adminhtml_customer'],
        ]);

        $attribute->save();

Hope this works for you people.

1
  • Given solution is not complete according to the question, this the half part only. The answer given by @Aaron is correct.
    – Manish
    Jul 17, 2018 at 7:56

Your Answer

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

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