Magento 2 : Programmatically Create Customer and Then Login
Question
I am trying to create customer and then login programmatically. Below is my code :
<?php
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$obj = $bootstrap->getObjectManager();
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$websiteId = $storeManager->getStore()->getWebsiteId();
$firstName = 'Test';
$lastName = 'Test';
$email = 'test@example.com';
$password = 'Test@123';
$address = array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => $firstName,
'middlename' => '',
'lastname' => $lastName,
'suffix' => '',
'company' => '',
'street' => array(
'0' => 'Customer Address 1', // this is mandatory
'1' => 'Customer Address 2' // this is optional
),
'city' => 'New York',
'country_id' => 'US', // two letters country code
'region' => 'New York', // can be empty '' if no region
'region_id' => '43', // can be empty '' if no region_id
'postcode' => '10450',
'telephone' => '123-456-7890',
'fax' => '',
'save_in_address_book' => 1
);
$customerFactory = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();
/**
* check whether the email address is already registered or not
*/
$customer = $customerFactory->setWebsiteId($websiteId)->loadByEmail($email);
/**
* if email address already registered, return the error message
* else, create new customer account
*/
if ($customer->getId()) {
echo 'Customer with email '.$email.' is already registered.';
} else {
try {
$customer = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();
$customer->setWebsiteId($websiteId);
$customer->setEmail($email);
$customer->setFirstname($firstName);
$customer->setLastname($lastName);
$customer->setPassword($password);
// save customer
$customer->save();
$customer->setConfirmation(null);
$customer->save();
$customAddress = $objectManager->get('\Magento\Customer\Model\AddressFactory')->create();
$customAddress->setData($address)
->setCustomerId($customer->getId())
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
// save customer address
$customAddress->save();
// Create customer session
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
$customerSession->setCustomerAsLoggedIn($customer);
echo 'Customer with email '.$email.' is successfully created.';
} catch (Exception $e) {
echo $e->getMessage();
}
}
Above code create customer successfully as I can find them in database but they are not visible in admin customer grid. Also, after creating customer I am trying to login programmatically but no success. Please help.
Solution
Here is the solution :
<?php
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$obj = $bootstrap->getObjectManager();
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$websiteId = $storeManager->getStore()->getWebsiteId();
$firstName = 'Test';
$lastName = 'Test';
$email = 'aabb@example.com';
$password = 'Test@123';
$address = array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => $firstName,
'middlename' => '',
'lastname' => $lastName,
'suffix' => '',
'company' => '',
'street' => array(
'0' => 'Customer Address 1', // this is mandatory
'1' => 'Customer Address 2' // this is optional
),
'city' => 'New York',
'country_id' => 'US', // two letters country code
'region' => 'New York', // can be empty '' if no region
'region_id' => '43', // can be empty '' if no region_id
'postcode' => '10450',
'telephone' => '123-456-7890',
'fax' => '',
'save_in_address_book' => 1
);
$customerFactory = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();
/**
* check whether the email address is already registered or not
*/
$customer = $customerFactory->setWebsiteId($websiteId)->loadByEmail($email);
/**
* if email address already registered, return the error message
* else, create new customer account
*/
if ($customer->getId()) {
echo 'Customer with email '.$email.' is already registered.';
} else {
try {
$customer = $objectManager->get('\Magento\Customer\Model\CustomerFactory')->create();
$customer->setWebsiteId($websiteId);
$customer->setEmail($email);
$customer->setFirstname($firstName);
$customer->setLastname($lastName);
$customer->setPassword($password);
// save customer
$customer->save();
$customer->setConfirmation(null);
$customer->save();
$customAddress = $objectManager->get('\Magento\Customer\Model\AddressFactory')->create();
$customAddress->setData($address)
->setCustomerId($customer->getId())
->setIsDefaultBilling('1')
->setIsDefaultShipping('1')
->setSaveInAddressBook('1');
// save customer address
$customAddress->save();
//reindex customer grid index
$indexerFactory = $objectManager->get('Magento\Indexer\Model\IndexerFactory');
$indexerId = 'customer_grid';
$indexer = $indexerFactory->create();
$indexer->load($indexerId);
$indexer->reindexAll();
// Create customer session
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
$customerSession->setCustomerAsLoggedIn($customer);
echo 'Customer with email '.$email.' is successfully created.';
} catch (Exception $e) {
echo $e->getMessage();
}
}
OTHER TIPS
The customer probablu isn't visible in the admin customer grid because that get's cached. I also had that problem.
You can log in the customer like this:
public function loginNewCustomer($customer){
if (!$this->customerSession->isLoggedIn()) {
try {
$this->customerSession->setCustomerAsLoggedIn($customer);
} catch (\Exception $e) {
// Customer can't log in, this might be because the account needs to be confirmed.
}
}
}
If you don't have the customer object yet at that location you can get $customer like this:
$customer = $this->_customer->loadByEmail("test@m2s.com");
$this->customerSession->setCustomerAsLoggedIn($customer);
The correct way to do this using modern Magento 2 interfaces is as follows. Note I use the object manager directly, but best to use dependency injection. 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);
// Login the new customer
/** @var SessionFactory $customerSessionFactory */
$customerSessionFactory = $this->_bootstrap->getObjectManager()->get('Magento\Customer\Model\SessionFactory');
$session = $customerSessionFactory->create();
$session->setCustomerDataAsLoggedIn($customer);
// Send new account email
/** @var EmailNotification $emailNotification */
$emailNotification = $this->_bootstrap->getObjectManager()->get("\Magento\Customer\Model\EmailNotification");
$emailNotification->newAccount($customer);