overtrue/laravel-versionable

使Laravel模型支持版本控制。

资助包维护!
overtrue

5.2.6 2024-09-21 16:05 UTC

README

Build Status Latest Stable Version Latest Unstable Version Total Downloads License

这是一个使您的模型支持版本历史的简约方法,并且可以非常简单地回滚到指定的版本。

Sponsor me

要求

  1. PHP >= 8.1.0
  2. laravel/framework >= 9.0

功能

  • 保留指定数量的版本。
  • 版本可控属性的黑白名单。
  • 轻松回滚到指定版本。
  • 仅记录已更改的属性。
  • 易于定制。

安装

composer require overtrue/laravel-versionable -vvv

首先,发布配置文件和迁移文件

php artisan vendor:publish --provider="Overtrue\LaravelVersionable\ServiceProvider"

然后运行以下命令创建数据库迁移

php artisan migrate

用法

Overtrue\LaravelVersionable\Versionable 特性添加到模型中并设置版本可控属性

use Overtrue\LaravelVersionable\Versionable;

class Post extends Model
{
    use Versionable;

    /**
     * Versionable attributes
     *
     * @var array
     */
    protected $versionable = ['title', 'content'];

    // Or use a blacklist
    //protected $dontVersionable = ['created_at', 'updated_at'];

    <...>
}

在保存版本可控模型时将创建版本。

$post = Post::create(['title' => 'version1', 'content' => 'version1 content']);
$post->update(['title' => 'version2']);

获取版本

$post->versions; // all versions
$post->latestVersion; // latest version
// or
$post->lastVersion;

$post->versions->first(); // first version
// or
$post->firstVersion;

$post->versionAt('2022-10-06 12:00:00'); // get version from a specific time
// or
$post->versionAt(\Carbon\Carbon::create(2022, 10, 6, 12));

回滚

将模型实例回滚到指定版本

$post->getVersion(3)->revert();

// or

$post->revertToVersion(3);

不保存的回滚

$version = $post->versions()->first();

$post = $version->revertWithoutSaving();

删除版本

// soft delete
$post->removeVersion($versionId = 1);
$post->removeVersions($versionIds = [1, 2, 3]);
$post->removeAllVersions();

// force delete
$post->forceRemoveVersion($versionId = 1);
$post->forceRemoveVersions($versionIds = [1, 2, 3]);
$post->forceRemoveAllVersions();

通过id恢复已删除的版本

$post->restoreTrashedVersion($id);

暂时禁用版本控制

// create
Post::withoutVersion(function () use (&$post) {
    Post::create(['title' => 'version1', 'content' => 'version1 content']);
});

// update
Post::withoutVersion(function () use ($post) {
    $post->update(['title' => 'updated']);
});

自定义版本存储策略

您可以通过属性 protected $versionStrategy 设置以下不同的版本策略

  • Overtrue\LaravelVersionable\VersionStrategy::DIFF - 版本内容将仅包含已更改的属性(默认策略)。
  • Overtrue\LaravelVersionable\VersionStrategy::SNAPSHOT - 版本内容将包含所有版本可控属性值。

显示两个版本之间的差异

$diff = $post->getVersion(1)->diff($post->getVersion(2));

$diff 是一个对象 Overtrue\LaravelVersionable\Diff,它基于 jfcherng/php-diff

您可以将差异渲染到 多种格式,所有格式的结果如下

[
    $attribute1 => $diffOfAttribute1,
    $attribute2 => $diffOfAttribute2,
    ...
    $attributeN => $diffOfAttributeN,
]

toArray()

$diff->toArray();
//
[
    "name" => [
        "old" => "John",
        "new" => "Doe",
    ],
    "age" => [
        "old" => 25,
        "new" => 26,
    ],
]

其他格式

toArray(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toText(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toJsonText(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toContextText(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toInlineHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toJsonHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array
toSideBySideHtml(array $differOptions = [], array $renderOptions = [], bool $stripTags = false): array

注意

$differOptions$renderOptions 是可选的,您可以根据 jfcherng/php-diff 的 README 文件进行设置。$stripTags 允许您从差异中删除HTML标签,当您不想显示标签时很有用。

使用自定义版本模型

您可以在模型中定义 $versionModel,它使用此特性来更改版本的模型(表)

注意

模型必须扩展类 \Overtrue\LaravelVersionable\Version;

<?php

class PostVersion extends \Overtrue\LaravelVersionable\Version
{
    //
}

更新模型属性 $versionModel

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Overtrue\LaravelVersionable\Versionable;

class Post extends Model
{
    use Versionable;

    public string $versionModel = PostVersion::class;
}

集成

❤️ 赞助我

Sponsor me

如果您喜欢我的项目并想支持它,点击这里 ❤️

由 JetBrains 支持的项目

非常感谢 JetBrains 善意地为我提供许可证,以便我可以在本项目和其他开源项目中工作。

贡献

您可以通过以下三种方式之一进行贡献

  1. 使用 问题跟踪器 提交错误报告。
  2. 问题跟踪器 上回答问题或修复错误。
  3. 贡献新功能或更新 wiki。

代码贡献流程并不十分正式。你只需确保遵循PSR-0、PSR-1和PSR-2编码规范。任何新的代码贡献都必须附上适用的情况下的单元测试。

许可证

MIT