15

I need to create a customer programmatically in Magento 2, I haven't found much documentation around... basically what I need to do is translate the following code into "Magento 2":

$websiteId = Mage::app()->getWebsite()->getId();
$store = Mage::app()->getStore();

$customer = Mage::getModel("customer/customer");
$customer   ->setWebsiteId($websiteId)
            ->setStore($store)
            ->setFirstname('John')
            ->setLastname('Doe')
            ->setEmail('jd1@ex.com')
            ->setPassword('somepassword');

try{
    $customer->save();
}
  • you want to do this in a standalone script, or you have a model or something? – Marius Aug 10 '15 at 5:28
  • @Marius, I have been working on this module and I have created a controller. It this controller I need to prepare some data to be saved and the idea is to call the customer model and save that information. The code above can be placed in a controller I would like to do the same but for Magento 2. I am still a bit confused with the new structure of Magento 2 and stuck here now.. I know It has something to do with class injections and object instances but I am not sure how to do it... – Eduardo Aug 10 '15 at 15:06
24

Okay, after a while I found a solution in case someone else needs it.. Magento uses another approach to instantiate objects, the traditional way to instantiate objects in Magento 1.x was using "Mage::getModel(..)", this have changed in Magento 2. Now Magento uses an object manager to instantiate objets, I won't enter in details about how it works.. so, the equivalent code for creating customers in Magento 2 would look like this:

<?php

namespace ModuleNamespace\Module_Name\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    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);

        // Preparing data for new customer
        $customer->setEmail("email@domain.com"); 
        $customer->setFirstname("First Name");
        $customer->setLastname("Last name");
        $customer->setPassword("password");

        // Save data
        $customer->save();
        $customer->sendNewAccountEmail();
    }
}

Hope this snippet of code help someone else..

| improve this answer | |
  • 6
    You were very close. You should avoid using objectManager directly whenever possible--it's bad form. The proper way to do that is using dependency injection to get the 'factory' class, and use that to create an instance. If a factory class doesn't exist for a given class, it'll be auto-generated. I've edited your code to use this (added the factory to the constructor and class, and calling create()), and follow the PSR-2 code standards. – Ryan Hoerr Aug 10 '15 at 23:02
  • Thanks for the correction @RyanH. I thought about using factory classes but wasn't sure how to, so I used objectManager... I will read more about PSR-2 code standards for future projects. I am using the code with your corrections now and everything work perfectly. Thanks – Eduardo Aug 12 '15 at 1:11
  • @RyanH. Done ; ) – Eduardo Aug 12 '15 at 16:31
  • I can see it in databases but not for Admin panel. What happening? – Arni Dec 28 '15 at 20:46
  • 2
    @Arni; my first guess is that you'd need to reindex :) – Alex Timmer Sep 7 '16 at 8:08
4

Here is simple way to create a new customer with default group and current store.

use Magento\Framework\App\RequestFactory;
use Magento\Customer\Model\CustomerExtractor;
use Magento\Customer\Api\AccountManagementInterface;

class CreateCustomer extends \Magento\Framework\App\Action\Action
{
    /**
     * @var RequestFactory
     */
    protected $requestFactory;

    /**
     * @var CustomerExtractor
     */
    protected $customerExtractor;

    /**
     * @var AccountManagementInterface
     */
    protected $customerAccountManagement;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param RequestFactory $requestFactory
     * @param CustomerExtractor $customerExtractor
     * @param AccountManagementInterface $customerAccountManagement
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        RequestFactory $requestFactory,
        CustomerExtractor $customerExtractor,
        AccountManagementInterface $customerAccountManagement
    ) {
        $this->requestFactory = $requestFactory;
        $this->customerExtractor = $customerExtractor;
        $this->customerAccountManagement = $customerAccountManagement;
        parent::__construct($context);
    }

    /**
     * Retrieve sources
     *
     * @return array
     */
    public function execute()
    {
        $customerData = [
            'firstname' => 'First Name',
            'lastname' => 'Last Name',
            'email' => 'customer@email.com',
        ];

        $password = 'MyPass123'; //set null to auto-generate

        $request = $this->requestFactory->create();
        $request->setParams($customerData);

        try {
            $customer = $this->customerExtractor->extract('customer_account_create', $request);
            $customer = $this->customerAccountManagement->createAccount($customer, $password);
        } catch (\Exception $e) {
            //exception logic
        }
    }
}
| improve this answer | |
  • What is $request here?, can we add custom attributes also? – jafar pinjar Sep 5 '18 at 14:51
  • How to set custom attributes ? – jafar pinjar Sep 6 '18 at 7:27
2

All the above examples will work, but according to the coding standards you should always use service contracts than the concrete classes.

