Magento2: Umleitung von Observer

9

Wir wissen bereits, wie man von einem Observer für die magento 1.x-Version umleitet .

Für Magento 2 wissen wir jedoch nicht, wie man eine Umleitung von einem Beobachter mit Gewalt durchführt .

Ich habe google gemacht, bekomme aber keine Antwort.

Amit Bera
quelle
Haben Sie eine Lösung dafür gefunden?
BartZalas

Antworten:

20

Ja, ich habe selbst eine Lösung gefunden, indem ich recherchiert habe

Wenn Sie , dass dann tun wollen __construct()Funktion your class observer, müssen Sie zwei Klassen injizieren .

  • Erstens, \Magento\Framework\App\ResponseFactorydie für die Umleitung verantwortlich ist ,
  • Eine weitere Klasse, \Magento\Framework\UrlInterfacedie eine URL für diese Umleitung erstellt.
  • Erstellen Sie dann ein Objekt für ResponseFactory und verwenden Sie die setRedirect($YourUrl)->sendResponse();Umleitung zu Ihrer gewünschten URL.

Beobachter

<?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;
    }
}

Beispiel:

Hier schreibe ich ein Beispiel für diese Umleitung.

Grundsätzlich habe sales_quote_collect_totals_afterich versucht, gewaltsam umzuleiten, um uns zu kontaktieren.

Hier der Beobachtercode:

<?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;
    }
}
Amit Bera
quelle
3
Arbeiten Sie am frühen Morgen um 4 Uhr morgens? einfach unglaublich. Es gibt viel von dir zu lernen.
Baby in Magento
Hallo @amit, ich verwende das Ereignis 'sales_order_place_before' und die Bestellung wird mit ajax aufgegeben. Wenn ich den obigen Code verwende, wird er nicht umgeleitet, aber die Antwort wird gerendert. Ich möchte das nicht. Können Sie bitte eine Möglichkeit vorschlagen, auf eine Seite umzuleiten, wenn das Formular mit Ajax gespeichert wird? Danke
anujeet
2
Verwenden Sie nicht exit (); weil der Magento EcgM2-Codierungsstandard den Fehler "Die Verwendung des Exit-Sprachkonstrukts wird nicht empfohlen" anzeigt.
Prinz Patel
2
@AmitBera Wenn Sie exit nicht aufrufen, sollten Sie \Magento\Framework\App\Response\Httpstattdessen ein Konstruktorargument verwenden. Bei Verwendung der Factory-Klasse funktioniert dies nicht.
Milan Simek
3
Wenn Sie ein Predispatch-Ereignis verwenden, müssen Sie \ Magento \ Framework \ App \ ActionFlag in Ihren Konstruktor einfügen und in Ihrer Beobachterfunktion $ this -> _ actionFlag-> set ('', \ Magento \ Framework \ App \ Action \ verwenden) Aktion :: FLAG_NO_DISPATCH, true); Um Magento anzuweisen, die Verarbeitung der weiteren Ereignisse zu beenden, können Sie den Benutzer mit redirectInterface umleiten, wo immer Sie möchten.
Zeeshan Khuwaja
11

Durch das Injizieren des \Magento\Framework\App\ActionFlag $actionFlagund $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);wird Magento gezwungen, die Verarbeitung weiterer Ereignisse zu beenden und von einem Beobachter umzuleiten, insbesondere bei Verwendung eines Predispatch-Ereignisses.

Hier ist der Beispielcode

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;


}
Zeeshan Khuwaja
quelle
Es ist eine gute Lösung. Es ist besser, wenn Sie Ihrer Lösung die volle Klasse hinzufügen.
Abbas
5

Die obige Antwort funktioniert bei mir nicht. Ich habe meinen Beobachtercode aktualisiert

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);
    }
Himanshu
quelle
1

Ich arbeite auch an einem Formular, das Ajax für die Bearbeitung von Anfragen verwendet. Ich sende die Antwort in Form von json und verwende basierend auf Erfolg / Misserfolg der Ajax-Anfrage die Datei window.location.href , um auf eine Seite umzuleiten.

Sie können die erforderliche URL im json übergeben und in der Antwort mit dem Punkt (.) -Operator darauf zugreifen.

$.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);
    }
});

Das funktioniert gut für mich.

Sumit Verma
quelle
1

Abhängig vom Anwendungsfall haben die meisten vorgeschlagenen Lösungen ein Problem: Weiterleitungen können aufgrund anderer Stellen, an denen die Antwort festgelegt ist, zwischengespeichert werden.

Szenario: Sie führen eine Umleitung basierend auf dem Anmeldestatus durch -> Auch nach der Anmeldung wird die geschützte Seite, auf die sie vor der Anmeldung zugreifen wollten, weiterhin umgeleitet, da die 302-Antwort für einen Tag zwischengespeichert wird.

Am Ende habe ich Folgendes getan:

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

BEARBEITEN funktioniert nicht -> clearHeaders beendet die FPC - arbeitet an einer alternativen Lösung

EDIT2 Bessere Lösung:

        /**
         * @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');
Alex
quelle
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;
    }
}

Denken Sie daran \Magento\Framework\UrlInterface, die URL andernfalls zu generieren. Sie werden nicht zu einer Struktur der obersten Ebene umgeleitet, z. B. wenn Sie nicht verwenden UrlInterfaceund von "checkout" mit "a / b / c" umleiten möchten, wird "checkout / a" verarbeitet / b / c ".

Sie haben die Möglichkeit, die \Magento\Framework\App\ActionFlagweitere Verarbeitung von Beobachtern zu stoppen.

Adnan
quelle