9

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?

5

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.

0

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

  • Yeah I had thought about this, but it feels quite dirty :(. I'm surprised that I cannot find out if an object has just been created in a model_save_after event – Matthew Haworth Mar 1 '14 at 12:56
  • only a before event has the isObjectNew data as far as I know as the data is not saved yet. As far as dirty goes, I guess there would be more elegant ways but it's certainly not a hack – Sander Mangel Mar 1 '14 at 13:02
  • $customer->save(); $this->_dispatchRegisterSuccess($customer); unfortunately here, the customer is saved before the register event is triggered, so the observer method wouldn't work anyway :( – Matthew Haworth Mar 1 '14 at 13:04
0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.