1

I have wrote 2 Magento observers and they both do exactly what I want with the exception that they end on the wrong page. In other words, they write the log files, modify the databases, and talk with other servers, but they modify the page to page routing. For example, I have an observer that I used at login that modifies a database, writes a cookie, and writes to a log, but it changes the post log-in page to

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

and then gives me a 404 error. If I hit "Ctrl" + 'r' then I am logged in at

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

which is correct. If I change, app/code/local/my_module/my_model/etc/config.xml to app/code/local/my_module/my_model/etc/config.xml.1 (in other words take out the observer), then Magento routes to the correct page,

I'm thinking that I need router information in config.xml. My current config.xml is:

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

I'm guessing that the login inside Magento uses an observer, and I'm interfering with it.

Besides the , I'm guessing that I could also accomplish a similar thing in the PHP Observer code. My observer is:

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

I have read about routers, but the articles discussed it in terms of landing on some page before the extension is executed. As you can see, I need to land on the right page after the extension is executed.

Inside the PHP observer, I also tried redirects. For example,

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

Maybe I need a full URL address or something. I'm sure this is easy to fix, but my ignorance seems to be following me around. Please help if you know something about this.

4

2 回答 2

1

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

怎么修:

在说这不是那么简单之后,我确实碰巧看到了一个我们可以利用的作弊:

$session = Mage::getSingleton('customer/session');
$session->setBeforeAuthUrl($forwardToUrl);
于 2012-11-29T01:27:30.030 回答
1

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

app/code/core/Mage/Customer/controllers/AccountController.php

您将看到该loginPostAction方法以调用结束

$this->_loginPostRedirect();

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

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

这可能是导致您出现问题的代码,也可能是其他问题。一般的问题是最终调用响应对象的setRedirect方法会赢。

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

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

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

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

如果此重定向导致您出现问题,请在 Magento 之前创建一个admin_session_user_login_success使用 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 操作是在控制器调度之前运行的)

于 2012-11-29T03:39:16.400 回答