Magento - customer_save_after 总是触发两次

发布于 2024-11-04 01:39:33 字数 212 浏览 4 评论 0原文

我正在 magento 中使用 customer_save_after 事件,除了 1 件烦人的事情之外,一切都工作正常 - 它总是被触发两次。

没有其他模块重写这个,我找不到发生这种情况的其他原因。当我查看此时触发的所有事件时,该事件肯定被触发两次。

有人解释一下吗?

我正在编写一个与此挂钩的网络服务,但事实证明它的复制效率非常低。

I am using the customer_save_after event in magento, and all is working fine apart from 1 annoying thing - it is always fired twice.

There are no other modules rewriting this and I can find no other reason for this happening. When I look through all of the events getting fired at this time and this event is definately getting fired twice.

Anyone explain this?

I am writing a web service that hooks into this and its turning out to be quite inefficient to duplicate things.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

葬心 2024-11-11 01:39:33

我也注意到了这种双重保存行为。防止观察者出现问题的方法是在请求中设置一个可以检查的标志,例如

    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); 

I've noticed this double-save behaviour too. The way to prevent issue with your observer is to set a flag in the request that can be checked e.g.

    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); 
甜味拾荒者 2024-11-11 01:39:33

我也遇到了这个问题,并在观察者中为每个方法做了一个堆栈跟踪,并且可以告诉您至少一个它触发两次的原因(可能还有其他原因):

当新用户创建帐户时,createPostAction() 会在以下情况运行:表格已提交。此操作对客户执行save()

然后,在创建客户后,createPostAction() 会调用 setCustomerAsLoggedIn()。这又会调用 setCustomer(),其中包含以下代码:

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

这是两个调度 save 事件的 save()。我只知道在 Magento 1.5 中创建帐户时确实如此。我怀疑在管理区域中创建用户时或用户编辑其信息时它是否会被触发两次......但我不确定。

我希望这有帮助!

I ran into this as well and did a stack trace in the observer for each method, and can tell you at least ONE reason why it fires twice (there may be others):

When a new user creates an account, createPostAction() runs when the form is submitted. This action does a save() on the customer.

THEN, after the customer has been created, setCustomerAsLoggedIn() is called by createPostAction(). This in turn calls setCustomer(), which has this little bit of code:

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

Those are the two save()s which dispatch the save event. I only know this for sure for account creation in Magento 1.5. I doubt if it gets fired twice when creating users in the Admin area, or when a user edit's their information... but I don't know for sure.

I hope this helps!

dawn曙光 2024-11-11 01:39:33

请小心 Jonathan 的解决方案,“customer_save_observer_execulated”保留在会话中,因此事件不会在浏览器会话中再次触发。所以这通常是一个坏主意,因为它不允许连续注册两个或多个客户(实际上,它会,但事件不会被触发)

我建议以下解决方案:

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); 
}  

Be careful with Jonathans solution, 'customer_save_observer_executed' stays in the session, so event will not be fired again in the browser session. So it's generally a bad idea, because it will not allow to register two or more customers in a row(actually, it will, but events will not be fired)

I suggest the following solution:

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); 
}  
山田美奈子 2024-11-11 01:39:33

我使用了静态变量:

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++;
}

I used a static var:

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++;
}
ζ澈沫 2024-11-11 01:39:33

这两个事件之间的区别是其中一个无法获取客户信息,而另一个可以。所以解决办法是

    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
    }

The difference between these 2 events is one of them can't get customer info, while the other can. So the solution is

    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
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文