always-open/laravel-model-auditlog

跟踪对模型所做的更改并将它们记录到单独的表中。

v8.0.1 2023-07-17 16:24 UTC

README

Latest Version on Packagist Build Status Total Downloads Maintainability

当修改模型记录时,记录所做的更改和谁做了这些更改是非常有用的。已经有很多相关包了,但这个包的不同之处在于它将更改记录到单独的表中以提高性能,并支持真实的外键。

安装

您可以通过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 [];
}

与交叉表一起工作

审计日志也可以支持交叉模型上的更改。

在这个例子中,我们有一个 poststags 表,以及一个包含 post_idtag_idpost_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);
}

当通过 detachsync 删除交叉记录时,将为每个键(例如:post_idtag_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)。有关更多信息,请参阅许可证文件