I think the best way to do this would be to create a behavior that you can attach to your models that you want logged. Then you can share the behavior with us
I think the best way to do this would be to create a behavior that you can attach to your models that you want logged. Then you can share the behavior with us
Ok, but there are some things unclear to me:
Where to place the behavior-Classes meeting the standards?
How to attach the behavior to the AR-Classes? I read the Guide, but is there a more complete exaple somewhere?
How to access the fields of the AR (old/new values) from within the behavior's functions?
1. You can place the behavior class anywhere. Since you want to log changes to AR, your behavior class may extend from CActiveRecordbehavior.
I created a class ActiveRecordLogablebehavior (application.behaviors.ActiveRecordLogablebehavior), it extends the class CActiveRecordbehavior. It uses a new ActiveRecord "ActiveRecordLog", which represents the lines logged into the database table.
public function afterSave($event)
{
$log=new ActiveRecordLog;
if ($this->Owner->isNewRecord) {
$log->mode= 'INSERT';
} else {
$log->mode= 'UPDATE';
}
$log->model= get_class($this->Owner);
$log->idModel= $this->Owner->getPrimaryKey();
$log->NADA= date("Y-m-d H:i:s", time()); // creation date
$log->NAID= Yii::app()->user->Name; // user
$log->save();
}
Quote
2. Please check CModel::behaviors() on how to attach a behavior.
Works fine, thank you!
public function behaviors()
{
return array(
'ActiveRecordLogablebehavior'=>'application.behaviors.ActiveRecordLogablebehavior',
);
}
Quote
3. A behavior contains an 'owner' property which refers to the object it is attached to.
I managed to access the ActiveRecord using "owner", thank you. Is there a way to easily compare old and new values when saving or do I have to save the old values in onbeforeSave and compare them in onAfterSave?
Everything is working, only comparing old and new values is not done yet…
One time I considered having Yii comparing old values to new values for the user of detecting when a user email is changed, and then re-sending a verification email. I decided there was no good clean solution though
The best way I believe to do this would be to extend setAttributes() in the model, because that is where the new values are set so you can have your app inspect both old and new data at the same time.
However that can't be done with a behavior.
Maybe Yii should have another event added? something like this:?
setAttributes() is more like a shortcut to multiple attribute assignments. It is not a reliable place to capture old values because you may also have several attributes that need individual assignments.
afterFind() should be a good place because it is where the AR instance is populated with data coming from database. In the behavior object, we can keep a copy of the attributes.
afterFind() should be a good place because it is where the AR instance is populated with data coming from database. In the behavior object, we can keep a copy of the attributes.
I played around trying to implement this in the behavior object, but without success yet. Maybe my PHP knowledge is not sufficient enough or I had some errors in reasoning Right now when I fill a variable inside the behavior object with the attributes of the AR within afterFind() and try to compare them to the current attributes in the beforeSave(), the saved (old) attributes are empty.
When I find out the correct solution, maybe I will post this topic to the Cookbook (I suppose it is interesting for others also). Hints and code snipptes would be appreciated…