3

I am creating a module for redirect login/register success to checkout if customer has some items on quote but that's not working.

If I stop the event with that die; on Observer/Redirect.php above that redirect works, but I need continue for merge quotes.

events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
   <event name="customer_login">
       <observer name="lima_customer_login_redirect" instance="Lima\CustomerLoginRedirect\Observer\Redirect" />
   </event>
</config>

/Observer/Redirect.php

<?php
namespace Lima\CustomerLoginRedirect\Observer;

use \Magento\Framework\Event\Observer;
use \Magento\Framework\Event\ObserverInterface;
use \Magento\Quote\Model\QuoteFactory;
use \Magento\Framework\Controller\ResultFactory;
use \Magento\Framework\View\Element\Context;

class Redirect implements ObserverInterface
{
  protected $_objectManager;
  protected $_quote;
  protected $_responseFactory;
  protected $_url;
  protected $_scopeConfig;

  public function __construct(
    Context $context,
    QuoteFactory $quoteFactory,
    \Magento\Framework\App\ResponseFactory $responseFactory,
    \Magento\Framework\UrlInterface $url
  ) {
    $this->_quote= $quoteFactory;
    $this->_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $this->_responseFactory = $responseFactory;
    $this->_url = $url;
    $this->_scopeConfig = $context->getScopeConfig();
  }

  public function execute(Observer $observer)
  {
    $module_status = $this->_scopeConfig->getValue('customer_login_redirect/redirect/status', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
    if($module_status){
      $cart = $this->_objectManager->get('\Magento\Checkout\Model\Cart');
      $quote = $cart->getQuote();
      $totalItems = count($quote->getAllItems());

      if($totalItems > 0){
        $redirectionUrl = $this->_url->getUrl('onepagecheckout');
      }else{
        $redirectionUrl = $this->_url->getUrl('/');
      }
      $this->_responseFactory->create()->setRedirect($redirectionUrl)->sendResponse();
      // die;
      return $this;
    }
  }

}

Thanks.

1

1 Answer 1

4

Instead of using customer_login event, suggesting to you implement Plugin on class Magento\Checkout\Model\Session .

Implement after plugin method on method loadCustomerQuote, From where you have to set the setBeforeAuthUrl for the customer session.

As per as, Magento if you set your desired URL to setBeforeAuthUrl, then after login Magento automatically redirect method that desired URL.

Most of the important point, Magento merge customer existing quote object with the current quote which is created before login quote login using loadCustomerQuote using event customer_login.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="customer_login">
        <observer name="loadCustomerQuote" instance="Magento\Checkout\Observer\LoadCustomerQuoteObserver" />
    </event>
    <event name="customer_logout">
        <observer name="unsetAll" instance="Magento\Checkout\Observer\UnsetAllObserver" />
    </event>
</config>

So, now lets create a plugin.

First define plugin via di.xml at `app/code/{Vendor}/{Modulename}/etc/

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\Session">
        <plugin name="set_redirection_url_if_have quote" type="{Vendor}\{Modulename}\Plugin\LoginRedirection" />
    </type>
</config>

Plugin class LoginRedirection.php at app/code{Vendor}\{Modulename}\Plugin\LoginRedirection

<?php
namespace {Vendor}\{Modulename}\Plugin;
class LoginRedirection
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;
    /**
     * @var \Magento\Customer\Model\Session
     */
    protected $customerSession;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Customer\Model\Session $customerSession
    )
    {
        $this->storeManager = $storeManager;
        $this->customerSession = $customerSession;
    }
    public function afterLoadCustomerQuote(
        \Magento\Checkout\Model\Session $subject,
        $result
    )
    {
        $quote = $subject->getQuote();
        if(count($quote->getAllItems())>0){
            $this->customerSession
                ->setBeforeAuthUrl($this->storeManager->getStore()->getUrl('onepagecheckout/index/index'));
        }

    }

Also, this module should have:

  1. app/code/{Vendor}/{Modulename}/etc/module.xml.
  2. app/code/{Vendor}/{Modulename}/composer.json
  3. . app/code/{Vendor}/{Modulename}/registration.json.

Note that:

Donot forgot to '

  • do Cache flush php bin/magento cache:flush.
  • Di compile php bin/magento di:compile.

Aftre the changes .

5
  • As I know, the composer.json used for the module which is 'under' vendor folder. Commented May 18, 2018 at 6:35
  • No,it is always need for all module
    – Amit Bera
    Commented May 18, 2018 at 6:39
  • What is the purpose of composer.json when we put it under app folder? Commented May 18, 2018 at 6:57
  • Khoa TruongDinh, i don't have enough knowledge. But it is required and a required file.
    – Amit Bera
    Commented May 18, 2018 at 15:34
  • Work like a charm, thank you. Ps, my module has all scrtucture unless composer.json.
    – Plim
    Commented May 21, 2018 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.