antonyz89 / change-log-behavior
yii2模型的简单变更日志行为
1.2.4
2024-05-27 12:29 UTC
Requires
- yiisoft/yii2: ^2.0.17
README
为你的yii2-models提供简单行为
由 Cranky4/change-log-behavior 分支而来
安装
1- 通过composer安装包
composer require antonyz89/change-log-behavior "*"
2- 运行迁移
yii migrate --migrationPath=@vendor/antonyz89/change-log-behavior/src/migrations
使用方法
1- 将 ChangeLogBehavior 添加到任何模型或活动记录
public function behaviors() { return [ ... [ 'class' => ChangeLogBehavior::className(), 'db' => Yii::$app->other_db, # optional (default is the same as Yii::$app->db) 'excludedAttributes' => ['updated_at'], ], ... ]; }
注意:行为仅监视“安全”属性。如果您不想记录其更改,请将属性添加到 excludedAttributes 中。
2- 将 ChangeLogList 添加到视图中
echo ChangeLogList::widget([ 'model' => $model, ])
3- 添加自定义日志
$model->addCustomLog('hello world!', 'hello_type')
自定义字段
使用自定义字段,您可以在名为 custom_fields
的属性中存储额外的值。当您需要根据其他字段或关系生成值时,此功能非常有用。
public function behaviors() { return [ [ 'class' => ChangeLogBehavior::class, 'autoCache' => true, 'customFields' => [ 'total' => static function (self $model) { return $model->calculateTotal(); }, // or static function (self $model) { return $model->createdBy->name; } 'created_by' => 'createdBy.name' ] ] ]; }
在字段名称后使用 !
强制保存,即使它没有更改。
public function behaviors() { return [ [ 'class' => ChangeLogBehavior::class, 'autoCache' => true, 'customFields' => [ 'total' => static function (self $model) { return $model->calculateTotal(); }, // `user_id` will be registered even if it hasn't changed 'user_id!' => 'user.name', 'created_by' => 'createdBy.name' ] ] ]; }
工作原理
-
在查找模型时,自定义字段被激活以缓存自定义字段的当前值。在保存模型时,自定义字段被重新生成以存储前后值。
{ "title": ["Hello World", "New Title"], "custom_fields": { "total": [50, 100] } }
-
自动缓存自定义字段
- 默认情况下
$autoCache
是false
,自定义字段不会在触发ActiveRecord::EVENT_AFTER_FIND
时缓存,以防止性能问题。 - 调用
cacheCustomFields()
手动缓存自定义字段。class FooController extends Controller { // ... public function actionUpdate($id) { $model = $this->findModel($id); // cache custom fields manually // [[cacheCustomFields()]] is a magic method that calls [[ChangeLogBehavior::cacheCustomFields()]] $model->cacheCustomFields(); $modelChildren = array_map(function () { // imagine something cool here }, $this->request->post()); foreach ($modelChildren as $modelChild) { $modelChild->parent_id = $model->id; $modelChild->save(); } // on save the custom fields are computed again and saved if they changed $model->save(); } }
- 要启用
$autoCache
,将其设置为true
,则自定义字段将在触发ActiveRecord::EVENT_AFTER_FIND
时缓存。但请注意。
- 默认情况下
删除时保存数据
默认情况下,行为在删除时不保存数据。将 dataOnDelete
设置为 true
以在删除时保存数据。
/** * @inheritdoc */ public function behaviors() { return [ [ 'class' => ChangeLogBehavior::class, 'dataOnDelete' => true ] ]; }
结果将类似于
{ "field_1": ["value", null], "field_2": ["value", null], "field_3": ["value", null], }
最后值总是 null
。
dataOndelete = true
也会保存自定义字段。
父ID
为变更日志设置父ID。
这对于创建自定义的变更日志视图非常有用。
默认值: null
,接受: null
| string
| callable
public function behaviors() { return [ [ 'class' => ChangeLogBehavior::class, // get `user_id` from model ($model->user_id) 'parentId' => 'user_id', // get `user_id` from model using static function 'parentId' => static functiobn (self $model) { if ($model->type !== 'ADMIN') return $model->user_id; } return null; ] ]; }
示例
模型 Post
/** * @propertu int id * @property int created_at * @property int updated_at * @property string title * @property int rating */ class Post extends yii\db\ActiveRecord { /** * @inheritdoc */ public function behaviors() { return [ [ 'class' => ChangeLogBehavior::class, 'excludedAttributes' => ['created_at','updated_at'], // (optional) autoCache is disabled by default 'autoCache' => false, // (optional) - custom fields 'customFields' => [ 'total' => static function (self $model) { return $model->calculateTotal(); }, // or static function (self $model) { return $model->createdBy->name; } 'created_by' => 'createdBy.name' ] ] ]; } }
视图 post/view.php
use antonyz89\ChangeLogBehavior\ListWidget as ChangeLogList; use app\models\Post; /** * @var Post $model */ echo DetailView::widget([ 'model' => $model, 'attributes' => [ 'id', 'title', 'rating', 'created_at:datetime', 'updated_at:datetime', ], ]); echo ChangeLogList::widget([ 'db' => Yii::$app->other_db, # optional (default is the same as Yii::$app->db) 'model' => $model, ]);