Magento - customer_save_after总是被解雇两次

时间:2011-04-29 23:23:01

标签: php events magento observer-pattern

我在magento中使用customer_save_after事件,除了一件烦人的事情之外,所有事情都很好 - 它总是被解雇两次。

没有其他模块重写这个,我找不到其他原因。当我查看此时被解雇的所有事件时,这个事件肯定会被解雇两次。

有人解释这个吗?

我正在编写一个与此相关的Web服务,并且它的复制效果非常低效。

5 个答案:

答案 0 :(得分:23)

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

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

答案 1 :(得分:11)

我也碰到了这个,并且在每个方法的观察者中做了一个堆栈跟踪,并且至少可以告诉你为什么它会发射两次(可能还有其他的):

当新用户创建帐户时,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中的帐户创建肯定知道这一点。我怀疑在管理区域中创建用户时,或者当用户编辑他们的信息时,它是否会被解雇两次......但我不确定。

我希望这有帮助!

答案 2 :(得分:1)

小心使用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); 
}  

答案 3 :(得分:0)

我使用了静态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++;
}

答案 4 :(得分:0)

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

    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
    }