如果重写控制器,为什么控制器操作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)
);
}
// [...]
}
我不知道从哪里开始解决这个问题。以前有人曾经处理过这个问题吗?
答案 0 :(得分:5)
没有时间来测试你所描述的行为是否准确,但如果是,我想象_rewrite
函数中发生的事情会在该调用之后复制其他非事件代码的动作,并允许在重写之后继续preDispatch
会使“坏事”发生。
换句话说,这是一个被忽略的控制器重写实现中的错误,因为处理它的首选方法现在是the routing level。一般来说,当像这样的系统级别的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;
}
答案 1 :(得分:2)
嘿,我不确定(因为我不熟悉Magento的内部工作原理),但我发现_rewrite()
检查是否正在重定向对此特定操作的调用(重写)以mod_rewrite的方式)到不同的控制器/动作。从这个角度来看,原始动作的事件不会被触发是有道理的,因为整个请求都是由不同的动作处理的。