Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return data back to dispatcher from event observer in Magento

Tags:

php

magento

I have an extension for product registration that dispatches an event after the registration is saved. Another extension uses that event to generate a coupon for a virtual product if it is related to the registered product.

I need to get back data on the generated coupon to send to the user in an email along with the details of their product registration.

Is there a way to return data from the observer back to where the event is dispatched?

like image 691
Ryan Avatar asked Nov 07 '12 19:11

Ryan


2 Answers

No, there's nothing built in to the system for doing this. The Magento convention is to create a stdClass or Varien_Object transport object.

Take a look at the block event code

#File: app/code/core/Mage/Core/Block/Abstract.php

...
if (self::$_transportObject === null) 
{
    self::$_transportObject = new Varien_Object;
}

self::$_transportObject->setHtml($html);
Mage::dispatchEvent('core_block_abstract_to_html_after',
    array('block' => $this, 'transport' => self::$_transportObject));
$html = self::$_transportObject->getHtml();
...

Since self::$_transportObject is an object, and PHP objects behave in a reference like manner, any changes made to the transport object in an observer will be maintained. So, in the above example, if an observer developer said

$html = $observer->getTransport()-setHtml('<p>New Block HTML');

Back up in the system block code self::$_transportObject would contain the new HTML. Keep in mind that multiple observers will have a chance to change this value, and the order observers fire in Magento will be different for each configured system.

A second approach you could take is to use Magento's registry pattern. Register a variable before the dispatchEvent

like image 55
Alan Storm Avatar answered Nov 17 '22 09:11

Alan Storm


There is a trick available in Magento for your purpose. Since you can pass event data to the observers, like product or category model, it also possible to create a container from which you can get this data.

For instance such actions can be performed in dispatcher:

$couponContainer = new Varien_Object();
Mage::dispatchEvent('event_name', array('coupon_container' => $couponContainer));
if ($couponContainer->getCode()) { 
    // If some data was set by observer...
}

And an observer method can look like the following:

public function observerName(Varien_Event_Observer $observer) 
{
    $couponContainer = $observer->getEvent()->getCouponContainer();
    $couponContainer->setCode('some_coupon_code');
}

Enjoy and have fun!

like image 26
Ivan Chepurnyi Avatar answered Nov 17 '22 09:11

Ivan Chepurnyi