kangyasin / revisionable
无需思考即可为您的模型保留修订历史,作为Laravel的包创建
Requires
- php: >=5.3.0
- illuminate/support: ~4.0|~5.0|~5.1
Requires (Dev)
- orchestra/testbench: ~3.0
- dev-master
- 1.29.0
- 1.28.0
- 1.27.0
- 1.26.0
- 1.25.0
- 1.24.0
- 1.23.0
- 1.22.2
- 1.22.1
- 1.22.0
- 1.21.0
- 1.20.0
- 1.19.0
- 1.18.0
- 1.17.0
- 1.16.0
- 1.15.1
- 1.15.0
- 1.14.0
- 1.13.0
- 1.12.1
- 1.12.0
- 1.11.0
- 1.10.0
- 1.9.0
- 1.8.0
- 1.7.0
- 1.6.0
- 1.5.0
- 1.4.1
- 1.4.0
- 1.3
- 1.2.3
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.0
- dev-develop
This package is auto-updated.
Last update: 2021-11-02 06:36:52 UTC
README
如果在项目中为任何模型拥有修订历史,而不需要为此做任何工作,岂不是很好?通过简单地从模型扩展 revisionable,您可以立即获得所需的功能,并能够显示类似以下的历史记录
- Chris 将标题从 'Something' 更改为 'Something else'
- Chris 将类别从 'News' 更改为 'Breaking news'
- Matt 将类别从 'Breaking news' 更改为 'News'
因此,您不仅可以看到发生的历史,还可以看到谁做了什么,因此有问责制。
Revisionable 是一个 Laravel 包,允许您无需思考即可为模型保留修订历史。有关一些背景信息和信息,请参阅这篇文章
与第三方 Auth / Eloquent 扩展一起工作
Revisionable 支持 Cartalyst 的 Sentry 驱动的 Auth
Revisionable 现在也可以用作特质,因此您的模型可以继续扩展 Eloquent,或者任何扩展 Eloquent 的类(如 Ardent)。
安装
Revisionable 可通过 composer 安装,详细信息在 packagist,这里。
将以下内容添加到您项目的 composer.json 文件的 require 部分
"kangyasin/revisionable": "1.*",
运行 composer update 下载包
php composer.phar update
最后,您还需要对包运行迁移(Laravel 5.x)
php artisan migrate --path=vendor/kangyasin/revisionable/src/migrations
对于 Laravel 4.x 用户
php artisan migrate --package=kangyasin/revisionable
如果您将要频繁进行完全的迁移(使用
migrate:refresh),您可以采取的一项操作是将迁移文件从包复制到您的app/database文件夹中,并将类名从CreateRevisionsTable更改为类似CreateRevisionTable的名称(不带 's',否则您将收到重复类的错误消息)
cp vendor/kangyasin/revisionable/src/migrations/2013_04_09_062329_create_revisions_table.php app/database/migrations/
文档
实现
新的、基于特质的实现
对于您想要保留修订历史记录的任何模型,请包含 revisionable 命名空间并在模型中使用 RevisionableTrait,例如,如果您正在使用另一个可启动的特质,请确保在模型中覆盖 boot 方法;
namespace MyApp\Models; class Article extends Eloquent { use \Kangyasin\Revisionable\RevisionableTrait; public static function boot() { parent::boot(); } }
作为特质,revisionable 现在可以与标准 Eloquent 模型一起使用,或任何扩展 Eloquent 的类,例如 Ardent。
特质需要 PHP >= 5.4
传统基于类的实现
新的基于特质的策略与Revisionable的现有安装向后兼容。您仍然可以使用以下安装说明,这本质上是对特质的包装进行扩展。
对于您想要保留修订历史记录的任何模型,请包含revisionable命名空间,并扩展revisionable而不是eloquent,例如:
use Kangyasin\Revisionable\Revisionable; namespace MyApp\Models; class Article extends Revisionable { }
请注意,它也与命名空间模型兼容。
实现说明
如果需要,您可以在模型中将$revisionEnabled设置为false来禁用修订版。如果您想暂时禁用修订版,或者您想创建一个扩展修订版的基模型,所有模型都扩展该基模型,但您想为某些模型禁用修订版,这会很有用。
namespace MyApp\Models; class Article extends Eloquent { use Kangyasin\Revisionable\RevisionableTrait; protected $revisionEnabled = false; }
您还可以通过将$historyLimit设置为在停止修订之前要保留的修订次数来在X次修订后禁用修订版。
namespace MyApp\Models; class Article extends Eloquent { use Kangyasin\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 Kangyasin\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. }
存储软删除
默认情况下,如果您的模型支持软删除,revisionable将存储此删除和任何恢复作为模型的更新。
您可以通过将deleted_at添加到$dontKeepRevisionOf数组中来选择忽略删除和恢复。
为了更好地格式化deleted_at条目的输出,您可以使用isEmpty格式化程序(有关示例,请参阅格式输出)。
存储创建
默认情况下,新模型的创建不会作为修订版存储。只有模型的后续更改会被存储。
如果您想将创建作为修订版存储,可以通过在模型中添加以下内容来覆盖此行为,将revisionCreationsEnabled设置为true:
protected $revisionCreationsEnabled = true;
更多控制
毫无疑问,会有一些情况您不想只为模型的某些字段存储修订历史记录,这以两种不同的方式得到支持。在您的模型中,您可以指定您希望明确跟踪的字段,其他所有字段将被忽略
protected $keepRevisionOf = array( 'title' );
或者,您可以指定您明确不希望跟踪的字段。其他所有字段将被跟踪。
protected $dontKeepRevisionOf = array( 'category_id' );
$keepRevisionOf设置优先于$dontKeepRevisionOf
事件
每次创建模型修订时,都会触发一个事件。您可以监听revisionable.created、
revisionable.saved或revisionable.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 Kangyasin\Revisionable\Revisionable; class Article extends Revisionable { public function identifiableName() { return $this->title; } }
oldValue() 和 newValue()
获取模型更新前后的值。如果是外键,将调用identifiableName()。
作为修订的外键未知或无效
在旧值或新值为不再存在的外键或实际上为null的情况下,您可以在模型中设置两个变量来控制这些情况下的输出。
protected $revisionNullString = 'nothing'; protected $revisionUnknownString = 'unknown';
disableRevisionField()
有时暂时禁用一个可修订字段可能会有用,如果您想要保存更新,但又不需要保留更改记录。
$object->disableRevisionField('title'); // Disables title
或
$object->disableRevisionField(array('title', 'content')); // Disables title and content
贡献
鼓励并欢迎贡献;为了保持有序,所有错误和请求都应在GitHub的主项目问题标签中打开,在kangyasin/revisionable/issues。
所有pull请求都应提交到develop分支,以便在合并到master分支之前进行测试。
遇到问题了吗?
如果您在使用此软件包时遇到问题,那么其他人可能已经遇到了相同的问题。您可以在以下两个地方查找对您问题的常见答案:
如果您更愿意在StackOverflow上公开发布您的问题,请使用'revisionable'标签。