Magento:如果控制器被重写,为什么控制器动作predispatch事件不会触发?

mat*_*ndr 2 php extensibility controller event-handling magento

如果重写控制器,为什么控制器操作predispatch事件不会触发?这是一个片段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)
        );

    }
    // [...]
}
Run Code Online (Sandbox Code Playgroud)

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

Ala*_*orm 5

没有时间来测试你所描述的行为是否准确,但是如果它是我想象它在_rewrite函数中发生的事情会复制其他非事件代码在该调用之后的动作,并允许preDispatch在重写之后继续"坏事"发生了.

换句话说,这是一个被忽略的控制器重写实现中的错误,因为处理它的首选方法现在处于路由级别.一般来说,当像这样的系统级别的bug进入Magento时,它往往会留在那里,因为购物车所有者开始依赖破碎的行为并在任何变化时大声尖叫,即使这是一个bug修复.

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

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;
}
Run Code Online (Sandbox Code Playgroud)