Hence, the following way should be preferred for creating customer account programmatically.


use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Api\Data\CustomerInterfaceFactory;
use Magento\Store\Model\StoreManagerInterface;

class CustomerCreate
{
    public $store;

    public $customerFactory;

    public $customerRepository;

    public function __construct(
        StoreManagerInterface $store,
        CustomerInterfaceFactory $customerFactory,
        CustomerRepositoryInterface $customerRepository
    ) {
        $this->store = $store;
        $this->customerFactory = $customerFactory;
        $this->customerRepository = $customerRepository;
    }


    public function create()
    {
        try {
           /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */
           $customer = $this->customerFactory->create();
           $customer->setStoreId($this->store->getStoreId());
           $customer->setWebsiteId($this->store->getWebsiteId());
           $customer->setEmail($email);
           $customer->setFirstname($firstName);
           $customer->setLastname($lastName);

           /** @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository*/
           $customer = $this->customerRepository->save($customer);
           // Note: The save returns the saved customer object, else throws an exception.
       } catch (\Exception $e) {
          // Add log
       }
    }

}
| improve this answer | |
  • Argument 1 passed to Magento\Customer\Model\ResourceModel\CustomerRepository\Interceptor::save() must be an instance of Magento\Customer\Api\Data\CustomerInterface, instance of Magento\Customer\Model\Customer\Interceptor given I get this error running the above code – BrandenB171 Mar 19 at 22:16
  • Hi, @BrandenB171 I have updated the complete code. It may be due to the use of customer model than customer API. Love an upvote if this works for you. – Milind Singh Mar 21 at 9:02
  • 1
    That was it. I was not using CustomerInterfaceFactory, rather CustomerFactory, and that was returning the resource model – BrandenB171 Mar 22 at 16:45
0

This code run in external file or console file CLI Magento

namespace Company\Module\Console;

use Braintree\Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magento\Framework\App\Bootstrap;


class ImportProducts extends Command
{

    public function magentoStart()
    {
        $startMagento = $this->bootstrap();
        $state = $startMagento['objectManager']->get('Magento\Framework\App\State');
        $state->setAreaCode('frontend');
        return $startMagento['objectManager'];
    }

    protected function bootstrap()
    {
        require '/var/www/html/app/bootstrap.php';
        $bootstrap = Bootstrap::create(BP, $_SERVER);
        $objectManager = $bootstrap->getObjectManager();
        return array('bootstrap' => $bootstrap, 'objectManager' => $objectManager);
    }

    protected function createCustomers($item)
    {
        $objectManager      = $this->magentoStart();
        $storeManager       = $objectManager->create('Magento\Store\Model\StoreManagerInterface');
        $customerFactory    = $objectManager->create('Magento\Customer\Model\CustomerFactory');

        $websiteId  = $storeManager->getWebsite()->getWebsiteId();
        $customer   = $customerFactory->create();
        $customer->setWebsiteId($websiteId);
        $customer->setEmail("eu@mailinator.com");
        $customer->setFirstname("First Name");
        $customer->setLastname("Last name");
        $customer->setPassword("password");
        $customer->save();
    }
}
| improve this answer | |
0

The correct way to do this using modern Magento 2 interfaces is as follows. This will avoid deprecated function warnings:

    /**  @var CustomerInterfaceFactory $customerFactory */
    $customerFactory = $this->_bootstrap->getObjectManager()->get("\Magento\Customer\Api\Data\CustomerInterfaceFactory");

    $customer = $customerFactory->create();
    $customer->setWebsiteId(\ElectricLabs\MagentoHelpers::getCurrentStoreId());

    $customer->setEmail($emailAddress);
    $customer->setFirstname($firstName);
    $customer->setLastname($lastName);

    /**  @var CustomerRepositoryInterface $customerRepository */
    $customerRepository = $this->_bootstrap->getObjectManager()->get("\Magento\Customer\Api\CustomerRepositoryInterface");

    /**  @var Encryptor $encryptor */
    $encryptor = $this->_bootstrap->getObjectManager()->get("\Magento\Framework\Encryption\Encryptor");
    $passwordHash = $encryptor->getHash($password, true);
    $customer = $customerRepository->save($customer, $passwordHash);


    /**  @var SessionFactory $customerSessionFactory */
    $customerSessionFactory = $this->_bootstrap->getObjectManager()->get('Magento\Customer\Model\SessionFactory');
    $session = $customerSessionFactory->create();
    $session->setCustomerDataAsLoggedIn($customer);

    /**  @var EmailNotification $emailNotification */
    $emailNotification = $this->_bootstrap->getObjectManager()->get("\Magento\Customer\Model\EmailNotification");
    $emailNotification->newAccount($customer);
| improve this answer | |

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.