【问题标题】:Magento Observer DestinationMagento 观察者目的地
【发布时间】:2012-11-28 19:33:58
【问题描述】:

我写了 2 个 Magento 观察者,他们都做了我想要的,除了他们在错误的页面上结束。换句话说,他们编写日志文件、修改数据库并与其他服务器通信,但他们修改页面到页面的路由。例如,我有一个在登录时使用的观察者,它修改数据库、写入 cookie 并写入日志,但它会将登录后页面更改为

http://www.my-web-site.com/index.php/customer/login/post/

然后给我一个 404 错误。如果我点击 "Ctrl" + 'r' 然后我登录在

http://www.my-web-site.com/index.php/customer/account/index/

这是正确的。如果我改变, app/code/local/my_module/my_model/etc/config.xml 到 app/code/local/my_module/my_model/etc/config.xml.1 (换句话说,取出观察者),然后 Magento 路由到正确的页面,

我认为我需要 config.xml 中的路由器信息。我当前的 config.xml 是:

<?xml version="1.0" encoding="UTF-8"?>
<!-- The root node for Magento module configuration -->
<config>

  <!-- The module's node contains basic information about each Magento module -->
  <modules>

    <!-- This must exactly match the namespace and module's folder
      names, with directory separators replaced by underscores -->
    <MyCompany_LogIn>

      <!-- The version of our module, starting at 0.0.0 -->
      <version>0.0.0</version>

    </MyCompany_LogIn>
  </modules>

  <!-- Configure our module's behavior in the global scope -->
    <global>

        <!-- Defining models -->
        <models>

        <!-- Unique identifier in the model's node.
             By convention, we put the module's name in lowercase. -->
        <mycompany_login>

            <!-- The path to our models directory, 
             with directory separators replaced by underscores -->
          <class>MyCompany_LogIn_Model</class>

        </mycompany_login>
        </models>
    </global>

  <frontend>

    <!-- Defining an event observer -->
      <events>

        <!-- The code of the event we want to observe -->
        <customer_login>

            <!-- Defining an observer for this event -->
          <observers>

            <!-- Unique identifier within the catalog_product_save_after node.
                 By convention, we write the module's name in lowercase. -->
            <mycompany_login>

                <!-- The model to be instantiated -->
              <class>mycompany_login/observer</class>

              <!-- The method of the class to be called -->
              <method>wrtLogInCookie</method>

              <!-- The type of class to instantiate -->
              <type>singleton</type>

            </mycompany_login>
            </observers>
        </customer_login>
      </events>
  </frontend>
</config>    

我猜测 Magento 内部的登录使用了观察者,我正在干扰它。

除了 ,我猜我也可以在 PHP Observer 代码中完成类似的事情。我的观察者是:

<?php

  /**
  * Our class name should follow the directory structure of
  * our Observer.php model, starting from the namespace,
  * replacing directory separators with underscores.
  * i.e. /www/app/code/local/MyCompany/LogIn/Model/Observer.php
  */

  class MyCompany_LogIn_Model_Observer extends Varien_Event_Observer
    {
    /**
    * Magento passes a Varien_Event_Observer object as
    * the first parameter of dispatched events.
    */
    public function wrtLogInCookie(Varien_Event_Observer $observer)
    {
      // Retrieve the product being updated from the event observer
      $customer = $observer->getEvent()->getCustomer();

      $email = $customer->getEmail();
      Mage::log('The E-mail is: ' . $email);

      $ran_nmbr = rand(); 
      Mage::log('The random number is: ' . $ran_nmbr);

      $crnt_dat = date("m-d-Y::H:i:s");
      Mage::log('The date is: ' . $crnt_dat);

      return $this;
    }
    }
?>

我读过关于路由器的文章,但是文章讨论了在执行扩展之前登陆某个页面的方式。如您所见,我需要在扩展执行后登陆正确的页面。

在 PHP 观察者中,我也尝试了重定向。例如,

Mage::app()->getResponse()->setRedirect(Mage::getUrl('customer/account/login'));

也许我需要一个完整的 URL 地址或其他东西。我确信这很容易解决,但我的无知似乎在跟着我。如果您对此有所了解,请提供帮助。

