sofa/laravel-history

0.1.1 2021-06-19 06:53 UTC

This package is auto-updated.

Last update: 2024-09-19 14:01:09 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

无需设置,直接为您的 Eloquent 模型记录历史。只需安装、迁移即可使用!

路线图(欢迎贡献 🙏🏼)

  • 保留配置 & 命令
  • 将前端实现捆绑起来以以美丽的形式呈现历史 blade
  • 将前端实现捆绑起来以以美丽的形式呈现历史 vue
  • 将前端实现捆绑起来以以美丽的形式呈现历史 TALL stack
  • 将前端实现捆绑起来以以美丽的形式呈现历史 react

安装

您可以通过 composer 安装此包

composer require sofa/laravel-history

然后发布迁移和配置,然后运行迁移以创建所需的表

php artisan vendor:publish --provider="Sofa\History\HistoryServiceProvider"
php artisan migrate

这是发布配置文件的内容

return [
    /**
     * Model of the User performing actions and recorded in the history.
     *
     * @see \Sofa\History\History::user()
     */
    'user_model' => 'App\Models\User',

    /**
     * Custom user resolver for the actions recorded by the package.
     * Should be callable returning a User performing an action, or their raw identifier.
     * By default auth()->id() is used.
     *
     * @see \Sofa\History\HistoryListener::getUserId()
     */
    'user_resolver' => null,

    /**
     * **RETENTION** requires adding cleanup command to your schedule
     *
     * Retention period for the history records.
     * Accepts any parsable date string, eg.
     * '2021-01-01' -> retain anything since 2021-01-01
     * '3 months' -> retain anything no older than 3 months
     * '1 year' -> retain anything no older than 1 year
     * @see strtotime()
     *
     * @see \Sofa\History\RetentionCommand
     */
    'retention' => null,
];

用法

使用模型进行时间旅行

$postFromThePast = History::recreate(Post::class, $id, '2020-12-10', ['categories']);
// or: $postFromThePast = Post::recreate($id, '2020-12-10', ['categories']);

// model attributes as of 2020-12-10:
$postFromThePast->title;

// relations as of 2020-12-10:
$postFromThePast->categories->count()

// related models attributes also as of 2020-12-10:
$postFromThePast->categories->first->name;

获取您模型的完整历史/审计日志

$history = History::for($post)->get();

# For each update in the history you will get an entry like below:
>>> $history->first()
=> Sofa\History\History {#4320
     id: 16,
     model_type: "App\Models\Post",
     model_id: 5,
     action: "created",
     data: "{"title": "officiis", "user_id": 5, "created_at": "2021-06-07 00:00:00", "updated_at": "2021-06-07 00:00:00"}",
     user_id: null,
     created_at: "2021-06-07 00:00:00",
     updated_at: "2021-06-07 00:00:00",
   }

# And here you can see a sample of the recorded activity:
>>> $history->pluck('action')
=> Illuminate\Support\Collection {#4315
     all: [
       "created",
       "pivot_attached",
       "pivot_attached",
       "pivot_attached",
       "updated",
       "updated",
       "pivot_detached",
       "pivot_detached",
       "pivot_detached",
       "deleted",
       "restored",
       "pivot_attached",
       "pivot_attached",
     ],
   }

您还可以轻松为您的用户创建审计日志

// User model
public function auditLog()
{
    return $this->hasMany(History::class, 'user_id');
}

// Then
$auditLog = auth()->user()->auditLog()->paginate();

附加设置 & 已知限制

此包提供2个主要功能

  • 为模型记录完整历史
  • 以过去的形式重新创建具有所有关系的模型

历史记录为所有 Eloquent 模型自动工作(真的 😉)。此外,它还会记录和重新创建模型关系。然而,由于 Laravel 中关系的内部工作方式,存在一些限制

  • 完全支持自动创建 HasManyBelongsToMorphToMorphMany & HasManyThrough

  • 记录和重新创建多对多关系需要自定义 pivot 模型,以便 Laravel 触发相关事件(BelongsToManyMoprhToMany)。如果您已经在关系(s)上定义了自定义 pivot,则无需执行任何操作。否则,您可以使用提供的占位符 pivot 模型

    // original relations:
    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }
    
    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
    
    
    // change to:
    public function categories()
    {
        return $this->belongsToMany(Category::class)->using(\Sofa\History\PivotEvents::class);
    }
    
    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable')->using(\Sofa\History\MorphPivotEvents::class);
    }
  • 只有当满足特定要求时,HasOne 关系才能重新创建:关系定义上有单个 orderBy(...),并且没有 复杂where(...) 子句(它 不会影响 记录历史,只是重新创建具有关系的模型)

    // this will work:
    public function lastComment()
    {
        return $this->hasOne(Comment::class)->latest('id')->whereIn('status', ['approved', 'pending']);
    }
    
    // this will not work (currently...):
    public function lastComment()
    {
        return $this->hasOne(Comment::class) // no ordering
            ->where(fn ($q) => $q->where(...)->orWhere(...)); // unsupported where clause
    }
    • HasOneThrough 目前不支持

测试

composer test

变更日志

有关最近更改的更多信息,请参阅CHANGELOG

贡献

有关详细信息,请参阅CONTRIBUTING

鸣谢

许可证

MIT 许可证(MIT)。有关更多信息,请参阅许可证文件