always-open / laravel-model-auditlog
跟踪对模型所做的更改并将它们记录到单独的表中。
Requires
- php: ^7.3|^8.0
- always-open/laravel-process-stamps: ^5.0|^6.0|^7.0
- awobaz/compoships: ^2.0.3
- fico7489/laravel-pivot: ^3.0.1
- laravel/framework: ^8.0|^9.0|^10.0
Requires (Dev)
- doctrine/dbal: ^2.9|^3.0
- orchestra/testbench: ^6.0
- phpunit/phpunit: ^10.0
README
当修改模型记录时,记录所做的更改和谁做了这些更改是非常有用的。已经有很多相关包了,但这个包的不同之处在于它将更改记录到单独的表中以提高性能,并支持真实的外键。
安装
您可以通过composer安装此包
composer require always-open/laravel-model-auditlog
配置
php artisan vendor:publish --provider="\AlwaysOpen\AuditLog\AuditLogServiceProvider"
运行上述命令将发布配置文件。
用法
在您的表中添加适当的字段后,将特性添加到您的模型中。
// User model class User extends Model { use \AlwaysOpen\AuditLog\Traits\AuditLoggable;
要为您自己的模型生成审计日志模型/迁移,请使用以下命令
php artisan make:model-auditlog "\App\User"
将 \App\User
替换为您自己的模型名称。模型/表选项可以在配置文件中进行调整。
如果您需要忽略模型上的特定字段,扩展 getAuditLogIgnoredFields()
方法并返回一个字段数组。
public function getAuditLogIgnoredFields() : array { return ['posted_at']; }
使用该功能,您可以为应该记录的内容添加更多自定义逻辑。一个例子可能是不记录尚未发布的帖子标题的更改。
public function getAuditLogIgnoredFields() : array { if ($this->postHasBeenPublished()) { return ['title']; } return []; }
与交叉表一起工作
审计日志也可以支持交叉模型上的更改。
在这个例子中,我们有一个 posts
和 tags
表,以及一个包含 post_id
和 tag_id
的 post_tags
交叉表。
修改审计日志迁移,将 subject_id
列更改为使用两个交叉列。
Schema::create('post_tag_auditlog', function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedInteger('post_id')->index(); $table->unsignedInteger('tag_id')->index(); $table->unsignedTinyInteger('event_type')->index(); $table->unsignedInteger('user_id')->nullable()->index(); $table->string('field_name')->index(); $table->text('field_value_old')->nullable(); $table->text('field_value_new')->nullable(); $table->timestamp('occurred_at')->index()->default('CURRENT_TIMESTAMP'); });
为交叉表创建一个模型,它扩展了Laravel的Pivot类。此类必须使用AuditLoggablePivot特性,并定义一个 $audit_loggable_keys
变量,它用于将交叉表映射到审计日志表中。
class PostTag extends Pivot { use AuditLoggablePivot; /** * The array keys are the composite key in the audit log * table while the pivot table columns are the values. * * @var array */ protected $audit_loggable_keys = [ 'post_id' => 'post_id', 'tag_id' => 'tag_id', ]; }
注意:如果交叉表和审计日志表中已存在的列(例如:user_id
)具有相同的名称,则更改审计日志表中的列名(例如:audit_user_id
)并定义关系为 'audit_user_id' => 'user_id'
。
通过交叉表连接的两个模型需要更新,以便在交叉模型上触发事件。目前Laravel不支持交叉事件,因此需要第三方包。
composer require fico7489/laravel-pivot
让两个模型都使用PivotEventTrait
use Fico7489\Laravel\Pivot\Traits\PivotEventTrait; use Illuminate\Database\Eloquent\Model; class Post extends Model { use PivotEventTrait;
在两个相关模型中修改belongsToMany连接,包括使用函数和交叉模型。在Post模型中
public function tags() { return $this->belongsToMany(Tag::class) ->using(PostTag::class); }
在Tag模型中
public function posts() { return $this->belongsToMany(Post::class) ->using(PostTag::class); }
当通过 detach
或 sync
删除交叉记录时,将为每个键(例如:post_id
和 tag_id
)添加一个审计日志记录到审计日志表。 field_value_old
将是记录的id,而 field_value_new
将为null。记录将具有事件类型 PIVOT_DELETED
(id:6)。
如果您需要通过 auditLogs
关系(例如:$post_tag->auditLogs()->get())检索审计日志,则需要复合键的支持。
composer require awobaz/compoships
然后在交叉审计日志模型上使用特性
use Awobaz\Compoships\Compoships; use AlwaysOpen\AuditLog\Models\BaseModel; class PostTagAuditLog extends BaseModel { use Compoships;
有关交叉和审计日志的工作示例,请参阅 laravel-model-auditlog/tests/Fakes
,其中包含可工作的迁移和模型。
注意:两个模型必须使用AuditLoggable特性(例如:Post和Tag),以便 $post->tags()->sync([...])
的工作。
测试
composer test
使用Docker
所有资产都设置在docker-compose.yml文件下。第一次运行Docker镜像时,必须使用以下命令构建它
docker-compose build
然后您可以使用以下方式将其置于后台:
docker-compose up -d
由于图像已进行了抗锯齿处理,因此您可以通过以下方式访问其命令行:
docker exec -it processes-stamp-app /bin/bash
从那里,您可以在一个隔离的环境中运行测试
贡献
有关详细信息,请参阅贡献指南。
安全
如果您发现任何与安全相关的问题,请通过电子邮件@tomschlick / @qschmick联系,而不是使用问题跟踪器。
鸣谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。