Magento — customer_save_after всегда срабатывает дважды

Я использую событие customer_save_after в magento, и все работает нормально, за исключением 1 раздражающей вещи — оно всегда срабатывает дважды.

Нет других модулей, переписывающих это, и я не могу найти другой причины для этого. Когда я просматриваю все события, которые запускаются в это время, и это событие определенно запускается дважды.

Кто-нибудь объяснит это?

Я пишу веб-службу, которая подключается к этому, и оказалось, что дублировать вещи довольно неэффективно.


person David    schedule 29.04.2011    source источник


Ответы (5)


Я тоже заметил это двойное сохранение. Способ предотвратить проблему с вашим наблюдателем — установить флаг в запросе, который можно проверить, например.

    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); 
person Jonathan Day    schedule 20.05.2011

Я тоже столкнулся с этим и сделал трассировку стека в наблюдателе для каждого метода и могу сказать вам по крайней мере ОДНУ причину, почему он срабатывает дважды (могут быть и другие):

Когда новый пользователь создает учетную запись, createPostAction() запускается при отправке формы. Это действие воздействует на клиента save().

ЗАТЕМ, после того как клиент был создан, setCustomerAsLoggedIn() вызывается методом createPostAction(). Это, в свою очередь, вызывает setCustomer(), который имеет небольшой код:

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

Это две функции save(), которые отправляют событие сохранения. Я знаю это точно только для создания аккаунта в Magento 1.5. Я сомневаюсь, что он срабатывает дважды при создании пользователей в области администратора или когда пользователь редактирует свою информацию... но я точно не знаю.

Надеюсь, это поможет!

person thaddeusmt    schedule 19.05.2011
comment
Спасибо за детективную работу, это следует отметить как ответ. - person Phil; 09.05.2012

Будьте осторожны с решением Джонатана, «customer_save_observer_executed» остается в сеансе, поэтому событие не будет снова запущено в сеансе браузера. Так что это вообще плохая идея, т.к. не позволит зарегистрировать двух и более клиентов подряд(на самом деле позволит, но события не будут срабатывать)

Я предлагаю следующее решение:

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); 
}  
person Vladislav Mosalski    schedule 06.11.2013
comment
На самом деле, событие customer_register_success гораздо лучше подходит для наблюдения за регистрацией клиентов. - person Vladislav Mosalski; 07.11.2013
comment
Да, однако customer_register_success не срабатывает, когда пользователь сохраняет на панели управления учетной записи. - person DWils; 06.03.2014
comment
Записи реестра @VladislavMosalsky существуют только для этого запроса, они не остаются в сеансе (ref alanstorm. com/magento_registry_singleton_tutorial) - person Jonathan Day; 17.09.2014

Я использовал статическую переменную:

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++;
}
person dgianco    schedule 29.12.2013

Разница между этими двумя событиями в том, что одно из них не может получить информацию о клиенте, а другое — может. Итак, решение

    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
    }
person Eric Yue    schedule 19.12.2014