Magento: ¿Por qué los eventos previos al envío de acciones del controlador no se activan si el controlador se reescribe?

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?

preguntado el 08 de enero de 11 a las 18:01

afaik you cannot even rewrite abstract models in magento? only replace them as a whole in local/mage? -

2 Respuestas

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 cualquier cosa 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;
}

Respondido el 22 de diciembre de 15 a las 21:12

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.

Respondido el 08 de enero de 11 a las 23:01

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.