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 the
ir activities rel
eated 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 (
id
ActiveRecordLog INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
description VARCHAR(255) NULL,
action VARCHAR(20) NULL,[...]
creationdate TIMESTAMP NOT NULL,
userid VARCHAR(45) NULL,
PRIMARY KEY(idActiveRecordLog)
)
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...