It seems there is no order state event by default, so how do you usually go about observing order state change? There are two possibilities I see: a) Overwrite the sales/order model to create your custom event for a state change b) Observe the order save event and look at the state in there

Is one of these the way to go or is there a better option?

Edit: Thanks for your answers so far. The situation is a bit more complicated. I want to add information to the order depending on the current state. Now here is the problem: In the save_before event I still have the old state and do not now the new state, because in the sales/order model the _beforeSave() method is as follows:


So the event is processed in parent::_beforeSave(); BUT the order state is actually changed afterwards in $this->_checkState(); (this is the automatic change, e.g. if you create an invoice, the state is moved to processing if no shipment is there, yet)

I cannot use the save_after event either, since I want to save sth. at the order and it would probably break everything to call a save in the save_after event.

Any ideas? My only idea now is to replicate the $this->_checkState(); behavior in my save_before observer to find out what the state will finally be...

3 Answers 3


I would strongly advise against overwriting sales/order model because of two reasons:

  1. It is always better to use events instead of rewrites.
  2. Besides the general advice to use events instead of rewrites, it is particularly not a good idea to overwrite such a central and important Magento class. The possibility for a conflict with another extension is too high.

I do not have any idea for a better solution - I think it would be absolutely okay to observe the sales_order_save_after event and check if the state has been changed.

  • I updated my question - any idea for this? Thanks!
    – mpaepper
    Commented Mar 19, 2013 at 11:09

I would prefer to save the old sate from the original data in the sales_order_save_before event and check againts this in the sales_order_save_after or before, depending what you want to do.

  • 2
    I think you do not need to hook into the _before event in order to save the old state. You can use getOrigData() instead: stackoverflow.com/a/8184430/719023
    – Simon
    Commented Mar 7, 2013 at 15:44
  • 1
    I'm sure they are set new after the save, because if not, you can't be sure, whether something changed at the next save(), but I don't find a place where this happens Commented Mar 7, 2013 at 15:57
  • I updated my question - any idea for this? Thanks!
    – mpaepper
    Commented Mar 19, 2013 at 11:08

I find overriding the setState method in Mage_Sales_Model_Order easier and better:

protected function _setState($state, $status = false, $comment = '',
            $isCustomerNotified = null, $shouldProtectState = false)
        // dispatch an event before we attempt to do anything
        Mage::dispatchEvent('sales_order_status_before', array('order' => $this, 'state' => $state, 'status' => $status, 'comment' => $comment, 'isCustomerNotified' => $isCustomerNotified, 'shouldProtectState' => $shouldProtectState));


        Mage::dispatchEvent('sales_order_status_after', array('order' => $this, 'state' => $state, 'status' => $status, 'comment' => $comment, 'isCustomerNotified' => $isCustomerNotified, 'shouldProtectState' => $shouldProtectState));

        return $this;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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