Question

I have events that I wish to execute when a customer registers or saves their details. For this, I am using two events: customer_register_success and customer_save_after. The problem I am having is that I end up running the task twice as customer_save_after is always called in the same execution as customer_register_success.

I have tried to detect whether the customer is new by checking the original data and called isObjectNew, but both return data that implies the object is in fact not new. How can I check to see if the customer is just registering in the customer_save_after event short of setting something in the registry in the customer_register_success event?

Was it helpful?

Solution

First of all you can define your observer as singleton for both events

<global>
    <events>
        <customer_save_after>
            <observers>
                <namespace_module>
                    <type>singleton</type>
                    <class>namespace_module/observer</class>
                    <method>doSomething</method>
                </namespace_module>
            </observers>
        </customer_save_after>
        <customer_register_success>
            <observers>
                <namespace_module>
                    <type>singleton</type>
                    <class>namespace_module/observer</class>
                    <method>doSomething</method>
                </namespace_module>
            </observers>
        </customer_register_success>
    </events>
</global>

In this case the same observer object will be used for both events. So you can create flag in your observer and before doing some actions check it.

class [Namespace]_[Module]_Model_Observer
{
    protected $canDoSomething = false;

    public function doSomething($observer)
    {
        if (!$this->canDoSomething) {

            //here your code

            //now set flag to true to prevent executing your code twice 
            $this->canDoSomething = true;
        }
    }
}

Now your code will be executed only once.

OTHER TIPS

Easiest way to prevent this is to use a registry value. Your observer method would look something like the following

class [Namespace]_[Module]_Model_Observer
{
   public function triggeredObserver($observer)
   {
      if (!empty(Mage::registry('[module]_istriggered')) return $this;

      // here you can perform whatever you want to do with your code

      Mage::register('[module]_istriggered', 1);
   }
}

The first time the method is called it registeres a key, which means the second time it's triggered it's not empty anymore and the method will return at the start

Another approach is to check which controller and action triggered the event.

In the observer you can get the module, controller and action name.

$frontName = Mage::app()->getRequest()->getRouteName();
$controllerName = Mage::app()->getRequest()->getControllerName();
$actionName = Mage::app()->getRequest()->getActionName();

$myURI = $frontName . '_'. $controllerName . '_' . $actionName;

And later check in your method who's dispatching the event.

In a stock magento install, when creating a user from the user area the value of $myURI would be customer_account_createpost.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top