From 8d51d9e527742ec2c8836ad0d30c5d152d714538 Mon Sep 17 00:00:00 2001
From: Serhiy Shkolyarenko <sshkolyarenko@magento.com>
Date: Fri, 26 Feb 2016 18:15:28 +0200
Subject: [PATCH] MAGETWO-49692: Customer is not redirected to checkout on
 login if guest is disabled

added URL processing to login and registration controllers
---
 .../Checkout/view/frontend/web/js/sidebar.js  |  2 +
 .../Controller/Account/CreatePost.php         |  6 ++
 .../Customer/Controller/Account/LoginPost.php |  8 +++
 .../Customer/Controller/Ajax/Login.php        | 67 +++++++++++++++++++
 .../Customer/Model/Account/Redirect.php       | 66 ++++++++++++++++++
 .../view/frontend/web/js/action/login.js      |  2 +
 6 files changed, 151 insertions(+)

diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
index ee77efd1888..afb34aa7826 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -54,6 +54,8 @@ define([
                     customer = customerData.get('customer');
 
                 if (!customer().firstname && !cart().isGuestCheckoutAllowed) {
+                    // set URL for redirect on successful login/registration. It's postprocessed on backend.
+                    $.cookie('login_redirect', this.options.url.checkout);
                     if (this.options.url.isRedirectRequired) {
                         location.href = this.options.url.loginUrl;
                     } else {
diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php
index b332b694256..1346ace778b 100644
--- a/app/code/Magento/Customer/Controller/Account/CreatePost.php
+++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php
@@ -258,6 +258,12 @@ class CreatePost extends \Magento\Customer\Controller\AbstractAccount
             } else {
                 $this->session->setCustomerDataAsLoggedIn($customer);
                 $this->messageManager->addSuccess($this->getSuccessMessage());
+                $requestedRedirect = $this->accountRedirect->getRedirectCookie();
+                if (!$this->scopeConfig->getValue('customer/startup/redirect_dashboard') && $requestedRedirect) {
+                    $resultRedirect->setUrl($this->_redirect->success($requestedRedirect));
+                    $this->accountRedirect->clearRedirectCookie();
+                    return $resultRedirect;
+                }
                 $resultRedirect = $this->accountRedirect->getRedirect();
             }
             return $resultRedirect;
diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php
index a65e81ab876..a5ae36310fa 100644
--- a/app/code/Magento/Customer/Controller/Account/LoginPost.php
+++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php
@@ -117,6 +117,14 @@ class LoginPost extends \Magento\Customer\Controller\AbstractAccount
                     $customer = $this->customerAccountManagement->authenticate($login['username'], $login['password']);
                     $this->session->setCustomerDataAsLoggedIn($customer);
                     $this->session->regenerateId();
+                    $redirectUrl = $this->accountRedirect->getRedirectCookie();
+                    if (!$this->getScopeConfig()->getValue('customer/startup/redirect_dashboard') && $redirectUrl) {
+                        $this->accountRedirect->clearRedirectCookie();
+                        $resultRedirect = $this->resultRedirectFactory->create();
+                        // URL is checked to be internal in $this->_redirect->success()
+                        $resultRedirect->setUrl($this->_redirect->success($redirectUrl));
+                        return $resultRedirect;
+                    }
                 } catch (EmailNotConfirmedException $e) {
                     $value = $this->customerUrl->getEmailConfirmationUrl($login['username']);
                     $message = __(
diff --git a/app/code/Magento/Customer/Controller/Ajax/Login.php b/app/code/Magento/Customer/Controller/Ajax/Login.php
index 4258ebf1ef0..0c46ba76e52 100644
--- a/app/code/Magento/Customer/Controller/Ajax/Login.php
+++ b/app/code/Magento/Customer/Controller/Ajax/Login.php
@@ -9,6 +9,9 @@ namespace Magento\Customer\Controller\Ajax;
 use Magento\Customer\Api\AccountManagementInterface;
 use Magento\Framework\Exception\EmailNotConfirmedException;
 use Magento\Framework\Exception\InvalidEmailOrPasswordException;
+use Magento\Framework\App\ObjectManager;
+use Magento\Customer\Model\Account\Redirect as AccountRedirect;
+use Magento\Framework\App\Config\ScopeConfigInterface;
 
 /**
  * Login controller
@@ -43,6 +46,16 @@ class Login extends \Magento\Framework\App\Action\Action
      */
     protected $resultRawFactory;
 
+    /**
+     * @var AccountRedirect
+     */
+    protected $accountRedirect;
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
     /**
      * Initialize Login controller
      *
@@ -69,6 +82,55 @@ class Login extends \Magento\Framework\App\Action\Action
         $this->resultRawFactory = $resultRawFactory;
     }
 
+    /**
+     * Get account redirect.
+     * For release backward compatibility.
+     *
+     * @deprecated
+     * @return AccountRedirect
+     */
+    protected function getAccountRedirect()
+    {
+        if (!is_object($this->accountRedirect)) {
+            $this->accountRedirect = ObjectManager::getInstance()->get(AccountRedirect::class);
+        }
+        return $this->accountRedirect;
+    }
+
+    /**
+     * Account redirect setter for unit tests.
+     *
+     * @deprecated
+     * @param AccountRedirect $value
+     * @return void
+     */
+    public function setAccountRedirect($value)
+    {
+        $this->accountRedirect = $value;
+    }
+
+    /**
+     * @deprecated
+     * @return ScopeConfigInterface
+     */
+    protected function getScopeConfig()
+    {
+        if (!is_object($this->scopeConfig)) {
+            $this->scopeConfig = ObjectManager::getInstance()->get(ScopeConfigInterface::class);
+        }
+        return $this->scopeConfig;
+    }
+
+    /**
+     * @deprecated
+     * @param ScopeConfigInterface $value
+     * @return void
+     */
+    public function setScopeConfig($value)
+    {
+        $this->scopeConfig = $value;
+    }
+
     /**
      * Login registered users and initiate a session.
      *
@@ -103,6 +165,11 @@ class Login extends \Magento\Framework\App\Action\Action
             );
             $this->customerSession->setCustomerDataAsLoggedIn($customer);
             $this->customerSession->regenerateId();
+            $redirectRoute = $this->getAccountRedirect()->getRedirectCookie();
+            if (!$this->getScopeConfig()->getValue('customer/startup/redirect_dashboard') && $redirectRoute) {
+                $response['redirectUrl'] = $this->_redirect->success($redirectRoute);
+                $this->getAccountRedirect()->clearRedirectCookie();
+            }
         } catch (EmailNotConfirmedException $e) {
             $response = [
                 'errors' => true,
diff --git a/app/code/Magento/Customer/Model/Account/Redirect.php b/app/code/Magento/Customer/Model/Account/Redirect.php
index ac134182e2a..d3a74c51542 100644
--- a/app/code/Magento/Customer/Model/Account/Redirect.php
+++ b/app/code/Magento/Customer/Model/Account/Redirect.php
@@ -16,12 +16,17 @@ use Magento\Framework\App\Config\ScopeConfigInterface;
 use Magento\Framework\Controller\Result\Redirect as ResultRedirect;
 use Magento\Framework\Controller\Result\Forward as ResultForward;
 use Magento\Framework\Url\DecoderInterface;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Stdlib\CookieManagerInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Redirect
 {
+    /** URL to redirect user on successful login or registration */
+    CONST LOGIN_REDIRECT_URL = 'login_redirect';
+
     /**
      * @var RequestInterface
      */
@@ -57,6 +62,11 @@ class Redirect
      */
     protected $resultFactory;
 
+    /**
+     * @var CookieManagerInterface
+     */
+    protected $cookieManager;
+
     /**
      * @param RequestInterface $request
      * @param Session $customerSession
@@ -205,4 +215,60 @@ class Redirect
     {
         $this->session->setBeforeAuthUrl($url);
     }
+
+    /**
+     * Get Cookie manager. For release backward compatibility.
+     *
+     * @deprecated
+     * @return CookieManagerInterface
+     */
+    protected function getCookieManager()
+    {
+        if (!is_object($this->cookieManager)) {
+            $this->cookieManager = ObjectManager::getInstance()->get(CookieManagerInterface::class);
+        }
+        return $this->cookieManager;
+    }
+
+    /**
+     * Set cookie manager. For unit tests.
+     *
+     * @deprecated
+     * @param $value
+     */
+    public function setCookieManager($value)
+    {
+        $this->cookieManager = $value;
+    }
+
+    /**
+     * Get redirect route from cookie for case of successful login/registration
+     *
+     * @return null|string
+     */
+    public function getRedirectCookie()
+    {
+        return $this->getCookieManager()->getCookie(self::LOGIN_REDIRECT_URL, null);
+    }
+
+    /**
+     * Save redirect route to cookie for case of successful login/registration
+     *
+     * @param string $route
+     * @return void
+     */
+    public function setRedirectCookie($route)
+    {
+        $this->getCookieManager()->setPublicCookie(self::LOGIN_REDIRECT_URL, $route);
+    }
+
+    /**
+     * Clear cookie with requested route
+     *
+     * @return void
+     */
+    public function clearRedirectCookie()
+    {
+        $this->getCookieManager()->deleteCookie(self::LOGIN_REDIRECT_URL);
+    }
 }
diff --git a/app/code/Magento/Customer/view/frontend/web/js/action/login.js b/app/code/Magento/Customer/view/frontend/web/js/action/login.js
index 2cbc02ba074..67bc734bcb7 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/action/login.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/action/login.js
@@ -32,6 +32,8 @@ define(
                         customerData.invalidate(['customer']);
                         if (redirectUrl) {
                             window.location.href = redirectUrl;
+                        } else if (response.redirectUrl) {
+                            window.location.href = response.redirectUrl;
                         } else {
                             location.reload();
                         }
-- 
GitLab