in the default onepage checkout, an existing customer can choose to login within the checkout process. this fires the usual observers. my module is observing the event sales_quote_merge_before to check if a persistent cart quote is being merged into the current quote. if so, the customer should be redirected to the /checkout/cart page.
this works fine for non-checkout pages. but setting the setBeforeAuthUrl
and/or setAfterAuthUrl
on the \Magento\Customer\Model\Session
object does not seem to work for logins within the checkout process.
here's my (simplified) observer that works for non-checkout logins, that I now need to make work with the checkout login as well:
namespace My\Module\Observer;
class SalesQuoteMergeBefore implements \Magento\Framework\Event\ObserverInterface
{
/**
* @var \Magento\Customer\Model\Session
*/
protected $_customerSession;
/**
* @var \Magento\Framework\View\Element\Context
*/
protected $_context;
/**
* SalesQuoteMergeBefore constructor.
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Framework\View\Element\Context $context
*/
public function __construct(
\Magento\Customer\Model\Session $customerSession,
\Magento\Framework\View\Element\Context $context
)
{
$this->_customerSession = $customerSession;
$this->_context = $context;
}
/**
* redirect to cart when quote was merged
*
* @see \Magento\Quote\Model\Quote::merge()
* @param \Magento\Framework\Event\Observer $observer
* @return $this
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
/** @var \Magento\Quote\Model\Quote $target */
$target = $observer->getData('source');
if ($target && $target->hasItems())
{
$url = $this->_context->getUrlBuilder()->getUrl('checkout/cart');
// setting just the after_auth_url does not seem to be enough...
$this->_customerSession->setBeforeAuthUrl($url);
$this->_customerSession->setAfterAuthUrl($url);
}
return $this;
}
}
my understanding is that I somehow need to signal the javascript app a redirect should happen, but I failed to find any way to do this.
Best Answer
the
\Magento\Customer\Controller\Ajax\Login::execute()
function checks for alogin_redirect
cookie. if there's such a cookie, its value will be returned as the json attributeredirectUrl
, which in turnMagento_Customer/js/action/login.js
uses as a redirect target after the successful login.so faking the cookie is a simple way to control where the user should be redirected when logged in through the checkout ajax login. the relevant updated part of the observer in the question:
one could also get the instance of
\Magento\Customer\Model\Account\Redirect
and usesetRedirectCookie($url)
, but I did not want to actually set a cookie in the response as the login at this point was already completed successfully.