rockerkk / revisionable-mongodb
无需思考即可为您的模型保存修订历史,作为Laravel和mongoDB的包创建
Requires
- php: >=5.4.0
- illuminate/support: ~4.0|~5.0|~5.1|^6.0|^7.0|^8.0
- jenssegers/mongodb: >=3.0.0
- laravel/framework: ~5.4|^6.0|^7.0|^8.0
Requires (Dev)
- orchestra/testbench: ~3.0
- dev-master
- 1.36.0
- 1.35.0
- 1.34.0
- 1.33.0
- 1.32.0
- 1.31.1
- 1.31.0
- 1.30.1
- 1.29.1
- 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 not auto-updated.
Last update: 2024-09-28 02:48:01 UTC
README
在项目中为任何模型保留修订历史,而不必为此做任何工作,不是很好吗?只需将RevisionableTrait特性添加到您的模型中,您就可以立即获得它,并能够显示类似于以下的历史记录:
- Chris将标题从'Something'更改为'Something else'
- Chris将类别从'新闻'更改为'重大新闻'
- Matt将类别从'重大新闻'更改为'新闻'
因此,您不仅可以查看发生的事情的历史,还可以查看是谁做了什么,因此有问责制。
Revisionable是一个Laravel包,允许您无需思考即可为模型保留修订历史。有关背景和信息的更多内容,请参阅此文章
与第三方Auth / Eloquent扩展一起使用
Revisionable支持由以下提供的Auth
(推荐) Revisionable现在也可以作为特性使用,因此您的模型可以继续扩展Eloquent,或任何扩展Eloquent的类(如Ardent)。
安装
Revisionable可以通过composer进行安装,详细信息在packagist,此处。
将以下内容添加到您的项目的composer.json文件中的require部分
"rockerkk/revisionable-mongodb": "1.*",
运行composer update以下载包
php composer.phar update
打开config/app.php并注册所需的服务提供程序(Laravel 5.x)
'providers' => [
Venturecraft\Revisionable\RevisionableServiceProvider::class,
]
发布配置和迁移(Laravel 5.x)
php artisan vendor:publish --provider="Venturecraft\Revisionable\RevisionableServiceProvider"
最后,您还需要在包上运行迁移(Laravel 5.x)
php artisan migrate
Laravel 4.x用户
php artisan migrate --package=rockerkk/revisionable-mongodb
如果您将经常完全迁移上下文(使用
migrate:refresh),您可以选择将迁移文件从包复制到您的app/database文件夹中,并将类名从CreateRevisionsTable更改为类似CreateRevisionTable(不带's',否则您将收到错误消息,表明存在重复的类)
cp vendor/rockerkk/revisionable-mongodb/src/migrations/2013_04_09_062329_create_revisions_table.php database/migrations/
文档
实现
新的基于特性的实现(推荐)
特性需要PHP >= 5.4
对于您想要保留修订历史的任何模型,请包含VentureCraft\Revisionable命名空间,并在您的模型中使用RevisionableTrait,例如:
namespace App; use \Venturecraft\Revisionable\RevisionableTrait; class Article extends \Illuminate\Database\Eloquent\Model { use RevisionableTrait; }
作为一个特性,Revisionable现在可以与标准Eloquent模型一起使用,或与任何扩展Eloquent的类一起使用,例如Ardent。
基于旧类实现
新的基于特质的方法与现有的Revisionable安装向后兼容。您仍然可以使用以下安装说明,这实际上是为特质扩展包装器。
对于您想要保留修订历史的任何模型,请包含VentureCraft\Revisionable命名空间,并在您的模型中使用RevisionableTrait,例如:
use Venturecraft\Revisionable\Revisionable; namespace App; class Article extends Revisionable { }
注意:这也适用于命名空间模型。
实现说明
如果需要,您可以在模型中将 $revisionEnabled 设置为 false 来禁用版本控制。这如果您想暂时禁用版本控制,或者如果您想创建一个继承自Revisionable的基模型,所有模型都继承该模型,但您想关闭某些模型的Revisionable功能,这将很有用。
namespace App; use \Venturecraft\Revisionable\RevisionableTrait; class Article extends \Illuminate\Database\Eloquent\Model { protected $revisionEnabled = false; }
您还可以通过将 $historyLimit 设置为在停止版本控制前要保留的版本数来在 X 次修订后禁用版本控制。
namespace App; use \Venturecraft\Revisionable\RevisionableTrait; class Article extends \Illuminate\Database\Eloquent\Model { protected $revisionEnabled = true; protected $historyLimit = 500; //Stop tracking revisions after 500 changes have been made. }
为了保持历史记录的限制,但如果您想要删除旧版本而不是停止跟踪修订,可以通过设置 $revisionCleanup 来实现这一功能。
namespace App; use \Venturecraft\Revisionable\RevisionableTrait; class Article extends \Illuminate\Database\Eloquent\Model { 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 格式化器(请参阅格式化输出中的示例)。
存储强制删除
默认情况下,模型的强制删除不会作为版本存储。
如果您想将强制删除存储为版本,您可以通过将以下内容添加到模型中来覆盖此行为,将 revisionForceDeleteEnabled 设置为 true
protected $revisionForceDeleteEnabled = true;
在这种情况下,created_at 字段将以键的形式存储,其 oldValue() 值等于模型创建日期,而 newValue() 值等于 null。
注意!请谨慎启用此设置!因为现在保存在版本中的模型已不存在,所以您将无法获取其对象或其关系。
存储创建
默认情况下,新模型的创建不会作为版本存储。只有对模型的后续更改才会存储。
如果您想将创建存储为版本,您可以通过将 revisionCreationsEnabled 设置为 true 来覆盖此行为,并将其添加到您的模型中
protected $revisionCreationsEnabled = true;
更多控制
毫无疑问,会有一些情况您不希望只为模型的某些字段存储版本历史记录,这以两种不同的方式得到支持。在您的模型中,您可以指定您希望显式跟踪的字段,其他字段将被忽略
protected $keepRevisionOf = ['title'];
或者,您可以指定您显式不希望跟踪的字段。其他所有字段都将被跟踪。
protected $dontKeepRevisionOf = ['category_id'];
$keepRevisionOf设置优先于$dontKeepRevisionOf
在版本中存储额外字段
在某些情况下,您可能希望在每个版本中从模型中获取额外的元数据。例如,如果您必须同时跟踪账户和用户。只需创建自己的新迁移来添加您想添加到修订模型中的字段,然后将其添加到您的 config/revisionable.php 中的数组中,如下所示
'additional_fields' => ['account_id', 'permissions_id', 'other_id'],
如果列存在于模型中,它将包含在版本中。
请确保如果您不能保证每个模型都有该列,您在迁移中将该列设置为 nullable()。
事件
每次创建模型版本时都会触发一个事件。您可以监听 revisionable.created,
revisionable.saved 或 revisionable.deleted。
// app/Providers/EventServiceProvider.php public function boot() { parent::boot(); $events->listen('revisionable.*', function($model, $revisions) { // Do something with the revisions or the changed model. dd($model, $revisions); }); }
格式输出
您可以使用
Eloquent 访问器在模型中设置值输出,有关更多信息,请参阅 Laravel 文档。以下文档已过时
在您想控制值输出格式的情况下,例如布尔字段,您可以在模型中设置它们在 $revisionFormattedFields 数组中。例如:
protected $revisionFormattedFields = [ '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 = [ '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
选项
类似于“布尔”,任何文本或数值都可以作为源值(通常标志存储在数据库中)。该格式允许您根据值指定不同的输出。将其视为关联数组,其中键与值之间由点分隔。数组元素由竖线分隔。
options: search.On the search|network.In networks
日期时间
日期时间默认会显示为 Y-m-d H:i:s。在值前加上 datetime:,然后添加您的日期时间格式,例如:
datetime:m/d/Y g:i A
是否为空
这依赖于布尔值,但不是检查真或假值,而是检查值是否为 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(['title', 'content']); // Disables title and content
贡献
鼓励并欢迎贡献;为了保持有序,所有错误和请求应在主项目的GitHub问题标签页中打开,在rockerkk/revisionable-mongodb/issues
所有拉取请求应提交到develop分支,以便在合并到master分支之前进行测试。
遇到麻烦了吗?
如果您在使用此包时遇到麻烦,很可能其他人已经遇到过相同的问题。您可以查找常见问题答案的两个地方是
如果您更愿意在StackOverflow上公开提问,请使用'revisionable'标签。