Pregunta

¿Alguien sabe si es posible anular el registro de un observador de eventos mediante programación? Tengo un observador en newsletter_subscribe_save_after que las actualizaciones de un atributo personalizado en el modelo cliente pero cuando el registro de cliente se salvan, esto desencadena el evento customer_save_after definido en Mage_All.xml que luego re-guarda el estado boletín de suscripción que resulta en un bucle infinito que se dispara el PHP error recursión debido a la anidación de 100 veces.

Lo ideal sería anular el registro del evento customer_save_after sólo cuando mis fuegos observadores.

¿Fue útil?

Solución

Se puede tratar de marcar su evento como dispatched y en el segundo intento de ejecutarlo simplemente no hacer nada si ya se envió. Por ejemplo digamos que su método se llama updateCustomer().

public function updateCustomer($observer){
    if (Mage::registry('my_event_was_dispatched') == 1){//do nothing if the event was dispatched
        return $this;
    }
    //your code here
    Mage::register('my_event_was_dispatched', 1);//mark the event as dispatched.
}

El nombre clave de registro no es importante, sólo asegúrese de que utiliza la misma en ambos casos.

Otros consejos

Se puede anular el registro de un evento observador sobre la marcha mediante programación de la siguiente manera:

$area = Mage::app()->getStore()->isAdmin() ? 'adminhtml' : 'frontend';
foreach (array($area, 'global') as $branch) {
    $path = $branch . '/events/customer_save_after/observers/your_module/type';
    Mage::app()->getConfig()->setNode($path, 'disabled');
}

No se puede anular el registro de un evento en sí. Para desactivar por completo un evento, que tendría que bucle sobre todos los hijos de $branch . '/events/customer_save_after/observers' y desactivar cada una de ellas.

Si es sólo un único método específico observador no desea volver a correr, se puede establecer su tipo a ser singleton y luego sólo tiene que utilizar una propiedad booleana como un indicador para comprobar si ya se llamó una vez la siguiente manera:

class Your_Module_Model_Observer
{
    private $_processFlag = false;

    public function customerSaveAfter($data)
    {
        if (! $this->_processFlag) {
            $this->_processFlag = true;
            // do your thing with $customer->save()
        }
    }
}

here's a proof-of-concept helper method that toggles an existing observer. if you want to have the event disabled as default, add <type>disabled</type> to your observer's config.xml definition.

public function toggleObserver($area, $event, $name, $enable)
{
    $app = Mage::app();

    // reflection on the property Mage_Core_Model_App::_events
    $class = new ReflectionClass(get_class($app));
    $property = $class->getProperty('_events');
    $property->setAccessible(true);

    // get the events
    $events = $property->getValue($app);

    // make sure the event config is loaded
    if (!isset($events[$area][$event]))
    {
        // load observers from config
        /** @see Mage_Core_Model_App::dispatchEvent() */

        $config = $app->getConfig()->getEventConfig($area, $event);
        if (!$config)
        {
            // event is not configured
            return;
        }

        // create observers array
        $observers = array();
        foreach ($config->observers->children() as $name => $values)
        {
            $observers[$name] = array(
                'type'  => (string) $values->type,
                'model' => $values->class ? (string) $values->class : $values->getClassName(),
                'method'=> (string) $values->method,
                'args'  => (array) $values->args,
            );
        }
        $events[$area][$event]['observers'] = $observers;
    }

    if ($events[$area][$event] && isset($events[$area][$event]['observers'][$name]))
    {
        // enable/disable the observer by changing its type
        $events[$area][$event]['observers'][$name]['type'] = $enable ? '' : 'disabled';

        // update the object
        $property->setValue($app, $events);
    }
}

the function makes use of reflection to access the otherwise protected $_events property of Mage_Mage_Core_Model_App. the same trick could be used to inject previously undefined observers.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top