Magento2:オブザーバーからのリダイレクト


9

magento 1.xバージョンのオブザーバーからリダイレクトする方法はすでに知っています。

しかし、magento 2の場合、観測者から強制的にリダイレクトする方法はわかりません。

私はグーグルをやったが、答えは得られない。


これに対する解決策を見つけましたか?
BartZalas

回答:


20

うん、研究して自分で解決策を見つけ

これを行う場合__construct()your class observer、の関数で、2つのクラスを注入する必要があります

  • まず、リダイレクトを担当し\Magento\Framework\App\ResponseFactory
  • \Magento\Framework\UrlInterfaceそのリダイレクトのURLを作成する別のクラス。
  • 次に、のオブジェクトを作成し、希望のURLへのリダイレクトをResponseFactory 使用 setRedirect($YourUrl)->sendResponse();します。

観察者

<?php
namespace [Vendor]\[modulename]\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class [YourClass] implements ObserverInterface
{
    /**
     * @var \Magento\Framework\App\ResponseFactory
     */
    private $responseFactory;

    /**
     * @var \Magento\Framework\UrlInterface
     */
    private $url;

    public function __construct(
        ......
        \Magento\Framework\App\ResponseFactory $responseFactory,
        \Magento\Framework\UrlInterface $url,
        ......
    ) {
        $this->responseFactory = $responseFactory;
        $this->url = $url;
    }

    public function execute(Observer $observer)
    {
        $redirectionUrl = $this->url->getUrl('[ModuleName]/[ModuleName]/[[Action]');
        $this->responseFactory->create()->setRedirect($redirectionUrl)->sendResponse();

        return $this;
    }
}

例:

ここで私はそのリダイレクトの例を書いています。

基本的にsales_quote_collect_totals_after、私は強制的に私たちに連絡するようリダイレクトすることを試みました

ここでオブザーバーコード:

<?php
namespace Devamit\Mgoto\Observer;
use \Magento\Framework\Event\Observer;
use \Magento\Framework\Event\ObserverInterface;

class Challo implements ObserverInterface {
    protected $_responseFactory;
    protected $_url;

    public function __construct(

        \Magento\Framework\App\ResponseFactory $responseFactory,
        \Magento\Framework\UrlInterface $url
    ) {
        $this->_responseFactory = $responseFactory;
        $this->_url = $url;
    }

    public function execute(Observer $observer) {
        $event = $observer->getEvent();

            $myfile = fopen("var/log/debug.log", "a+") or die("Unable to open file!");
          fwrite($myfile, 'Amitber',true);
          fclose($myfile);
      // $this->_responseFactory->create()->setRedirect('www.google.com')->sendResponse();
           $customerBeforeAuthUrl = $this->_url->getUrl('contact/index/index');
          $this->_responseFactory->create()->setRedirect($customerBeforeAuthUrl)->sendResponse();
      return $this;
    }
}

3
あなたは早朝4時に働いていますか?信じられないほどです。あなたから学ぶことはたくさんあります。
Magentoの赤ちゃん

こんにちは@amit、私は 'sales_order_place_before'イベントを使用しており、注文はajaxを使用して行われます。上記のコードを使用すると、リダイレクトは行われませんが、応答がレンダリングされます。それは欲しくない。ajaxを使用してフォームを保存するときにページにリダイレクトする方法を提案していただけますか。ありがとう
anujeet

2
exit();は使用しないでください。Magento EcgM2コーディング標準が「出口言語構造の使用は推奨されない」というエラーを表示するためです。
Patel王子

2
@AmitBera exitを呼び出さない場合は、\Magento\Framework\App\Response\Http代わりにコンストラクタ引数として使用する必要があります。ファクトリクラスを使用する場合は機能しません。
Milan Simek、

3
事前ディスパッチイベントを使用している場合は、コンストラクターに\ Magento \ Framework \ App \ ActionFlagを注入する必要があり、オブザーバー関数内で$ this-> _ actionFlag-> set( ''、\ Magento \ Framework \ App \ Action \を使用しますAction :: FLAG_NO_DISPATCH、true); それ以降のイベントの処理を停止するようにmagentoに指示し、redirectInterfaceを使用してユーザーをどこにでもリダイレクトできます。
Zeeshan Khuwaja

11

\Magento\Framework\App\ActionFlag $actionFlagandを注入することは、$this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);Magentoが以降のイベントの処理を停止し、特別にpredispatchイベントを使用する場合にオブザーバーからリダイレクトするように強制する方法です。

これがサンプルコードです

