Перенаправление с плагина Magento 2
Я пытаюсь перенаправить на пользовательский URL-адрес с помощью плагина функции Magento 2, но почему-то я не могу его перенаправить. Для этого я попробовал несколько вариантов, таких как
Magento2: перенаправление от наблюдателя
Magento2: Перенаправление С Помощью Плагина (С Ограничениями НА Веб-Сайт)
Но не смог добиться успеха в этом. Я могу это сделать, если добавляю exit();
после метода перенаправления, но это не очень хорошая практика чтобы написать exit();
. У кого-нибудь есть какой-нибудь намек на это?
Я использую плагин around
и до plugin
Я написал плагин для класса Magento\Customer\Model\AccountManagement
.
Спасибо
5 answers
Согласно нашей дискуссии, я делюсь идеей, которая может вам помочь.
- Сначала передайте переменную реестра из initiatePasswordReset, чтобы переменная реестра содержала нужный вам URL-адрес.
- Затем в
controller_action_postdispatch_customer_account_forgotPasswordPost
событие улавливает значение переменной реестра, эту страницу
Создайте плагин поверх initiatePasswordReset
вызова и используйте после, до, вокруг метода, в зависимости от вашего выбора.
Здесь я использую метод around.
<?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);
}
}
Теперь, controller_action_postdispatch_customer_account_forgotPasswordPost
событие,
Перенаправить этот 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;
}
}
Я не совсем уверен, чего вы здесь пытаетесь достичь, но если вы ограничите свою проблему перенаправлением на другой URL-адрес из плагина, я могу дать вам несколько идей.
Поскольку Magento\Customer\Api\AccountManagementInterface
не действует как контроллер, возможно, вам не следует пытаться перенаправлять с одного из методов реализации этого интерфейса.
только контроллеры должны обрабатывать запрос и отправлять ответ.
Метод initiatePasswordReset
вызывается из 2 действий контроллера Magento\Customer\Controller\Adminhtml\Index\ResetPassword::execute
и Magento\Customer\Controller\Account\ForgotPasswordPost::execute
.
Может быть, ты следует подключить эти методы с помощью after
или around
.
Оба описанных выше метода возвращают экземпляр \Magento\Backend\Model\View\Result\Redirect
, поэтому их возвращаемое значение довольно легко изменить с помощью плагина. (Я предлагаю after
, но вам может понадобиться around
, не уверен в ваших требованиях).
Плагин after может выглядеть так (но вы это уже знаете):
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;
}
Если у вас много пользовательской логики, во избежание дублирования содержимого вы можете переместить логику в пользовательский класс и использовать этот класс в качестве зависимость в обоих плагинах, которые вы создаете.
Ниже приведен рабочий пример из моего собственного кода. Для этого требуется всего 2 файла.
Создать di.xml файл
<?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>
Создайте файл плагина
<?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;
}
}
Введите 2 класса в конструктор, как показано ниже:
public function __construct(\Magento\Framework\UrlInterface $url, Magento\Framework\Controller\ResultFactory $resultFactory)
{
$this->resultFactory = $resultFactory;
$this->url = $url;
}
Код для перенаправления:
$result = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$result->setUrl($this->url->getUrl('path/to/controller'));
return $result;
Используйте приведенный ниже код и замените setUrl
на setPath
$result = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$result->setPath('path/to/controller'); //ex. 'customer/account/login'
return $result;