Redirect from plugin Magento 2
I'm not sure exactly what you are trying to achieve here, but if you limit your problem to redirecting to a different url from a plugin, I can give you some ideas.
Since the Magento\Customer\Api\AccountManagementInterface
does not act as a controller maybe you should not try to redirect from one of the methods from the implementation of this interface.
only controllers should handle the request and send the response.
The method initiatePasswordReset
is called from 2 controller actions Magento\Customer\Controller\Adminhtml\Index\ResetPassword::execute
and Magento\Customer\Controller\Account\ForgotPasswordPost::execute
.
Maybe you should pluginize these methods using after
or around
.
Both methods above return an instance of \Magento\Backend\Model\View\Result\Redirect
so it is pretty easy to change the return value of them via a plugin. (I suggest after
, but you may need around
, not sure of your requirements).
an after plugin could look like this (but you already know that):
public function afterExecute(
\Magento\Customer\Controller\Account\ResetPassword $subject, $redirect,
\Magento\Backend\Model\View\Result\Redirect $redirect
) {
//custom logic in here;
if (your condition) {
$redirect->setPath('custom/action/page');
}
return $redirect;
}
If you have a lot of custom logic, in order to avoid content duplication you can move the logic to a custom class and use that class as a dependency in both plugins you are creating.
Below is a working example from my own code. It only requires 2 files.
Create di.xml file
<?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\Backend\App\AbstractAction">
<plugin name="Vendorname\Modulename\Plugin\Backend\App\AbstractAction" type="Vendorname\Modulename\Plugin\Backend\App\AbstractAction" />
</type>
</config>
Create the plugin file
<?php
namespace Vendorname\Modulename\Plugin\Backend\App;
class AbstractAction
{
/**
* @var \Magento\Framework\Controller\ResultFactory
*/
private $resultFactory;
/**
* @var \Magento\Framework\App\Response\RedirectInterface
*/
private $redirect;
/**
* AbstractAction constructor.
*
* @param \Magento\Framework\Controller\ResultFactory $resultFactory
* @param \Magento\Framework\App\Response\RedirectInterface $redirect
*/
public function __construct(
\Magento\Framework\Controller\ResultFactory $resultFactory,
\Magento\Framework\App\Response\RedirectInterface $redirect
) {
$this->resultFactory = $resultFactory;
$this->redirect = $redirect;
}
/**
* @param \Magento\Backend\App\AbstractAction $subject
* @param \Closure $procede
* @param \Magento\Framework\App\RequestInterface $request
*
* @return \Magento\Framework\App\RequestInterface|\Magento\Framework\Controller\ResultInterface|\Magento\Framework\Controller\Result\Json
*/
public function aroundDispatch($subject, $procede, $request)
{
if ($yourCondition) {
$resultRedirect = $this->resultFactory->create(
\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT
);
// if you want to redirect to the previous page
$result = $resultRedirect->setUrl($this->redirect->getRefererUrl());
// if you want to redirect to an external url
$result = $resultRedirect->setUrl('https://www.google.com');
} else {
$result = $procede($request);
}
return $result;
}
}
As per as, our discussion, I am sharing an idea that might help you.
- First, pass a registry variable from initiatePasswordReset that registry variable will contain your desired URL.
- Then at
controller_action_postdispatch_customer_account_forgotPasswordPost
event catch that registry variable value, that page
Create Plugin over initiatePasswordReset
call and use after, before ,around method depend on your choose.
Here, i am using around method.
<?php
/**
* Created by Amit Bera.
* User: Amit Kumar Bera
* Email: [email protected]
* Date: 19-05-2018
* Time: 17:03
*/
namespace StackExchange\Works\Plugin;
use Magento\Framework\Registry;
class InitiatePasswordResetPlugin
{
protected $registry;
public function __construct(
Registry $registry
)
{
$this->registry = $registry;
}
public function aroundInitiatePasswordReset(
\Magento\Checkout\Model\Session $subject,
\Closure $proceed,
$email,
$template,
$websiteId
)
{
// Do business logic here
if($this->registry->registry('my_custom_redirect')){
$this->registry->unregister('my_custom_redirect');
}
$this->registry->register('my_custom_redirect','{YourUrl}');
return $proceed($email, $template, $websiteId);
}
}
Now, controller_action_postdispatch_customer_account_forgotPasswordPost
event,
redirect that URL my_custom_redirect
.
<?php
namespace StackExchange\Works\Observer\Frontend;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Registry;
class ControllerActionPostdispatchForgotPasswordPost implements ObserverInterface
{
/**
* @var \Magento\Framework\App\ActionFlag
*/
protected $actionFlag;
public function __construct(
\Magento\Framework\App\ActionFlag $actionFlag,
Registry $registry
) {
$this->registry = $registry;
$this->actionFlag = $actionFlag;
}
public function execute(Observer $observer)
{
$action = $observer->getEvent()->getControllerAction();
if($this->registry->registry('my_custom_redirect')){
$this->actionFlag->set('', \Magento\Framework\App\ActionInterface::FLAG_NO_DISPATCH, true);
$action->getResponse()->setRedirect($this->registry->registry('my_custom_redirect'));
return $this;
}
return $this;
}
}