Have you ever heard about Yii events system? It allows you attach handlers to certain events in the application. Events could be raised by any application component (e.g. model, widget or controller) and could be very useful in some cases. You can read more about events here:

http://www.yiiframework.com/doc/guide/1.1/en/basics.component#component-event http://www.yiiframework.com/wiki/44/behaviors-events/

Yii events seem good, but have one drawback: you can attach handlers only to created objects. I.e. if you have Post model, then you can attach handler to ‘onAfterSave’ event only after creating instance of Post, but you can’t attach global handler to all instances of Post model. Our team developed an extension that could help you to avoid this restriction.

Installation:

  1. Download extension: http://weavora.com/yii/events_observer.zip
  2. Unzip package to your app folder
  3. Change protected/config/main.php:
return array(
    ...
   
    // append preloaded components with DemoObserver
    // (it's just example of observer)
    'preload'=>array(..., 'DemoObserver'),

    ...

    // add to application components ActiveRecord and DemoObserver
    // (it's just example of observer)
    'components' => array(
        ...
        'DemoObserver' => array(
            'class' => 'DemoObserver',
        ),
        'ActiveRecord',
    ),
    ...
);
  1. Important: Make sure that all your models extend from ActiveRecord class (not CActiveRecord)
  2. Modify protected/components/DemoObserver.php in concordance with your wishes

Example of usage:

class DemoObserver extends CComponent
{
    /**
     * Attach event handlers here
     */

    public function init()
    {
        Post::model()->attachEventHandler('onAfterSave', array($this, 'savePost'));
    }
   
    /**
     * Just example of event handler
     *
     * @param object $event
     */

    public function savePost($event)
    {
        $post = $event->sender;
        // do some actions with post
        // e.g.:
        if ($post->isNewRecord)
        {
            echo 'User ' . Yii::app()->user->id . ' just created new post "' . $post->name . '"';
        }
    }
}

This observer will print ‘User USER_ID just created new post “POST_NAME”‘ anytime new post created.

Advanced example of usage: Activity Feed

You can create observer which would be ‘spawn’ for user and log his actions (then you can show activity feed for user friends and so on).

class ActivityObserver extends CComponent
{
    /**
     * Attach event handlers here
     */

    public function init()
    {
        Post::model()->attachEventHandler('onAfterSave', array($this, 'savePost'));
        Comment::model()->attachEventHandler('onAfterSave', array($this, 'saveComment'));
        User::model()->attachEventHandler('onAfterSave', array($this, 'saveProfile'));
    }
   
    public function savePost($event)
    {
        $post = $event->sender;
        if ($post->isNewRecord)
        {
            $activity = new Activity();
            $activity->user_id = Yii::app()->user->id;
            $activity->message = "created new post '" . CHtml::encode($post->name) . "'";
            $activity->created_at = time();
            $activity->save();
        }
    }
   
    public function saveComment($event)
    {
        $comment = $event->sender;
        if ($comment->isNewRecord)
        {
            $activity = new Activity();
            $activity->user_id = Yii::app()->user->id;
            $activity->message = "commented post '" . CHtml::encode($comment->post->name) . "'";
            $activity->created_at = time();
            $activity->save();
        }
    }
   
    public function saveProfile($event)
    {
        $profile = $event->sender;
        if (!$profile->isNewRecord)
        {
            $activity = new Activity();
            $activity->user_id = $profile->id;
            $activity->message = "updated profile";
            $activity->created_at = time();
            $activity->save();
        }
    }
}

Now you can easily show friends activity:

class Activity extends ActiveRecord {

    public function scopes()
    {
        return array(
            'desc'=>array(
                'order' => 'created_at DESC',
            ),
        );
    }

    public function findAllForUser($friendsIds)
    {
        $criteria = new CDbCriteria();
        $criteria->condition = 'user_id IN (' . join(',', $friendsIds) . ')';
        return $this->desc()->findAll($criteria);
    }
}

$friendsActivity = Activity::model()->findAllForUser($friendsIds);

Hope this component will be helpful for you and profitable for your projects :)