Hi jbru,
first of all: I don’t think events should be used to collect stuff. An application should not decide what to next depending of results of event handlers. Events happen. If an event is being raised, it indicates that something just had happened. It’s a mechanism for other components to be notified and take according actions on their own behalf. Not for other components to feedback information about how to go on. But that’s maybe only my very own point of view regarding events. Throughout the framework, there are a few uses of events that do exactly what I think they should not do. For example CActiveRecord’s onBeforeSave event can be used cancel a save operation.
To make something like this work you need to pass something to the event handlers when you invoke the event. The event handlers can work on this data, to indicate what they normally would return. It’s not possible to simply return some value from your event handler, because there might be many event handlers attached to one event (well I guess it would be possible to store all the results in a list, but the framework does not do anything like that):
$myComponent->onForestRan = array(new SomeOtherClass, 'eventHandler1');
$myComponent->onForestRan = array(new SomeOtherClass, 'eventHandler2');
So when the ForestRan event is raised, those two handlers will be invoked one after another. Remember how the event handler’s signature looks like:
public funtion SomeOtherClass::eventHandler1( CEvent $event )
{
}
You normally raise the event by doing something like this:
// definition of the event
public function onForestRan($event)
{
$this->raiseEvent('onForestRan',$event);
}
public function somewhereElse()
{
// invocation of the event
$event = new CEvent( $this /*, array('param1'=>$value1, 'param2'=>$value2) */);
$this->onForestRun( $event );
}
Now to collect results from your event handlers, you can either use your own EventClass, or you can pass a reference to the handlers.
First example, using own class:
class ForestRanEvent extends CEvent
{
public $aResults = array();
}
// definition of the event
public function onForestRan($event) {
$this->raiseEvent('onForestRan',$event);
}
public function somewhereElse()
{
// invocation of the event
$event = new ForestRanEvent( $this /*, array('param1'=>$value1, 'param2'=>$value2) */);
$this->onForestRan( $event );
// check results
foreach ($event->aResults as $result) {
// ...
}
}
// handling the event and returning data
public funtion SomeOtherClass::eventHandler1( ForestRanEvent $event )
{
// do stuff
// "return" result
$event->aResults[] = $thisHandlersResult;
}
Second example, using reference:
// definition of the event
public function onForestRan($event) {
$this->raiseEvent('onForestRan',$event);
}
public function somewhereElse()
{
// invocation of the event
$aResults = array();
$event = new CEvent( $this, array(
'results' => &$aResults, // pass results array as reference
/*
'param1' => $value1,
'param2' => $value2,
*/
));
$this->onForestRan( $event );
// check results
foreach ($aResults as $result) {
// ...
}
}
// handling the event and returning data
public funtion SomeOtherClass::eventHandler1( CEvent $event )
{
// do stuff
// "return" result
$event->params['results'][] = $thisHandlersResult;
}