lostcause / revisionable
无需思考即可为您的模型保留修订历史,作为Laravel 4的包创建
Requires
- php: >=5.3.0
- illuminate/support: ~4.0|~5.0
README
我因为它添加了来自VentureCraft#120的'postCreate'代码而进行了分支。我还需要集成https://github.com/ollieread/multiauth。
如果能够在项目中为任何模型都保留修订历史,而不需要为此做任何工作,那岂不是很好?通过简单地从您的模型扩展revisionable,您就可以立即拥有这样的功能,并且能够显示类似于以下的历史记录
- Chris将标题从'Something'改为'Something else'
- Chris将分类从'新闻'改为'重大新闻'
- Matt将分类从'重大新闻'改为'新闻'
因此,您不仅可以查看发生了什么,还可以知道是谁做的,这样就有责任可追。
Revisionable是一个laravel包,允许您无需思考即可为您的模型保留修订历史。有关背景信息和信息,请参阅这篇文章
与第三方Auth / Eloquent扩展一起工作
Revisionable支持由Cartalyst提供的Auth
Revisionable现在也可以作为特性使用,因此您的模型可以继续扩展Eloquent,或任何扩展Eloquent的类(如Ardent)。
安装
Revisionable可以通过composer安装,详细信息在packagist,这里。
将以下内容添加到项目的composer.json文件的require
部分
"lostcause/revisionable": "1.*",
运行composer update以下载包
php composer.phar update
最后,您还需要运行包的迁移
php artisan migrate --package=lostcause/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/
文档
实现
新的基于特性的实现
对于您想要保留修订历史记录的任何模型,请包含revisionable命名空间,并在模型中使用RevisionableTrait
,例如:
namespace MyApp\Models; class Article extends Eloquent { use \Venturecraft\Revisionable\RevisionableTrait; }
作为特性,revisionable现在可以与标准Eloquent模型一起使用,或任何扩展Eloquent的类,例如Ardent。
特性要求PHP >= 5.4
基于旧类的方法实现
新的基于特性的方法与Revisionable现有安装向后兼容。您仍然可以使用以下安装说明,它基本上是扩展特性的包装器。
对于任何您想要保留修订历史记录的模型,请包含可修订的命名空间并扩展可修订而不是eloquent,例如:
use Venturecraft\Revisionable\Revisionable; namespace MyApp\Models; class Article extends Revisionable { }
注意,这也适用于命名空间模型。
实现说明
如果需要,您可以在模型中将 $revisionEnabled
设置为 false 来禁用修订。如果您想暂时禁用修订,或者您想创建一个扩展可修订的基础模型,该模型扩展了所有您的模型,但您希望关闭某些模型的修订,这可能会很有用。
namespace MyApp\Models; class Article extends Eloquent { use Venturecraft\Revisionable\RevisionableTrait; protected $revisionEnabled = false; }
存储软删除
默认情况下,如果您的模型支持软删除,修订将存储此操作以及任何恢复作为模型的更新。
您可以通过将 deleted_at
添加到 $dontKeepRevisionOf
数组中来选择忽略删除和恢复。
为了更好地格式化 deleted_at
条目的输出,您可以使用 isEmpty
格式化器(请参阅格式化输出以获取此示例。)
更多控制
无疑,您会希望只存储模型某些字段的修订历史记录的情况,这以两种不同的方式支持。在您的模型中,您可以选择显式指定要跟踪的字段,所有其他字段将被忽略
protected $keepRevisionOf = array( 'title' );
或者,您可以指定显式不希望跟踪的字段。所有其他字段将被跟踪。
protected $dontKeepRevisionOf = array( 'category_id' );
设置
$keepRevisionOf
优先于$dontKeepRevisionOf
格式输出
您可以使用
eloquent 访问器
在模型中继续使用(并且鼓励使用)来设置值的输出,请参阅laravel 文档以获取有关访问器的更多信息。以下文档因此已弃用
在您想控制值输出格式的情况下,例如布尔字段,您可以在模型中的 $revisionFormattedFields
数组中设置它们。例如:
protected $revisionFormattedFields = array( 'title' => 'string:<strong>%s</strong>', 'public' => 'boolean:No|Yes', '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
是否为空
这是基于布尔值的,但它不是检查真或假值,而是检查值是否为 null 或空字符串。
isEmpty:No|Yes
它也可以接受 %s
,如果您想输出值,以下示例将显示“Nothing”如果值为空,或者如果存在实际值则显示该值
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
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()。
未知或无效的外键作为修订
在旧值或新版本的值是不再存在的外键或确实是null的情况下,您可以在模型中设置两个变量来控制这些情况下的输出
protected $revisionNullString = 'nothing'; protected $revisionUnknownString = 'unknown';
disableRevisionField()
有时暂时禁用可修订字段可能很有用,如果您想保存更新但不需要记录更改。
$object->disableRevisionField('title'); // Disables title
或者
$object->disableRevisionField(array('title', 'content')); // Disables title and content
贡献
欢迎贡献;为了保持有序,所有错误和请求都应在主项目的GitHub issues标签中打开,网址为venturecraft/revisionable/issues
所有拉取请求都应提交到develop分支,以便在合并到master分支之前进行测试。
遇到问题了吗?
如果您在使用此包时遇到问题,可能有人已经遇到了相同的问题。您可以在以下两个地方查找常见问题的答案
如果您更喜欢在公共场合在StackOverflow上发布您的问题,请使用'revisionable'标签。