public function execute(\Magento\Framework\Event\Observer $observer)
{

    /** @var \Magento\Customer\Controller\Account\LoginPost\Interceptor $controller_action */
    $controller_action = $observer->getData( 'controller_action' );
    $parameters = $controller_action->getRequest()->getParams();
    $session = $this->customerSession;

    if({yourcondition}){


        // setting an action flag to stop processing further hierarchy
        $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);



        /// redirecting back to its referred url
        $observer->getControllerAction()->getResponse()->setRedirect($this->_redirectInterface->getRefererUrl());
        $session->setCustomerFormData($parameters);

    }

    return $this;


}

それは良い解決策です。ソリューションに完全なクラスを追加した方がよいでしょう。
Abbas

5

上記の答えがうまくいかないオブザーバーコードを更新しました

public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $params = []; 

        // If you want to redirect with data
        // $url = $this->_urlInterface->getUrl('checkout/cart/index',$params);

        $url = $this->_urlInterface->getUrl('checkout/cart/index');

        $observer->getControllerAction()
                    ->getResponse()
                    ->setRedirect($url);
    }

1

リクエスト処理にAjaxを使用するフォームにも取り組んでいます。jsonの形式で応答を送信し、Ajaxリクエストの成功/失敗に基づいて、window.location.hrefを使用してページにリダイレクトします。

jsonで必要なURLを渡し、ドット(。)演算子を使用して応答でアクセスできます。

$.ajax({
    url:url,
    data:$("#form-id").serialize(),
    type:'POST',
    dataType:'json',
    showLoader: true,
    success:function(result) {
        if(result.status == true) {
            if (result.product_url) {
                window.location.href = result.product_url;
            }
        }
    },
    error:function(xhr,textStatus,thrownError){
        alert(thrownError);
    }
});

これは私にとってはうまくいきます。


1

ユースケースによっては、提案されたソリューションのほとんどに問題があります。応答が設​​定されている他の場所が原因で、リダイレクトがキャッシュされる可能性があります。

シナリオ:ログインステータスに基づいてリダイレクトを実行します->ログイン後でも、302応答が1日間キャッシュされるため、ログイン前にアクセスしようとした保護されたページがリダイレクトされます。

私はこれを行うことになりました:

    if (!$isCustomerLoggedIn && !in_array($actionFullName, self::ALLOWED_ROUTES)) {
        $response = $observer->getEvent()->getControllerAction()->getResponse();
        $response->clearHeaders();
        $this->redirect->redirect($response, 'customer/account/login');
    }

EDITが機能しない-> clearHeadersがFPCを終了させる-代替ソリューションの開発

EDIT2より良いソリューション:

        /**
         * @var $action Action
         */
        $action = $observer->getEvent()->getControllerAction();

        /**
         * @var $response \Magento\Framework\App\Response\Http
         */
        $response = $action->getResponse();
        $response->clearHeaders()->setNoCacheHeaders();
        $this->redirect->redirect($response, 'customer/account/login');

1
namespace Adnan\Redirect\Observer;

use Magento\Framework\Event\ObserverInterface;

/**
 * Class Example
 *
 * phpcs:disable Generic.Files.LineLength
 *
 * @package Adnan\Example\Redirect
 */
class Example implements ObserverInterface
{
    /**
     * @var \Magento\Framework\App\ActionFlag
     */
    private $actionFlag;
    /**
     * @var \Magento\Framework\UrlInterface
     */
    private $url;

    /**
     * Data constructor.
     *
     * @param \Magento\Framework\App\ActionFlag $actionFlag
     * @param \Magento\Framework\UrlInterface   $url
     */
    public function __construct(
        \Magento\Framework\App\ActionFlag $actionFlag,
        \Magento\Framework\UrlInterface $url
    ) {

        $this->actionFlag = $actionFlag;
        $this->url = $url;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // Stop further processing if your condition is met
        $this->actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
        // then in last redirect
        $observer->getControllerAction()->getResponse()->setRedirect($this->url->getUrl("[FrontName]/[Controller]/[Action]"));

        return $this;
    }
}

\Magento\Framework\UrlInterfaceそれ以外の場合はを使用してURLを生成することを忘れないでください。トップレベルの構造UrlInterfaceにリダイレクトされません。たとえば、使用せずに「チェックアウト」から「a / b / c」でリダイレクトしたい場合は、「チェックアウト/ a」を処理します。 /紀元前"。

を使用するオプションがあり\Magento\Framework\App\ActionFlag、オブザーバーの以降の処理を停止します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.