Hi,
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. We developed an extension that could help you to avoid this restriction.
Installation
[list=1]
[*]Download package from attachment
[*]Unzip package to your app folder
[*]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',
),
...
);
[*]Important: Make sure that all your models extend from ActiveRecord class (not CActiveRecord)
[*]Modify protected/components/DemoObserver.php in concordance with your wishes
[/list]
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.
One more example: 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 extension will be helpful for you and profitable for your projects.