Magento Events and Observers

In this post we will see how magento manages events and observers.

Basics

Magento has a very powerful event/observer pattern which we can use very effectively in our custom modules. The basic principal of event/observer pattern is, certain events are fired/dispatched by magento through out its code base. These events have specific class objects attached as function parameters. Observers (class functions) can be setup which run when these events are fired and receive the class objects. The observer can manipulate, extract data from these class object and do additional processing required. So this help us to extend magento functionality without changing the magento core. So in practice it works like this, there are various events dispatched throughout magento using

Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $this)); 

Here ‘controller_action_predispatch’ is the name of the event and $this is class object which is passes as a parameter.

Next we define observer for this events in our module config.xml file e.g

<global>
        <events>
            <log_log_clean_after> <!-- event name -->
                <observers>
                    <catalog_product_compare_item>  <!-- unique event code -->
                        <class>catalog/observer</class>
                        <method>catalogProductCompareClean</method>
                    </catalog_product_compare_item>
                </observers>
            </log_log_clean_after>
        </events>
</global>

This way we can specify which observer method to fire for any event.

Magento Event Processing

Files To Refer
app/code/core/Mage/Core/Model/App.php

Entire core functionality for magento event handling is written in class “Mage_Core_Model_App” and function “dispatchEvent()”

So the way this function works, when a event gets dispatched from magento it first checks in the configuration object if any observers have been added for that event. If observers are found, it appends them all into an array.

Finally each observer is called serially one after the other. The code event/observer is quite simple in magento and can easily be understood looking at this function.

This how events are defined in config.xml file in any module

    <global>
        <events>
            <customer_login> <!-- Actual Event Name -->
                <observers>
                    <catalog> <!-- Unique Name For Each Observer -->
                        <type>model</type>
                        <class>catalog/product_compare_item</class>
                        <method>bindCustomerLogin</method>
                    </catalog>
                </observers>
            </customer_login>
</events>
    </global>

The first tag “global” is the event area. There are 3 possible event areas, “global”, “frontend” , “admin”.
The “type” tag in event has various option
1. disabled : observer method won’t run
2. object: this will create a singleton object of the “class” mentioned and fire the method
3. model: this will create a new object of the “class” and fire the method

Event Observer Arguments

The “class” which you defined as the event observer gets “Varien_Event_Observer” as a parameter in the method. It exposes the following methods

public function bindCustomerLogin(Varien_Event_Observer $event){

      $event->getEvent()->getObject1();  //the various class object can be accessed like this
      $event->getEvent()->getObject2();
}

Troubleshooting Events

If event created by you is not firing you can debug it at “Mage_Core_Model_App” class “dispatchEvent()” function.
First check the area of your event (global, frontend, adminhtml) and see if it loads in the dispatchEvent() function.
Next in this line

foreach ($eventConfig->observers->children() as $obsName => $obsConfig) {

So if your event shows up, if not then there is some problem with the config.xml for event.
Next check the

$this->_callObserverMethod($object, $method, $observer);

this function throws an exception but only when developer module is turned on. So you check here if an exception is thrown. By checking these 3 area’s you should come to know why your event is not firing.