CE 1.9.2 – Custom sales_order_save_after Observer Fires Twice

ce-1.9.2.0event-observermodule

This has been driving me crazy for the last few hours now. I created a module to test sending Suppliers a custom email only once the order has been paid for (Order status changes to Processing). I thought everything was working well: emails were been sent, the correct data was coming through the emails … until I realised that the emails were being sent twice.

To troubleshoot this, I skipped the email function, and instead wrote the word hello to a custom log file. And indeed hello was written twice. Here are some excerpts from my code for my custom module which is currently observing the sales_order_save_after event.

inside config.xml

<events>
    <sales_order_save_after>
        <observers>
            <test_suppliernotification>
                <type>singleton</type>
                <class>test_mod/observer</class>
                <method>notifySupplier</method>
            </test_suppliernotification>
        </observers>
    </sales_order_save_after>
</events>

inside app/code/local/Test/SupplierNotification/Model/Observer.php

class Test_SupplierNotification_Model_Observer
{
    public function notifySupplier(Varien_Event_Observer $observer) {
        $order = $observer->getEvent()->getOrder();
        $stateProcessing = Mage_Sales_Model_Order::STATE_PROCESSING;

        if($order->getState() == $stateProcessing && $order->getOrigData('state') != $stateProcessing) {
            Mage::log("hello", null, 'test_suppliernotification.log');
            return true;
        }
    }
}

output of var/log/test_suppliernotification.log

2015-10-02T01:17:49+00:00 DEBUG (7): hello
2015-10-02T01:17:49+00:00 DEBUG (7): hello

I cannot figure this one out! Has something like this happen to any of you, and if so, how did you solve it? I'm not sure what additional info you may require, so please let me know if you need to see any additional code. I'd really appreciate any assistance in this regard.

EDIT
Forgot to mention that for the particular order that I had tested, the Order status moved from Pending -> Pending Payment -> Processing.

Best Answer

I donot know why this is happing but you can prevent using registry variable (Mage::registry('VARIEABLE')).

<?php
class Test_SupplierNotification_Model_Observer
{
    public function notifySupplier(Varien_Event_Observer $observer) {

  /*check registry variable and 

  on first time Mage::registry('prevent_observer') does not save value 
  So, it will execuate only on first time 
  */
  if(!Mage::registry('prevent_observer')):
      $order = $observer->getEvent()->getOrder();
      $stateProcessing = Mage_Sales_Model_Order::STATE_PROCESSING;
   // Assign value to registry variable
  Mage::register('prevent_observer',true);

      if($order->getState() == $stateProcessing && $order->getOrigData('state') != $stateProcessing) {
          Mage::log("hello", null, 'test_suppliernotification.log');
          return true;
      }

      endif;
    }
}
Related Topic