Call our sales line
08000 484 679
Home > Magento Tips > Using a Controller Observer to Dispatch your Own Event

Using a Controller Observer to Dispatch your Own Event

Posted on: 4th Dec 2012 By: Robert Kent 3 Comments

Sometimes you may find that the big bad Magento Observer Cheatsheet does not cut it. When you want to do a particular thing and there’s no observer for it you kick yourself, because it means you have to inevitably rewrite a block or something silly like that. However there is one more saviour that I stumbled across in somebodies comments on another website earlier last week – using the controller observer to dispatch your events.

Normally events are dispatched within blocks and models – all of which are called by particular controllers depending where you are on a Magento website. However there is a very obscure event that is fired within a controller – in fact it is fired every single time you change pages on Magento – and we can use an observer to observer it.

The event I am talking about is the controller_action_predispatch event located within app>code>core>Mage>Core>Controller>Varien>Action.php – funnily enough you will find this on the cheat sheet. By using an observer on this event we can check what controller/action we are currently on at any time on the website, in theory this means that we can then dispatch our own event when we hit a certain controller action.

Getting confused? Let’s give an example, looking through the cheat sheet I cannot see an observer for a very fundamental part of an e-commerce website – the checkout_cart_product_add_before event. Now there is an “after” event but what good would that be if you are perhaps querying an external stock system and need to know the users selected quantity as they add to basket but before the product is actually placed in their basket? We need to somehow check the stock of that product via an API as it is picked off the shelf and on the way to the cart. Before it reaches the cart we need to know whether or not the customer is allowed their chosen quantity – so we need to stop the add to cart action and send the customer back to the product page with an error message. Therefore we need to run some custom code before the product is added to cart – checkout_cart_product_add_before.

So how does this tie in with our predispatch event? Well we need to fire our checkout_cart_product_add_before when the customer is adding a product to their cart – therefore we know that the customer is going to have to visit a particular controller / action – namely checkout_cart_add – or the addAction() of Checkout/CartController.php.

So first of all we set up an observer to check our predispatch like so (in our config.xml of our module):

<frontend>
<events>
<controller_action_predispatch>
 <observers>
 <add_event>
 <type>singleton</type>
 <class>module/observer</class>
 <method>addEvent</method>
 </add_event>
 </observers>
 </controller_action_predispatch>
</events>
</frontend>

So now we have a php function that we can use to dispatch our own event. Within this php function in your module’s Model>Observer.php we need the following:


public function addEvent($observer)
 {
if($observer->getEvent()->getControllerAction()->getFullActionName() == 'checkout_cart_add')
{
Mage::dispatchEvent('checkout_cart_product_add_before', $observer);
}
return $this;
 }

From the above you can see we are checking out the FullActionName – which we then check is equal to our checkout_cart_add action. If this is the case then we can dispatch our own custom event using the dispatchEvent name above – in our case checkout_cart_product_add_before.

Now we know that the checkout_cart_product_add_before event is being fired – we can add our own observer for it – so lets return to config.xml and amend it so we are now observing our custom event.

<frontend>
<events>
<controller_action_predispatch>
 <observers>
 <add_event>
 <type>singleton</type>
 <class>module/observer</class>
 <method>addEvent</method>
 </add_event>
 </observers>
 </controller_action_predispatch>
<checkout_cart_product_add_before>
 <observers>
 <add_event>
 <type>singleton</type>
 <class>module/observer</class>
 <method>ourCheckoutCartProductAddBeforeFunction</method>
 </add_event>
 </observers>
</checkout_cart_product_add_before>
</events>
</frontend>

Now we can simply add some code into our new function and this will be fired every time we are about to add a product to our cart! The good news is on this example we are using a controller and we know that we are posting data across – so retrieving our product data for use in the function is fairly easy. We simple check the request:


$request = Mage::app()->getRequest()->getPost();

Thanks for reading!

By Robert Kent

Rob is Ecommerce Web Design’s lead PHP developer, and an expert at customising the Magento framework to create completely unique sites. Follow him on twitter (because he's a twit) http://twitter.com/kent_robert. - .

3 Responses to “ Using a Controller Observer to Dispatch your Own Event ”

  1. m4e
    #1 | 4th December 2012

    Thanks, great article!
    And I think it’s better to get $request instance from $observer->getEvent()->getControllerAction()->getRequest() isn’t it?

  2. Robert Kent
    #2 | 4th December 2012

    Hi m4e in this case that is very true – as long as you have an observer to grab it from – the other code is for general grabbing of a request from say a controller file

  3. Ville Köykkä
    #3 | 2nd January 2013

    Hi,

    Nice article. This can also be implemented by listening a event for the controller action directly. Just using the same controller_action_predispatch but writing a name of the controller action to the end.

    Syntax:
    controller_action_predispatch_[route_controller_method]

    The example in the article would be:

    <controller_action_predispatch_checkout_cart_add>
        <observers>
            <add_event>
                <type>singleton</type>
                <class>module/observer</class>
                <method>ourCheckoutCartProductAddBeforeFunction</method>
            </add_event>
        </observers>
    </controller_action_predispatch_checkout_cart_add>
    

Post A Comment

Your comments:
Enclose code snippets within the appropriate tags: [php][/php]   [js][/js]   [xml][/xml]   [css][/css]   [html][/html]
E.g: [php]<?php echo "hello world"; ?>[/php]

Search Blog

Follow us on Twitter

Archives

For the record...

Views & opinions in this blog are those of the individual and do not necessarily reflect those of E-commerce Web Design or the Creare Group.