event-interceptor A component, that allows to intercept events raised by observed components.

  1. Requirements
  2. Usage
  3. Change Log

The EventInterceptor component allows you to observe another component, which we call "subject". The EventInterceptor will register to the events of the subject. Every time the subject raises an event, the interceptor will raise an InterceptionEvent. This InterceptionEvent contains the name of the event raised by subject, as well as the intercepted CEvent instance.

This general InterceptionEvent can be usefull, whenever you want to handle events in the same way. An example would be event logging (see Usage).

Requirements

  • Should work with any version of Yii
  • Requires PHP 5.3 or above due to the usage of closures

Usage

This is an example that shows, how the EventInterceptor could be used to log events.

First, we implement a behavior EventLoggerBehavior:

class EventLoggerBehavior extends CBehavior
{
  private $_eventInterceptor = null;

  public function attach($owner)
  {
    parent::attach( $owner );

    $this->_eventInterceptor = new EventInterceptor();
    $this->_eventInterceptor->initialize( $owner );
    $this->_eventInterceptor->onEventIntercepted = array( $this, 'logEvent' );
  }

  public function logEvent( InterceptionEvent $event )
  {
    $interceptedEvent = $event->getInterceptedEvent();
    
    $msg  = 'Component "' . get_class($interceptedEvent->sender) . "' ";
    $msg .= 'raised event "' . $event->getInterceptedEventName() . "'.";
    // maybe include $interceptedEvent->params...
        
    Yii::log( $msg );
  }

}

Now, we can attach the behavior to any component, to log it's events. In this example, we use a controller, which raises events whenever one of its actions are invoked:

class SiteController extends Controller
{
  public function behaviors()
  {
    return array(
      'eventLogger' => array(
        'class'   => 'alias.to.EventLoggerBehavior',
      ),
    );
  }

  public function onBeforeActionInvoked(CEvent $event)
  {
    $this->raiseEvent( 'onBeforeActionInvoked', $event );
  }

  public function onAfterActionInvoked(CEvent $event)
  {
    $this->raiseEvent( 'onAfterActionInvoked', $event );
  }

  public function actionIndex()
  {
    $this->onBeforeActionInvoked( new CEvent($this, array(
      'action' => 'index'
    )) );

    $this->render('index');

    $this->onAfterActionInvoked( new CEvent($this, array(
      'whatever' => ...,
    )) );
  }

}

So now, whenever the controllers index action is invoked, the EventInterceptor will intercept the two events and raise its onEventIntercepted event with the original events embedded. The behavior, which has registered to the interceptor will be notified and will log the events.

If you don't want to intercept all events raised by your subject, you can provide a second argument to EventInterceptor::initialize(). This second parameter must be an array, which contains the names of the events that shall be intercepted. It defaults to an array with one entry "*", which means "intercept all events". So for the example above, if you were only interested in the "onBeforeActionInvoked" events, you had to modify the following:

class EventLoggerBehavior extends CBehavior
{
  [...]
  public $events = array('*');

  public function attach($owner)
  {
    [...]
    $this->_eventInterceptor->initialize( $owner, $this->events );
    [...]
  }

  [...]
}

class SiteController extends Controller
{
  public function behaviors()
  {
    return array(
      'eventLogger' => array(
        'class'   => 'alias.to.EventLoggerBehavior',
        'events'  => array( 'onBeforeActionInvoked' ),
      ),
    );
  }

  [...]
}

Change Log

June 13, 2011

  • Initial release
3 0
8 followers
401 downloads
Yii Version: 1.1
License: BSD-2-Clause
Category: Others
Tags:
Developed by: Ben
Created on: Jun 13, 2011
Last updated: 12 years ago

Downloads

show all