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

Внимавайте с решението на Jonathans, '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 съществуват само за тази заявка, те не остават в сесията (реф. 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

Разликата между тези 2 събития е, че едното от тях не може да получи информация за клиента, докато другото може. Така че решението е

    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