Viewing Magento model data changes on before/after save event?


I’ve been trying to do something that seems like it should be simple:

  • hook a MODEL_save_after event (or MODEL_save_before if that’s more appropriate)
  • check getData() vs getOrigData() to see what changes the user has made

Now, in the example of the ‘customer_address’ model, edited through the backend, I find that both the save events are triggered twice.

The first time 'customer_address_save_before' is triggered, followed by 'customer_address_save_after'. In both cases getOrigData() and getData() are identical, except getData() has a new ‘updated_at’ value, and has a ‘store_id’ set (is this a bug?). So, the model doesn’t have the submitted data from the user yet. The events are both before entering user data or validation, so this is of no use.

'customer_address_save_before' is triggered, followed by 'customer_address_save_after' a second time. This time (in both cases), getOrigData() is empty, and getData() now has all the submitted data from the user. So I can’t compare on these events either! It appears this is after validation, saving, the lot!

I’m also unsure why the save process appears to occur twice?

Magento v1.3.2.4 in use.

Am I missing something?

3/10/2010 9:11:54 PM

Accepted Answer

I wound up hooking customer_address_save_before, and comparing the results to what was in the database like so:

customer_address_save_before_listener ($event)
  $address = $event->getCustomerAddress();

  $database_address = Mage::getModel('customer/address')->load($address->getId());

And comparing the getData() returns from the two. There were three gotcha's that I came across:

  • Use getEntityTypeId() on $address and check it. Despite hooking 'customer_address_save_before', you also get OrderAddress models being sent to your listener (this seems wrong to me, but ah well).
  • Check for arrays in $address->getData() values. For example, 'street' is returned from the DB as a single string, while the address your listener is passed has this exploded on endlines.
  • The CustomerAddress your listener is passed has a 'store_id'. Even though CustomerAddress doesn't store 'store_id', and it doesn't get saved (or loaded from) the database.
3/12/2010 12:37:31 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow