exceedone/revisionable

此包已被废弃且不再维护。没有推荐替代包。

无需思考即可为您的模型保留修订历史,该包专为与Laravel一起使用而创建

v2.0.1 2018-12-04 08:51 UTC

README

  • 此存储库由 VentureCraft/revisionable 分支而来。我修复了比较json值的相关bug。
  • 此存储库仅供 exceedone/exment 使用。

Revisionable

Laravel 4.x Laravel 5.2 Latest Version Downloads License

在您的项目中为任何模型保留修订历史记录,而不必为此做任何工作,这不是很好吗?通过简单地从您的模型扩展 revisionable,您可以立即获得这样的功能,并能显示类似以下的历史记录

  • Chris 将标题从 'Something' 更改为 'Something else'
  • Chris 将类别从 'News' 更改为 'Breaking news'
  • Matt 将类别从 'Breaking news' 更改为 'News'

因此,您不仅可以查看发生的历史,还可以查看是谁做了什么,从而实现问责制。

Revisionable 是一个 Laravel 包,允许您无需思考即可为您的模型保留修订历史。有关背景和更多信息,请参阅这篇文章

与第三方 Auth / Eloquent 扩展一起工作

Revisionable 支持 Auth,由以下提供

Revisionable 现在也可以作为一个特性使用,因此您的模型可以继续扩展 Eloquent,或任何扩展 Eloquent 的其他类(如Ardent)。

安装

Revisionable 可以通过 composer 安装,详情请见 packagist,此处。

将以下内容添加到您的项目的 composer.json 文件的 require 部分

"venturecraft/revisionable": "1.*",

运行 composer update 下载包

php composer.phar update

最后,您还需要在包上运行迁移(Laravel 5.x)

php artisan migrate --path=vendor/venturecraft/revisionable/src/migrations

对于 Laravel 4.x 用户

php artisan migrate --package=venturecraft/revisionable

如果您将频繁进行完全的迁移(使用 migrate:refresh),您可以采取的一种替代方法是,将迁移文件从包中复制到您的 app/database 文件夹,并将类名从 CreateRevisionsTable 更改为类似 CreateRevisionTable 的内容(不带 's',否则您将收到错误消息,指出存在重复的类)

cp vendor/venturecraft/revisionable/src/migrations/2013_04_09_062329_create_revisions_table.php app/database/migrations/

文档

实现

基于特性(Trait)的新实现

对于您希望保留修订历史记录的任何模型,请包含 revisionable 命名空间,并在您的模型中使用 RevisionableTrait,例如:如果您正在使用其他可启动的特性(bootable trait),请确保在您的模型中覆盖 boot 方法;

namespace MyApp\Models;

class Article extends Eloquent {
    use \Venturecraft\Revisionable\RevisionableTrait;

    public static function boot()
    {
        parent::boot();
    }
}

作为特性,可修订性现在可以与标准Eloquent模型或任何扩展Eloquent的类一起使用,例如Ardent

特性需要PHP >= 5.4

旧类基于实现

基于新特性的方法与现有的Revisionable安装兼容。您仍然可以使用以下安装说明,这实际上是扩展特性的包装。

对于您希望保留修订历史记录的任何模型,请包含revisionable命名空间并扩展revisionable而不是eloquent,例如:

use Venturecraft\Revisionable\Revisionable;

namespace MyApp\Models;

class Article extends Revisionable { }

注意,它也适用于命名空间模型。

实现说明

如果需要,您可以通过在模型中将$revisionEnabled设置为false来禁用修订。如果您想暂时禁用修订,或者您想创建一个继承自revisionable的基本模型,该模型的所有模型都继承自它,但您想为某些模型关闭修订,这将很有用。

namespace MyApp\Models;

class Article extends Eloquent {
    use Venturecraft\Revisionable\RevisionableTrait;

    protected $revisionEnabled = false;
}

您还可以通过将$historyLimit设置为要停止修订之前要保留的修订数量来在X多次修订后禁用修订。

namespace MyApp\Models;

class Article extends Eloquent {
    use Venturecraft\Revisionable\RevisionableTrait;

    protected $revisionEnabled = true;
    protected $historyLimit = 500; //Stop tracking revisions after 500 changes have been made.
}

为了限制历史记录但不想停止跟踪修订,而是要删除旧修订,您可以通过设置$revisionCleanup来提供该功能。

namespace MyApp\Models;

class Article extends Eloquent {
    use Venturecraft\Revisionable\RevisionableTrait;

    protected $revisionEnabled = true;
    protected $revisionCleanup = true; //Remove old revisions (works only when used with $historyLimit)
    protected $historyLimit = 500; //Maintain a maximum of 500 changes at any point of time, while cleaning up old revisions.
}

存储软删除

默认情况下,如果您的模型支持软删除,修订性将存储此删除和任何恢复作为模型的更新。

您可以通过将deleted_at添加到$dontKeepRevisionOf数组中,选择忽略删除和恢复。

为了更好地格式化deleted_at条目的输出,您可以使用isEmpty格式化器(有关示例,请参阅格式输出)。

存储创建

默认情况下,新模型的创建不会存储为修订。只有模型随后的更改才会存储。

如果您想将创建存储为修订,可以通过将以下内容添加到模型中,将此行为覆盖为true:

protected $revisionCreationsEnabled = true;

更多控制

毫无疑问,会有一些情况您只想为模型的某些字段存储修订历史记录,这以两种不同的方式支持。在您的模型中,您可以选择明确指定要跟踪哪些字段,而其他所有字段都将被忽略

protected $keepRevisionOf = array(
    'title'
);

或者,您可以指定明确不希望跟踪哪些字段。所有其他字段将被跟踪。

protected $dontKeepRevisionOf = array(
    'category_id'
);

设置$keepRevisionOf优先于$dontKeepRevisionOf

事件

每次创建模型修订时都会触发一个事件。您可以监听revisionable.created
revisionable.savedrevisionable.deleted

// app/Providers/EventServiceProviders.php
public function boot(DispatcherContract $events)
{
    parent::boot($events);

    $events->listen('revisionable.*', function($model, $revisions) {
        // Do something with the revisions or the changed model. 
        dd($model, $revisions);
    });
}

格式输出

您可以使用eloquent访问器在模型中继续(并鼓励)设置值的输出,有关访问器的更多信息,请参阅laravel文档。下面的文档已过时。

在您想要控制值输出格式的情况下,例如布尔字段,您可以在模型中的$revisionFormattedFields数组中设置它们。例如:

protected $revisionFormattedFields = array(
    'title'  => 'string:<strong>%s</strong>',
    'public' => 'boolean:No|Yes',
    'modified' => 'datetime:m/d/Y g:i A',
    'deleted_at' => 'isEmpty:Active|Deleted'
);

您还可以通过模型中的$revisionFormattedFieldNames数组覆盖字段名称输出,例如:

protected $revisionFormattedFieldNames = array(
    'title' => 'Title',
    'small_name' => 'Nickname',
    'deleted_at' => 'Deleted At'
);

当您使用$revision->fieldName()输出修订字段名称时,这就会发挥作用。

字符串

要格式化字符串,只需在值前加上string:前缀,并确保包含%s(这是实际值将在格式化响应中出现的位置),例如:

string:<strong>%s</strong>

布尔值

布尔值默认会显示为0或1,这相当单调,对最终用户来说意义不大,因此可以使用此格式化程序输出更友好的内容。在值前加上boolean:前缀,然后使用管道符号分隔false和true选项,例如:

boolean:No|Yes

日期时间

日期时间默认会显示为Y-m-d H:i:s。在值前加上datetime:前缀,然后添加您的日期时间格式,例如:

datetime:m/d/Y g:i A

是否为空

这依赖于布尔值,但不是测试true或false值,而是检查值是否为null或空字符串。

isEmpty:No|Yes

它也可以接受%s,如果您想输出值,以下示例将显示'无内容'如果值为空,或如果存在实际值。

isEmpty:Nothing|%s

加载修订历史

要加载给定模型的修订历史,只需在该模型上调用revisionHistory方法,例如:

$article = Article::find($id);
$history = $article->revisionHistory;

显示历史记录

大多数情况下,修订历史将包含足够的信息以直接输出变更历史,但在外键更新时,我们需要能够进行一些映射,并显示比plan_id从3更改为1更友好的内容。

为此,有几个辅助方法可以帮助显示更深入的信息,因此您可以显示类似于Chris将计划从青铜更改为黄金的内容。

上面的结果将是以下内容的输出:

@foreach($account->revisionHistory as $history )
    <li>{{ $history->userResponsible()->first_name }} changed {{ $history->fieldName() }} from {{ $history->oldValue() }} to {{ $history->newValue() }}</li>
@endforeach

如果您已启用创建修订,则可以像这样显示:

@foreach($resource->revisionHistory as $history)
  @if($history->key == 'created_at' && !$history->old_value)
    <li>{{ $history->userResponsible()->first_name }} created this resource at {{ $history->newValue() }}</li>
  @else
    <li>{{ $history->userResponsible()->first_name }} changed {{ $history->fieldName() }} from {{ $history->oldValue() }} to {{ $history->newValue() }}</li>
  @endif
@endforeach

userResponsible()

返回负责进行修订的用户。返回用户模型,如果没有记录用户则返回null。

加载的用户模型取决于您在config/auth.php文件中为model变量设置的设置。

fieldName()

返回更新的字段名称,如果更新的字段是外键(在此阶段,它只是检查字段是否具有_id后缀)则返回_id之前的内容。例如,如果字段是plan_id,则返回plan

记住,您可以使用模型中的$revisionFormattedFieldNames数组覆盖字段名称的输出。

identifiableName()

当值(旧值或新值)是外键关系ID时使用。

默认情况下,它简单地返回被更新的模型的ID。是否需要您在自己的模型中重写此方法以返回有意义的值。例如:

use Venturecraft\Revisionable\Revisionable;

class Article extends Revisionable
{
    public function identifiableName()
    {
        return $this->title;
    }
}

oldValue() 和 newValue()

获取模型更新前后的值。如果是外键,则调用 identifiableName()。

未知或无效的外键作为修订

在旧值或新值是已不存在的外键,或者实际上为空的情况下,您可以在模型中设置两个变量来控制这些情况下的输出。

protected $revisionNullString = 'nothing';
protected $revisionUnknownString = 'unknown';

disableRevisionField()

有时暂时禁用可修订字段可能会很有用,如果您想要保存更新但不需要记录更改。

$object->disableRevisionField('title'); // Disables title

或者

$object->disableRevisionField(array('title', 'content')); // Disables title and content

贡献

鼓励并欢迎贡献;为了保持有序,所有错误和请求都应在主要项目的 GitHub 问题的标签页中打开,在 venturecraft/revisionable/issues

所有拉取请求都应提交到 develop 分支,以便在合并到 master 分支之前进行测试。

遇到问题了吗?

如果您在使用此包时遇到问题,其他人可能已经遇到相同的问题。您可以查找常见答案的两个地方是

如果您倾向于在 StackOverflow 上公开发布问题,请使用 'revisionable' 标签。