laravel-用户活动以及模型变动日志-spatie/laravel-activitylog
用户活动以及模型变动日志 ——spatie/laravel-activitylog
今天要学习的扩展包是 spatie/laravel-activitylog 它为我们提供了记录用户活动日志的功能,同时还提供了记录模型日志的功能。这个扩展包的开发者你应该比较熟悉了,spatie/laravel-backup
, spatie/laravel-responsecache
, spatie/laravel-permission
都是他们这个组织开发的。
之前的课程中我们介绍的扩展包 venturecraft/revisionable 也有类似的功能,可以记录模型的变动日志,这节课我们可以对比看看今天要学习的扩展包是不是更加方便。
安装
$ composer require spatie/laravel-activitylog
将迁移文件发布出来。
$ php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="migrations"
执行 migrate 创建数据表。
$ php artisan migrate
看一下数据结构:
字段描述
id自增 ID 主键
log_name日志名称,用于归类
description日志内容
subject_idsubject 模型多态关联 id
subject_typesubject 模型多态关联 type
causer_idcauser 模型多态关联 id
causer_typecauser 模型多态关联 type
properties属性,保存为 json
created_at创建时间
updated_at修改时间
最后将配置文件发布出来:
$ php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="config"
使用
记录使用日志
打开 tinker 测试一下:
activity()->log('hello world');
如果当前有用户登录,则会记录下来登录的用户:
$user = User::find(2);
auth()->setUser($user);
activity()->log('记录登录用户的日志');
命令行中我们想模拟用户登录,可以使用 auth()->setUser
。
当然我们也可以传入参数指定相关数据:
- inLog —— 等同于 useLog,记录日志的名称,用于分类;
- performedOn —— 影响的模型;
- causedBy —— 由谁引起的日志;
- withProperties —— 其他需要记录的属性。
$topic = Topic::first();
$causedUser = User::find(3);
activity()->inLog('test')->performedOn($topic)->causedBy($causedUser)->withProperties(['data' => 'test'])->log('测试参数');
查看一下数据:
- 未登录用户的,只是记录了描述日志;
- 登录用户,记录用户,以及描述日志;
- 修改相关参数后的日志。
使用起来非常简单,只需要在需要记录的地方添加上面这样的代码即可。
比如我们记录一下用户的回复日志。
app/Http/Controllers/RepliesController.php
.
.
.
public function store(ReplyRequest $request, Reply $reply)
{
$reply->content = $request->content;
$reply->user_id = Auth::id();
$reply->topic_id = $request->topic_id;
$reply->save();
activity('reply')->performedOn($reply)->log(':causer.name 添加了一条回复: :subject.content');
return redirect()->to($reply->topic->link())->with('sucess', '回复创建成功!');
}
public function destroy(Reply $reply)
{
$this->authorize('destroy', $reply);
$reply->delete();
activity('reply')->performedOn($reply)->log(':causer.name 删除了一条回复: :subject.content');
return redirect()->to($reply->topic->link())->with('success', '成功删除回复!');
}
.
.
.
在记录日志的时候,也就是 log
方法的参数中可以使用变量,这些变量会被替换:
:subject
—— 表示performedOn
的模型,可以使用点(:subject.column
)表示模型属性:causer
—— 表示causedBy
的模型,可以使用点(:causer.column
)表示模型属性:properties
—— 表示withProperties
自定义的属性,可以使用点(:properties.column
)表示对应的模型。
添加一个回复:
删除这个回复:
查看数据库日志:
查询相关日志
扩展包使用的日志模型在这里 ——Spatie\Activitylog\Models\Activity
。
所以我们可以直接通过这个模型做一些查询。打开 tinker:
查询对应名称的日志,比如我们查询所有回复相关的日志。
use Spatie\Activitylog\Models\Activity
Activity::inLog('reply')->get();
查询 id 为 2 的用户相关的日志:
$user = User::find(2);
Activity::causedBy($user)->get();
还可以进一步过滤
Activity::causedBy($user)->inLog('default')->get();
查询某个回复相关的日志:
$topic = Topic::find(1);
Activity::forSubject($topic)->get();
我们可以灵活的利用扩展包的模型,进行查询,总结一下:
- inLog —— 查询日志名称;
- forSubject —— 查询 subject;
- causedBy—— 查询 causer。
还可以通过模型方便的获取属性。
$activity = Activity::forSubject($topic)->first();
$activity->causer;
$activity->subject;
$activity->getExtraProperty('data');
getExtraProperty
方法可以获取 Properties
中的值。
记录模型变化
默认情况下扩展包会通过模型的 created
, updated
, deleted
事件,记录模型变化,测试一下。
首先需要给需要记录的模型增加一个 Trait
app/Models/Topic.php
.
.
.
use Spatie\Activitylog\Traits\LogsActivity;
class Topic extends Model
{
use LogsActivity;
.
.
.
创建一个话题,修改属性,然后删除,查看数据库:
创建,修改,删除都会触发日志的记录,但是默认情况下 description 只记录了模型的事件名,而且修改日志没有记录模型属性的前后变化,我们需要继续修改一下。
app/Models/Topic.php
.
.
.
protected static $ignoreChangedAttributes = ['updated_at'];
protected static $logAttributes = ['title', 'category_id'];
protected static $logOnlyDirty = true;
public function getDescriptionForEvent(string $eventName): string
{
switch ($eventName) {
case 'created':
$description = '话题被创建';
break;
case 'updated':
$description = '话题被修改';
break;
case 'deleted':
$description = '话题被删除';
break;
default:
$description = $eventName;
break;
}
return $description;
}
.
.
.
重新添加并修改一个话题,查看数据库:
description 被修改我们定义的样子,properties 中记录了模型的属性,打开 tinker 测试一下,修改了代码记得重启 tinker:
$topic = Topic::find(103);
$topic->activity
由于我们给 Topic 模型增加了 Trait,所以可以直接通过 activity
关系获取模型相关的所有日志。
由于我们记录了 title
以及 category_id
的变化,所以通过 activity
的 changes
方法就可以获取所有的模型的变化情况。
attributes
是模型当前的属性日志,old
是变化之前的属性日志。
扩展包并没有提供根据单个模型清理日志的功能,提供了一个命令 activitylog:clean
用来清除config('activitylog.delete_records_older_than_days)
之前的日志,我们可以根据需要调整配置,并且增加一个计划任务。
代码版本控制
$ git add -A
$ git commit -m 'spatie/laravel-activitylog'
tags: laravel,activitylog