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?

  • I followed the same, but still facing the same issue. I used setData() instead of setCustomAttribute(), but no use. – Venu Joginpally Feb 20 '17 at 7:44
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');
| improve this answer | |
  • thanks, i have created the custom attribute correct. but i missed the setData () function. now it works thx! – Umfi Jul 18 '16 at 9:44
  • @AaronAllen, I have used the same(setData()), still its not saving the data of custom attributes. Could you please help me. – Venu Joginpally Feb 22 '17 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.

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

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.