【问题标题】:Magento - Redirect Customer from Observer MethodMagento - 从观察者方法重定向客户
【发布时间】:2012-04-02 16:32:13
【问题描述】:

在此事件checkout_cart_add_product_complete 中,我希望将客户重定向到外部网页http://www.example.com/。为此,我正在使用这段代码,它根本不起作用:-

public function moduleMethod() {
    /* @var $response1 Mage_Core_Controller_Response_Http */
    $response1 = $observer->getEvent()->getResponse();

    /* @var $response2 Mage_Core_Controller_Response_Http */
    $response2 = Mage::app()->getResponse();

    $url = 'http://www.example.com/';
    $response1->setRedirect($url);

    return;
}

我对这两个变量“$response1”和“$response2”都使用了“setRedirect()”方法,但它们都向我显示了购物车页面,而我想查看此页面http://www.example.com/而是。

我想要什么:

  • 我不想重写控制器类,只是为了重定向客户,当我可以有效地使用事件观察器进程时。
  • 我不想使用 PHP 内置函数“header()”,因为 Magento 框架以有效的方式提供了此功能。

【问题讨论】:

    标签: php magento redirect


    【解决方案1】:

    您可以使用_redirectUrl()方法,它用于从magento重定向到外部网站。

    【讨论】:

      【解决方案2】:

      我必须通过getFront:

      public function moduleMethod($observer) {
        $observer->getEvent()->getFront()->getResponse()->setRedirect('http://www.google.com');
      }
      

      【讨论】:

      • 如果你看到“Ben”给出的答案,你会看到他使用上下文对象($this)来获取响应$this->getResponse()而不是$observer对象。希望对您有所帮助。
      • 是的,但他的最终解决方案(即在请求中设置 return_url 参数)对我正在做的事情不起作用,我认为这不直观。这段代码完成了我认为您的代码最初试图做的事情。
      • 是的,我的要求是非常具体的,所以我相信“本”提供的解决方案可能不适合你。我很抱歉之前的混乱。也为了得到回应,你能试试$observer->getResponse()吗?我在我的 Magento 本地尝试过,它对我有用,而不是使用 $observer->getEvent()->getFront()->getResponse()。希望对您有所帮助。
      • 参数中可用的对象将根据所观察的事件而有所不同。响应对象实际上是应用程序中的单例,因此访问它的方式是学术性的; Mage::app()->getResponse() 将在“任何地方”工作。
      【解决方案3】:

      tl;dr: 更正底部的观察者代码。

      回答前的注意事项:确保观察者被触发;单步执行您的代码或使用die('here');。如所写,您的示例方法没有正确的原型来接收事件观察者数据(缺少参数)。

      在这种情况下使用事件观察器进行重定向逻辑是完全合适的,正如核心团队将请求和响应对象显式传递给观察器所证明的那样。您的尝试很好,但我认为您的条件和配置导致执行流向Mage_Checkout_CartController::_goBack(),特别是流向该行

      $this->_redirect('checkout/cart');
      

      所以我们需要修改我们的方法。现在,您可以通过操纵响应并调用前端控制器的 sendResponse() 方法来阻止任何请求/响应逻辑在事件观察者之后处理,如下所示(nb:不要这样做!):

      public function moduleMethod($observer) //note I added a param
      {
          /* @var $response1 Mage_Core_Controller_Response_Http */
          $response1 = $observer->getResponse(); // observers have event args
      
          $url = 'http://www.example.com/';
          $response1->setRedirect($url);
      
          /* SHOULDN'T DO THIS */
          Mage::app()->getFrontController()->sendResponse();
      }
      

      这应该可行,但我认为它会通过触发来自空灵系统组件 (EDA) 的输出来混淆关注领域。让我们看看命令控制结构中是否有我们可以使用的东西......

      就在checkout_cart_add_product_complete 事件执行之后到达购物车控制器的_goBack() 方法。这个方法名称的问题在于它所做的比它的名字所暗示的要多:

      /**
       * Set back redirect url to response
       *
       * @return Mage_Checkout_CartController
       */
      protected function _goBack()
      {
          $returnUrl = $this->getRequest()->getParam('return_url');
          if ($returnUrl) {
              // clear layout messages in case of external url redirect
              if ($this->_isUrlInternal($returnUrl)) {
                  $this->_getSession()->getMessages(true);
              }
              $this->getResponse()->setRedirect($returnUrl);
          }
          //...
      }
      

      看起来我们可以在请求对象上设置一个return_url 参数并完成我们需要的操作。

      public function moduleMethod(Varien_Event_Observer $observer)
      {
          $observer->getRequest()->setParam('return_url','http://www.google.com/');
      }
      

      我已经对此进行了测试,它应该可以解决问题!

      【讨论】:

      • 非常感谢您在此答案中提供的糟糕细节,这些信息非常有效!是的,我错过了在方法定义中提到的参数,所以感谢您纠正我。如果您能在 Magento 上多说一些 EDA 及其优缺点,那就太好了!
      • Magento 有一个深入的调用堆栈,可以遍历许多层。如果没有它的事件架构,许多自定义将是令人望而却步的侵入性,并会导致大量错误。
      • 当我这样做时,我得到错误:外部网址重定向到“google.com”被拒绝!有人知道我做错了什么吗?
      • @J.S 你应该把这个作为一个新问题来问。
      • @Slimshadddyyy 您提到的方法有效。但是,它涉及在事件观察器内部刷新输出,而不是从调用堆栈中的通常点(前端控制器的dispatch() 方法)。这违反了关注点分离,这有助于使 Magento(和其他 MVC 框架)不那么混乱。但是,如果它对你有用,并且你有一个令人信服的理由来采用这种方法,那就去吧! (顺便说一句,我确实在我的回答中涵盖了您提出的解决方案。)
      猜你喜欢
      • 2013-08-11
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 2012-10-25
      相关资源
      最近更新 更多