2011-04-29 9 views
15

Estoy usando el evento customer_save_after en magento, y todo funciona bien, aparte de 1 cosa molesta: siempre se dispara dos veces.Magento - customer_save_after siempre despedido dos veces

No hay otros módulos que reescriban esto y no puedo encontrar ninguna otra razón para que esto ocurra. Cuando veo todos los eventos que son despedidos en este momento, este evento definitivamente es despedido dos veces.

¿Alguien explica esto?

Estoy escribiendo un servicio web que se engancha en esto y resulta ser bastante ineficiente para duplicar cosas.

Respuesta

11

me encontré con esto también e hizo un seguimiento de la pila en el observador para cada método, y se puede decir al menos una razón por la que dispara dos veces (puede haber otros):

Cuando un nuevo usuario crea una cuenta, createPostAction() se ejecuta cuando se envía el formulario. Esta acción hace un save() en el cliente.

LUEGO, después de que el cliente ha sido creado, setCustomerAsLoggedIn() es llamado por createPostAction(). Esto a su vez llama setCustomer(), que tiene este pequeño trozo de código:

if ((!$customer->isConfirmationRequired()) && $customer->getConfirmation()) { 
    $customer->setConfirmation(null)->save(); // here is the second save 
    $customer->setIsJustConfirmed(true); 
} 

Esos son los dos save() s, que distribuye el evento guardar. Solo sé esto con seguridad para la creación de cuentas en Magento 1.5. Dudo si se dispara dos veces al crear usuarios en el área de administración, o cuando un usuario edita su información ... pero no estoy seguro.

Espero que esto ayude!

+0

¡buen trabajo de detective, gracias! –

+0

Gracias por el trabajo de detective, esto debería marcarse como una respuesta. – Phil

23

Me he dado cuenta de este comportamiento de doble guardado también. La forma de evitar problemas con su observador es establecer un indicador en la solicitud que se puede verificar, p.

if(Mage::registry('customer_save_observer_executed')){ 
     return $this; //this method has already been executed once in this request (see comment below) 
    } 

    ...execute arbitrary code here.... 

    /* Customer Addresses seem to call the before_save event twice, 
    * so we need to set a variable so we only process it once, otherwise we get duplicates 
    */ 
    Mage::register('customer_save_observer_executed',true); 
+0

awesom ¡funciona! – huzefam

0

tener cuidado con solución Jonathans, 'customer_save_observer_executed' se queda en la sesión, por lo que caso no se disparará de nuevo en la sesión del navegador. Por lo que es generalmente una mala idea, ya que no permitirá registrar dos o más clientes en una fila (en realidad, lo hará, pero no se disparará eventos)

sugiero la siguiente solución:

public function customerRegister(Varien_Event_Observer $observer) 
{  
    $customer = $observer->getEvent()->getCustomer();   
    if (!$customer->getId()) 
     return $this;     

    if(Mage::registry('customer_save_observer_executed_'.$customer->getId())) 
     return $this; 

    //your code goes here 

    Mage::register('customer_save_observer_executed_'.$customer->getId(),true); 
} 
+1

En realidad, el evento customer_register_success es mucho mejor para observar el registro de clientes. –

+0

Sí, sin embargo, customer_register_success no se activa cuando el usuario guarda en el panel de la cuenta. – DWils

+0

@VladislavMosalsky solo existen entradas de registro para esa solicitud, no * permanecen * en la sesión (ref http://alanstorm.com/magento_registry_singleton_tutorial) –

0

he usado un var estática:

private static $_handleCustomerFirstSearchCounter = 1; 

public function Savest($observer) { 
    if (self::$_handleCustomerFirstSearchCounter > 1) { 
     return $this; 
    } 

    $customerData = Mage::getSingleton('customer/session')->getCustomer(); 
    $model = Mage::getModel('customerst/customerst') 
     ->setQueryText(Mage::app()->getRequest()->getParam('q')) 
     ->setCustomerId($customerData->getId()) 
     ->setCustomerName($customerData->getName()) 
     ->save(); 

    self::$_handleCustomerFirstSearchCounter++; 
} 
0

la diferencia entre estos 2 eventos es uno de ellos no se puede obtener información del cliente, mientras que el otro puede. Entonces la solución es

public function email_CustomerRegister(Varien_Event_Observer $observer){ 

     $customer = Mage::getSingleton('customer/session')->getCustomer(); 
     $customer_email     = $customer->getEmail(); 


     if(empty($customer_email)){ 
      return; 
     } 

     // do something 
    }