Question

I need to get the customer e-mail address in the checkout. I need it after the user went to Step 2 of the checkout (After he entered Address/before he can select his payment option).

I tried:

$quote->getCustomerEmail()
$this->session->getQuote()->getCustomerEmail();
$quote->getBillingAddress()->getEmail();

And many more.

The thing is: The e-mail is nowhere, I used XDebugg and looked deeply in Session, Quote and many more data. But the e-mail address is available after the user clicks on "place order", this is way to late.

I found unsolved questions with the same problem:

https://community.magento.com/t5/Magento-2-x-Programming/get-guest-quote-email/td-p/102751

Magento2 : How to get guest email address after shipping address and before placeorder?

Probably I have to change Magento checkout behavior, so that it also sends the e-mail together with the shipping address to the controller, because it only sends the address without the e-mail.

BUT, I've no idea, how I can do this.

Edit: I've tried the answer (Method2) of Rakesh Jakhar, but it seems I do something wrong.

I created the File /app/code/Myself/Test/Model/Customer/AccountManagement.php:

<?php

namespace Myself\Test\Model\Customer;

use /* same as original file */

/**
 * Handle various customer account actions
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @SuppressWarnings(PHPMD.TooManyFields)
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
 */
class AccountManagement extends \Magento\Customer\Model\AccountManagement
{
    /**
     * @var CustomerRepositoryInterface
     */
    private $customerRepository;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    private $storeManager;

    /**
     * @inheritdoc
     */
    public function isEmailAvailable($customerEmail, $websiteId = null)
    {
        $objectManager   =  \Magento\Framework\App\ObjectManager::getInstance();
        $checkoutSession = $objectManager->get('\Magento\Checkout\Model\Session');
        $checkoutSession->setGuestCustomerEmail($customerEmail);

        try {
            if ($websiteId === null) {
                $websiteId = $this->storeManager->getStore()->getWebsiteId();
            }
            $this->customerRepository->get($customerEmail, $websiteId);
            return false;
        } catch (NoSuchEntityException $e) {
            return true;
        }
    }
}

I added to my di.xml:

<preference for="Magento\Customer\Model\AccountManagement" type="Myself\Test\Model\Customer\AccountManagement" />

The class seems to get overridden, because in the checkout it now says "You already have an account with us. Sign in or continue as guest.". So I think the method or class is broken now.

Edit2:

So I tried Rakesh Jakhar method 1. But I did it wrong. Where did I the mistake?

I copied /vendor/magento/module-checkout/view/frontend/web/js/view/form/element/email.js to /app/code/Myself/Test/web/js/view/form/element/email.js.

I added the cookie:

/**
 * Callback on changing email property
 */
emailHasChanged: function () {
    var self = this;

    clearTimeout(this.emailCheckTimeout);

    if (self.validateEmail()) {
        quote.guestEmail = self.email();
        checkoutData.setValidatedEmailValue(self.email());
        $.cookie("checkoutemail", self.email());
    }
    this.emailCheckTimeout = setTimeout(function () {
        if (self.validateEmail()) {
            self.checkEmailAvailability();
        } else {
            self.isPasswordVisible(false);
        }
    }, self.checkDelay);

    checkoutData.setInputFieldEmailValue(self.email());
},

Then I probably did the mistake. I created /app/code/Myself/Test/view/frontend/requirejs-config.js with the following content:

var config = {
    map: {
        '*':
            {
                'Magento_Checkout/js/view/form/element/email.js':'Myself_Test/js/view/form/element/email.js'
            }
    }
};

The override don't work, the original email.js file is loaded in the checkout. (I executed the setup:upgrade command only, because I'm in developer mode.)

Was it helpful?

Solution

Method 1.

When a custom enter email the following file function are called to validate the email

Magento_Checkout/web/js/view/form/element/email.js

Look the function

emailHasChanged: function () {
        var self = this;

        clearTimeout(this.emailCheckTimeout);

        if (self.validateEmail()) {
            quote.guestEmail = self.email();
            checkoutData.setValidatedEmailValue(self.email());
        }
        this.emailCheckTimeout = setTimeout(function () {
            if (self.validateEmail()) {     
               self.checkEmailAvailability();
            } else {
                self.isPasswordVisible(false);
            }
        }, self.checkDelay);

        checkoutData.setInputFieldEmailValue(self.email());
    },

Inside this function quote.guestEmail gives you the email, you can fire an ajax and save that in seesion and use.

Another option saves the email in the browser cookie

$.cookie("checkoutemail", self.email());

and retrieve the cookie value.

Method 2.

Override the following file:-

Magento\Customer\Model\AccountManagement.php

Replace the following function:-

public function isEmailAvailable($customerEmail, $websiteId = null)
{
    $objectManager   =  \Magento\Framework\App\ObjectManager::getInstance();
    $checkoutSession = $objectManager->get('\Magento\Checkout\Model\Session');
    $checkoutSession->setGuestCustomerEmail($customerEmail);
    try {
        if ($websiteId === null) {
            $websiteId = $this->storeManager->getStore()->getWebsiteId();
        }

        $this->customerRepository->get($customerEmail, $websiteId);
        return false;
    } catch (NoSuchEntityException $e) {
        return true;
    }
}

Use the following to retrieve the email:-

$objectManager   =  \Magento\Framework\App\ObjectManager::getInstance();
$checkoutSession = $objectManager->get('\Magento\Checkout\Model\Session');
$guestEmail = $checkoutSession->getGuestCustomerEmail();

Follow this to override model

https://magenticians.com/override-model-magento-2/

OTHER TIPS

You have override email.js in wrong way. It should be like this :

var config = { map: { '*': { 'Magento_Checkout/js/view/form/element/email':'Myself_Test/js/view/form/element/email' } } };

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top