Magento2 redirection from Observer

Magento2 redirection from Observer

Magento2 redirection from Observer needs serval times.In Some events, you need to forcefully redirect to some pages basic your business logic.

At magento 1.x,we can do using Mage::app()->getResponse()->setRedirect(‘YourRedirectUrl’)->sendResponse();

 

Something is required forMagent0 2.X version.This version uses modern technologies   Namespace, interface, Factory class etc.So there not easy to do a redirection from an Observer.

Most case,  developer need to implement forceful redirection  to Observer as per their client requirement

===========================================

 

I have found a solution by myself by doing a research

If you want to do that then you should below inject two classes.

  • First, \Magento\Framework\App\ResponseFactory which responsible for redirection,
  • Another class which\Magento\Framework\UrlInterface will make an url for that redirection.(This can optional).
  • Then You should create  a response Object  $this->_response->create()  from Magento\Framework\App\ResponseFactory.
  • Then using method setRedirect() and sendResponse(),you can redirect url.Where setRedirect() set url for redirection and sendReponse() send response this url.

 

 

Observer

<?php
namespace [Vendorname]\[ModuleName]\Observer;
use Magento\Framework\Event\ObserverInterface;
/**
 * @category   Devamitbera
 * @author     Amit Bera <[email protected]>
 * @website    http://www.amitbera.com
* @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class [MyObserverClass]  implements ObserverInterface
{

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     * @var \Magento\Framework\UrlInterface
     */
    protected $_urlInterFace;

    /**
     * @var \Magento\Framework\App\ResponseFactory
     */
    protected $_response;
    /**
     * 
     * @param \Magento\Framework\App\ResponseFactory $_response
     * @param \Magento\Framework\UrlInterface $_urlInterFace
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        /* Inject The Class */
        \Magento\Framework\App\ResponseFactory $_response,
        \Magento\Framework\UrlInterface $_urlInterFace,
        \Psr\Log\LoggerInterface $logger    
    ) {
        
        $this->_response = $_response;
        $this->_urlInterFace = $_urlInterFace;
        $this->logger = $logger;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
       
       $this->logger->debug(__METHOD__); 
       //$url = $this->_urlInterFace->getUrl($routePath, $routeParams);
        /* Suppose want to redirect to Customer login 
         * then You know Customer login pager er route path is customer/account/login
         * where **customer is route in name
         *  **account is the path of controler 
         * login is Action name name 
         */
        $url = $this->_urlInterFace->getUrl($routePath, $routeParams);
        $this->logger->debug('Url->'.$url );
       /* 
        * force  redirect 
        * 
        */
        $this->_response->create()
                ->setRedirect($url)
                ->sendResponse();
        exit(0);
        return $this;
    }

    
}

 

Case1: For Controllers events

  • ‘controller_action_predispatch’
  • ‘controller_action_predispatch_’ . $request->getFullActionName() . like controller_action_predispatch_customer_account_logout
  •  ‘controller_action_predispatch_’ . $request->getRouteName().  like controller_action_predispatch_customer
  • ‘controller_action_postdispatch
  • ‘controller_action_postdispatch_’ . $request->getFullActionName()  . like controller_action_postdispatch_customer_account_logout
  •  ‘controller_action_postdispatch_’ . $request->getRouteName().
  •   like controller_action_postdispatch_customer

 

If  want redirection from Observer for an event which has controller_action object as it  events parameters

Then time, my suggestion avoid using \Magento\Framework\App\ResponseFactory  because of

If you have controller_action object and by injecting \Magento\Framework\App\ActionFlag   then  using below code you redirect to your desired URL

 

$action = $observer->getEvent()->getControllerAction();
$this->actionFlag->set('', \Magento\Framework\App\ActionInterface::FLAG_NO_DISPATCH, true);
$action->getResponse()->setRedirect($redirectUrl);

 

Example:

Here i am written an example of that redirection.

I have used event,checkout_cart_add_product_complete I was trying to forcefully redirect to Customer login page

Here the observer code:

<?php
namespace Devamitbera\Common\Observer;
use Magento\Framework\Event\ObserverInterface;
/**
 * @category   Devamitbera
 * @package    Devamitbera_Common
 * @author     Amit Bera <[email protected]>
 * @website    http://www.amitbera.com
* @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class ForceRedirection  implements ObserverInterface
{

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;

    /**
     * @var \Magento\Framework\UrlInterface
     */
    protected $_urlInterFace;

    /**
     * @var \Magento\Framework\App\ResponseFactory
     */
    protected $_response;
    /**
     * 
     * @param \Magento\Framework\App\ResponseFactory $_response
     * @param \Magento\Framework\UrlInterface $_urlInterFace
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
        \Magento\Framework\App\ResponseFactory $_response,
        \Magento\Framework\UrlInterface $_urlInterFace,
        \Psr\Log\LoggerInterface $logger    
    ) {
        
        $this->_response = $_response;
        $this->_urlInterFace = $_urlInterFace;
        $this->logger = $logger;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
       
       $this->logger->debug(__METHOD__); 
       //$url = $this->_urlInterFace->getUrl($routePath, $routeParams);
        /* Suppose want to redirect to Customer login 
         * then You know Customer login pager er route path is customer/account/login
         * where **customer is route in name
         *  **account is the path of controler 
         * login is Action name name 
         */
        $url = $this->_urlInterFace->getUrl('customer/account/login');
        $this->logger->debug('Url->'.$url );
       /* 
        * force  redirect 
        * 
        */
        $this->_response->create()
                ->setRedirect($url)
                ->sendResponse();
        exit(0);
        return $this;
    }

    
}

Controller event example:

For this case ,I have used event controller_action_postdispatch_newsletter_subscriber_newI was trying to forcefully redirect to Customer login page

<?php
namespace Devamitbera\Common\Observer;
use Magento\Framework\Event\ObserverInterface;
/**
 * @category   Devamitbera
 * @package    Devamitbera_Common
 * @author     Amit Bera <[email protected]>
 * @website    http://www.amitbera.com
* @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class NewsletterForceRedirection  implements ObserverInterface
{
 
    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $logger;
 
    /**
     * @var \Magento\Framework\UrlInterface
     */
    protected $_urlInterFace;
 
    /**
     * @var \Magento\Framework\App\ActionFlag
     */
    protected $actionFlag;
    /**
     * 
     * @param \Magento\Framework\UrlInterface $_urlInterFace
     * @param \Psr\Log\LoggerInterface $logger
     */
    public function __construct(
         \Magento\Framework\App\ActionFlag $actionFlag,
        \Magento\Framework\UrlInterface $_urlInterFace,
        \Psr\Log\LoggerInterface $logger    
    ) {
        
        $this->_response = $_response;
        $this->_urlInterFace = $_urlInterFace;
        $this->logger = $logger;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
       
       $this->logger->debug(__METHOD__); 
       //$url = $this->_urlInterFace->getUrl($routePath, $routeParams);
        /* Suppose want to redirect to Customer login 
         * then You know Customer login pager er route path is customer/account/login
         * where **customer is route in name
         *  **account is the path of controler 
         * login is Action name name 
         */
        $url = $this->_urlInterFace->getUrl('customer/account/login');
        $this->logger->debug('Url->'.$url );
       /* 
        * force  redirect 
        * 
        */
  
	$action = $observer->getEvent()->getControllerAction();
	$this->actionFlag->set('', \Magento\Framework\App\ActionInterface::FLAG_NO_DISPATCH, true);
	$action->getResponse()->setRedirect($url);
	return $this;
    }
 
    
}