【问题讨论】:

  • 对于实验,您可以删除包含“extends Varien_Event_Observer”的代码部分吗?
  • 感谢您的评论。我删除了“扩展 Varien_Event_Observer”,但没有任何区别。
  • 我会留下这个,以防有人遇到类似问题。代码按照我提出的方式运行,只是在 Observer.php 中的结束标记后有空格。错误“无法重新生成会话 ID”是最终导致我遇到问题的原因。

标签: magento observers


【解决方案1】:

不幸的是,这并不像简单的修复那么简单。你看,如果我们在loginPostAction() 中查看app/code/core/Mage/Customer/controllers/AccountController.php,我们会看到customer/session 单例触发了customer_login 调用。但是,这里导致跳闸的原因是,在调用之后,回到控制器中,控制器调用$this-&gt;_loginPostRedirect(),因此您所做的所有重新路由工作都将被覆盖。

如何解决:

说起来没那么简单,我确实碰巧看到了一个我们可以利用的作弊:

$session = Mage::getSingleton('customer/session');
$session->setBeforeAuthUrl($forwardToUrl);

【讨论】:

  • 感谢您的帮助。我无法完成这项工作。看起来很多地方都使用了 setBeforeAuthUrl()。 $forwardToUrl 在我的日志文件中设置正确(据我所知),但我得到的结果与最初发布的结果完全相同。我在尝试时也收到“无法重新生成会话 ID”错误。
【解决方案2】:

你说对了一部分。您遇到的问题是 Magento 的重定向机制适用于“最后一个说点什么”赢得哲学。如果您查看

中的标准登录代码
app/code/core/Mage/Customer/controllers/AccountController.php

你会看到loginPostAction方法以调用结束

$this->_loginPostRedirect();

哪个(最终)调用了一些看起来像这样的代码

$this->getResponse()->setRedirect($url);

这可能是导致您出现问题的代码,也可能是其他原因。一般的问题是对响应对象的setRedirect 方法的final 调用将获胜。

我通常的解决方案是在我想要执行重定向时设置某种全局标志(类上的静态变量,使用Mage::register 设置的标志),然后为controller_action_postdispatch 创建一个额外的观察者。在这个观察者中,我寻找我设置的全局标志,如果找到,就在那里设置重定向。

这处理了 99% 的重定向情况,应该可以处理您的情况。在某些管理员登录案例以及 URL 重写的情况下,这将不起作用。

管理员登录包含一些使用 Magento 响应对象的重定向代码

#File: app/code/core/Mage/Admin/Model/Session.php
...
header('Location: ' . $requestUri);
exit;    
...

如果此重定向导致您出现问题,请为 admin_session_user_login_success 创建一个侦听器,该侦听器在 Magento 之前使用 PHP 标头重定向。

同样,如果 Magento 使用重写对象,以下代码可能会运行

#File: app/code/core/Mage/Core/Model/Url/Rewrite.php
if ($isPermanent) {
    header('HTTP/1.1 301 Moved Permanently');
}

header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Pragma: no-cache');
header('Location: ' . $url);
exit;

(也就是说,重写代码很少会成为您的问题,因为在标准 Magento 操作中运行 before 控制器调度)

【讨论】:

  • 嗨艾伦,我很喜欢你的文章。感谢您的回复。我真的不想重定向,我只想要一个不会弄乱路由的观察者。当观察者中没有路由指令时,观察者通常会更改路由吗?
  • 啊,我误解了你的问题——我以为你试图从观察者那里重定向,但 Magento 的重定向成功了。不,观察者对响应对象没有任何作用。我的直觉告诉我要查看你在观察者中所做的具体事情——例如,将其清空,清除缓存,确保一切正常。然后找出您正在调用的观察者中的哪个代码(间接)导致问题。此外,使用 mageDebugBacktrace 的重定向方法中的一些临时调试代码将帮助您查看创建“坏”重定向的原因。祝你好运。
  • 我能够按照您的建议通过删减代码来解决它。问题是 Observer.php 在结束标记后有空格。我不知道那会是个问题。当我删除结束标记后的空白时,观察者和路由按预期工作。
  • @VectorVortec 啊,这是 PHP 的一个老问题。该空白被解释为输出,这会在 PHP 中触发“不再有标头”行为。以防万一您不知道,您可以将结束标记从 PHP 文件中删除,它仍然可以工作。这已成为事实上的标准做事方式(在模板之外)
猜你喜欢
  • 1970-01-01
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-01
相关资源
最近更新 更多