Magento 1 - 如果控制器被重写,为什么控制器操作预调度事件不会触发?

发布于 2024-10-11 04:43:03 字数 725 浏览 4 评论 0 原文

如果控制器被重写,为什么控制器操作预调度事件不会触发?这是store/app/code/core/Mage/Core/Controller/Varien/Action.php的片段:

abstract class Mage_Core_Controller_Varien_Action
{
    // [...]
    public function preDispatch()
    {
        // [...]
        if ($this->_rewrite()) {
            return; // [What is the purpose if this?]
        }
        // [...]

        // [This is where my event needs to be firing, but this code never gets 
        // executed because the controller is rewritten]
        Mage::dispatchEvent(
            'controller_action_predispatch_'.$this->getFullActionName(),
            array('controller_action'=>$this)
        );

    }
    // [...]
}

我不知道从哪里开始解决这个问题。以前有人处理过这个吗?

Why do controller action predispatch events not fire if the controller is rewritten? Here is a snippet of store/app/code/core/Mage/Core/Controller/Varien/Action.php:

abstract class Mage_Core_Controller_Varien_Action
{
    // [...]
    public function preDispatch()
    {
        // [...]
        if ($this->_rewrite()) {
            return; // [What is the purpose if this?]
        }
        // [...]

        // [This is where my event needs to be firing, but this code never gets 
        // executed because the controller is rewritten]
        Mage::dispatchEvent(
            'controller_action_predispatch_'.$this->getFullActionName(),
            array('controller_action'=>$this)
        );

    }
    // [...]
}

I don't know where to start fixing this problem. Anyone out there ever dealt with this before?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉殇 2024-10-18 04:43:03

没有时间测试您所描述的行为是否准确,但如果是的话,我想这就是 _rewrite 函数中发生的情况,该函数会重复该调用后其他非事件代码的操作,并允许preDispatch 在重写后继续会导致“坏事”发生。

换句话说,这是控制器重写实现中的一个错误,已被忽略,因为处理此问题的首选方法现在位于 路由级别。一般来说,当像这样的系统级错误进入 Magento 时,它往往会留在那里,因为购物车所有者开始依赖损坏的行为,并在任何事情发生变化时大声尖叫,即使它是一个错误使固定。

如果您无法按照上面的链接中所述重构您的解决方案,您仍然可以使用旧式面向对象编程在控制器类中自行触发事件。将以下内容添加到您的自定义控制器(您要重写的控制器)

protected function _rewrite()
{
    //call the parent rewrite method so every that needs
    //to happen happens
    $original_result = parent::_rewrite();

    //fire the event ourselve, since magento isn't firing it
    Mage::dispatchEvent(
        'controller_action_predispatch_'.$this->getFullActionName(),
        array('controller_action'=>$this)
    );      

    //return the original result in case another method is relying on it
    return $original_result;
}

No time to test if the the behavior you're describing is accurate, but if it is I imagine it's what happens in the _rewrite function duplicates the actions of other non-event code after that call, and allowing preDispatch to continue after the rewrite would have made "bad things" happen.

In other words, it's a bug in the implementation of controller re-writing that's been ignored, because the preferred way of handling this is now at the routing level. In general, when a system level bug like this makes it into Magento, it tends to stay there, because cart owners start to rely on the broken behavior and scream loudly when anything changes, even if it's a bug fix.

If you can't re-factor your solution as described in the link above, you can still fire the event yourself in the controller class with old fashion Object Oriented Programming. Add the following to your custom controller (the one you're rewriting to)

protected function _rewrite()
{
    //call the parent rewrite method so every that needs
    //to happen happens
    $original_result = parent::_rewrite();

    //fire the event ourselve, since magento isn't firing it
    Mage::dispatchEvent(
        'controller_action_predispatch_'.$this->getFullActionName(),
        array('controller_action'=>$this)
    );      

    //return the original result in case another method is relying on it
    return $original_result;
}
清醇 2024-10-18 04:43:03

嘿,我不确定(因为我不太熟悉 Magento 的内部工作原理),但我突然想到 _rewrite() 检查对此特定操作的调用是否被重定向(以 mod_rewrite 方式重写)到不同的控制器/操作。从这个角度来看,原始操作的事件不会被触发是有道理的,因为整个请求是由不同的操作处理的。

Hey, I'm not sure (as I'm not very familiar with the inner workings of Magento), but it occurs to me that _rewrite() checks whether a call to this specific action is being redirected (rewritten in a mod_rewrite kind of way) to a different controller/action. In this light, it would make sense that events for the original action would not be fired, since the whole request gets handled by a different action.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文