Laravel package for storing model versions
eribloo/laravel-model-snapshots is a Laravel package for laravel package for storing model versions.
It currently has 3 GitHub stars and 2.484 downloads on Packagist (latest version v0.4.3).
Install it with composer require eribloo/laravel-model-snapshots.
Discover more Laravel packages by eribloo
or browse all Laravel packages to compare alternatives.
Last updated
:warning: Disclaimer
This package is still under development and may change often.
This package allows creating snapshots of models.
While a typical approach of adding a version column is often enough when there is a need of versioning models, this package stores snapshots in dedicated table. This provides better control over snapshotting process and keeps your tables clean.
My motivation while creating this package was to create configurable snapshots only when I need them, in contrast to generating new version with every update, while keeping connection to up-to-date original model.
You can install the package via composer:
composer require eribloo/laravel-model-snapshots
You can publish and run the migrations with:
php artisan vendor:publish --tag="model-snapshots-migrations"
php artisan migrate
You can publish the config file with:
php artisan vendor:publish --tag="model-snapshots-config"
This is the contents of the published config file:
return [
/**
* Snapshot class used. Must implement EriBloo\LaravelModelSnapshots\Contracts\Snapshot interface.
*/
'snapshot_class' => EriBloo\LaravelModelSnapshots\Models\Snapshot::class,
/**
* Versionist class used. Must implement EriBloo\LaravelModelSnapshots\Contracts\Versionist interface.
*/
'versionist_class' => EriBloo\LaravelModelSnapshots\Support\Versionists\IncrementingVersionist::class,
];
You can create snapshot by using a helper snapshot() function:
snapshot(Document::find(1))->commit();
This will snapshot model using default options defined in EriBloo\LaravelModelSnapshots\SnapshotOptions class:
Each snapshot stores an array of model attributes, options that it was created with, version and optional description.
Snapshots provide toModel(bool $fillExcludedAttributes = false) method, that returns model filled with
snapshotted attributes. If optional fillExcludedAttributes option is true, returned model will use current model
attributes as a base, otherwise missing attributes will be null.
Accordingly, if you retrieve collection of snapshots you can use its toModels(bool $fillExcludedAttributes = false)
method to map all snapshots to corresponding classes.
Snapshots have 3 helper methods to revert model, or to create a new one, from its snapshot:
revert() - reverts original model to its snapshotted version, all snapshots created after the one used are deletedbranch() - creates new model from snapshotted version and duplicates all snapshots up to, and including, the one
used, associating them with new modelfork() - creates new model from snapshotted version with no snapshots historyAttributes excluded from snapshotting will be filled with current model values.
In addition, package provides separate table to store snapshot relations with other models. There are morphToMany and
morphToOne relations available that return either Snapshots or Models in HasSnapshotRelations trait.
Options can be defined by creating getSnapshotOptions() method on model:
public function getSnapshotOptions(): SnapshotOptions
{
return SnapshotOptions::defaults();
}
Configurable options include:
withVersionist(Versionist $versionist) - set Versionist usedsnapshotExcept(array $exclude) - exclude attributes from being storedsnapshotHidden(bool $option = true) - store hidden attributessnapshotDuplicate(bool $option = true) - force snapshot even if the same already existsMost can be later overridden while snapshotting using those methods:
version(Closure $closure) - Closure that will receive current Versionist object, so you can access and call its
methods if neededdescription(?string) - add optional short descriptionsetExcept(array $except), appendExcept(array $except), removeExcept(array $except) - modify excluded attributes
listwithHidden(), withoutHidden() - modify if hidden attributes should be snapshottedforceDuplicate(), noDuplicate() - if snapshot should be forced even if duplicate already existsVersionist is a class responsible for determining next snapshot version. There are 2 classes available by default:
IncrementingVersionist - increments versionsSemanticVersionist - keeps versions in major.minor formatIf you would like to create your own versionist class it must implement
EriBloo\LaravelModelSnapshots\Contracts\Versionist with methods:
public function getFirstVersion(): string;
public function getNextVersion(string $version): string;
While no trait is needed to make a snapshot, package provides 2 helper traits for retrieving snapshots:
HasSnapshots - provides snapshots() relationship for retrieving stored snapshots as well as few getters:
getLatestSnapshot()getSnapshotByVersion(string $version) - returns snapshot by specific versiongetSnapshotByDate(DateTimeImmutable $date) - returns last snapshot created before dateHasSnapshotRelations - provides relationship methods for creating connections with snapshots:
morphSnapshots(string $snapshotClass) - helper morphToManymorphSnapshot(string $snapshotClass) - helper morphToOnemorphSnapshotAsModels(string $snapshotClass) - morphToMany that returns snapshots with toModels(false)
appliedmorphSnapshotAsModel(string $snapshotClass) - morphToOne that returns snapshot with toModel(false)
appliedThere are a few events that get dispatched:
SnapshotCommitted - dispatched when new snapshot is committed, but not when duplicate is foundSnapshotReverted - dispatched when snapshot is revertedSnapshotBranched - dispatched when new snapshot branch is createdSnapshotForked - dispatched when snapshot is forkedcomposer test
Please see CHANGELOG for more information on what has changed recently.
The MIT License (MIT). Please see License File for more information.