Difference between #3 and #12 of
How to log changes of ActiveRecords?

Changes

Title unchanged

How to log changes of ActiveRecords?

Category unchanged

Tutorials

Yii version unchanged

Tags changed

Logging

Content changed

If you want to knowA simple and effective way to keep track what theyour users are doing within your application, you need is to log their activities releated to database modifications. Normally you would like to knowYou can log whenever a record was inserted, changed or deleted, and also when and by which user this was done. For a [CActiveRecord] Model you could use a behavior for this purpose. SoThis way you will be able to add log functionality to ActiveRecords very easily. First of all you have to create a table for the log-lines in the database. Here is an example (MySQL):     [sql]
 
CREATE TABLE ActiveRecordLog ( idActiveRecordLog INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
description VARCHAR(255) NULL,
action VARCHAR(20) NULL,
[...]
creationdate TIMESTAMP NOT NULL,
userid VARCHAR(45) NULL,
PRIMARY KEY(id
ActiveRecordLog)
)
TYPE=InnoDB;
[...]
To be able to log the changes we will use a behavior class. So you have to create one (i.e. ActiveRecordLogableBehavior) and store it somewhere in your application directory (i.e. \protected\behaviors). The behavior class should extend [CActiveRecordBehavior] as we want to work with ActiveRecords here.

     
```php 
class ActiveRecordLogableBehavior extends CActiveRecordBehavior     { private $_oldattributes = array();
 
public function afterSave($event) {
 
if (!$this->Owner->isNewRecord) {

// new attributes
[...]
// compare old and new
foreach ($newattributes as $name => $value) {
if (!empty($oldattributes)) {
$old = $oldattributes[$name];
[...]
}


 
if ($value != $old) { //$changes = $name . ' ('.$old.') => ('.$value.'), '; $log=new ActiveRecordLog; $log->description= 'User ' . Yii::app()->user->Name . ' changed ' . $name . ' for ' . get_class($this->Owner)
 
                                            . ' changed ' . $name . ' for ' 
 
                                            . get_class($this->Owner) 
 
                                           
. '[' . $this->Owner->getPrimaryKey() .'].'; $log->action= 'CHANGE'; $log->model= get_class($this->Owner); $log->idModel= $this->Owner->getPrimaryKey(); $log->field= $name; $log->creationdate= date("Y-m-d H:i:s", timenew CDbExpression('NOW()'); $log->userid= Yii::app()->user->Nameid; $log->save();
 
 
 
} } } else { $log=new ActiveRecordLog; $log->description= 'User ' . Yii::app()->user->Name
 
                                    
. ' created ' . get_class($this->Owner)
 
                                    
. '[' . $this->Owner->getPrimaryKey() .'].'; $log->action= 'CREATE'; $log->model= get_class($this->Owner); $log->idModel= $this->Owner->getPrimaryKey(); $log->field= ''; $log->creationdate= date("Y-m-d H:i:s", time new CDbExpression('NOW()'); $log->userid= Yii::app()->user->Nameid; $log->save(); } }
 
 
public function afterDelete($event) { $log=new ActiveRecordLog; $log->description= 'User ' . Yii::app()->user->Name . ' deleted ' . get_class($this->Owner)
 
                                . get_class($this->Owner) 
 
                               
. '[' . $this->Owner->getPrimaryKey() .'].'; $log->action= 'DELETE'; $log->model= get_class($this->Owner); $log->idModel= $this->Owner->getPrimaryKey(); $log->field= ''; $log->creationdate= date("Y-m-d H:i:s", time new CDbExpression('NOW()'); $log->userid= Yii::app()->user->Nameid; $log->save(); }
 
 
public function afterFind($event)
{
// Save old values
[...]
$this->_oldattributes=$value;
}
}
 
```


The behavior class uses the ActiveRecordLog Model to store the log lines into the database. It will log a line each time a record is inserted or deleted. It will also log a line for each field which is changed.
[...]
In order to make an ActiveRecord Model use this behavior, you have to add the following code to the Model class:

     
```php 
public function behaviors()     { return array(      // Classname => path to Class      'ActiveRecordLogableBehavior'=>      'application.behaviors.ActiveRecordLogableBehavior', );     } 
 
}
 
```


Of course this simple example could be enhanced:
[...]
+ savethe attributeLabels instead of the field names
+ make description customizable
+ and so on...

 
 
 
31 1
47 followers
Viewed: 74 193 times
Version: 1.1
Category: Tutorials
Tags: Logging
Written by: pfth
Last updated by: Yang He
Created on: Feb 13, 2009
Last updated: 12 years ago
Update Article

Revisions

View all history